GP-2355 added support for AARCH64 ilp32

This commit is contained in:
emteere 2022-07-22 17:20:26 -04:00 committed by ghidra1
parent 6a9f0913fb
commit 35c013e109
6 changed files with 313 additions and 16 deletions

View File

@ -11,6 +11,7 @@ data/languages/AARCH64BE.slaspec||GHIDRA||||END|
data/languages/AARCH64_AMXext.sinc||GHIDRA||||END|
data/languages/AARCH64_AppleSilicon.slaspec||GHIDRA||||END|
data/languages/AARCH64_base_PACoptions.sinc||GHIDRA||||END|
data/languages/AARCH64_ilp32.cspec||GHIDRA||||END|
data/languages/AARCH64_win.cspec||GHIDRA||||END|
data/languages/AARCH64base.sinc||GHIDRA||||END|
data/languages/AARCH64instructions.sinc||GHIDRA||||END|

View File

@ -25,6 +25,8 @@
<global>
<range space="ram"/>
<!-- The decompiler will treat registers in this range as global variables.
ie: tmp_ldWn, tmp_ldXn, tmp_stWn, tmp_stXn -->
<range space="register" first="0x3000" last="0x3fff"/>
</global>

View File

@ -13,7 +13,6 @@
<compiler name="default" spec="AARCH64.cspec" id="default"/>
<compiler name="Visual Studio" spec="AARCH64_win.cspec" id="windows"/>
<external_name tool="gnu" name="aarch64"/>
<external_name tool="gnu" name="aarch64:ilp32"/>
<external_name tool="DWARF.register.mapping.file" name="AARCH64.dwarf"/>
</language>
<language processor="AARCH64"
@ -29,6 +28,36 @@
<description>Generic ARM v8.5-A LE instructions, BE data, missing some 8.5 vector</description>
<compiler name="default" spec="AARCH64.cspec" id="default"/>
<external_name tool="gnu" name="aarch64"/>
<external_name tool="DWARF.register.mapping.file" name="AARCH64.dwarf"/>
</language>
<language processor="AARCH64"
endian="little"
size="32"
variant="ilp32"
version="1.5"
slafile="AARCH64.sla"
processorspec="AARCH64.pspec"
manualindexfile="../manuals/AARCH64.idx"
id="AARCH64:LE:32:ilp32">
<description>Generic ARM v8.5-A LE instructions, LE data, ilp32</description>
<truncate_space space="ram" size="4"/>
<compiler name="default" spec="AARCH64_ilp32.cspec" id="default"/>
<external_name tool="gnu" name="aarch64:ilp32"/>
<external_name tool="DWARF.register.mapping.file" name="AARCH64.dwarf"/>
</language>
<language processor="AARCH64"
endian="big"
instructionEndian="little"
size="32"
variant="ilp32"
version="1.5"
slafile="AARCH64BE.sla"
processorspec="AARCH64.pspec"
manualindexfile="../manuals/AARCH64.idx"
id="AARCH64:BE:32:ilp32">
<description>Generic ARM v8.5-A LE instructions, BE data, ilp32</description>
<truncate_space space="ram" size="4"/>
<compiler name="default" spec="AARCH64_ilp32.cspec" id="default"/>
<external_name tool="gnu" name="aarch64:ilp32"/>
<external_name tool="DWARF.register.mapping.file" name="AARCH64.dwarf"/>
</language>

View File

@ -2,6 +2,9 @@
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
<constraint primary="183" processor="AARCH64" size="64" variant="v8A" />
</constraint>
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
<constraint primary="183" processor="AARCH64" size="32" variant="ilp32" />
</constraint>
<constraint loader="Mac OS X Mach-O" compilerSpecID="default">
<constraint primary="16777228" processor="AARCH64" endian="little" size="64" variant="AppleSilicon" />
</constraint>

