Two functions in DwarfDebug, addBlockByrefAddress() and
addComplexAddress(), contain this snippet of code:
// Decode the original location, and use that as the start of the byref
// variable's location.
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
if (Location.isReg()) {
if (Reg < 32)
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
else {
Reg = Reg - dwarf::DW_OP_reg0;
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
}
} else {
if (Reg < 32)
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
else {
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
}
addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
}
What's going on in the 'else' block of the first nested 'if'
(where
Location.isReg() && Reg >=32)? It looks wrong to me.
If you expand out the opcode parameter, you get:
Opcode = DW_OP_breg0 + Reg
= DW_OP_breg0 + (RegOriginal - DW_OP_reg0)
= RegOriginal + (DW_OP_breg0 - DW_OP_reg0)
= RegOriginal + (0x70 - 0x50)
= RegOriginal + 0x20
= RegOriginal + DW_OP_not
Since we know that RegOriginal >= 32, the opcode that gets generated
is one that has a value >= 0x40, which is DW_OP_lit16.
There is a very similar snippet in the addAddress() function. It uses
the DW_OP_regx opcode to encode the register number:
// ...
if (Location.isReg()) {
if (Reg < 32) {
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
} else {
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
}
} else {
// ...
Should addBlockByrefAddress() and addComplexAddress() be doing the same?
-Ken