[llvm] r221150 - Emit .eh_frame with relocations to functions, rather than sections

Eric Christopher echristo at gmail.com
Mon Nov 3 18:46:58 PST 2014


FWIW I don't like that we're using "last emitted label" to track this. It
means that we could start failing if someone emitted a label between the
function label and the cfi directive and we wouldn't know why it's failing.

I see you've reverted it for the time being, but before recommitting could
you try to organize this a bit differently?

Thanks!

-eric

On Mon Nov 03 2014 at 4:18:30 AM Oliver Stannard <oliver.stannard at arm.com>
wrote:

> Author: olista01
> Date: Mon Nov  3 06:02:51 2014
> New Revision: 221150
>
> URL: http://llvm.org/viewvc/llvm-project?rev=221150&view=rev
> Log:
> 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.
>
>
> Modified:
>     llvm/trunk/include/llvm/MC/MCObjectStreamer.h
>     llvm/trunk/include/llvm/MC/MCStreamer.h
>     llvm/trunk/lib/CodeGen/AsmPrinter/ARMException.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
>     llvm/trunk/lib/MC/MCAsmStreamer.cpp
>     llvm/trunk/lib/MC/MCObjectStreamer.cpp
>     llvm/trunk/lib/MC/MCParser/AsmParser.cpp
>     llvm/trunk/lib/MC/MCStreamer.cpp
>     llvm/trunk/test/DebugInfo/AArch64/eh_frame.s
>     llvm/trunk/test/DebugInfo/AArch64/eh_frame_personality.ll
>
> Modified: llvm/trunk/include/llvm/MC/MCObjectStreamer.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/MC/MCObjectStreamer.h?rev=221150&r1=221149&r2=221150&view=diff
> ============================================================
> ==================
> --- llvm/trunk/include/llvm/MC/MCObjectStreamer.h (original)
> +++ llvm/trunk/include/llvm/MC/MCObjectStreamer.h Mon Nov  3 06:02:51 2014
> @@ -41,7 +41,8 @@ class MCObjectStreamer : public MCStream
>    SmallVector<MCSymbolData *, 2> PendingLabels;
>
>    virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&)
> = 0;
> -  void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
> +  void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
> +                            MCSymbol *FuncSym) override;
>    void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
>
>    // If any labels have been emitted but not assigned fragments, ensure
> that
>
> Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/MC/MCStreamer.h?rev=221150&r1=221149&r2=221150&view=diff
> ============================================================
> ==================
> --- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
> +++ llvm/trunk/include/llvm/MC/MCStreamer.h Mon Nov  3 06:02:51 2014
> @@ -198,7 +198,7 @@ class MCStreamer {
>  protected:
>    MCStreamer(MCContext &Ctx);
>
> -  virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
> +  virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame, MCSymbol
> *FuncSym);
>    virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame);
>
>    WinEH::FrameInfo *getCurrentWinFrameInfo() {
> @@ -661,7 +661,7 @@ public:
>
>    virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID);
>    virtual void EmitCFISections(bool EH, bool Debug);
> -  void EmitCFIStartProc(bool IsSimple);
> +  void EmitCFIStartProc(bool IsSimple, MCSymbol *FuncSym);
>    void EmitCFIEndProc();
>    virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
>    virtual void EmitCFIDefCfaOffset(int64_t Offset);
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/ARMException.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> CodeGen/AsmPrinter/ARMException.cpp?rev=221150&
> r1=221149&r2=221150&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/ARMException.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/ARMException.cpp Mon Nov  3
> 06:02:51 2014
> @@ -66,7 +66,7 @@ void ARMException::beginFunction(const M
>           "non-EH CFI not yet supported in prologue with EHABI lowering");
>    if (MoveType == AsmPrinter::CFI_M_Debug) {
>      shouldEmitCFI = true;
> -    Asm->OutStreamer.EmitCFIStartProc(false);
> +    Asm->OutStreamer.EmitCFIStartProc(false, Asm->CurrentFnSym);
>    }
>  }
>
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> CodeGen/AsmPrinter/DwarfCFIException.cpp?rev=221150&r1=221149&r2=221150&
> view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp Mon Nov  3
> 06:02:51 2014
> @@ -102,7 +102,7 @@ void DwarfCFIException::beginFunction(co
>    if (!shouldEmitPersonality && !shouldEmitMoves)
>      return;
>
> -  Asm->OutStreamer.EmitCFIStartProc(/*IsSimple=*/false);
> +  Asm->OutStreamer.EmitCFIStartProc(/*IsSimple=*/false,
> Asm->CurrentFnSym);
>
>    // Indicate personality routine, if any.
>    if (!shouldEmitPersonality)
>
> Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/
> MCAsmStreamer.cpp?rev=221150&r1=221149&r2=221150&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
> +++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Mon Nov  3 06:02:51 2014
> @@ -54,7 +54,8 @@ private:
>    unsigned UseDwarfDirectory : 1;
>
>    void EmitRegisterName(int64_t Register);
> -  void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
> +  void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
> +                            MCSymbol *FuncSym) override;
>    void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
>
>  public:
> @@ -925,7 +926,8 @@ void MCAsmStreamer::EmitCFISections(bool
>    EmitEOL();
>  }
>
> -void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
> +void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
> +                                         MCSymbol *FuncSym) {
>    OS << "\t.cfi_startproc";
>    if (Frame.IsSimple)
>      OS << " simple";
>
> Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/
> MCObjectStreamer.cpp?rev=221150&r1=221149&r2=221150&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original)
> +++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Mon Nov  3 06:02:51 2014
> @@ -128,10 +128,13 @@ void MCObjectStreamer::EmitValueImpl(con
>    DF->getContents().resize(DF->getContents().size() + Size, 0);
>  }
>
> -void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
> -  // We need to create a local symbol to avoid relocations.
> -  Frame.Begin = getContext().CreateTempSymbol();
> -  EmitLabel(Frame.Begin);
> +void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
> +                                            MCSymbol *FuncSym) {
> +  if (!FuncSym) {
> +    FuncSym = getContext().CreateTempSymbol();
> +    EmitLabel(FuncSym);
> +  }
> +  Frame.Begin = FuncSym;
>  }
>
>  void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
>
> Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/
> MCParser/AsmParser.cpp?rev=221150&r1=221149&r2=221150&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
> +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Mon Nov  3 06:02:51 2014
> @@ -172,6 +172,9 @@ private:
>    /// \brief Are we parsing ms-style inline assembly?
>    bool ParsingInlineAsm;
>
> +  /// \brief The last symbol we emitted, used for call frame information.
> +  MCSymbol *LastFuncSymbol;
> +
>  public:
>    AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
>              const MCAsmInfo &MAI);
> @@ -491,7 +494,8 @@ AsmParser::AsmParser(SourceMgr &_SM, MCC
>      : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
>        PlatformParser(nullptr), CurBuffer(_SM.getMainFileID()),
>        MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0),
> -      AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
> +      AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false),
> +      LastFuncSymbol(nullptr) {
>    // Save the old handler.
>    SavedDiagHandler = SrcMgr.getDiagHandler();
>    SavedDiagContext = SrcMgr.getDiagContext();
> @@ -1305,6 +1309,9 @@ bool AsmParser::parseStatement(ParseStat
>      if (!ParsingInlineAsm)
>        Out.EmitLabel(Sym);
>
> +    // Record the symbol, so that it can be used for call frame
> information
> +    LastFuncSymbol = Sym;
> +
>      // If we are generating dwarf for assembly source files then gather
> the
>      // info to make a dwarf label entry for this label if needed.
>      if (getContext().getGenDwarfForAssembly())
> @@ -2961,7 +2968,7 @@ bool AsmParser::parseDirectiveCFIStartPr
>      if (parseIdentifier(Simple) || Simple != "simple")
>        return TokError("unexpected token in .cfi_startproc directive");
>
> -  getStreamer().EmitCFIStartProc(!Simple.empty());
> +  getStreamer().EmitCFIStartProc(!Simple.empty(), LastFuncSymbol);
>    return false;
>  }
>
>
> Modified: llvm/trunk/lib/MC/MCStreamer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/
> MCStreamer.cpp?rev=221150&r1=221149&r2=221150&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/MC/MCStreamer.cpp (original)
> +++ llvm/trunk/lib/MC/MCStreamer.cpp Mon Nov  3 06:02:51 2014
> @@ -211,14 +211,14 @@ void MCStreamer::EmitCFISections(bool EH
>    assert(EH || Debug);
>  }
>
> -void MCStreamer::EmitCFIStartProc(bool IsSimple) {
> +void MCStreamer::EmitCFIStartProc(bool IsSimple, MCSymbol *FuncSym) {
>    MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
>    if (CurFrame && !CurFrame->End)
>      report_fatal_error("Starting a frame before finishing the previous
> one!");
>
>    MCDwarfFrameInfo Frame;
>    Frame.IsSimple = IsSimple;
> -  EmitCFIStartProcImpl(Frame);
> +  EmitCFIStartProcImpl(Frame, FuncSym);
>
>    const MCAsmInfo* MAI = Context.getAsmInfo();
>    if (MAI) {
> @@ -233,8 +233,8 @@ void MCStreamer::EmitCFIStartProc(bool I
>    DwarfFrameInfos.push_back(Frame);
>  }
>
> -void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
> -}
> +void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
> +                                      MCSymbol *FuncSym) {}
>
>  void MCStreamer::EmitCFIEndProc() {
>    EnsureValidDwarfFrame();
>
> Modified: llvm/trunk/test/DebugInfo/AArch64/eh_frame.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> DebugInfo/AArch64/eh_frame.s?rev=221150&r1=221149&r2=221150&view=diff
> ============================================================
> ==================
> --- llvm/trunk/test/DebugInfo/AArch64/eh_frame.s (original)
> +++ llvm/trunk/test/DebugInfo/AArch64/eh_frame.s Mon Nov  3 06:02:51 2014
> @@ -1,5 +1,6 @@
>  // RUN: llvm-mc -triple aarch64-none-linux-gnu -filetype=obj %s -o %t
> -// RUN: llvm-objdump -s %t | FileCheck %s
> +// RUN: llvm-objdump -s %t | FileCheck %s --check-prefix=CHECK
> +// RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC
>          .text
>          .globl foo
>          .type foo, at function
> @@ -46,3 +47,11 @@ foo:
>  // 00000000: PC begin for this FDE is at 00000000 (relocation is applied
> here)
>  // 04000000: FDE applies up to PC begin+0x14
>  // 00: Augmentation string length 0 for this FDE
> +
> +
> +// Check the relocations applied to the .eh_frame section.
> +// These must not contain section-relative relocations to a section which
> +// is part of a group, as it could be removed.
> +// RELOC: Section ({{[0-9]+}}) .rela.eh_frame {
> +// RELOC-NEXT:   0x{{[0-9A-F]+}} R_AARCH64_PREL32 foo 0x0
> +// RELOC-NEXT: }
>
> Modified: llvm/trunk/test/DebugInfo/AArch64/eh_frame_personality.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> DebugInfo/AArch64/eh_frame_personality.ll?rev=221150&r1=
> 221149&r2=221150&view=diff
> ============================================================
> ==================
> --- llvm/trunk/test/DebugInfo/AArch64/eh_frame_personality.ll (original)
> +++ llvm/trunk/test/DebugInfo/AArch64/eh_frame_personality.ll Mon Nov  3
> 06:02:51 2014
> @@ -1,5 +1,6 @@
>  ; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu %s
> -filetype=obj -o %t
> -; RUN: llvm-objdump -s %t | FileCheck %s
> +; RUN: llvm-objdump -s %t | FileCheck %s --check-prefix=CHECK
> +; RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC
>
>  declare i32 @__gxx_personality_v0(...)
>
> @@ -44,3 +45,12 @@ clean:
>  ; 00: Second part of aug (language-specific data): absolute pointer
> format used
>  ; 1b: pointer format: pc-relative signed 4-byte. Just like GNU.
>  ; 0c 1f 00: Initial instructions ("DW_CFA_def_cfa x31 ofs 0" in this case)
> +
> +; Check the relocations applied to the .eh_frame section.
> +; These must not contain section-relative relocations to a section which
> +; is part of a group, as it could be removed.
> +; RELOC: Section ({{[0-9]+}}) .rela.eh_frame {
> +; RELOC-NEXT:   0x{{[0-9A-F]+}} R_AARCH64_ABS64 __gxx_personality_v0 0x0
> +; RELOC-NEXT:   0x{{[0-9A-F]+}} R_AARCH64_PREL32 foo 0x0
> +; RELOC-NEXT:   0x{{[0-9A-F]+}} R_AARCH64_ABS64 .gcc_except_table 0x0
> +; RELOC-NEXT: }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141104/8468ab46/attachment.html>


More information about the llvm-commits mailing list