View File

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="4" />
<default_alignment value="1" />
<default_pointer_alignment value="8" />
<pointer_size value="4" />
<wchar_size value="4" />
<short_size value="2" />
<integer_size value="4" />
<long_size value="4" />
<long_long_size value="8" />
<float_size value="4" />
<double_size value="8" />
<long_double_size value="8" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="8" />
</size_alignment_map>
</data_organization>
<global>
<range space="ram"/>
<!-- The decompiler will treat registers in this range as global variables.
ie: tmp_ldWn, tmp_ldXn, tmp_stWn, tmp_stXn -->
<range space="register" first="0x3000" last="0x3fff"/>
</global>
<aggressivetrim signext="true"/> <!-- Aggressively try to eliminate sign extensions -->
<stackpointer register="sp" space="ram"/>
<funcptr align="4"/> <!-- Function pointers are word aligned and leastsig bit may encode otherstuff -->
<prefersplit style="inhalf">
<register name="q0"/>
<register name="q1"/>
<register name="q2"/>
<register name="q3"/>
<register name="q4"/>
<register name="q5"/>
<register name="q6"/>
<register name="q7"/>
<register name="q8"/>
<register name="q9"/>
<register name="q10"/>
<register name="q11"/>
<register name="q12"/>
<register name="q13"/>
<register name="q14"/>
<register name="q15"/>
<register name="q16"/>
<register name="q17"/>
<register name="q18"/>
<register name="q19"/>
<register name="q20"/>
<register name="q21"/>
<register name="q22"/>
<register name="q23"/>
<register name="q24"/>
<register name="q25"/>
<register name="q26"/>
<register name="q27"/>
<register name="q28"/>
<register name="q29"/>
<register name="q30"/>
</prefersplit>
<default_proto>
<prototype name="__cdecl" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d0"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d1"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d2"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d3"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d4"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d5"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d6"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d7"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x0"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x1"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x2"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x3"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x4"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x5"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x6"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x7"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d0"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x0"/>
</pentry>
<pentry minsize="9" maxsize="16" extension="zero">
<addr space="join" piece1="x1" piece2="x0"/>
</pentry>
</output>
<unaffected>
<register name="x19"/>
<register name="x20"/>
<register name="x21"/>
<register name="x22"/>
<register name="x23"/>
<register name="x24"/>
<register name="x25"/>
<register name="x26"/>
<register name="x27"/>
<register name="x28"/>
<register name="x29"/>
<register name="x30"/>
<register name="sp"/>
<!-- vectors -->
<register name="d8"/>
<register name="d9"/>
<register name="d10"/>
<register name="d11"/>
<register name="d12"/>
<register name="d13"/>
<register name="d14"/>
<register name="d15"/>
</unaffected>
<killedbycall>
<!-- x8: indirect result location register, which is not
reflected in the pentry list -->
<register name="x8"/>
<register name="x9"/>
<register name="x10"/>
<register name="x11"/>
<register name="x12"/>
<register name="x13"/>
<register name="x14"/>
<register name="x15"/>
<register name="x16"/>
<register name="x17"/>
<register name="x18"/>
<!-- vectors -->
<register name="d16"/>
<register name="d17"/>
<register name="d18"/>
<register name="d19"/>
<register name="d20"/>
<register name="d21"/>
<register name="d22"/>
<register name="d23"/>
<register name="d24"/>
<register name="d25"/>
<register name="d26"/>
<register name="d27"/>
<register name="d28"/>
<register name="d29"/>
<register name="d30"/>
<register name="d31"/>
</killedbycall>
</prototype>
</default_proto>
<callfixup name="PlaceHolderCallFixup"> <!-- This is here just to force call fixup and NoReturn fixup. Will be fixed in Ghidra V6.0 -->
<target name="___NotARealFunctionName___"/>
<pcode>
<body><![CDATA[
tmpptr:4 = 0;
]]></body>
</pcode>
</callfixup>
</compiler_spec>

View File

