[BOLT] Do not emit duplicate org symbols

Summary:
When adding symbols for patched functions, we may end up emitting
multiple symbols per function if the function has multiple names (e.g.
after identical code folding by the linker).

(cherry picked from FBD22294112)
This commit is contained in:
Maksim Panchenko 2020-06-24 12:36:15 -07:00
parent 250ca4082e
commit ffaba22476
1 changed files with 21 additions and 3 deletions

View File

@ -3760,16 +3760,34 @@ void RewriteInstance::updateELFSymbolTable(
std::vector<ELFSymTy> Symbols;
// Add extra symbols for the function.
//
// Note that addExtraSymbols() could be called multiple times for the same
// function with different FunctionSymbol matching the main function entry
// point.
auto addExtraSymbols = [&](const BinaryFunction &Function,
const ELFSymTy &FunctionSymbol) {
if (Function.isPatched()) {
Function.forEachEntryPoint([&](uint64_t Offset, const MCSymbol *Symbol) {
ELFSymTy OrgSymbol = FunctionSymbol;
SmallVector<char, 256> Buf;
OrgSymbol.st_name = AddToStrTab(
Twine(Symbol->getName()).concat(".org.0").toStringRef(Buf));
if (!Offset) {
// Use the original function symbol name. This guarantees that the
// name will be unique.
OrgSymbol.st_name = AddToStrTab(
Twine(cantFail(FunctionSymbol.getName(StringSection)))
.concat(".org.0").
toStringRef(Buf));
OrgSymbol.st_size = Function.getSize();
} else {
// It's unlikely that multiple functions with secondary entries will
// get folded/merged. However, in case this happens, we force local
// symbol visibility for secondary entries.
OrgSymbol.st_name = AddToStrTab(
Twine(Symbol->getName()).concat(".org.0").toStringRef(Buf));
OrgSymbol.setBindingAndType(ELF::STB_LOCAL, ELF::STT_FUNC);
OrgSymbol.st_size = 0;
}
OrgSymbol.st_value = Function.getAddress() + Offset;
OrgSymbol.st_size = Offset ? 0 : Function.getSize();
OrgSymbol.st_shndx =
NewSectionIndex[Function.getSection().getSectionRef().getIndex()];
Symbols.emplace_back(OrgSymbol);