Index: llvm/test/tools/dsymutil/X86/global_downgraded_to_static.c =================================================================== --- /dev/null +++ llvm/test/tools/dsymutil/X86/global_downgraded_to_static.c @@ -0,0 +1,24 @@ +// REQUIRES : system-darwin +// RUN: dsymutil -oso-prepend-path %p/.. -dump-debug-map %p/../Inputs/global_downgraded_to_static.x86_64 2>&1 | FileCheck %s +// +// To build: +// clang -g -c -DFILE1 global_downgraded_to_static.c -o 1.o +// clang -g -c -DFILE2 global_downgraded_to_static.c -o 2.o +// ld -r -exported_symbol _foo 1.o -o 1.r.o +// clang 1.r.o 2.o -o global_downgraded_to_static.x86_64 + +#if defined(FILE1) +int global_to_become_static = 42; +// CHECK: sym: _global_to_become_static, +// CHECK-SAME: binAddr: 0x0000000100001000 +int foo() { + return global_to_become_static; +} +#elif defined(FILE2) +int foo(void); +int main() { + return foo(); +} +#else +#error Define FILE1 or FILE2 +#endif Index: llvm/tools/dsymutil/MachODebugMapParser.cpp =================================================================== --- llvm/tools/dsymutil/MachODebugMapParser.cpp +++ llvm/tools/dsymutil/MachODebugMapParser.cpp @@ -511,14 +511,16 @@ // Skip undefined and STAB entries. if ((Type == SymbolRef::ST_Debug) || (Type == SymbolRef::ST_Unknown)) continue; - // The only symbols of interest are the global variables. These - // are the only ones that need to be queried because the address - // of common data won't be described in the debug map. All other - // addresses should be fetched for the debug map. + // In theory, the only symbols of interest are the global variables. These + // are the only ones that need to be queried because the address of common + // data won't be described in the debug map. All other addresses should be + // fetched for the debug map. In reality, by playing with 'ld -r' and + // export lists, you can get symbols described as N_GSYM in the debug map, + // but associated with a local symbol. Gather all the symbols, but prefer + // the global ones. uint8_t SymType = MainBinary.getSymbolTableEntry(Sym.getRawDataRefImpl()).n_type; - if (!(SymType & (MachO::N_EXT | MachO::N_PEXT))) - continue; + bool Extern = SymType & (MachO::N_EXT | MachO::N_PEXT); Expected SectionOrErr = Sym.getSection(); if (!SectionOrErr) { // TODO: Actually report errors helpfully. @@ -538,7 +540,11 @@ StringRef Name = *NameOrErr; if (Name.size() == 0 || Name[0] == '\0') continue; - MainBinarySymbolAddresses[Name] = Addr; + // Override only if the new key is global. + if (Extern) + MainBinarySymbolAddresses[Name] = Addr; + else + MainBinarySymbolAddresses.try_emplace(Name, Addr); } }