From b13b4d64ee619e9b41dd36abdc90a558c9f2d528 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Sun, 5 Jan 2020 18:41:43 +0100 Subject: [PATCH] Add Xtensa ELF constants Put together by @mumbel, thanks! --- .../Xtensa_ElfRelocationConstants.java | 58 ++++ .../Xtensa_ElfRelocationHandler.java | 292 ++++++++++++++++++ 2 files changed, 350 insertions(+) create mode 100644 src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java create mode 100644 src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java diff --git a/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java b/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java new file mode 100644 index 0000000..f74eb6d --- /dev/null +++ b/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java @@ -0,0 +1,58 @@ +package ghidra.app.util.bin.format.elf.relocation; + +public class Xtensa_ElfRelocationConstants { + /* Xtensa processor ELF architecture-magic number */ + + // EM_XTENSA is already definded + public static final int EM_XTENSA_OLD = 0xABC7; + + /* Xtensa relocations defined by the ABIs */ + + public static final int R_XTENSA_NONE = 0; + public static final int R_XTENSA_32 = 1; + public static final int R_XTENSA_RTLD = 2; + public static final int R_XTENSA_GLOB_DAT = 3; + public static final int R_XTENSA_JMP_SLOT = 4; + public static final int R_XTENSA_RELATIVE = 5; + public static final int R_XTENSA_PLT = 6; + public static final int R_XTENSA_OP0 = 8; + public static final int R_XTENSA_OP1 = 9; + public static final int R_XTENSA_OP2 = 10; + public static final int R_XTENSA_ASM_EXPAND = 11; + public static final int R_XTENSA_ASM_SIMPLIFY = 12; + public static final int R_XTENSA_GNU_VTINHERIT = 15; + public static final int R_XTENSA_GNU_VTENTRY = 16; + public static final int R_XTENSA_DIFF8 = 17; + public static final int R_XTENSA_DIFF16 = 18; + public static final int R_XTENSA_DIFF32 = 19; + public static final int R_XTENSA_SLOT0_OP = 20; + public static final int R_XTENSA_SLOT1_OP = 21; + public static final int R_XTENSA_SLOT2_OP = 22; + public static final int R_XTENSA_SLOT3_OP = 23; + public static final int R_XTENSA_SLOT4_OP = 24; + public static final int R_XTENSA_SLOT5_OP = 25; + public static final int R_XTENSA_SLOT6_OP = 26; + public static final int R_XTENSA_SLOT7_OP = 27; + public static final int R_XTENSA_SLOT8_OP = 28; + public static final int R_XTENSA_SLOT9_OP = 29; + public static final int R_XTENSA_SLOT10_OP = 30; + public static final int R_XTENSA_SLOT11_OP = 31; + public static final int R_XTENSA_SLOT12_OP = 32; + public static final int R_XTENSA_SLOT13_OP = 33; + public static final int R_XTENSA_SLOT14_OP = 34; + public static final int R_XTENSA_SLOT0_ALT = 35; + public static final int R_XTENSA_SLOT1_ALT = 36; + public static final int R_XTENSA_SLOT2_ALT = 37; + public static final int R_XTENSA_SLOT3_ALT = 38; + public static final int R_XTENSA_SLOT4_ALT = 39; + public static final int R_XTENSA_SLOT5_ALT = 40; + public static final int R_XTENSA_SLOT6_ALT = 41; + public static final int R_XTENSA_SLOT7_ALT = 42; + public static final int R_XTENSA_SLOT8_ALT = 43; + public static final int R_XTENSA_SLOT9_ALT = 44; + public static final int R_XTENSA_SLOT10_ALT = 45; + public static final int R_XTENSA_SLOT11_ALT = 46; + public static final int R_XTENSA_SLOT12_ALT = 47; + public static final int R_XTENSA_SLOT13_ALT = 48; + public static final int R_XTENSA_SLOT14_ALT = 49; +} diff --git a/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java b/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java new file mode 100644 index 0000000..5882690 --- /dev/null +++ b/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java @@ -0,0 +1,292 @@ +package ghidra.app.util.bin.format.elf.relocation; + +import ghidra.app.util.bin.format.elf.ElfConstants; +import ghidra.app.util.bin.format.elf.ElfHeader; +import ghidra.app.util.bin.format.elf.ElfRelocation; +import ghidra.app.util.bin.format.elf.ElfSymbol; +import ghidra.program.model.address.Address; +import ghidra.program.model.listing.Program; +import ghidra.program.model.mem.Memory; +import ghidra.program.model.mem.MemoryAccessException; +import ghidra.util.exception.NotFoundException; + +public class Xtensa_ElfRelocationHandler extends ElfRelocationHandler { + + @Override + public boolean canRelocate(ElfHeader elf) { + return elf.e_machine() == ElfConstants.EM_XTENSA || + elf.e_machine() == Xtensa_ElfRelocationConstants.EM_XTENSA_OLD; + } + + @Override + public void relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation, Address relocationAddress) + throws MemoryAccessException, NotFoundException { + ElfHeader elf = elfRelocationContext.getElfHeader(); + if (!canRelocate(elf)) { + return; + } + + int type=relocation.getType(); + if (Xtensa_ElfRelocationConstants.R_XTENSA_NONE == type) { + return; + } + + Program program = elfRelocationContext.getProgram(); + Memory memory = program.getMemory(); + + long addend = relocation.hasAddend() ? relocation.getAddend() : memory.getInt(relocationAddress); + long offset = relocationAddress.getOffset(); + long base = elfRelocationContext.getImageBaseWordAdjustmentOffset(); + ElfSymbol sym = null; + long symbolValue = 0; + String symbolName = null; + + int symbolIndex = relocation.getSymbolIndex(); + if (symbolIndex != 0) { + sym = elfRelocationContext.getSymbol(symbolIndex); + } + + if (null != sym) { + symbolValue = elfRelocationContext.getSymbolValue(sym); + symbolName = sym.getNameAsString(); + } + + switch(type) { + case Xtensa_ElfRelocationConstants.R_XTENSA_32: + markAsWarning(program, relocationAddress, "R_XTENSA_32", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_RTLD: + markAsWarning(program, relocationAddress, "R_XTENSA_RTLD", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_GLOB_DAT: + markAsWarning(program, relocationAddress, "R_XTENSA_GLOB_DAT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_JMP_SLOT: + markAsWarning(program, relocationAddress, "R_XTENSA_JMP_SLOT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_RELATIVE: + markAsWarning(program, relocationAddress, "R_XTENSA_RELATIVE", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_PLT: + markAsWarning(program, relocationAddress, "R_XTENSA_PLT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_OP0: + markAsWarning(program, relocationAddress, "R_XTENSA_OP0", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_OP1: + markAsWarning(program, relocationAddress, "R_XTENSA_OP1", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_OP2: + markAsWarning(program, relocationAddress, "R_XTENSA_OP2", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_EXPAND: + markAsWarning(program, relocationAddress, "R_XTENSA_ASM_EXPAND", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_SIMPLIFY: + markAsWarning(program, relocationAddress, "R_XTENSA_ASM_SIMPLIFY", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTINHERIT: + markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTINHERIT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTENTRY: + markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTENTRY", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF8: + markAsWarning(program, relocationAddress, "R_XTENSA_DIFF8", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF16: + markAsWarning(program, relocationAddress, "R_XTENSA_DIFF16", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF32: + markAsWarning(program, relocationAddress, "R_XTENSA_DIFF32", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_OP: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_OP", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_ALT: + markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_ALT", + symbolName, symbolIndex, "TODO, needs support ", + elfRelocationContext.getLog()); + break; + default: + markAsUnhandled(program, relocationAddress, type, symbolIndex, + symbolName, elfRelocationContext.getLog()); + break; + } + } + +}