Skip to content

Commit ce5f6b4

Browse files
committed
Merge remote-tracking branch
'origin/GP-3435_ghidra1_PR-5292_dukesilverrr_R_AARCH64_MOVW_UABS_G_Relocs' (Closes #3545, Closes #3546, Closes #5292)
2 parents 4b99900 + 90d4864 commit ce5f6b4

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationHandler.java

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ public RelocationResult relocate(ElfRelocationContext elfRelocationContext,
7171

7272
boolean is64bit = true;
7373

74+
boolean overflowCheck = true; // *_NC type relocations specify "no overflow check"
75+
7476
Address symbolAddr = elfRelocationContext.getSymbolAddress(sym);
7577
long symbolValue = elfRelocationContext.getSymbolValue(sym);
7678
long newValue = 0;
@@ -137,6 +139,87 @@ public RelocationResult relocate(ElfRelocationContext elfRelocationContext,
137139
break;
138140
}
139141

142+
// MOV[ZK]: ((S+A) >> 0) & 0xffff
143+
case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G0_NC: {
144+
overflowCheck = false;
145+
// fall-through
146+
}
147+
case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G0: {
148+
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
149+
long imm = (symbolValue + addend) >> 0;
150+
151+
oldValue &= ~(0xffff << 5);
152+
newValue = oldValue | ((imm & 0xffff) << 5);
153+
154+
memory.setInt(relocationAddress, (int) newValue, isBigEndianInstructions);
155+
156+
if (overflowCheck && imm > 0xffffL) {
157+
// relocation already applied; report overflow condition
158+
markAsError(program, relocationAddress, "R_AARCH64_MOVW_UABS_G0", symbolName,
159+
"Failed overflow check for R_AARCH64_MOVW_UABS_G0 immediate value",
160+
elfRelocationContext.getLog());
161+
}
162+
break;
163+
}
164+
165+
// MOV[ZK]: ((S+A) >> 16) & 0xffff
166+
case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G1_NC: {
167+
overflowCheck = false;
168+
// fall-through
169+
}
170+
case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G1: {
171+
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
172+
long imm = (symbolValue + addend) >> 16;
173+
174+
oldValue &= ~(0xffff << 5);
175+
newValue = oldValue | ((imm & 0xffff) << 5);
176+
177+
memory.setInt(relocationAddress, (int) newValue, isBigEndianInstructions);
178+
179+
if (overflowCheck && imm > 0xffffL) {
180+
// relocation already applied; report overflow condition
181+
markAsError(program, relocationAddress, "R_AARCH64_MOVW_UABS_G0", symbolName,
182+
"Failed overflow check for R_AARCH64_MOVW_UABS_G0 immediate value",
183+
elfRelocationContext.getLog());
184+
}
185+
break;
186+
}
187+
188+
// MOV[ZK]: ((S+A) >> 32) & 0xffff
189+
case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G2_NC: {
190+
overflowCheck = false;
191+
// fall-through
192+
}
193+
case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G2: {
194+
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
195+
long imm = (symbolValue + addend) >> 32;
196+
197+
oldValue &= ~(0xffff << 5);
198+
newValue = oldValue | ((imm & 0xffff) << 5);
199+
200+
memory.setInt(relocationAddress, (int) newValue, isBigEndianInstructions);
201+
202+
if (overflowCheck && imm > 0xffffL) {
203+
// relocation already applied; report overflow condition
204+
markAsError(program, relocationAddress, "R_AARCH64_MOVW_UABS_G0", symbolName,
205+
"Failed overflow check for R_AARCH64_MOVW_UABS_G0 immediate value",
206+
elfRelocationContext.getLog());
207+
}
208+
break;
209+
}
210+
211+
// MOV[ZK]: ((S+A) >> 48) & 0xffff
212+
case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G3: {
213+
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
214+
long imm = (symbolValue + addend) >> 48;
215+
216+
oldValue &= ~(0xffff << 5);
217+
newValue = oldValue | ((imm & 0xffff) << 5);
218+
219+
memory.setInt(relocationAddress, (int) newValue, isBigEndianInstructions);
220+
break;
221+
}
222+
140223
// ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff
141224
case AARCH64_ElfRelocationConstants.R_AARCH64_ADR_PREL_PG_HI21:
142225
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_ADR_PREL_PG_HI21: {

0 commit comments

Comments
 (0)