@ -64,6 +64,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
boolean isBigEndianInstructions =
program.getLanguage().getLanguageDescription().getInstructionEndian().isBigEndian();
boolean is64bit = true;
Address symbolAddr = elfRelocationContext.getSymbolAddress(sym);
long symbolValue = elfRelocationContext.getSymbolValue(sym);
long newValue = 0;
@ -81,14 +83,17 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
}
// .word: (S+A)
case AARCH64_ElfRelocationConstants.R_AARCH64_ABS32: {
case AARCH64_ElfRelocationConstants.R_AARCH64_ABS32:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_ABS32:{
newValue = (symbolValue + addend);
memory.setInt(relocationAddress, (int) (newValue & 0xffffffff));
break;
}
// .half: (S+A)
case AARCH64_ElfRelocationConstants.R_AARCH64_ABS16: {
case AARCH64_ElfRelocationConstants.R_AARCH64_ABS16:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_ABS16: {
newValue = (symbolValue + addend);
memory.setShort(relocationAddress, (short) (newValue & 0xffff));
break;
@ -103,7 +108,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
}
// .word: (S+A-P)
case AARCH64_ElfRelocationConstants.R_AARCH64_PREL32: {
case AARCH64_ElfRelocationConstants.R_AARCH64_PREL32:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_PREL32: {
newValue = (symbolValue + addend);
newValue -= (offset); // PC relative
memory.setInt(relocationAddress, (int) (newValue & 0xffffffff));
@ -111,7 +117,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
}
// .half: (S+A-P)
case AARCH64_ElfRelocationConstants.R_AARCH64_PREL16: {
case AARCH64_ElfRelocationConstants.R_AARCH64_PREL16:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_PREL16: {
newValue = (symbolValue + addend);
newValue -= (offset); // PC relative
memory.setShort(relocationAddress, (short) (newValue & 0xffff));
@ -119,7 +126,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
}
// ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff
case AARCH64_ElfRelocationConstants.R_AARCH64_ADR_PREL_PG_HI21: {
case AARCH64_ElfRelocationConstants.R_AARCH64_ADR_PREL_PG_HI21:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_ADR_PREL_PG_HI21: {
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
newValue = ((PG(symbolValue + addend) - PG(offset)) >> 12) & 0x1fffff;
@ -131,7 +139,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
}
// ADD: (S+A) & 0xfff
case AARCH64_ElfRelocationConstants.R_AARCH64_ADD_ABS_LO12_NC: {
case AARCH64_ElfRelocationConstants.R_AARCH64_ADD_ABS_LO12_NC:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_ADD_ABS_LO12_NC: {
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
newValue = (int) (symbolValue + addend) & 0xfff;
@ -142,7 +151,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
}
// LD/ST8: (S+A) & 0xfff
case AARCH64_ElfRelocationConstants.R_AARCH64_LDST8_ABS_LO12_NC: {
case AARCH64_ElfRelocationConstants.R_AARCH64_LDST8_ABS_LO12_NC:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_LDST8_ABS_LO12_NC: {
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
newValue = (int) (symbolValue + addend) & 0xfff;
@ -155,7 +165,9 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
// B: ((S+A-P) >> 2) & 0x3ffffff.
// BL: ((S+A-P) >> 2) & 0x3ffffff
case AARCH64_ElfRelocationConstants.R_AARCH64_JUMP26:
case AARCH64_ElfRelocationConstants.R_AARCH64_CALL26: {
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_JUMP26:
case AARCH64_ElfRelocationConstants.R_AARCH64_CALL26:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_CALL26: {
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
newValue = (symbolValue + addend);
@ -168,7 +180,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
}
// LD/ST16: (S+A) & 0xffe
case AARCH64_ElfRelocationConstants.R_AARCH64_LDST16_ABS_LO12_NC: {
case AARCH64_ElfRelocationConstants.R_AARCH64_LDST16_ABS_LO12_NC:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_LDST16_ABS_LO12_NC: {
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
newValue = (int) ((symbolValue + addend) & 0xffe) >> 1;
@ -179,7 +192,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
}
// LD/ST32: (S+A) & 0xffc
case AARCH64_ElfRelocationConstants.R_AARCH64_LDST32_ABS_LO12_NC: {
case AARCH64_ElfRelocationConstants.R_AARCH64_LDST32_ABS_LO12_NC:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_LDST32_ABS_LO12_NC: {
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
newValue = (int) ((symbolValue + addend) & 0xffc) >> 2;
@ -191,6 +205,7 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
// LD/ST64: (S+A) & 0xff8
case AARCH64_ElfRelocationConstants.R_AARCH64_LDST64_ABS_LO12_NC:
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_LDST64_ABS_LO12_NC:
case AARCH64_ElfRelocationConstants.R_AARCH64_LD64_GOT_LO12_NC: {
int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions);
newValue = (int) ((symbolValue + addend) & 0xff8) >> 3;
@ -212,16 +227,20 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
break;
}
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_GLOB_DAT:
is64bit = false;
case AARCH64_ElfRelocationConstants.R_AARCH64_GLOB_DAT: {
// Corresponds to resolved local/EXTERNAL symbols within GOT
if (elfRelocationContext.extractAddend()) {
addend = memory.getLong(relocationAddress);
addend = getValue(memory, relocationAddress, is64bit);
}
newValue = symbolValue + addend;
memory.setLong(relocationAddress, newValue);
setValue(memory, relocationAddress, newValue, is64bit);
break;
}
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_JUMP_SLOT:
is64bit = false;
case AARCH64_ElfRelocationConstants.R_AARCH64_JUMP_SLOT: {
// Corresponds to lazy dynamically linked external symbols within
// GOT/PLT symbolValue corresponds to PLT entry for which we need to
@ -233,7 +252,7 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
boolean isExternalSym =
block != null && MemoryBlock.EXTERNAL_BLOCK_NAME.equals(block.getName());
if (!isPltSym) {
memory.setLong(relocationAddress, symAddress.getOffset());
setValue(memory, relocationAddress, symAddress.getOffset(), is64bit);
}
if (isPltSym || isExternalSym) {
Function extFunction =
@ -249,15 +268,18 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
break;
}
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_RELATIVE:
is64bit = false;
case AARCH64_ElfRelocationConstants.R_AARCH64_RELATIVE: {
if (elfRelocationContext.extractAddend()) {
addend = memory.getLong(relocationAddress);
addend = getValue(memory, relocationAddress, is64bit);
}
newValue = elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend;
memory.setLong(relocationAddress, newValue);
setValue(memory, relocationAddress, newValue, is64bit);
break;
}
case AARCH64_ElfRelocationConstants.R_AARCH64_P32_COPY:
case AARCH64_ElfRelocationConstants.R_AARCH64_COPY: {
markAsWarning(program, relocationAddress, "R_AARCH64_COPY", symbolName, symbolIndex,
"Runtime copy not supported", elfRelocationContext.getLog());
@ -271,6 +293,39 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler {
}
}
/**
* Set the new value in memory
* @param memory memory
* @param addr address to set new value
* @param value value
* @param is64bit true if value is 64, false if 32bit
* @throws MemoryAccessException on set of value
*/
private void setValue(Memory memory, Address addr, long value, boolean is64bit)
throws MemoryAccessException {
if (is64bit) {
memory.setLong(addr, value);
} else {
memory.setInt(addr, (int) value);
}
}
/**
* Get a 64 or 32 bit value from memory
* @param memory memory
* @param addr address in memory
* @param is64bit true if 64 bit value, false if 32 bit value
* @return value from memory as a long
* @throws MemoryAccessException
*/
private long getValue(Memory memory, Address addr, boolean is64bit)
throws MemoryAccessException {
if (is64bit) {
return memory.getLong(addr);
}
return memory.getInt(addr);
}
long PG(long addr) {
return addr & (~0xfff);
}