You've already forked linux-packaging-mono
Imported Upstream version 6.4.0.137
Former-commit-id: 943baa9f16a098c33e129777827f3a9d20da00d6
This commit is contained in:
parent
e9207cf623
commit
ef583813eb
@ -1422,7 +1422,8 @@ RuntimeDyldELF::processRelocationRef(
|
||||
SectionEntry &Section = Sections[SectionID];
|
||||
uint8_t *Target = Section.getAddressWithOffset(Offset);
|
||||
bool RangeOverflow = false;
|
||||
if (!Value.SymbolName && SymType != SymbolRef::ST_Unknown) {
|
||||
bool IsExtern = Value.SymbolName || SymType == SymbolRef::ST_Unknown;
|
||||
if (!IsExtern) {
|
||||
if (AbiVariant != 2) {
|
||||
// In the ELFv1 ABI, a function call may point to the .opd entry,
|
||||
// so the final symbol value is calculated based on the relocation
|
||||
@ -1432,21 +1433,24 @@ RuntimeDyldELF::processRelocationRef(
|
||||
} else {
|
||||
// In the ELFv2 ABI, a function symbol may provide a local entry
|
||||
// point, which must be used for direct calls.
|
||||
uint8_t SymOther = Symbol->getOther();
|
||||
Value.Addend += ELF::decodePPC64LocalEntryOffset(SymOther);
|
||||
if (Value.SectionID == SectionID){
|
||||
uint8_t SymOther = Symbol->getOther();
|
||||
Value.Addend += ELF::decodePPC64LocalEntryOffset(SymOther);
|
||||
}
|
||||
}
|
||||
uint8_t *RelocTarget =
|
||||
Sections[Value.SectionID].getAddressWithOffset(Value.Addend);
|
||||
int64_t delta = static_cast<int64_t>(Target - RelocTarget);
|
||||
// If it is within 26-bits branch range, just set the branch target
|
||||
if (SignExtend64<26>(delta) == delta) {
|
||||
if (SignExtend64<26>(delta) != delta) {
|
||||
RangeOverflow = true;
|
||||
} else if ((AbiVariant != 2) ||
|
||||
(AbiVariant == 2 && Value.SectionID == SectionID)) {
|
||||
RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);
|
||||
addRelocationForSection(RE, Value.SectionID);
|
||||
} else {
|
||||
RangeOverflow = true;
|
||||
}
|
||||
}
|
||||
if (Value.SymbolName || SymType == SymbolRef::ST_Unknown ||
|
||||
if (IsExtern || (AbiVariant == 2 && Value.SectionID != SectionID) ||
|
||||
RangeOverflow) {
|
||||
// It is an external symbol (either Value.SymbolName is set, or
|
||||
// SymType is SymbolRef::ST_Unknown) or out of range.
|
||||
@ -1503,10 +1507,10 @@ RuntimeDyldELF::processRelocationRef(
|
||||
RelType, 0);
|
||||
Section.advanceStubOffset(getMaxStubSize());
|
||||
}
|
||||
if (Value.SymbolName || SymType == SymbolRef::ST_Unknown) {
|
||||
if (IsExtern || (AbiVariant == 2 && Value.SectionID != SectionID)) {
|
||||
// Restore the TOC for external calls
|
||||
if (AbiVariant == 2)
|
||||
writeInt32BE(Target + 4, 0xE8410018); // ld r2,28(r1)
|
||||
writeInt32BE(Target + 4, 0xE8410018); // ld r2,24(r1)
|
||||
else
|
||||
writeInt32BE(Target + 4, 0xE8410028); // ld r2,40(r1)
|
||||
}
|
||||
|
Reference in New Issue
Block a user