From d543ca8e3d1eafb724f1d67bc2eafbc5bf530ba4 Mon Sep 17 00:00:00 2001 From: Ivan Kuzmenko <6745157+rndtrash@users.noreply.github.com> Date: Fri, 17 Nov 2023 07:32:11 +0300 Subject: [PATCH 1/2] Add support for PowerPC COFF Relocations --- .../PowerPC_CoffRelocationHandler.java | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/coff/relocation/PowerPC_CoffRelocationHandler.java diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/coff/relocation/PowerPC_CoffRelocationHandler.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/coff/relocation/PowerPC_CoffRelocationHandler.java new file mode 100644 index 0000000000..826e4eb8f9 --- /dev/null +++ b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/coff/relocation/PowerPC_CoffRelocationHandler.java @@ -0,0 +1,194 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.coff.relocation; + +import ghidra.app.util.bin.format.RelocationException; +import ghidra.app.util.bin.format.coff.CoffFileHeader; +import ghidra.app.util.bin.format.coff.CoffMachineType; +import ghidra.app.util.bin.format.coff.CoffRelocation; +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.program.model.reloc.Relocation; +import ghidra.program.model.reloc.RelocationResult; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; + +public class PowerPC_CoffRelocationHandler implements CoffRelocationHandler { + + @Override + public boolean canRelocate(CoffFileHeader fileHeader) { + return fileHeader.getMachine() == CoffMachineType.IMAGE_FILE_MACHINE_POWERPC; + } + + @Override + public RelocationResult relocate(Address address, CoffRelocation relocation, + CoffRelocationContext relocationContext) + throws MemoryAccessException, RelocationException { + + Program program = relocationContext.getProgram(); + Memory mem = program.getMemory(); + + int addend = mem.getInt(address); + + int byteLength = 4; // most relocations affect 4-bytes (change if different) + + switch (relocation.getType()) { + + // We are implementing these types: + case IMAGE_REL_PPC_ADDR32: { + int value = (int) relocationContext.getSymbolAddress(relocation) + .add(addend) + .getOffset(); + program.getMemory().setInt(address, value); + break; + } + case IMAGE_REL_PPC_ADDR32NB: { + int value = (int) relocationContext.getSymbolAddress(relocation) + .add(addend) + .subtract(program.getImageBase()); + mem.setInt(address, value); + break; + } + + // We are choosing to ignore these types: + case IMAGE_REL_PPC_ABSOLUTE: + case IMAGE_REL_PPC_SECTION: + case IMAGE_REL_PPC_SECREL: + case IMAGE_REL_PPC_TOKEN: { + return RelocationResult.SKIPPED; + } + + // We haven't implemented these types yet: + case IMAGE_REL_PPC_ADDR64: + case IMAGE_REL_PPC_ADDR24: + case IMAGE_REL_PPC_ADDR16: + case IMAGE_REL_PPC_ADDR14: + case IMAGE_REL_PPC_REL24: + case IMAGE_REL_PPC_REL14: + case IMAGE_REL_PPC_SECREL16: + case IMAGE_REL_PPC_REFHI: + case IMAGE_REL_PPC_REFLO: + case IMAGE_REL_PPC_PAIR: + case IMAGE_REL_PPC_SECRELLO: + case IMAGE_REL_PPC_GPREL: + default: { + return RelocationResult.UNSUPPORTED; + } + } + return new RelocationResult(Relocation.Status.APPLIED, byteLength); + } + + /** + * The relocation is ignored. + */ + public final static short IMAGE_REL_PPC_ABSOLUTE = 0x0000; + + /** + * The 64-bit VA of the target. + */ + public final static short IMAGE_REL_PPC_ADDR64 = 0x0001; + + /** + * The 32-bit VA of the target. + */ + public final static short IMAGE_REL_PPC_ADDR32 = 0x0002; + + /** + * The low 24 bits of the VA of the target. + * This is valid only when the target symbol is absolute and can be sign-extended to its original value. + */ + public final static short IMAGE_REL_PPC_ADDR24 = 0x0003; + + /** + * The low 16 bits of the target's VA. + */ + public final static short IMAGE_REL_PPC_ADDR16 = 0x0004; + + /** + * The low 14 bits of the target's VA. + * This is valid only when the target symbol is absolute and can be sign-extended to its original value. + */ + public final static short IMAGE_REL_PPC_ADDR14 = 0x0005; + + /** + * A 24-bit PC-relative offset to the symbol's location. + */ + public final static short IMAGE_REL_PPC_REL24 = 0x0006; + + /** + * A 14-bit PC-relative offset to the symbol's location. + */ + public final static short IMAGE_REL_PPC_REL14 = 0x0007; + + /** + * The 32-bit RVA of the target. + */ + public final static short IMAGE_REL_PPC_ADDR32NB = 0x000A; + + /** + * The 32-bit offset of the target from the beginning of its section. + * This is used to support debugging information and static thread local storage. + */ + public final static short IMAGE_REL_PPC_SECREL = 0x000B; + + /** + * The 16-bit section index of the section that contains the target. + * This is used to support debugging information. + */ + public final static short IMAGE_REL_PPC_SECTION = 0x000C; + + /** + * The 16-bit offset of the target from the beginning of its section. + * This is used to support debugging information and static thread local storage. + */ + public final static short IMAGE_REL_PPC_SECREL16 = 0x000F; + + /** + * The high 16 bits of the target's 32-bit VA. + * This is used for the first instruction in a two-instruction sequence that loads a full address. + * This relocation must be immediately followed by a PAIR relocation whose SymbolTableIndex contains a signed + * 16-bit displacement that is added to the upper 16 bits that was taken from the location that is being relocated. + */ + public final static short IMAGE_REL_PPC_REFHI = 0x0010; + + /** + * The low 16 bits of the target's VA. + */ + public final static short IMAGE_REL_PPC_REFLO = 0x0011; + + /** + * A relocation that is valid only when it immediately follows a REFHI or SECRELHI relocation. + * Its SymbolTableIndex contains a displacement and not an index into the symbol table. + */ + public final static short IMAGE_REL_PPC_PAIR = 0x0012; + + /** + * The low 16 bits of the 32-bit offset of the target from the beginning of its section. + */ + public final static short IMAGE_REL_PPC_SECRELLO = 0x0013; + + /** + * The 16-bit signed displacement of the target relative to the GP register. + */ + public final static short IMAGE_REL_PPC_GPREL = 0x0015; + + /** + * The CLR token. + */ + public final static short IMAGE_REL_PPC_TOKEN = 0x0016; +} From c3b4f5eda0401072a361da642e6b465ecb2de215 Mon Sep 17 00:00:00 2001 From: Ryan Kurtz Date: Mon, 20 Nov 2023 14:24:10 -0500 Subject: [PATCH 2/2] GP-0: Formatting/Certify. Also removing untested code. --- .../PowerPC_CoffRelocationHandler.java | 270 ++++++++---------- 1 file changed, 121 insertions(+), 149 deletions(-) diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/coff/relocation/PowerPC_CoffRelocationHandler.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/coff/relocation/PowerPC_CoffRelocationHandler.java index 826e4eb8f9..7c2d078632 100644 --- a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/coff/relocation/PowerPC_CoffRelocationHandler.java +++ b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/coff/relocation/PowerPC_CoffRelocationHandler.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,179 +16,151 @@ package ghidra.app.util.bin.format.coff.relocation; import ghidra.app.util.bin.format.RelocationException; -import ghidra.app.util.bin.format.coff.CoffFileHeader; -import ghidra.app.util.bin.format.coff.CoffMachineType; -import ghidra.app.util.bin.format.coff.CoffRelocation; +import ghidra.app.util.bin.format.coff.*; 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.program.model.reloc.Relocation; import ghidra.program.model.reloc.RelocationResult; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; public class PowerPC_CoffRelocationHandler implements CoffRelocationHandler { - @Override - public boolean canRelocate(CoffFileHeader fileHeader) { - return fileHeader.getMachine() == CoffMachineType.IMAGE_FILE_MACHINE_POWERPC; - } + @Override + public boolean canRelocate(CoffFileHeader fileHeader) { + return fileHeader.getMachine() == CoffMachineType.IMAGE_FILE_MACHINE_POWERPC; + } - @Override - public RelocationResult relocate(Address address, CoffRelocation relocation, - CoffRelocationContext relocationContext) - throws MemoryAccessException, RelocationException { + @Override + public RelocationResult relocate(Address address, CoffRelocation relocation, + CoffRelocationContext relocationContext) + throws MemoryAccessException, RelocationException { - Program program = relocationContext.getProgram(); - Memory mem = program.getMemory(); + switch (relocation.getType()) { - int addend = mem.getInt(address); + // We are choosing to ignore these types: + case IMAGE_REL_PPC_ABSOLUTE: + case IMAGE_REL_PPC_SECTION: + case IMAGE_REL_PPC_SECREL: + case IMAGE_REL_PPC_TOKEN: { + return RelocationResult.SKIPPED; + } - int byteLength = 4; // most relocations affect 4-bytes (change if different) + // We haven't implemented these types yet: + case IMAGE_REL_PPC_ADDR32: + case IMAGE_REL_PPC_ADDR32NB: + case IMAGE_REL_PPC_ADDR64: + case IMAGE_REL_PPC_ADDR24: + case IMAGE_REL_PPC_ADDR16: + case IMAGE_REL_PPC_ADDR14: + case IMAGE_REL_PPC_REL24: + case IMAGE_REL_PPC_REL14: + case IMAGE_REL_PPC_SECREL16: + case IMAGE_REL_PPC_REFHI: + case IMAGE_REL_PPC_REFLO: + case IMAGE_REL_PPC_PAIR: + case IMAGE_REL_PPC_SECRELLO: + case IMAGE_REL_PPC_GPREL: + default: { + return RelocationResult.UNSUPPORTED; + } + } + } - switch (relocation.getType()) { + /** + * The relocation is ignored. + */ + public final static short IMAGE_REL_PPC_ABSOLUTE = 0x0000; - // We are implementing these types: - case IMAGE_REL_PPC_ADDR32: { - int value = (int) relocationContext.getSymbolAddress(relocation) - .add(addend) - .getOffset(); - program.getMemory().setInt(address, value); - break; - } - case IMAGE_REL_PPC_ADDR32NB: { - int value = (int) relocationContext.getSymbolAddress(relocation) - .add(addend) - .subtract(program.getImageBase()); - mem.setInt(address, value); - break; - } + /** + * The 64-bit VA of the target. + */ + public final static short IMAGE_REL_PPC_ADDR64 = 0x0001; - // We are choosing to ignore these types: - case IMAGE_REL_PPC_ABSOLUTE: - case IMAGE_REL_PPC_SECTION: - case IMAGE_REL_PPC_SECREL: - case IMAGE_REL_PPC_TOKEN: { - return RelocationResult.SKIPPED; - } + /** + * The 32-bit VA of the target. + */ + public final static short IMAGE_REL_PPC_ADDR32 = 0x0002; - // We haven't implemented these types yet: - case IMAGE_REL_PPC_ADDR64: - case IMAGE_REL_PPC_ADDR24: - case IMAGE_REL_PPC_ADDR16: - case IMAGE_REL_PPC_ADDR14: - case IMAGE_REL_PPC_REL24: - case IMAGE_REL_PPC_REL14: - case IMAGE_REL_PPC_SECREL16: - case IMAGE_REL_PPC_REFHI: - case IMAGE_REL_PPC_REFLO: - case IMAGE_REL_PPC_PAIR: - case IMAGE_REL_PPC_SECRELLO: - case IMAGE_REL_PPC_GPREL: - default: { - return RelocationResult.UNSUPPORTED; - } - } - return new RelocationResult(Relocation.Status.APPLIED, byteLength); - } + /** + * The low 24 bits of the VA of the target. + * This is valid only when the target symbol is absolute and can be sign-extended to its + * original value. + */ + public final static short IMAGE_REL_PPC_ADDR24 = 0x0003; - /** - * The relocation is ignored. - */ - public final static short IMAGE_REL_PPC_ABSOLUTE = 0x0000; + /** + * The low 16 bits of the target's VA. + */ + public final static short IMAGE_REL_PPC_ADDR16 = 0x0004; - /** - * The 64-bit VA of the target. - */ - public final static short IMAGE_REL_PPC_ADDR64 = 0x0001; + /** + * The low 14 bits of the target's VA. + * This is valid only when the target symbol is absolute and can be sign-extended to its original value. + */ + public final static short IMAGE_REL_PPC_ADDR14 = 0x0005; - /** - * The 32-bit VA of the target. - */ - public final static short IMAGE_REL_PPC_ADDR32 = 0x0002; + /** + * A 24-bit PC-relative offset to the symbol's location. + */ + public final static short IMAGE_REL_PPC_REL24 = 0x0006; - /** - * The low 24 bits of the VA of the target. - * This is valid only when the target symbol is absolute and can be sign-extended to its original value. - */ - public final static short IMAGE_REL_PPC_ADDR24 = 0x0003; + /** + * A 14-bit PC-relative offset to the symbol's location. + */ + public final static short IMAGE_REL_PPC_REL14 = 0x0007; - /** - * The low 16 bits of the target's VA. - */ - public final static short IMAGE_REL_PPC_ADDR16 = 0x0004; + /** + * The 32-bit RVA of the target. + */ + public final static short IMAGE_REL_PPC_ADDR32NB = 0x000A; - /** - * The low 14 bits of the target's VA. - * This is valid only when the target symbol is absolute and can be sign-extended to its original value. - */ - public final static short IMAGE_REL_PPC_ADDR14 = 0x0005; + /** + * The 32-bit offset of the target from the beginning of its section. + * This is used to support debugging information and static thread local storage. + */ + public final static short IMAGE_REL_PPC_SECREL = 0x000B; - /** - * A 24-bit PC-relative offset to the symbol's location. - */ - public final static short IMAGE_REL_PPC_REL24 = 0x0006; + /** + * The 16-bit section index of the section that contains the target. + * This is used to support debugging information. + */ + public final static short IMAGE_REL_PPC_SECTION = 0x000C; - /** - * A 14-bit PC-relative offset to the symbol's location. - */ - public final static short IMAGE_REL_PPC_REL14 = 0x0007; + /** + * The 16-bit offset of the target from the beginning of its section. + * This is used to support debugging information and static thread local storage. + */ + public final static short IMAGE_REL_PPC_SECREL16 = 0x000F; - /** - * The 32-bit RVA of the target. - */ - public final static short IMAGE_REL_PPC_ADDR32NB = 0x000A; + /** + * The high 16 bits of the target's 32-bit VA. This is used for the first instruction in a + * two-instruction sequence that loads a full address. This relocation must be immediately + * followed by a PAIR relocation whose SymbolTableIndex contains a signed 16-bit displacement + * that is added to the upper 16 bits that was taken from the location that is being relocated. + */ + public final static short IMAGE_REL_PPC_REFHI = 0x0010; - /** - * The 32-bit offset of the target from the beginning of its section. - * This is used to support debugging information and static thread local storage. - */ - public final static short IMAGE_REL_PPC_SECREL = 0x000B; + /** + * The low 16 bits of the target's VA. + */ + public final static short IMAGE_REL_PPC_REFLO = 0x0011; - /** - * The 16-bit section index of the section that contains the target. - * This is used to support debugging information. - */ - public final static short IMAGE_REL_PPC_SECTION = 0x000C; + /** + * A relocation that is valid only when it immediately follows a REFHI or SECRELHI relocation. + * Its SymbolTableIndex contains a displacement and not an index into the symbol table. + */ + public final static short IMAGE_REL_PPC_PAIR = 0x0012; - /** - * The 16-bit offset of the target from the beginning of its section. - * This is used to support debugging information and static thread local storage. - */ - public final static short IMAGE_REL_PPC_SECREL16 = 0x000F; + /** + * The low 16 bits of the 32-bit offset of the target from the beginning of its section. + */ + public final static short IMAGE_REL_PPC_SECRELLO = 0x0013; - /** - * The high 16 bits of the target's 32-bit VA. - * This is used for the first instruction in a two-instruction sequence that loads a full address. - * This relocation must be immediately followed by a PAIR relocation whose SymbolTableIndex contains a signed - * 16-bit displacement that is added to the upper 16 bits that was taken from the location that is being relocated. - */ - public final static short IMAGE_REL_PPC_REFHI = 0x0010; + /** + * The 16-bit signed displacement of the target relative to the GP register. + */ + public final static short IMAGE_REL_PPC_GPREL = 0x0015; - /** - * The low 16 bits of the target's VA. - */ - public final static short IMAGE_REL_PPC_REFLO = 0x0011; - - /** - * A relocation that is valid only when it immediately follows a REFHI or SECRELHI relocation. - * Its SymbolTableIndex contains a displacement and not an index into the symbol table. - */ - public final static short IMAGE_REL_PPC_PAIR = 0x0012; - - /** - * The low 16 bits of the 32-bit offset of the target from the beginning of its section. - */ - public final static short IMAGE_REL_PPC_SECRELLO = 0x0013; - - /** - * The 16-bit signed displacement of the target relative to the GP register. - */ - public final static short IMAGE_REL_PPC_GPREL = 0x0015; - - /** - * The CLR token. - */ - public final static short IMAGE_REL_PPC_TOKEN = 0x0016; + /** + * The CLR token. + */ + public final static short IMAGE_REL_PPC_TOKEN = 0x0016; }