[BOLT] Fix getNewValueForSymbol()

Summary:
getNewValueForSymbol() uses orc::RTDyldObjectLinkingLayer::findSymbol()
to resolve symbol values. The latter will always return JITSymbol,
even if there was no symbol defined. The address for the undefined
symbol will be zero, but some symbols could legally be resolved to zero
too.

We need to distinguish between real zero-valued symbols and symbols that
were not emitted and are not visible by orc::RTDyldObjectLinkingLayer.
If zero address is returned by ORC, check for a binary data with the
same name and use its address for the symbol resolution.

(cherry picked from FBD22175269)
This commit is contained in:
Maksim Panchenko 2020-06-22 16:16:08 -07:00
parent ae296ea665
commit 4946b881a8
2 changed files with 18 additions and 5 deletions

View File

@ -1074,13 +1074,15 @@ void RewriteInstance::discoverFileObjects() {
PreviousFunction->getAddress() != Address) {
if (PreviousFunction->isSymbolValidInScope(Symbol, SymbolSize)) {
if (opts::Verbosity >= 1) {
outs() << "BOLT-DEBUG: possibly another entry for function "
outs() << "BOLT-DEBUG: skipping possibly another entry for function "
<< *PreviousFunction << " : " << UniqueName << '\n';
}
} else {
outs() << "BOLT-INFO: using " << UniqueName << " as another entry to "
<< "function " << *PreviousFunction << '\n';
registerName(0);
PreviousFunction->
addEntryPointAtOffset(Address - PreviousFunction->getAddress());
@ -4576,6 +4578,20 @@ void RewriteInstance::writeEHFrameHeader() {
<< EHFrameSection->getOutputSize() << '\n');
}
uint64_t RewriteInstance::getNewValueForSymbol(const StringRef Name) {
uint64_t Value = cantFail(OLT->findSymbol(Name, false).getAddress(),
"findSymbol() failed");
if (Value != 0)
return Value;
// Return the original value if we haven't emitted the symbol.
auto *BD = BC->getBinaryDataByName(Name);
if (!BD)
return 0;
return BD->getAddress();
}
uint64_t RewriteInstance::getFileOffsetForAddress(uint64_t Address) const {
// Check if it's possibly part of the new segment.
if (Address >= NewTextSegmentAddress) {

View File

@ -174,10 +174,7 @@ private:
uint64_t getNewFunctionAddress(uint64_t OldAddress);
/// Return value for the symbol \p Name in the output.
uint64_t getNewValueForSymbol(const StringRef Name) {
return cantFail(OLT->findSymbol(Name, false).getAddress(),
"findSymbol failed");
}
uint64_t getNewValueForSymbol(const StringRef Name);
/// Detect addresses and offsets available in the binary for allocating
/// new sections.