forked from OSchip/llvm-project
[JITLink][MachO] Fix "find-symbol-by-address" logic.
Only search within the requested section, and allow one-past-then-end addresses. This is needed to support section-end-address references to sections with no symbols in them.
This commit is contained in:
parent
efa896e5f7
commit
2272ec1c63
|
@ -318,16 +318,19 @@ Error MachOLinkGraphBuilder::createNormalizedSymbols() {
|
|||
}
|
||||
|
||||
void MachOLinkGraphBuilder::addSectionStartSymAndBlock(
|
||||
Section &GraphSec, uint64_t Address, const char *Data, uint64_t Size,
|
||||
uint32_t Alignment, bool IsLive) {
|
||||
unsigned SecIndex, Section &GraphSec, uint64_t Address, const char *Data,
|
||||
uint64_t Size, uint32_t Alignment, bool IsLive) {
|
||||
Block &B =
|
||||
Data ? G->createContentBlock(GraphSec, ArrayRef<char>(Data, Size),
|
||||
Address, Alignment, 0)
|
||||
: G->createZeroFillBlock(GraphSec, Size, Address, Alignment, 0);
|
||||
auto &Sym = G->addAnonymousSymbol(B, 0, Size, false, IsLive);
|
||||
assert(!AddrToCanonicalSymbol.count(Sym.getAddress()) &&
|
||||
auto SecI = IndexToSection.find(SecIndex);
|
||||
assert(SecI != IndexToSection.end() && "SecIndex invalid");
|
||||
auto &NSec = SecI->second;
|
||||
assert(!NSec.CanonicalSymbols.count(Sym.getAddress()) &&
|
||||
"Anonymous block start symbol clashes with existing symbol address");
|
||||
AddrToCanonicalSymbol[Sym.getAddress()] = &Sym;
|
||||
NSec.CanonicalSymbols[Sym.getAddress()] = &Sym;
|
||||
}
|
||||
|
||||
Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
|
||||
|
@ -441,8 +444,8 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
|
|||
<< formatv("{0:x16}", NSec.Address) << " -- "
|
||||
<< formatv("{0:x16}", NSec.Address + NSec.Size) << "\n";
|
||||
});
|
||||
addSectionStartSymAndBlock(*NSec.GraphSection, NSec.Address, NSec.Data,
|
||||
NSec.Size, NSec.Alignment,
|
||||
addSectionStartSymAndBlock(SecIndex, *NSec.GraphSection, NSec.Address,
|
||||
NSec.Data, NSec.Size, NSec.Alignment,
|
||||
SectionIsNoDeadStrip);
|
||||
} else
|
||||
LLVM_DEBUG({
|
||||
|
@ -480,8 +483,8 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
|
|||
<< formatv("{0:x16}", NSec.Address) << " -- "
|
||||
<< formatv("{0:x16}", NSec.Address + AnonBlockSize) << " ]\n";
|
||||
});
|
||||
addSectionStartSymAndBlock(*NSec.GraphSection, NSec.Address, NSec.Data,
|
||||
AnonBlockSize, NSec.Alignment,
|
||||
addSectionStartSymAndBlock(SecIndex, *NSec.GraphSection, NSec.Address,
|
||||
NSec.Data, AnonBlockSize, NSec.Alignment,
|
||||
SectionIsNoDeadStrip);
|
||||
}
|
||||
|
||||
|
@ -580,7 +583,7 @@ Symbol &MachOLinkGraphBuilder::createStandardGraphSymbol(NormalizedSymbol &NSym,
|
|||
NSym.GraphSymbol = &Sym;
|
||||
|
||||
if (IsCanonical)
|
||||
setCanonicalSymbol(Sym);
|
||||
setCanonicalSymbol(getSectionByIndex(NSym.Sect - 1), Sym);
|
||||
|
||||
return Sym;
|
||||
}
|
||||
|
@ -607,7 +610,6 @@ Error MachOLinkGraphBuilder::graphifySectionsWithCustomParsers() {
|
|||
|
||||
Error MachOLinkGraphBuilder::graphifyCStringSection(
|
||||
NormalizedSection &NSec, std::vector<NormalizedSymbol *> NSyms) {
|
||||
|
||||
assert(NSec.GraphSection && "C string literal section missing graph section");
|
||||
assert(NSec.Data && "C string literal section has no data");
|
||||
|
||||
|
@ -661,7 +663,7 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
|
|||
// If there's no symbol at the start of this block then create one.
|
||||
if (NSyms.empty() || NSyms.back()->Value != B.getAddress()) {
|
||||
auto &S = G->addAnonymousSymbol(B, 0, BlockSize, false, false);
|
||||
setCanonicalSymbol(S);
|
||||
setCanonicalSymbol(NSec, S);
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Adding anonymous symbol for c-string block "
|
||||
<< formatv("{0:x16} -- {1:x16}", S.getAddress(),
|
||||
|
|
|
@ -77,6 +77,7 @@ protected:
|
|||
uint32_t Flags = 0;
|
||||
const char *Data = nullptr;
|
||||
Section *GraphSection = nullptr;
|
||||
std::map<JITTargetAddress, Symbol *> CanonicalSymbols;
|
||||
};
|
||||
|
||||
using SectionParserFunction = std::function<Error(NormalizedSection &S)>;
|
||||
|
@ -135,19 +136,21 @@ protected:
|
|||
|
||||
/// Returns the symbol with the highest address not greater than the search
|
||||
/// address, or null if no such symbol exists.
|
||||
Symbol *getSymbolByAddress(JITTargetAddress Address) {
|
||||
auto I = AddrToCanonicalSymbol.upper_bound(Address);
|
||||
if (I == AddrToCanonicalSymbol.begin())
|
||||
Symbol *getSymbolByAddress(NormalizedSection &NSec,
|
||||
JITTargetAddress Address) {
|
||||
auto I = NSec.CanonicalSymbols.upper_bound(Address);
|
||||
if (I == NSec.CanonicalSymbols.begin())
|
||||
return nullptr;
|
||||
return std::prev(I)->second;
|
||||
}
|
||||
|
||||
/// Returns the symbol with the highest address not greater than the search
|
||||
/// address, or an error if no such symbol exists.
|
||||
Expected<Symbol &> findSymbolByAddress(JITTargetAddress Address) {
|
||||
auto *Sym = getSymbolByAddress(Address);
|
||||
Expected<Symbol &> findSymbolByAddress(NormalizedSection &NSec,
|
||||
JITTargetAddress Address) {
|
||||
auto *Sym = getSymbolByAddress(NSec, Address);
|
||||
if (Sym)
|
||||
if (Address < Sym->getAddress() + Sym->getSize())
|
||||
if (Address <= Sym->getAddress() + Sym->getSize())
|
||||
return *Sym;
|
||||
return make_error<JITLinkError>("No symbol covering address " +
|
||||
formatv("{0:x16}", Address));
|
||||
|
@ -178,8 +181,8 @@ private:
|
|||
static unsigned getPointerSize(const object::MachOObjectFile &Obj);
|
||||
static support::endianness getEndianness(const object::MachOObjectFile &Obj);
|
||||
|
||||
void setCanonicalSymbol(Symbol &Sym) {
|
||||
auto *&CanonicalSymEntry = AddrToCanonicalSymbol[Sym.getAddress()];
|
||||
void setCanonicalSymbol(NormalizedSection &NSec, Symbol &Sym) {
|
||||
auto *&CanonicalSymEntry = NSec.CanonicalSymbols[Sym.getAddress()];
|
||||
// There should be no symbol at this address, or, if there is,
|
||||
// it should be a zero-sized symbol from an empty section (which
|
||||
// we can safely override).
|
||||
|
@ -189,9 +192,10 @@ private:
|
|||
}
|
||||
|
||||
Section &getCommonSection();
|
||||
void addSectionStartSymAndBlock(Section &GraphSec, uint64_t Address,
|
||||
const char *Data, uint64_t Size,
|
||||
uint32_t Alignment, bool IsLive);
|
||||
void addSectionStartSymAndBlock(unsigned SecIndex, Section &GraphSec,
|
||||
uint64_t Address, const char *Data,
|
||||
uint64_t Size, uint32_t Alignment,
|
||||
bool IsLive);
|
||||
|
||||
Error createNormalizedSections();
|
||||
Error createNormalizedSymbols();
|
||||
|
@ -226,7 +230,6 @@ private:
|
|||
Section *CommonSection = nullptr;
|
||||
|
||||
DenseMap<uint32_t, NormalizedSymbol *> IndexToSymbol;
|
||||
std::map<JITTargetAddress, Symbol *> AddrToCanonicalSymbol;
|
||||
StringMap<SectionParserFunction> CustomSectionParserFunctions;
|
||||
};
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ private:
|
|||
auto ToSymbolSec = findSectionByIndex(UnsignedRI.r_symbolnum - 1);
|
||||
if (!ToSymbolSec)
|
||||
return ToSymbolSec.takeError();
|
||||
ToSymbol = getSymbolByAddress(ToSymbolSec->Address);
|
||||
ToSymbol = getSymbolByAddress(*ToSymbolSec, ToSymbolSec->Address);
|
||||
assert(ToSymbol && "No symbol for section");
|
||||
FixupValue -= ToSymbol->getAddress();
|
||||
}
|
||||
|
@ -205,14 +205,18 @@ private:
|
|||
continue;
|
||||
}
|
||||
|
||||
// Skip relocations for debug symbols.
|
||||
auto NSec =
|
||||
findSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
|
||||
if (!NSec)
|
||||
return NSec.takeError();
|
||||
|
||||
// Skip relocations for MachO sections without corresponding graph
|
||||
// sections.
|
||||
{
|
||||
auto &NSec =
|
||||
getSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
|
||||
if (!NSec.GraphSection) {
|
||||
if (!NSec->GraphSection) {
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Skipping relocations for MachO section "
|
||||
<< NSec.SegName << "/" << NSec.SectName
|
||||
<< NSec->SegName << "/" << NSec->SectName
|
||||
<< " which has no associated graph section\n";
|
||||
});
|
||||
continue;
|
||||
|
@ -231,18 +235,15 @@ private:
|
|||
|
||||
// Find the address of the value to fix up.
|
||||
JITTargetAddress FixupAddress = SectionAddress + (uint32_t)RI.r_address;
|
||||
|
||||
LLVM_DEBUG({
|
||||
auto &NSec =
|
||||
getSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
|
||||
dbgs() << " " << NSec.SectName << " + "
|
||||
dbgs() << " " << NSec->SectName << " + "
|
||||
<< formatv("{0:x8}", RI.r_address) << ":\n";
|
||||
});
|
||||
|
||||
// Find the block that the fixup points to.
|
||||
Block *BlockToFix = nullptr;
|
||||
{
|
||||
auto SymbolToFixOrErr = findSymbolByAddress(FixupAddress);
|
||||
auto SymbolToFixOrErr = findSymbolByAddress(*NSec, FixupAddress);
|
||||
if (!SymbolToFixOrErr)
|
||||
return SymbolToFixOrErr.takeError();
|
||||
BlockToFix = &SymbolToFixOrErr->getBlock();
|
||||
|
@ -324,7 +325,11 @@ private:
|
|||
break;
|
||||
case Pointer64Anon: {
|
||||
JITTargetAddress TargetAddress = *(const ulittle64_t *)FixupContent;
|
||||
if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
|
||||
auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1);
|
||||
if (!TargetNSec)
|
||||
return TargetNSec.takeError();
|
||||
if (auto TargetSymbolOrErr =
|
||||
findSymbolByAddress(*TargetNSec, TargetAddress))
|
||||
TargetSymbol = &*TargetSymbolOrErr;
|
||||
else
|
||||
return TargetSymbolOrErr.takeError();
|
||||
|
|
|
@ -170,7 +170,7 @@ private:
|
|||
auto ToSymbolSec = findSectionByIndex(UnsignedRI.r_symbolnum - 1);
|
||||
if (!ToSymbolSec)
|
||||
return ToSymbolSec.takeError();
|
||||
ToSymbol = getSymbolByAddress(ToSymbolSec->Address);
|
||||
ToSymbol = getSymbolByAddress(*ToSymbolSec, ToSymbolSec->Address);
|
||||
assert(ToSymbol && "No symbol for section");
|
||||
FixupValue -= ToSymbol->getAddress();
|
||||
}
|
||||
|
@ -216,14 +216,18 @@ private:
|
|||
continue;
|
||||
}
|
||||
|
||||
// Skip relocations for debug symbols.
|
||||
auto NSec =
|
||||
findSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
|
||||
if (!NSec)
|
||||
return NSec.takeError();
|
||||
|
||||
// Skip relocations for MachO sections without corresponding graph
|
||||
// sections.
|
||||
{
|
||||
auto &NSec =
|
||||
getSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
|
||||
if (!NSec.GraphSection) {
|
||||
if (!NSec->GraphSection) {
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Skipping relocations for MachO section "
|
||||
<< NSec.SegName << "/" << NSec.SectName
|
||||
<< NSec->SegName << "/" << NSec->SectName
|
||||
<< " which has no associated graph section\n";
|
||||
});
|
||||
continue;
|
||||
|
@ -240,16 +244,14 @@ private:
|
|||
JITTargetAddress FixupAddress = SectionAddress + (uint32_t)RI.r_address;
|
||||
|
||||
LLVM_DEBUG({
|
||||
auto &NSec =
|
||||
getSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
|
||||
dbgs() << " " << NSec.SectName << " + "
|
||||
dbgs() << " " << NSec->SectName << " + "
|
||||
<< formatv("{0:x8}", RI.r_address) << ":\n";
|
||||
});
|
||||
|
||||
// Find the block that the fixup points to.
|
||||
Block *BlockToFix = nullptr;
|
||||
{
|
||||
auto SymbolToFixOrErr = findSymbolByAddress(FixupAddress);
|
||||
auto SymbolToFixOrErr = findSymbolByAddress(*NSec, FixupAddress);
|
||||
if (!SymbolToFixOrErr)
|
||||
return SymbolToFixOrErr.takeError();
|
||||
BlockToFix = &SymbolToFixOrErr->getBlock();
|
||||
|
@ -342,7 +344,11 @@ private:
|
|||
break;
|
||||
case MachOPointer64Anon: {
|
||||
JITTargetAddress TargetAddress = *(const ulittle64_t *)FixupContent;
|
||||
if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
|
||||
auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1);
|
||||
if (!TargetNSec)
|
||||
return TargetNSec.takeError();
|
||||
if (auto TargetSymbolOrErr =
|
||||
findSymbolByAddress(*TargetNSec, TargetAddress))
|
||||
TargetSymbol = &*TargetSymbolOrErr;
|
||||
else
|
||||
return TargetSymbolOrErr.takeError();
|
||||
|
@ -363,7 +369,11 @@ private:
|
|||
case MachOPCRel32Anon: {
|
||||
JITTargetAddress TargetAddress =
|
||||
FixupAddress + 4 + *(const little32_t *)FixupContent;
|
||||
if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
|
||||
auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1);
|
||||
if (!TargetNSec)
|
||||
return TargetNSec.takeError();
|
||||
if (auto TargetSymbolOrErr =
|
||||
findSymbolByAddress(*TargetNSec, TargetAddress))
|
||||
TargetSymbol = &*TargetSymbolOrErr;
|
||||
else
|
||||
return TargetSymbolOrErr.takeError();
|
||||
|
@ -379,7 +389,11 @@ private:
|
|||
1ULL << (*MachORelocKind - MachOPCRel32Minus1Anon));
|
||||
JITTargetAddress TargetAddress =
|
||||
FixupAddress + Delta + *(const little32_t *)FixupContent;
|
||||
if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
|
||||
auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1);
|
||||
if (!TargetNSec)
|
||||
return TargetNSec.takeError();
|
||||
if (auto TargetSymbolOrErr =
|
||||
findSymbolByAddress(*TargetNSec, TargetAddress))
|
||||
TargetSymbol = &*TargetSymbolOrErr;
|
||||
else
|
||||
return TargetSymbolOrErr.takeError();
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o %t %s
|
||||
# RUN: llvm-jitlink -noexec %t
|
||||
#
|
||||
# Check that JITLink handles anonymous relocations to the end of MachO sections.
|
||||
|
||||
.section __TEXT,__text,regular,pure_instructions
|
||||
.build_version macos, 11, 0 sdk_version 11, 1
|
||||
.globl _main
|
||||
.p2align 4, 0x90
|
||||
_main:
|
||||
|
||||
movq _R(%rip), %rax
|
||||
retq
|
||||
|
||||
.section __TEXT,__anon,regular
|
||||
L__anon_start:
|
||||
.byte 7
|
||||
L__anon_end:
|
||||
|
||||
.private_extern _R
|
||||
.section __DATA,__data
|
||||
.globl _R
|
||||
.p2align 3
|
||||
_R:
|
||||
.quad L__anon_end
|
||||
|
||||
.subsections_via_symbols
|
Loading…
Reference in New Issue