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. Reviewed By: maksfb Differential Revision: D15010517 fbshipit-source-id: 330f12580c1
This commit is contained in:
parent
449c43120f
commit
32fd328ade
@ -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
Block a user