llvm.org GIT mirror llvm / b63d71e
Emit .eh_frame with relocations to functions, rather than sections When LLVM emits DWARF call frame information, it currently creates a local, section-relative symbol in the code section, which is pointed to by a relocation on the .eh_frame section. However, for C++ we emit some functions in section groups, and the SysV ABI has some rules to make it easier to remove these sections (http://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_group_rules): A symbol table entry with STB_LOCAL binding that is defined relative to one of a group's sections, and that is contained in a symbol table section that is not part of the group, must be discarded if the group members are discarded. References to this symbol table entry from outside the group are not allowed. This means that we need to use the function symbol for the relocation, not a temporary symbol. There was a comment in the code claiming that the local symbol was used to avoid creating a relocation, but a relocation must be created anyway as the code and CFI are in different sections. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221150 91177308-0d34-0410-b5e6-96231b3b80d8 Oliver Stannard 6 years ago
10 changed file(s) with 51 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
4040 SmallVector PendingLabels;
4141
4242 virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
43 void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
43 void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
44 MCSymbol *FuncSym) override;
4445 void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
4546
4647 // If any labels have been emitted but not assigned fragments, ensure that
197197 protected:
198198 MCStreamer(MCContext &Ctx);
199199
200 virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
200 virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame, MCSymbol *FuncSym);
201201 virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame);
202202
203203 WinEH::FrameInfo *getCurrentWinFrameInfo() {
660660
661661 virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID);
662662 virtual void EmitCFISections(bool EH, bool Debug);
663 void EmitCFIStartProc(bool IsSimple);
663 void EmitCFIStartProc(bool IsSimple, MCSymbol *FuncSym);
664664 void EmitCFIEndProc();
665665 virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
666666 virtual void EmitCFIDefCfaOffset(int64_t Offset);
6565 "non-EH CFI not yet supported in prologue with EHABI lowering");
6666 if (MoveType == AsmPrinter::CFI_M_Debug) {
6767 shouldEmitCFI = true;
68 Asm->OutStreamer.EmitCFIStartProc(false);
68 Asm->OutStreamer.EmitCFIStartProc(false, Asm->CurrentFnSym);
6969 }
7070 }
7171
101101 if (!shouldEmitPersonality && !shouldEmitMoves)
102102 return;
103103
104 Asm->OutStreamer.EmitCFIStartProc(/*IsSimple=*/false);
104 Asm->OutStreamer.EmitCFIStartProc(/*IsSimple=*/false, Asm->CurrentFnSym);
105105
106106 // Indicate personality routine, if any.
107107 if (!shouldEmitPersonality)
5353 unsigned UseDwarfDirectory : 1;
5454
5555 void EmitRegisterName(int64_t Register);
56 void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
56 void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
57 MCSymbol *FuncSym) override;
5758 void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
5859
5960 public:
924925 EmitEOL();
925926 }
926927
927 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
928 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
929 MCSymbol *FuncSym) {
928930 OS << "\t.cfi_startproc";
929931 if (Frame.IsSimple)
930932 OS << " simple";
127127 DF->getContents().resize(DF->getContents().size() + Size, 0);
128128 }
129129
130 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
131 // We need to create a local symbol to avoid relocations.
132 Frame.Begin = getContext().CreateTempSymbol();
133 EmitLabel(Frame.Begin);
130 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
131 MCSymbol *FuncSym) {
132 if (!FuncSym) {
133 FuncSym = getContext().CreateTempSymbol();
134 EmitLabel(FuncSym);
135 }
136 Frame.Begin = FuncSym;
134137 }
135138
136139 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
171171 /// \brief Are we parsing ms-style inline assembly?
172172 bool ParsingInlineAsm;
173173
174 /// \brief The last symbol we emitted, used for call frame information.
175 MCSymbol *LastFuncSymbol;
176
174177 public:
175178 AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
176179 const MCAsmInfo &MAI);
490493 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
491494 PlatformParser(nullptr), CurBuffer(_SM.getMainFileID()),
492495 MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0),
493 AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
496 AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false),
497 LastFuncSymbol(nullptr) {
494498 // Save the old handler.
495499 SavedDiagHandler = SrcMgr.getDiagHandler();
496500 SavedDiagContext = SrcMgr.getDiagContext();
13031307 // Emit the label.
13041308 if (!ParsingInlineAsm)
13051309 Out.EmitLabel(Sym);
1310
1311 // Record the symbol, so that it can be used for call frame information
1312 LastFuncSymbol = Sym;
13061313
13071314 // If we are generating dwarf for assembly source files then gather the
13081315 // info to make a dwarf label entry for this label if needed.
29602967 if (parseIdentifier(Simple) || Simple != "simple")
29612968 return TokError("unexpected token in .cfi_startproc directive");
29622969
2963 getStreamer().EmitCFIStartProc(!Simple.empty());
2970 getStreamer().EmitCFIStartProc(!Simple.empty(), LastFuncSymbol);
29642971 return false;
29652972 }
29662973
210210 assert(EH || Debug);
211211 }
212212
213 void MCStreamer::EmitCFIStartProc(bool IsSimple) {
213 void MCStreamer::EmitCFIStartProc(bool IsSimple, MCSymbol *FuncSym) {
214214 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
215215 if (CurFrame && !CurFrame->End)
216216 report_fatal_error("Starting a frame before finishing the previous one!");
217217
218218 MCDwarfFrameInfo Frame;
219219 Frame.IsSimple = IsSimple;
220 EmitCFIStartProcImpl(Frame);
220 EmitCFIStartProcImpl(Frame, FuncSym);
221221
222222 const MCAsmInfo* MAI = Context.getAsmInfo();
223223 if (MAI) {
232232 DwarfFrameInfos.push_back(Frame);
233233 }
234234
235 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
236 }
235 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
236 MCSymbol *FuncSym) {}
237237
238238 void MCStreamer::EmitCFIEndProc() {
239239 EnsureValidDwarfFrame();
0 // RUN: llvm-mc -triple aarch64-none-linux-gnu -filetype=obj %s -o %t
1 // RUN: llvm-objdump -s %t | FileCheck %s
1 // RUN: llvm-objdump -s %t | FileCheck %s --check-prefix=CHECK
2 // RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC
23 .text
34 .globl foo
45 .type foo,@function
4546 // 00000000: PC begin for this FDE is at 00000000 (relocation is applied here)
4647 // 04000000: FDE applies up to PC begin+0x14
4748 // 00: Augmentation string length 0 for this FDE
49
50
51 // Check the relocations applied to the .eh_frame section.
52 // These must not contain section-relative relocations to a section which
53 // is part of a group, as it could be removed.
54 // RELOC: Section ({{[0-9]+}}) .rela.eh_frame {
55 // RELOC-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_PREL32 foo 0x0
56 // RELOC-NEXT: }
0 ; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu %s -filetype=obj -o %t
1 ; RUN: llvm-objdump -s %t | FileCheck %s
1 ; RUN: llvm-objdump -s %t | FileCheck %s --check-prefix=CHECK
2 ; RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC
23
34 declare i32 @__gxx_personality_v0(...)
45
4344 ; 00: Second part of aug (language-specific data): absolute pointer format used
4445 ; 1b: pointer format: pc-relative signed 4-byte. Just like GNU.
4546 ; 0c 1f 00: Initial instructions ("DW_CFA_def_cfa x31 ofs 0" in this case)
47
48 ; Check the relocations applied to the .eh_frame section.
49 ; These must not contain section-relative relocations to a section which
50 ; is part of a group, as it could be removed.
51 ; RELOC: Section ({{[0-9]+}}) .rela.eh_frame {
52 ; RELOC-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_ABS64 __gxx_personality_v0 0x0
53 ; RELOC-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_PREL32 foo 0x0
54 ; RELOC-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_ABS64 .gcc_except_table 0x0
55 ; RELOC-NEXT: }