1010#include " ConcatOutputSection.h"
1111#include " Config.h"
1212#include " ExportTrie.h"
13+ #include " ICF.h"
1314#include " InputFiles.h"
1415#include " MachOStructs.h"
1516#include " ObjC.h"
@@ -1204,6 +1205,14 @@ void SymtabSection::emitEndFunStab(Defined *defined) {
12041205 stabs.emplace_back (std::move (stab));
12051206}
12061207
1208+ Defined *SymtabSection::getFuncBodySym (Defined *originalSym) {
1209+ // If the Defined is not a thunk, we can use it directly
1210+ if (originalSym->identicalCodeFoldingKind != Symbol::ICFFoldKind::Thunk)
1211+ return originalSym;
1212+
1213+ return macho::getBodyForThunkFoldedSym (originalSym);
1214+ }
1215+
12071216void SymtabSection::emitStabs () {
12081217 if (config->omitDebugInfo )
12091218 return ;
@@ -1214,9 +1223,14 @@ void SymtabSection::emitStabs() {
12141223 stabs.emplace_back (std::move (astStab));
12151224 }
12161225
1217- // Cache the file ID for each symbol in an std::pair for faster sorting.
1218- using SortingPair = std::pair<Defined *, int >;
1219- std::vector<SortingPair> symbolsNeedingStabs;
1226+ struct SymbolStabInfo {
1227+ Defined *originalSym; // Original Defined symbol - this may be an ICF thunk
1228+ int fileId; // File ID associated with the STABS symbol
1229+ Defined *mainBodySym; // Symbol that consists of the full function body -
1230+ // use this for the STABS entry
1231+ };
1232+
1233+ std::vector<SymbolStabInfo> symbolsNeedingStabs;
12201234 for (const SymtabEntry &entry :
12211235 concat<SymtabEntry>(localSymbols, externalSymbols)) {
12221236 Symbol *sym = entry.sym ;
@@ -1229,20 +1243,10 @@ void SymtabSection::emitStabs() {
12291243 if (defined ->isAbsolute ())
12301244 continue ;
12311245
1232- // Never generate a STABS entry for a symbol that has been ICF'ed using a
1233- // thunk, just as we do for fully ICF'ed functions. Otherwise, we end up
1234- // generating invalid DWARF as dsymutil will assume the entire function
1235- // body is at that location, when, in reality, only the thunk is
1236- // present. This will end up causing overlapping DWARF entries.
1237- // TODO: Find an implementation that works in combination with
1238- // `--keep-icf-stabs`.
1239- if (defined ->identicalCodeFoldingKind == Symbol::ICFFoldKind::Thunk)
1240- continue ;
1241-
12421246 // Constant-folded symbols go in the executable's symbol table, but don't
1243- // get a stabs entry unless --keep-icf-stabs flag is specified
1247+ // get a stabs entry unless --keep-icf-stabs flag is specified.
12441248 if (!config->keepICFStabs &&
1245- defined ->identicalCodeFoldingKind == Symbol::ICFFoldKind::Body )
1249+ defined ->identicalCodeFoldingKind != Symbol::ICFFoldKind::None )
12461250 continue ;
12471251
12481252 ObjFile *file = defined ->getObjectFile ();
@@ -1251,26 +1255,26 @@ void SymtabSection::emitStabs() {
12511255
12521256 // We use 'originalIsec' to get the file id of the symbol since 'isec()'
12531257 // might point to the merged ICF symbol's file
1254- symbolsNeedingStabs.emplace_back (defined ,
1255- defined ->originalIsec ->getFile ()->id );
1258+ Defined *funcBodySym = getFuncBodySym (defined );
1259+ symbolsNeedingStabs.emplace_back (SymbolStabInfo{
1260+ defined , funcBodySym->originalIsec ->getFile ()->id , funcBodySym});
12561261 }
12571262 }
12581263
12591264 llvm::stable_sort (symbolsNeedingStabs,
1260- [&](const SortingPair &a, const SortingPair &b) {
1261- return a.second < b.second ;
1265+ [&](const SymbolStabInfo &a, const SymbolStabInfo &b) {
1266+ return a.fileId < b.fileId ;
12621267 });
12631268
12641269 // Emit STABS symbols so that dsymutil and/or the debugger can map address
12651270 // regions in the final binary to the source and object files from which they
12661271 // originated.
12671272 InputFile *lastFile = nullptr ;
1268- for (SortingPair &pair : symbolsNeedingStabs) {
1269- Defined *defined = pair.first ;
1273+ for (const SymbolStabInfo &info : symbolsNeedingStabs) {
12701274 // We use 'originalIsec' of the symbol since we care about the actual origin
12711275 // of the symbol, not the canonical location returned by `isec()`.
1272- InputSection *isec = defined ->originalIsec ;
1273- ObjFile *file = cast<ObjFile>(isec ->getFile ());
1276+ InputSection *bodyIsec = info. mainBodySym ->originalIsec ;
1277+ ObjFile *file = cast<ObjFile>(bodyIsec ->getFile ());
12741278
12751279 if (lastFile == nullptr || lastFile != file) {
12761280 if (lastFile != nullptr )
@@ -1282,16 +1286,16 @@ void SymtabSection::emitStabs() {
12821286 }
12831287
12841288 StabsEntry symStab;
1285- symStab.sect = isec ->parent ->index ;
1286- symStab.strx = stringTableSection.addString (defined ->getName ());
1287- symStab.value = defined ->getVA ();
1289+ symStab.sect = bodyIsec ->parent ->index ;
1290+ symStab.strx = stringTableSection.addString (info. originalSym ->getName ());
1291+ symStab.value = info. mainBodySym ->getVA ();
12881292
1289- if (isCodeSection (isec )) {
1293+ if (isCodeSection (bodyIsec )) {
12901294 symStab.type = N_FUN;
12911295 stabs.emplace_back (std::move (symStab));
1292- emitEndFunStab (defined );
1296+ emitEndFunStab (info. mainBodySym );
12931297 } else {
1294- symStab.type = defined ->isExternal () ? N_GSYM : N_STSYM;
1298+ symStab.type = info. originalSym ->isExternal () ? N_GSYM : N_STSYM;
12951299 stabs.emplace_back (std::move (symStab));
12961300 }
12971301 }
0 commit comments