[PATCH] [MC] Use the non-EH register mapping in the debug_frame section.
Jim Grosbach
grosbach at apple.com
Thu Feb 12 13:22:56 PST 2015
Oof. The patch itself seems reasonable. I tend to agree with your thought that it may not be a root cause. Do you have any ideas about what a deeper solution would look like?
-Jim
> On Feb 12, 2015, at 8:32 AM, Frederic Riss <friss at apple.com> wrote:
>
> Hi grosbach,
>
> On 32bits x86 Darwin, the register mappings for the eh_frane and
> debug_frame sections are different. Thus the same CFI instructions
> should result in different registers in the object file. The
> problem isn't target specific though, but it requires that the
> mappings for EH register numbers be different from the standard
> Dwarf one.
>
> The patch is really ugly. The CFI instructions are emitted with
> register operands that are already Dwarf EH register numbers,
> allthough they will be used to emit both EH and non-EH frame
> descriptions. I first thought the right solution was to encode
> LLVM register numbers in the CFI instructions and do the
> conversion at object emission time. This however breaks a lot
> of tests that where the .cfi_* asm directives are tested (which
> means it would break targets not using the integrated assembler).
>
> What this patch does instead is to do a double conversion when
> emitting the debug_frame section. Knowing the CFI instruction
> references EH reg numbers, it converts them back to LLVM reg num
> and again back to the correct Dwarf mapping.
>
> I'll add a test, but I first wanted to reach out for opinions
> as this looks like a bandaid rahter than a fix.
>
> Fixes PR22363.
>
> http://reviews.llvm.org/D7593
>
> Files:
> lib/MC/MCDwarf.cpp
>
> Index: lib/MC/MCDwarf.cpp
> ===================================================================
> --- lib/MC/MCDwarf.cpp
> +++ lib/MC/MCDwarf.cpp
> @@ -1045,11 +1045,16 @@
> void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
> const MCCFIInstruction &Instr) {
> int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
> + auto *MRI = Streamer.getContext().getRegisterInfo();
>
> switch (Instr.getOperation()) {
> case MCCFIInstruction::OpRegister: {
> unsigned Reg1 = Instr.getRegister();
> unsigned Reg2 = Instr.getRegister2();
> + if (!IsEH) {
> + Reg1 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg1, true), false);
> + Reg2 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg2, true), false);
> + }
> Streamer.EmitIntValue(dwarf::DW_CFA_register, 1);
> Streamer.EmitULEB128IntValue(Reg1);
> Streamer.EmitULEB128IntValue(Reg2);
> @@ -1082,17 +1087,23 @@
> return;
> }
> case MCCFIInstruction::OpDefCfa: {
> + unsigned Reg = Instr.getRegister();
> + if (!IsEH)
> + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
> Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
> - Streamer.EmitULEB128IntValue(Instr.getRegister());
> + Streamer.EmitULEB128IntValue(Reg);
> CFAOffset = -Instr.getOffset();
> Streamer.EmitULEB128IntValue(CFAOffset);
>
> return;
> }
>
> case MCCFIInstruction::OpDefCfaRegister: {
> + unsigned Reg = Instr.getRegister();
> + if (!IsEH)
> + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
> Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
> - Streamer.EmitULEB128IntValue(Instr.getRegister());
> + Streamer.EmitULEB128IntValue(Reg);
>
> return;
> }
> @@ -1103,6 +1114,9 @@
> Instr.getOperation() == MCCFIInstruction::OpRelOffset;
>
> unsigned Reg = Instr.getRegister();
> + if (!IsEH)
> + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
> +
> int Offset = Instr.getOffset();
> if (IsRelative)
> Offset -= CFAOffset;
> @@ -1136,6 +1150,8 @@
> }
> case MCCFIInstruction::OpRestore: {
> unsigned Reg = Instr.getRegister();
> + if (!IsEH)
> + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
> Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
> return;
> }
> @@ -1290,10 +1306,10 @@
> if (CIEVersion == 1) {
> assert(MRI->getRARegister() <= 255 &&
> "DWARF 2 encodes return_address_register in one byte");
> - streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true), 1);
> + streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), IsEH), 1);
> } else {
> streamer.EmitULEB128IntValue(
> - MRI->getDwarfRegNum(MRI->getRARegister(), true));
> + MRI->getDwarfRegNum(MRI->getRARegister(), IsEH));
> }
>
> // Augmentation Data Length (optional)
>
> EMAIL PREFERENCES
> http://reviews.llvm.org/settings/panel/emailpreferences/
> <D7593.19836.patch>
More information about the llvm-commits
mailing list