Skip to content

Commit 73f36fe

Browse files
committed
[RuntimeDyld][ELF][AArch64] Fix resolveAArch64ShortBranch.
We don't know the load addresses when this function is called, so it shouldn't be trying to use them to determine whether or not the branch is short. Notably, this will fail in the case where the code is being loaded into a target in such a way that the section offsets differ between the process generating the code and the target process.
1 parent c66e398 commit 73f36fe

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,8 @@ uint32_t RuntimeDyldELF::getMatchingLoRelocation(uint32_t RelType,
11281128
bool RuntimeDyldELF::resolveAArch64ShortBranch(
11291129
unsigned SectionID, relocation_iterator RelI,
11301130
const RelocationValueRef &Value) {
1131-
uint64_t Address;
1131+
uint64_t TargetOffset;
1132+
unsigned TargetSectionID;
11321133
if (Value.SymbolName) {
11331134
auto Loc = GlobalSymbolTable.find(Value.SymbolName);
11341135

@@ -1137,23 +1138,32 @@ bool RuntimeDyldELF::resolveAArch64ShortBranch(
11371138
return false;
11381139

11391140
const auto &SymInfo = Loc->second;
1140-
Address =
1141-
uint64_t(Sections[SymInfo.getSectionID()].getLoadAddressWithOffset(
1142-
SymInfo.getOffset()));
1141+
1142+
TargetSectionID = SymInfo.getSectionID();
1143+
TargetOffset = SymInfo.getOffset();
11431144
} else {
1144-
Address = uint64_t(Sections[Value.SectionID].getLoadAddress());
1145+
TargetSectionID = Value.SectionID;
1146+
TargetOffset = 0;
11451147
}
1146-
uint64_t Offset = RelI->getOffset();
1147-
uint64_t SourceAddress = Sections[SectionID].getLoadAddressWithOffset(Offset);
1148+
1149+
// We don't actually know the load addresses at this point, so if the
1150+
// branch is cross-section, we don't know exactly how far away it is.
1151+
if (TargetSectionID != SectionID)
1152+
return false;
1153+
1154+
uint64_t SourceOffset = RelI->getOffset();
11481155

11491156
// R_AARCH64_CALL26 requires immediate to be in range -2^27 <= imm < 2^27
11501157
// If distance between source and target is out of range then we should
11511158
// create thunk.
1152-
if (!isInt<28>(Address + Value.Addend - SourceAddress))
1159+
if (!isInt<28>(TargetOffset + Value.Addend - SourceOffset))
11531160
return false;
11541161

1155-
resolveRelocation(Sections[SectionID], Offset, Address, RelI->getType(),
1156-
Value.Addend);
1162+
RelocationEntry RE(SectionID, SourceOffset, RelI->getType(), Value.Addend);
1163+
if (Value.SymbolName)
1164+
addRelocationForSymbol(RE, Value.SymbolName);
1165+
else
1166+
addRelocationForSection(RE, Value.SectionID);
11571167

11581168
return true;
11591169
}

0 commit comments

Comments
 (0)