[lld] r372843 - [LLD] [COFF] Resolve source locations for undefined references using dwarf

Martin Storsjo via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 25 04:03:49 PDT 2019


Author: mstorsjo
Date: Wed Sep 25 04:03:48 2019
New Revision: 372843

URL: http://llvm.org/viewvc/llvm-project?rev=372843&view=rev
Log:
[LLD] [COFF] Resolve source locations for undefined references using dwarf

This fixes PR42407.

Differential Revision: https://reviews.llvm.org/D67053

Added:
    lld/trunk/test/COFF/undefined-symbol-dwarf.s
Modified:
    lld/trunk/COFF/CMakeLists.txt
    lld/trunk/COFF/Config.h
    lld/trunk/COFF/PDB.cpp
    lld/trunk/COFF/PDB.h
    lld/trunk/COFF/SymbolTable.cpp

Modified: lld/trunk/COFF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/CMakeLists.txt?rev=372843&r1=372842&r2=372843&view=diff
==============================================================================
--- lld/trunk/COFF/CMakeLists.txt (original)
+++ lld/trunk/COFF/CMakeLists.txt Wed Sep 25 04:03:48 2019
@@ -36,6 +36,7 @@ add_lld_library(lldCOFF
   Object
   Option
   Support
+  Symbolize
   WindowsManifest
 
   LINK_LIBS

Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=372843&r1=372842&r2=372843&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Wed Sep 25 04:03:48 2019
@@ -18,6 +18,12 @@
 #include <set>
 #include <string>
 
+namespace llvm {
+namespace symbolize {
+class LLVMSymbolizer;
+}
+} // namespace llvm
+
 namespace lld {
 namespace coff {
 
@@ -226,6 +232,8 @@ struct Configuration {
   bool swaprunNet = false;
   bool thinLTOEmitImportsFiles;
   bool thinLTOIndexOnly;
+
+  llvm::symbolize::LLVMSymbolizer *symbolizer = nullptr;
 };
 
 extern Configuration *config;

Modified: lld/trunk/COFF/PDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/PDB.cpp?rev=372843&r1=372842&r2=372843&view=diff
==============================================================================
--- lld/trunk/COFF/PDB.cpp (original)
+++ lld/trunk/COFF/PDB.cpp Wed Sep 25 04:03:48 2019
@@ -1800,8 +1800,8 @@ static bool findLineTable(const SectionC
 // Use CodeView line tables to resolve a file and line number for the given
 // offset into the given chunk and return them, or {"", 0} if a line table was
 // not found.
-std::pair<StringRef, uint32_t> coff::getFileLine(const SectionChunk *c,
-                                                 uint32_t addr) {
+std::pair<StringRef, uint32_t> coff::getFileLineCodeView(const SectionChunk *c,
+                                                         uint32_t addr) {
   ExitOnError exitOnErr;
 
   DebugStringTableSubsectionRef cVStrTab;

Modified: lld/trunk/COFF/PDB.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/PDB.h?rev=372843&r1=372842&r2=372843&view=diff
==============================================================================
--- lld/trunk/COFF/PDB.h (original)
+++ lld/trunk/COFF/PDB.h Wed Sep 25 04:03:48 2019
@@ -29,8 +29,8 @@ void createPDB(SymbolTable *symtab,
                llvm::ArrayRef<uint8_t> sectionTable,
                llvm::codeview::DebugInfo *buildId);
 
-std::pair<llvm::StringRef, uint32_t> getFileLine(const SectionChunk *c,
-                                                 uint32_t addr);
+std::pair<llvm::StringRef, uint32_t> getFileLineCodeView(const SectionChunk *c,
+                                                         uint32_t addr);
 }
 }
 

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=372843&r1=372842&r2=372843&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Wed Sep 25 04:03:48 2019
@@ -15,6 +15,7 @@
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
 #include "lld/Common/Timer.h"
+#include "llvm/DebugInfo/Symbolize/Symbolize.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/Object/WindowsMachineFlag.h"
 #include "llvm/Support/Debug.h"
@@ -107,6 +108,30 @@ static std::vector<std::string> getSymbo
   return {res};
 }
 
+static std::pair<StringRef, uint32_t> getFileLineDwarf(const SectionChunk *c,
+                                                       uint32_t addr) {
+  if (!config->symbolizer)
+    config->symbolizer = make<symbolize::LLVMSymbolizer>();
+  Expected<DILineInfo> expectedLineInfo = config->symbolizer->symbolizeCode(
+      *c->file->getCOFFObj(), {addr, c->getSectionNumber() - 1});
+  if (!expectedLineInfo)
+    return {"", 0};
+  const DILineInfo &lineInfo = *expectedLineInfo;
+  if (lineInfo.FileName == DILineInfo::BadString)
+    return {"", 0};
+  return {saver.save(lineInfo.FileName), lineInfo.Line};
+}
+
+static std::pair<StringRef, uint32_t> getFileLine(const SectionChunk *c,
+                                                  uint32_t addr) {
+  // MinGW can optionally use codeview, even if the default is dwarf.
+  std::pair<StringRef, uint32_t> fileLine = getFileLineCodeView(c, addr);
+  // If codeview didn't yield any result, check dwarf in MinGW mode.
+  if (fileLine.first.empty() && config->mingw)
+    fileLine = getFileLineDwarf(c, addr);
+  return fileLine;
+}
+
 // Given a file and the index of a symbol in that file, returns a description
 // of all references to that symbol from that file. If no debug information is
 // available, returns just the name of the file, else one string per actual

Added: lld/trunk/test/COFF/undefined-symbol-dwarf.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/undefined-symbol-dwarf.s?rev=372843&view=auto
==============================================================================
--- lld/trunk/test/COFF/undefined-symbol-dwarf.s (added)
+++ lld/trunk/test/COFF/undefined-symbol-dwarf.s Wed Sep 25 04:03:48 2019
@@ -0,0 +1,100 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple=x86_64-windows-gnu -filetype=obj -o %t.o %s
+# RUN: not lld-link /lldmingw /out:%t.exe %t.o /entry:entry 2>&1 | FileCheck %s
+
+# CHECK: error: undefined symbol: bar()
+# CHECK-NEXT: >>> referenced by /path/to/src/undef.cpp:17
+# CHECK-NEXT: >>>               {{.*}}.o:(entry)
+# CHECK-EMPTY:
+# CHECK-NEXT: error: undefined symbol: foo()
+# CHECK-NEXT: >>> referenced by /path/to/src/undef.cpp:7
+# CHECK-NEXT: >>>               {{.*}}.o:(A::afunc())
+
+        .text
+        .file   "undef.cpp"
+        .file   1 "/path/to/src" "undef.cpp"
+        .globl  entry                   # -- Begin function entry
+entry:                                  # @entry
+.Lfunc_begin0:
+        .loc    1 14 0                  # undef.cpp:14:0
+        subq    $40, %rsp
+.Ltmp0:
+        leaq    32(%rsp), %rcx
+.Ltmp1:
+        .loc    1 16 4 prologue_end     # undef.cpp:16:4
+        callq   _ZN1A5afuncEv
+        .loc    1 17 2                  # undef.cpp:17:2
+        callq   _Z3barv
+        .loc    1 18 1                  # undef.cpp:18:1
+        addq    $40, %rsp
+        retq
+.Ltmp2:
+.Lfunc_end0:
+
+        .def     _ZN1A5afuncEv;
+        .scl    2;
+        .type   32;
+        .endef
+        .section        .text$_ZN1A5afuncEv,"xr",discard,_ZN1A5afuncEv
+        .globl  _ZN1A5afuncEv           # -- Begin function _ZN1A5afuncEv
+        .p2align        1, 0x90
+_ZN1A5afuncEv:                          # @_ZN1A5afuncEv
+.Lfunc_begin1:
+        .loc    1 6 0                   # undef.cpp:6:0
+        .loc    1 7 3 prologue_end      # undef.cpp:7:3
+        jmp     _Z3foov                 # TAILCALL
+.Ltmp3:
+.Lfunc_end1:
+
+        .section        .debug_abbrev,"dr"
+.Lsection_abbrev:
+        .byte   1                       # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   37                      # DW_AT_producer
+        .byte   37                      # DW_FORM_strx1
+        .byte   19                      # DW_AT_language
+        .byte   5                       # DW_FORM_data2
+        .byte   3                       # DW_AT_name
+        .byte   37                      # DW_FORM_strx1
+        .byte   16                      # DW_AT_stmt_list
+        .byte   23                      # DW_FORM_sec_offset
+        .byte   27                      # DW_AT_comp_dir
+        .byte   37                      # DW_FORM_strx1
+        .byte   17                      # DW_AT_low_pc
+        .byte   1                       # DW_FORM_addr
+        .byte   85                      # DW_AT_ranges
+        .byte   23                      # DW_FORM_sec_offset
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   0                       # EOM(3)
+        .section        .debug_info,"dr"
+.Lsection_info:
+.Lcu_begin0:
+        .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+        .short  4                       # DWARF version number
+        .secrel32       .Lsection_abbrev # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .byte   1                       # Abbrev [1] 0xb:0xb0 DW_TAG_compile_unit
+        .byte   0                       # DW_AT_producer
+        .short  4                       # DW_AT_language
+        .byte   0                       # DW_AT_name
+        .secrel32       .Lline_table_start0 # DW_AT_stmt_list
+        .byte   0                       # DW_AT_comp_dir
+        .quad   0                       # DW_AT_low_pc
+        .secrel32       .Ldebug_ranges0 # DW_AT_ranges
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end0:
+        .section        .debug_ranges,"dr"
+.Ldebug_range:
+.Ldebug_ranges0:
+        .quad   .Lfunc_begin0
+        .quad   .Lfunc_end0
+        .quad   .Lfunc_begin1
+        .quad   .Lfunc_end1
+        .quad   0
+        .quad   0
+
+        .section        .debug_line,"dr"
+.Lline_table_start0:




More information about the llvm-commits mailing list