diff options
-rwxr-xr-x | llvm/test/tools/dsymutil/Inputs/private/tmp/common/common.x86_64 | bin | 0 -> 4688 bytes | |||
-rw-r--r-- | llvm/test/tools/dsymutil/Inputs/private/tmp/common/common1.o | bin | 0 -> 2108 bytes | |||
-rw-r--r-- | llvm/test/tools/dsymutil/Inputs/private/tmp/common/common2.o | bin | 0 -> 2096 bytes | |||
-rw-r--r-- | llvm/test/tools/dsymutil/X86/common-sym-multi.test | 39 | ||||
-rw-r--r-- | llvm/tools/dsymutil/MachODebugMapParser.cpp | 35 |
5 files changed, 72 insertions, 2 deletions
diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/common/common.x86_64 b/llvm/test/tools/dsymutil/Inputs/private/tmp/common/common.x86_64 Binary files differnew file mode 100755 index 00000000000..8260af4a1b7 --- /dev/null +++ b/llvm/test/tools/dsymutil/Inputs/private/tmp/common/common.x86_64 diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/common/common1.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/common/common1.o Binary files differnew file mode 100644 index 00000000000..f238fc8fd03 --- /dev/null +++ b/llvm/test/tools/dsymutil/Inputs/private/tmp/common/common1.o diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/common/common2.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/common/common2.o Binary files differnew file mode 100644 index 00000000000..a1d637c9f26 --- /dev/null +++ b/llvm/test/tools/dsymutil/Inputs/private/tmp/common/common2.o diff --git a/llvm/test/tools/dsymutil/X86/common-sym-multi.test b/llvm/test/tools/dsymutil/X86/common-sym-multi.test new file mode 100644 index 00000000000..1f33b37283b --- /dev/null +++ b/llvm/test/tools/dsymutil/X86/common-sym-multi.test @@ -0,0 +1,39 @@ +RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/common.x86_64 -f -o - | llvm-dwarfdump -debug-info - | FileCheck %s +RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/common.x86_64 -dump-debug-map | FileCheck %s --check-prefix DEBUGMAP + +The test was compiled from two source files: +$ cd /private/tmp/common +$ cat common1.c +int i[1000]; +int main() { + return i[1]; +} +$ cat common2.c +extern int i[1000]; +int bar() { + return i[0]; +} +$ clang -fcommon -g -c common1.c -o common1.o +$ clang -fcommon -g -c common2.c -o common2.o +$ clang -fcommon -g common1.o common2.o -o common.x86_64 + +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:{{.*}}common1.o +DEBUGMAP: symbols: +DEBUGMAP: sym: _i, binAddr: 0x0000000100001000, size: 0x00000000 +DEBUGMAP: filename:{{.*}}common2.o +DEBUGMAP: symbols: +DEBUGMAP: sym: _i, binAddr: 0x0000000100001000, size: 0x00000000 diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp index 27379c232de..487fbfff50c 100644 --- a/llvm/tools/dsymutil/MachODebugMapParser.cpp +++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp @@ -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::resetParserState() { 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::loadCurrentObjectFileSymbols( // 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; + } } } |