[lld] r285680 - Allow fetching source line, when multiple "AX" sections present

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 1 02:17:51 PDT 2016


Author: evgeny777
Date: Tue Nov  1 04:17:50 2016
New Revision: 285680

URL: http://llvm.org/viewvc/llvm-project?rev=285680&view=rev
Log:
Allow fetching source line, when multiple "AX" sections present

Differential revision: https://reviews.llvm.org/D26070

Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/test/ELF/Inputs/undef-debug.s
    lld/trunk/test/ELF/undef.s

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=285680&r1=285679&r2=285680&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Tue Nov  1 04:17:50 2016
@@ -23,6 +23,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/LTO/LTO.h"
 #include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -36,13 +37,31 @@ using namespace lld::elf;
 
 std::vector<InputFile *> InputFile::Pool;
 
-template <class ELFT> DIHelper<ELFT>::DIHelper(elf::InputFile *F) {
+namespace {
+// In ELF object file all section addresses are zero. If we have multiple
+// .text sections (when using -ffunction-section or comdat group) then
+// LLVM DWARF parser will not be able to parse .debug_line correctly, unless
+// we assign each section some unique address. This callback method assigns
+// each section an address equal to its offset in ELF object file.
+class ObjectInfo : public LoadedObjectInfo {
+public:
+  uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override {
+    return static_cast<const ELFSectionRef &>(Sec).getOffset();
+  }
+  std::unique_ptr<LoadedObjectInfo> clone() const override {
+    return std::unique_ptr<LoadedObjectInfo>();
+  }
+};
+}
+
+template <class ELFT> DIHelper<ELFT>::DIHelper(InputFile *F) {
   Expected<std::unique_ptr<object::ObjectFile>> Obj =
       object::ObjectFile::createObjectFile(F->MB);
   if (!Obj)
     return;
 
-  DWARFContextInMemory Dwarf(*Obj.get());
+  ObjectInfo ObjInfo;
+  DWARFContextInMemory Dwarf(*Obj.get(), &ObjInfo);
   DwarfLine.reset(new DWARFDebugLine(&Dwarf.getLineSection().Relocs));
   DataExtractor LineData(Dwarf.getLineSection().Data,
                          ELFT::TargetEndianness == support::little,
@@ -55,7 +74,9 @@ template <class ELFT> DIHelper<ELFT>::DI
 
 template <class ELFT> DIHelper<ELFT>::~DIHelper() {}
 
-template <class ELFT> std::string DIHelper<ELFT>::getLineInfo(uintX_t Offset) {
+template <class ELFT>
+std::string DIHelper<ELFT>::getLineInfo(InputSectionBase<ELFT> *S,
+                                        uintX_t Offset) {
   if (!DwarfLine)
     return "";
 
@@ -65,7 +86,12 @@ template <class ELFT> std::string DIHelp
   const DWARFDebugLine::LineTable *LineTbl = DwarfLine->getLineTable(0);
   if (!LineTbl)
     return "";
-  LineTbl->getFileLineInfoForAddress(Offset, nullptr, Spec.FLIKind, LineInfo);
+
+  // Use fake address calcuated by adding section file offset and offset in
+  // section.
+  // See comments for ObjectInfo class
+  LineTbl->getFileLineInfoForAddress(S->Offset + Offset, nullptr, Spec.FLIKind,
+                                     LineInfo);
   return LineInfo.Line != 0
              ? LineInfo.FileName + " (" + std::to_string(LineInfo.Line) + ")"
              : "";

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=285680&r1=285679&r2=285680&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Tue Nov  1 04:17:50 2016
@@ -69,7 +69,7 @@ template <class ELFT> class DIHelper {
 public:
   DIHelper(InputFile *F);
   ~DIHelper();
-  std::string getLineInfo(uintX_t Offset);
+  std::string getLineInfo(InputSectionBase<ELFT> *S, uintX_t Offset);
 
 private:
   std::unique_ptr<llvm::DWARFDebugLine> DwarfLine;

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=285680&r1=285679&r2=285680&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Nov  1 04:17:50 2016
@@ -75,7 +75,9 @@ InputSectionBase<ELFT>::InputSectionBase
                                          Kind SectionKind)
     : InputSectionBase(File, Hdr->sh_flags, Hdr->sh_type, Hdr->sh_entsize,
                        Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
-                       getSectionContents(File, Hdr), Name, SectionKind) {}
+                       getSectionContents(File, Hdr), Name, SectionKind) {
+  this->Offset = Hdr->sh_offset;
+}
 
 template <class ELFT> size_t InputSectionBase<ELFT>::getSize() const {
   if (auto *D = dyn_cast<InputSection<ELFT>>(this))

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=285680&r1=285679&r2=285680&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Tue Nov  1 04:17:50 2016
@@ -88,6 +88,7 @@ protected:
 public:
   // These corresponds to the fields in Elf_Shdr.
   uintX_t Flags;
+  uintX_t Offset = 0;
   uintX_t Entsize;
   uint32_t Type;
   uint32_t Link;

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=285680&r1=285679&r2=285680&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Tue Nov  1 04:17:50 2016
@@ -544,7 +544,7 @@ static std::string getLocation(SymbolBod
   ObjectFile<ELFT> *File = S.getFile();
 
   // First check if we can get desired values from debugging information.
-  std::string LineInfo = File->getDIHelper()->getLineInfo(Offset);
+  std::string LineInfo = File->getDIHelper()->getLineInfo(&S, Offset);
   if (!LineInfo.empty())
     return LineInfo;
 

Modified: lld/trunk/test/ELF/Inputs/undef-debug.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/undef-debug.s?rev=285680&r1=285679&r2=285680&view=diff
==============================================================================
--- lld/trunk/test/ELF/Inputs/undef-debug.s (original)
+++ lld/trunk/test/ELF/Inputs/undef-debug.s Tue Nov  1 04:17:50 2016
@@ -1,3 +1,11 @@
 .file 1 "undef-debug.s"
 .loc 1 3
         .quad zed3
+
+.section .text.1,"ax"
+.loc 1 7
+        .quad zed4
+
+.section .text.2,"ax"
+.loc 1 11
+        .quad zed5

Modified: lld/trunk/test/ELF/undef.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/undef.s?rev=285680&r1=285679&r2=285680&view=diff
==============================================================================
--- lld/trunk/test/ELF/undef.s (original)
+++ lld/trunk/test/ELF/undef.s Tue Nov  1 04:17:50 2016
@@ -10,6 +10,8 @@
 # CHECK: error: undef.s (.text+0x10): undefined symbol 'foo(int)'
 # CHECK: error: {{.*}}2.a({{.*}}.o) (.text+0x0): undefined symbol 'zed2'
 # CHECK: error: undef-debug.s (3): undefined symbol 'zed3'
+# CHECK: error: undef-debug.s (7): undefined symbol 'zed4'
+# CHECK: error: undef-debug.s (11): undefined symbol 'zed5'
 
 # RUN: not ld.lld %t.o %t2.a -o %t.exe -no-demangle 2>&1 | \
 # RUN:   FileCheck -check-prefix=NO-DEMANGLE %s




More information about the llvm-commits mailing list