[llvm] r374139 - [dsymutil] Fix handling of common symbols in multiple object files.

Jonas Devlieghere via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 8 21:16:19 PDT 2019


Author: jdevlieghere
Date: Tue Oct  8 21:16:18 2019
New Revision: 374139

URL: http://llvm.org/viewvc/llvm-project?rev=374139&view=rev
Log:
[dsymutil] Fix handling of common symbols in multiple object files.

For common symbols the linker emits only a single symbol entry in the
debug map. This caused dsymutil to not relocate common symbols when
linking DWARF coming form object files that did not have this entry.
This patch fixes that by keeping track of common symbols in the object
files and synthesizing a debug map entry for them using the address from
the main binary.

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

Added:
    llvm/trunk/test/tools/dsymutil/Inputs/private/
    llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/
    llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/
    llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com   (with props)
    llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com1.o   (with props)
    llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com2.o   (with props)
    llvm/trunk/test/tools/dsymutil/X86/common-sym-multi.test
Modified:
    llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp

Added: llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com?rev=374139&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com1.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com1.o?rev=374139&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com1.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com2.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com2.o?rev=374139&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/dsymutil/Inputs/private/tmp/common/com2.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/dsymutil/X86/common-sym-multi.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/common-sym-multi.test?rev=374139&view=auto
==============================================================================
--- llvm/trunk/test/tools/dsymutil/X86/common-sym-multi.test (added)
+++ llvm/trunk/test/tools/dsymutil/X86/common-sym-multi.test Tue Oct  8 21:16:18 2019
@@ -0,0 +1,39 @@
+RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/com -f -o - | llvm-dwarfdump -debug-info - | FileCheck %s
+RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/com -dump-debug-map | FileCheck %s --check-prefix DEBUGMAP
+
+The test was compiled from two source files:
+$ cd /private/tmp/common
+$ cat com1.c
+int i[1000];
+int main() {
+  return i[1];
+}
+$ cat com2.c
+extern int i[1000];
+int bar() {
+  return i[0];
+}
+$ clang -fcommon -g -c com1.c -o com1.o
+$ clang -fcommon -g -c com2.c -o com2.o
+$ clang -fcommon -g com1.o com2.o -o com
+
+CHECK: DW_TAG_compile_unit
+CHECK:   DW_TAG_variable
+CHECK-NOT: {{NULL|DW_TAG}}
+CHECK:     DW_AT_name{{.*}}"i"
+CHECK-NOT: {{NULL|DW_TAG}}
+CHECK:     DW_AT_location{{.*}}DW_OP_addr 0x100001000)
+
+CHECK: DW_TAG_compile_unit
+CHECK:   DW_TAG_variable
+CHECK-NOT: {{NULL|DW_TAG}}
+CHECK:     DW_AT_name{{.*}}"i"
+CHECK-NOT: {{NULL|DW_TAG}}
+CHECK:     DW_AT_location{{.*}}DW_OP_addr 0x100001000)
+
+DEBUGMAP: filename:{{.*}}com1.o
+DEBUGMAP: symbols:
+DEBUGMAP: sym: _i, binAddr: 0x0000000100001000, size: 0x00000000
+DEBUGMAP: filename:{{.*}}com2.o
+DEBUGMAP: symbols:
+DEBUGMAP: sym: _i, binAddr: 0x0000000100001000, size: 0x00000000

Modified: llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp?rev=374139&r1=374138&r2=374139&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp (original)
+++ llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp Tue Oct  8 21:16:18 2019
@@ -14,6 +14,7 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
+#include <vector>
 
 namespace {
 using namespace llvm;
@@ -51,6 +52,8 @@ private:
   StringRef MainBinaryStrings;
   /// The constructed DebugMap.
   std::unique_ptr<DebugMap> Result;
+  /// List of common symbols that need to be added to the debug map.
+  std::vector<std::string> CommonSymbols;
 
   /// Map of the currently processed object file symbol addresses.
   StringMap<Optional<uint64_t>> CurrentObjectAddresses;
@@ -81,6 +84,8 @@ private:
                                STE.n_value);
   }
 
+  void addCommonSymbols();
+
   /// Dump the symbol table output header.
   void dumpSymTabHeader(raw_ostream &OS, StringRef Arch);
 
@@ -122,11 +127,32 @@ void MachODebugMapParser::resetParserSta
   CurrentDebugMapObject = nullptr;
 }
 
+/// Commons symbols won't show up in the symbol map but might need to be
+/// relocated. We can add them to the symbol table ourselves by combining the
+/// information in the object file (the symbol name) and the main binary (the
+/// address).
+void MachODebugMapParser::addCommonSymbols() {
+  for (auto &CommonSymbol : CommonSymbols) {
+    uint64_t CommonAddr = getMainBinarySymbolAddress(CommonSymbol);
+    if (CommonAddr == 0) {
+      // The main binary doesn't have an address for the given symbol.
+      continue;
+    }
+    if (!CurrentDebugMapObject->addSymbol(CommonSymbol, None /*ObjectAddress*/,
+                                          CommonAddr, 0 /*size*/)) {
+      // The symbol is already present.
+      continue;
+    }
+  }
+  CommonSymbols.clear();
+}
+
 /// Create a new DebugMapObject. This function resets the state of the
 /// parser that was referring to the last object file and sets
 /// everything up to add symbols to the new one.
 void MachODebugMapParser::switchToNewDebugMapObject(
     StringRef Filename, sys::TimePoint<std::chrono::seconds> Timestamp) {
+  addCommonSymbols();
   resetParserState();
 
   SmallString<80> Path(PathPrefix);
@@ -466,10 +492,15 @@ void MachODebugMapParser::loadCurrentObj
     // relocations will use the symbol itself, and won't need an
     // object file address. The object file address field is optional
     // in the DebugMap, leave it unassigned for these symbols.
-    if (Sym.getFlags() & (SymbolRef::SF_Absolute | SymbolRef::SF_Common))
+    uint32_t Flags = Sym.getFlags();
+    if (Flags & SymbolRef::SF_Absolute) {
       CurrentObjectAddresses[*Name] = None;
-    else
+    } else if (Flags & SymbolRef::SF_Common) {
+      CurrentObjectAddresses[*Name] = None;
+      CommonSymbols.push_back(*Name);
+    } else {
       CurrentObjectAddresses[*Name] = Addr;
+    }
   }
 }
 




More information about the llvm-commits mailing list