summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorOliver Stannard <oliver.stannard@arm.com>2014-11-03 12:02:51 +0000
committerOliver Stannard <oliver.stannard@arm.com>2014-11-03 12:02:51 +0000
commit652ec6ee895fb9f5cf7a1e3c9d7f6996f68be132 (patch)
tree74e976ac90417eca54415e2eb31ecf140841300f /llvm/lib
parent2fdec7d71a6ec85e9264164759da93c42a065b37 (diff)
downloadbcm5719-llvm-652ec6ee895fb9f5cf7a1e3c9d7f6996f68be132.tar.gz
bcm5719-llvm-652ec6ee895fb9f5cf7a1e3c9d7f6996f68be132.zip
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. llvm-svn: 221150
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/ARMException.cpp2
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp2
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp6
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp11
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp11
-rw-r--r--llvm/lib/MC/MCStreamer.cpp8
6 files changed, 26 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
index 251f5effd6b..e79ede9a5ae 100644
--- a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
@@ -66,7 +66,7 @@ void ARMException::beginFunction(const MachineFunction *MF) {
"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);
}
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
index 74215aa695d..b8051fee9fa 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
@@ -102,7 +102,7 @@ void DwarfCFIException::beginFunction(const MachineFunction *MF) {
if (!shouldEmitPersonality && !shouldEmitMoves)
return;
- Asm->OutStreamer.EmitCFIStartProc(/*IsSimple=*/false);
+ Asm->OutStreamer.EmitCFIStartProc(/*IsSimple=*/false, Asm->CurrentFnSym);
// Indicate personality routine, if any.
if (!shouldEmitPersonality)
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index f60c7fc5041..9e100333e9b 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -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 EH, bool Debug) {
EmitEOL();
}
-void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
+void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
+ MCSymbol *FuncSym) {
OS << "\t.cfi_startproc";
if (Frame.IsSimple)
OS << " simple";
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 21e68678e75..17371a28508 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -128,10 +128,13 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
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) {
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index de7d96129f1..5a56094a3c7 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -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, MCContext &_Ctx, MCStreamer &_Out,
: 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(ParseStatementInfo &Info,
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::parseDirectiveCFIStartProc() {
if (parseIdentifier(Simple) || Simple != "simple")
return TokError("unexpected token in .cfi_startproc directive");
- getStreamer().EmitCFIStartProc(!Simple.empty());
+ getStreamer().EmitCFIStartProc(!Simple.empty(), LastFuncSymbol);
return false;
}
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index f11ee669b4b..23e816c24bf 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -211,14 +211,14 @@ void MCStreamer::EmitCFISections(bool EH, bool Debug) {
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 IsSimple) {
DwarfFrameInfos.push_back(Frame);
}
-void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
-}
+void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame,
+ MCSymbol *FuncSym) {}
void MCStreamer::EmitCFIEndProc() {
EnsureValidDwarfFrame();
OpenPOWER on IntegriCloud