summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2018-10-22 21:44:21 +0000
committerVedant Kumar <vsk@apple.com>2018-10-22 21:44:21 +0000
commit74533bd3b80c9e57940e06579b162c7db67d5b9d (patch)
tree7e450efbe51936dfecb72196af0a0d837f09f476 /llvm/lib/CodeGen/AsmPrinter
parentdd1c3df72d33c426d08d20dc0f08b53a9075a7d4 (diff)
downloadbcm5719-llvm-74533bd3b80c9e57940e06579b162c7db67d5b9d.tar.gz
bcm5719-llvm-74533bd3b80c9e57940e06579b162c7db67d5b9d.zip
[DWARF] Use a function-local offset for AT_call_return_pc
Logs provided by @stella.stamenova indicate that on Linux, lldb adds a spurious slide offset to the return PC it loads from AT_call_return_pc attributes (see the list thread: "[PATCH] D50478: Add support for artificial tail call frames"). This patch side-steps the issue by getting rid of the load address calculation in lldb's CallEdge::GetReturnPCAddress. The idea is to have the DWARF writer emit function-local offsets to the instruction after a call. I.e. return-pc = label-after-call-insn - function-entry. LLDB can simply add this offset to the base address of a function to get the return PC. Differential Revision: https://reviews.llvm.org/D53469 llvm-svn: 344960
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp15
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h4
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp12
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h9
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp7
5 files changed, 38 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 580f682b9a6..a362dd40e3b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -125,6 +125,21 @@ MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) {
return LabelsAfterInsn.lookup(MI);
}
+// Return the function-local offset of an instruction.
+const MCExpr *
+DebugHandlerBase::getFunctionLocalOffsetAfterInsn(const MachineInstr *MI) {
+ MCContext &MC = Asm->OutContext;
+
+ MCSymbol *Start = Asm->getFunctionBegin();
+ const auto *StartRef = MCSymbolRefExpr::create(Start, MC);
+
+ MCSymbol *AfterInsn = getLabelAfterInsn(MI);
+ assert(AfterInsn && "Expected label after instruction");
+ const auto *AfterRef = MCSymbolRefExpr::create(AfterInsn, MC);
+
+ return MCBinaryExpr::createSub(AfterRef, StartRef, MC);
+}
+
/// If this type is derived from a base type then return base type size.
uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) {
DIType *Ty = TyRef.resolve();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
index 4b0ce0e3f03..cdf8dc72b07 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
@@ -125,6 +125,10 @@ public:
/// Return Label immediately following the instruction.
MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
+ /// Return the function-local offset of an instruction. A label for the
+ /// instruction \p MI should exist (\ref getLabelAfterInsn).
+ const MCExpr *getFunctionLocalOffsetAfterInsn(const MachineInstr *MI);
+
/// If this type is derived from a base type then return base type size.
static uint64_t getBaseTypeSize(const DITypeRef TyRef);
};
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 81eb0c2aa9e..1d9c1d38a24 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -821,7 +821,7 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
const DISubprogram &CalleeSP,
bool IsTail,
- const MCSymbol *ReturnPC) {
+ const MCExpr *PCOffset) {
// Insert a call site entry DIE within ScopeDIE.
DIE &CallSiteDIE =
createAndAddDIE(dwarf::DW_TAG_call_site, ScopeDIE, nullptr);
@@ -838,8 +838,8 @@ DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
} else {
// Attach the return PC to allow the debugger to disambiguate call paths
// from one function to another.
- assert(ReturnPC && "Missing return PC information for a call");
- addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_return_pc, ReturnPC);
+ assert(PCOffset && "Missing return PC information for a call");
+ addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset);
}
return CallSiteDIE;
}
@@ -1103,6 +1103,12 @@ void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, Form, DIEExpr(Expr));
}
+void DwarfCompileUnit::addAddressExpr(DIE &Die, dwarf::Attribute Attribute,
+ const MCExpr *Expr) {
+ Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr,
+ DIEExpr(Expr));
+}
+
void DwarfCompileUnit::applySubprogramAttributesToDefinition(
const DISubprogram *SP, DIE &SPDie) {
auto *SPDecl = SP->getDeclaration();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 97a944e9b95..13679c37fe5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -210,10 +210,10 @@ public:
/// Construct a call site entry DIE describing a call within \p Scope to a
/// callee described by \p CalleeSP. \p IsTail specifies whether the call is
- /// a tail call. \p ReturnPC must be non-null for non-tail calls and point
- /// to the PC value after the call returns.
+ /// a tail call. \p PCOffset must be non-zero for non-tail calls or be the
+ /// function-local offset to PC value after the call instruction.
DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram &CalleeSP,
- bool IsTail, const MCSymbol *ReturnPC);
+ bool IsTail, const MCExpr *PCOffset);
/// Construct import_module DIE.
DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
@@ -292,6 +292,9 @@ public:
/// Add a Dwarf expression attribute data and value.
void addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr);
+ /// Add an attribute containing an address expression to \p Die.
+ void addAddressExpr(DIE &Die, dwarf::Attribute Attribute, const MCExpr *Expr);
+
void applySubprogramAttributesToDefinition(const DISubprogram *SP,
DIE &SPDie);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 2f14f5464fd..5f91674d9f0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -548,14 +548,15 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
// For tail calls, no return PC information is needed. For regular calls,
// the return PC is needed to disambiguate paths in the call graph which
// could lead to some target function.
- const MCSymbol *ReturnPC = IsTail ? nullptr : getLabelAfterInsn(&MI);
+ const MCExpr *PCOffset =
+ IsTail ? nullptr : getFunctionLocalOffsetAfterInsn(&MI);
- assert((IsTail || ReturnPC) && "Call without return PC information");
+ assert((IsTail || PCOffset) && "Call without return PC information");
LLVM_DEBUG(dbgs() << "CallSiteEntry: " << MF.getName() << " -> "
<< CalleeDecl->getName() << (IsTail ? " [tail]" : "")
<< "\n");
CU.constructCallSiteEntryDIE(ScopeDIE, *CalleeDecl->getSubprogram(),
- IsTail, ReturnPC);
+ IsTail, PCOffset);
}
}
}
OpenPOWER on IntegriCloud