forked from OSchip/llvm-project
[BOLT] Update symbols for secondary entry points
Summary: Update the output ELF symbol table for symbols representing secondary entry points for functions. Previously, those were left unchanged in the symtab. (cherry picked from FBD15010517)
This commit is contained in:
parent
eba1a67730
commit
4e4d39c21c
|
@ -1242,7 +1242,8 @@ BinaryContext::calculateEmittedSize(BinaryFunction &BF) {
|
|||
BinaryFunction *
|
||||
BinaryContext::getBinaryFunctionContainingAddress(uint64_t Address,
|
||||
bool CheckPastEnd,
|
||||
bool UseMaxSize) {
|
||||
bool UseMaxSize,
|
||||
bool Shallow) {
|
||||
auto FI = BinaryFunctions.upper_bound(Address);
|
||||
if (FI == BinaryFunctions.begin())
|
||||
return nullptr;
|
||||
|
@ -1255,6 +1256,9 @@ BinaryContext::getBinaryFunctionContainingAddress(uint64_t Address,
|
|||
return nullptr;
|
||||
|
||||
auto *BF = &FI->second;
|
||||
if (Shallow)
|
||||
return BF;
|
||||
|
||||
while (BF->getParentFunction())
|
||||
BF = BF->getParentFunction();
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ using namespace object;
|
|||
namespace bolt {
|
||||
|
||||
class BinaryFunction;
|
||||
class BinaryBasicBlock;
|
||||
class DataReader;
|
||||
|
||||
/// Helper function to truncate a \p Value to given size in \p Bytes.
|
||||
|
@ -183,7 +184,8 @@ public:
|
|||
/// body and the next object in address ranges that we check.
|
||||
BinaryFunction *getBinaryFunctionContainingAddress(uint64_t Address,
|
||||
bool CheckPastEnd = false,
|
||||
bool UseMaxSize = false);
|
||||
bool UseMaxSize = false,
|
||||
bool Shallow = false);
|
||||
|
||||
/// Return BinaryFunction which has a fragment that starts at a given
|
||||
/// \p Address. If the BinaryFunction is a child fragment, then return its
|
||||
|
|
|
@ -3307,8 +3307,9 @@ void RewriteInstance::updateOutputValues(const MCAsmLayout &Layout) {
|
|||
Layout.getSymbolOffset(*Function.getFunctionEndLabel()));
|
||||
}
|
||||
|
||||
// Update basic block output ranges only for the debug info.
|
||||
if (!opts::UpdateDebugSections)
|
||||
// Update basic block output ranges only for the debug info or if we have
|
||||
// secondary entry points in the symbol table to update
|
||||
if (!opts::UpdateDebugSections && !Function.isMultiEntry())
|
||||
return;
|
||||
|
||||
// Output ranges should match the input if the body hasn't changed.
|
||||
|
@ -4042,11 +4043,17 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
|
|||
|
||||
for (const Elf_Sym &Symbol : cantFail(Obj->symbols(Section))) {
|
||||
auto NewSymbol = Symbol;
|
||||
const auto *Function = BC->getBinaryFunctionAtAddress(Symbol.st_value,
|
||||
/*Shallow=*/true);
|
||||
|
||||
const auto *Function =
|
||||
BC->getBinaryFunctionContainingAddress(NewSymbol.st_value,
|
||||
/*CheckPastEnd=*/false,
|
||||
/*UseMaxSize=*/true,
|
||||
/*Shallow=*/true);
|
||||
|
||||
// Some section symbols may be mistakenly associated with the first
|
||||
// function emitted in the section. Dismiss if it is a section symbol.
|
||||
if (Function &&
|
||||
Function->getAddress() == NewSymbol.st_value &&
|
||||
!Function->getPLTSymbol() &&
|
||||
NewSymbol.getType() != ELF::STT_SECTION) {
|
||||
NewSymbol.st_value = Function->getOutputAddress();
|
||||
|
@ -4102,9 +4109,24 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
|
|||
uint32_t OldSectionIndex = NewSymbol.st_shndx;
|
||||
auto *BD = !Function ? BC->getBinaryDataAtAddress(NewSymbol.st_value)
|
||||
: nullptr;
|
||||
if (BD && BD->isMoved() && !BD->isJumpTable()) {
|
||||
assert((!BD->getSize() ||
|
||||
!NewSymbol.st_size ||
|
||||
auto Output =
|
||||
Function && !Function->getPLTSymbol()
|
||||
? Function->translateInputToOutputAddress(NewSymbol.st_value)
|
||||
: 0;
|
||||
|
||||
// Handle secondary entry points for this function
|
||||
// (when Function->getAddress() != Symbol.st_value)
|
||||
if (Output && NewSymbol.getType() != ELF::STT_SECTION) {
|
||||
NewSymbol.st_value = Output;
|
||||
// Force secondary entry points to have zero size
|
||||
NewSymbol.st_size = 0;
|
||||
NewSymbol.st_shndx = Output >= Function->cold().getAddress() &&
|
||||
Output < Function->cold().getImageSize()
|
||||
? Function->getColdCodeSection()->getIndex()
|
||||
: Function->getCodeSection()->getIndex();
|
||||
OldSectionIndex = ELF::SHN_LORESERVE;
|
||||
} else if (BD && BD->isMoved() && !BD->isJumpTable()) {
|
||||
assert((!BD->getSize() || !NewSymbol.st_size ||
|
||||
NewSymbol.st_size == BD->getSize()) &&
|
||||
"sizes must match");
|
||||
|
||||
|
@ -4133,7 +4155,7 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
|
|||
if (NewSymbol.getType() == ELF::STT_NOTYPE &&
|
||||
NewSymbol.getBinding() == ELF::STB_LOCAL &&
|
||||
NewSymbol.st_size == 0) {
|
||||
auto ExpectedSec = File->getELFFile()->getSection(OldSectionIndex);
|
||||
auto ExpectedSec = File->getELFFile()->getSection(Symbol.st_shndx);
|
||||
if (ExpectedSec) {
|
||||
auto Section = *ExpectedSec;
|
||||
if (Section->sh_type == ELF::SHT_PROGBITS &&
|
||||
|
|
Loading…
Reference in New Issue