Skip to content

Commit b6ae0ba

Browse files
committed
Fixup corrupted DWARF function names using symbol table info
1 parent 9188eff commit b6ae0ba

File tree

1 file changed

+55
-10
lines changed

1 file changed

+55
-10
lines changed

llvm/tools/llvm-profgen/ProfiledBinary.cpp

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -854,11 +854,12 @@ void ProfiledBinary::loadSymbolsFromSymtab(const ObjectFile *Obj) {
854854
if (Size == 0 || Type != SymbolRef::ST_Function)
855855
continue;
856856

857+
const uint64_t EndAddr = StartAddr + Size;
857858
const StringRef SymName =
858859
FunctionSamples::getCanonicalFnName(Name, Suffixes);
859860

860861
auto Range = findFuncRange(StartAddr);
861-
if (!Range || Range->StartAddress != StartAddr) {
862+
if (!Range) {
862863
// Function from symbol table not found previously in DWARF, store ranges.
863864
auto Ret = BinaryFunctions.emplace(SymName, BinaryFunction());
864865
auto &Func = Ret.first->second;
@@ -868,23 +869,67 @@ void ProfiledBinary::loadSymbolsFromSymtab(const ObjectFile *Obj) {
868869
}
869870

870871
Func.FromSymtab = true;
871-
Func.Ranges.emplace_back(StartAddr, StartAddr + Size);
872+
Func.Ranges.emplace_back(StartAddr, EndAddr);
872873

873874
auto R = StartAddrToFuncRangeMap.emplace(StartAddr, FuncRange());
874875
FuncRange &FRange = R.first->second;
875876

876877
FRange.Func = &Func;
877878
FRange.StartAddress = StartAddr;
878-
FRange.EndAddress = StartAddr + Size;
879+
FRange.EndAddress = EndAddr;
879880

880-
} else if (SymName != Range->getFuncName() && ShowDetailedWarning) {
881-
// Function already found from DWARF, check consistency between symbol
882-
// table and DWARF.
883-
WithColor::warning() << "Conflicting name for symbol" << Name
884-
<< " at address " << format("%8" PRIx64, StartAddr)
881+
} else if (SymName != Range->getFuncName()) {
882+
// Function range already found from DWARF, but the symbol name from
883+
// symbol table is inconsistent with debug info.
884+
if (ShowDetailedWarning)
885+
WithColor::warning()
886+
<< "Conflicting name for symbol " << Name << " with range ("
887+
<< format("%8" PRIx64, StartAddr) << ", "
888+
<< format("%8" PRIx64, EndAddr) << ")"
889+
<< ", but the DWARF symbol " << Range->getFuncName()
890+
<< " indicates an overlapping range ("
891+
<< format("%8" PRIx64, Range->StartAddress) << ", "
892+
<< format("%8" PRIx64, Range->EndAddress) << ")\n";
893+
894+
assert(StartAddr == Range->StartAddress && EndAddr == Range->EndAddress &&
895+
"Mismatched function range");
896+
897+
auto ErrSym = BinaryFunctions.find(Range->getFuncName().str());
898+
auto Ret = BinaryFunctions.emplace(SymName, BinaryFunction());
899+
auto &Func = Ret.first->second;
900+
901+
// Symbol table may contain multiple symbol names of the same starting
902+
// address. Only need to pick one from these.
903+
if (!Ret.second)
904+
continue;
905+
906+
Func.FuncName = Ret.first->first;
907+
Func.Ranges = ErrSym->second.Ranges;
908+
Func.FromSymtab = true;
909+
910+
HashBinaryFunctions.erase(MD5Hash(Range->getFuncName()));
911+
BinaryFunctions.erase(ErrSym);
912+
913+
HashBinaryFunctions[MD5Hash(StringRef(SymName))] = &Func;
914+
Range->Func = &Func;
915+
for (auto [RangeStart, _] : Func.Ranges) {
916+
if (auto FRange = findFuncRangeForStartAddr(RangeStart)) {
917+
assert(FRange && "Cannot find function range");
918+
FRange->Func = &Func;
919+
}
920+
}
921+
} else if (StartAddr != Range->StartAddress &&
922+
EndAddr != Range->EndAddress) {
923+
// Function already found in DWARF, but the address range from symbol
924+
// table conflicts/overlaps with the debug info.
925+
WithColor::warning() << "Conflicting range for symbol " << Name
926+
<< " with range (" << format("%8" PRIx64, StartAddr)
927+
<< ", " << format("%8" PRIx64, EndAddr) << ")"
885928
<< ", but the DWARF symbol " << Range->getFuncName()
886-
<< " indicates a starting address at "
887-
<< format("%8" PRIx64, Range->StartAddress) << "\n";
929+
<< " indicates another range ("
930+
<< format("%8" PRIx64, Range->StartAddress) << ", "
931+
<< format("%8" PRIx64, Range->EndAddress) << ")\n";
932+
llvm_unreachable("invalid function range");
888933
}
889934
}
890935
}

0 commit comments

Comments
 (0)