From 4ac388f7caccc94065712878667829cebd7b8083 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 9 Oct 2019 04:16:18 +0000 Subject: [PATCH] [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 llvm-svn: 374139 --- .../tools/dsymutil/Inputs/private/tmp/common/com | Bin 0 -> 4680 bytes .../dsymutil/Inputs/private/tmp/common/com1.o | Bin 0 -> 2104 bytes .../dsymutil/Inputs/private/tmp/common/com2.o | Bin 0 -> 2096 bytes llvm/test/tools/dsymutil/X86/common-sym-multi.test | 39 +++++++++++++++++++++ llvm/tools/dsymutil/MachODebugMapParser.cpp | 35 ++++++++++++++++-- 5 files changed, 72 insertions(+), 2 deletions(-) create mode 100755 llvm/test/tools/dsymutil/Inputs/private/tmp/common/com create mode 100644 llvm/test/tools/dsymutil/Inputs/private/tmp/common/com1.o create mode 100644 llvm/test/tools/dsymutil/Inputs/private/tmp/common/com2.o create mode 100644 llvm/test/tools/dsymutil/X86/common-sym-multi.test diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/common/com b/llvm/test/tools/dsymutil/Inputs/private/tmp/common/com new file mode 100755 index 0000000000000000000000000000000000000000..3aec9758a0cba31c7cd6e2b3e8493433ae550011 GIT binary patch literal 4680 zcmeHL&ubG=5T0#PEVY<=@E3|MQp5^oHB=M?X{5narPltyQYer7*wTe=Qj(3fw_H4^ z2tA1CLCDdg{tX@kFa80Z1wlM|5fQ&{_dTbl07v9j8jQY7e|xRe81bIt=~wz0vX50}8pRCDQb+ zyypu*shRvzK4!yx2HsPD2)P28R)8;+nbx@Cy_&rS=W9z=-?b*3og_&9N z26kUvy6;7ONydrCI*qS~>8*)9a7UbJ7#QX#Py|1W{q;eS4)*=PJV1de1nWNp#Pfmv zlN^AT4U7R!tJ!ciy|Po?*{p(7jsvXYtM~o!c<$=8-RB?t%*x`Y9CS7i=FE)Z2QV6* z`4%E0L+7xf^gnVI_h%e_uj0bIR{+|g)>-)4THRVu&*DxqaQ*D{Eb8*g(WlQ~WBh3> zBiJW3XTK6jI*@cA=|IwfqytF@k`5#tNIH;o;Q#8ta`DmU;?v<4ZuP$KlXrVEonCvl zYed_Zje&E@3A#bzJ7*5gBvaUlw|YL|nX}9oW|8q|$^q*h#8Q~A)5_ma?zUTL1+Lm~ zOI5calYYso$@%qqU2>jWW`dNoPhshBY1@ngMYLbS+00th-|XXe!PirkEKI#xqn-E2 zVqwiZZvqoBPTd4>1fY=5VTto9m0J4qH=vK#vjfij_xkd4erA|w0P`D89rK$pjGXxm ze+g~_Mre=M!**q?$eT9Kz8M@$e9og8J`7xFKdJ4eAIuFsO`+KM2jK5FQhXidi3;C} zsj<zyGOj> zw!h_h2N}=d{GNUl&uY{$uRtz)H(jqP<@vK5s>B1v%dxS@_xdjC=l}Jey(pa~-bNT8 z<>&9?U&fncy!p*OQI<5oA}=Ws^>fYj6k>P%UNhd09P|M3i1ZY{x32uC&KYtT=%Z0R zp1mmh(Vw7>qNKNudB6qaPNJ)ixYOQ?ezE+=f8|y6IG#+sqlnc>{rY38W_k;`6}#DT z8(wa>FoeI{p~WEZTjTlsf*UL@SBCJ0^0nGZIDGFn8%wqoJ1NEaJ>MVyfiaY zx*}(%uTIIiD;K7ugu3Z^Aa;oFjBGq+WcKVgc8HzWOxg&r@O#sdv>6+%`~C)^MP2 zpw`CW46+d0_`8BzpGSi}i^Izp#D7H@*AsV9q>|hQpgy4D(nB-~jobmsv!ycaM%PVD z*G&{&ZTMa`kc>4AmhL?KrHE@~pK}n=AQC?NEOG|ais{ylxIb$@*l=Tr--1L4zYsojyNCS;;zHlfx@{67=r^=T>ET>Lx( z;#Njv`je?Y(Th;NK|b`JjU;=$~_!dVY#9L!K3EBi%M2(44 zfNgYKMcH^?U+O?SmN>0x=pO$6qWIw&E~8A0h0;){IHxGG53)oZ254ZSUcjmTXn+k; JHMewe`VsS6<`n<{ literal 0 HcmV?d00001 diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/common/com2.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/common/com2.o new file mode 100644 index 0000000000000000000000000000000000000000..a22d1afd7db2d9d90d66f73886b6e76e6ab69a89 GIT binary patch literal 2096 zcma)6OK%fF4EAgu4c)R01PKrb1t<~^(WIrc<=qI1QmH~!Ti!y$X0zKaN;a!xTV9t4 zBm{y(&m4e10OG_S;0JKw23I65NE|rvD)y|GhEPNtdF=7n-+F9M-hBP^vkO4P02kyq za+8)UGSX(`6z%^(0~Cn#jD4a#Vghjw9U@5?*f)Yu5BIa<7iL%Xk(OqK@CfoPB}cY6 zG)Y7xW!Ww*%*jSjS0*V>oi9wEj*cP1dBT>LoZoK;0IfyG{6ajlRI1yHl<%K-FWC7i z%QK1AXr-@;=Xy?!PTTPebt!Hi~x+-4Pv=n4J-W|qc0Xvfa%g^-viY+~} zYByHN?=AyfV3?g9;?+vmEDCAQ?;YdyG2ZPC@l<}kX|>}mx8XhQ5HGmtuX^8|Ty2N* zd;MQLt5(Il0=eK_cfGQdlczXTi6zF%vN6wn{SwXdU-M_rOQ(+A2m_@2^L@NzyfMa` zTA34N(E;Z9NQr2kE3T&y+w1q4@d_NYgm^^X|B)Z{O}(k!ZskYen~>wF@FIOE>8)cP zFooPo)T)SE?Vadniw`~&AF9Xka4df1wN){_x$L4{Z@4utJCN_kUv~F=5crM5x!jx^ z%rBJsu{F6$Wied#`}Nv2+X}J=h7UQ;pgB^uNAiwc9vwbl4IOmy19>YybZB&7*ep2* z%g*5F9>Dm)ehYGb-CZ;TI~P>_9NMZi4_t7)0H?b!JzcmcXC^L<%h`)l<5GfCtASW2 zb{UyO%t&wCVyqMEafq}bh#3=^6Ppj~M|2HK787D3gN54;6PXdbSfURdj_W#BE=j7c zA4j#TA1HooQ_P@10>Ev4Q7~6zIk82+<5eU4EIzE zssrKEZE4Jrs3v5hV>Y4IO6o0yPOWB$J}z!egSe3v>7K6C5<(HmR^^d^6UPpiGcOG?%yqSVPxUlu2}VKTpJxM>P$-(L}vOdF*m1 klOv%t6e>;`Zs|O^k0r(Q(!xXzxQ##SWrL*ImM-mn0dL3PRR910 literal 0 HcmV?d00001 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 0000000..008362e --- /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/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 diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp index 27379c2..487fbff 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 namespace { using namespace llvm; @@ -51,6 +52,8 @@ private: StringRef MainBinaryStrings; /// The constructed DebugMap. std::unique_ptr Result; + /// List of common symbols that need to be added to the debug map. + std::vector CommonSymbols; /// Map of the currently processed object file symbol addresses. StringMap> 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 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; + } } } -- 2.7.4