Skip to content

Commit d6375b0

Browse files
Merge pull request #8761 from al45tair/eng/PR-127673408-6.0
[RuntimeDyld][ELF][AArch64] Fix resolveAArch64ShortBranch.
2 parents aacd1ee + bb6fbcc commit d6375b0

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-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
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# RUN: llvm-mc -triple=arm64-none-linux-gnu -filetype=obj -o %t %s
2+
# RUN: llvm-rtdyld -triple=arm64-none-linux-gnu -verify -check=%s %t
3+
4+
.globl _main
5+
.weak _label1
6+
7+
.section .text.label1,"ax"
8+
_label1:
9+
nop
10+
11+
.section .text.main,"ax"
12+
_main:
13+
b _label1
14+
15+
# Branch must be to stub in .text.main, *not* back to _label1, because
16+
# in general sections could be loaded at arbitrary addresses in target memory,
17+
# and when initially processing locations and generating stubs we don't know
18+
# the final layout yet, so we can't tell if the branch offset is within range.
19+
20+
# rtdyld-check: *{4}(_main) = 0x14000001

0 commit comments

Comments
 (0)