From e69f1f5d668fc90160e184026dbf62090f6038fe Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Boric Date: Sun, 2 Jun 2024 16:59:57 +0200 Subject: [PATCH] tests: remove dependency on objcopy --- .../java/ghidra/DelinkerIntegrationTest.java | 53 +++++++------------ .../I386_ctype_o_IntegrationTest.java | 8 ++- .../I386_main_o_IntegrationTest.java | 9 ++-- .../Mipsel_ctype_o_IntegrationTest.java | 8 ++- .../Mipsel_main_o_IntegrationTest.java | 31 +++++------ 5 files changed, 42 insertions(+), 67 deletions(-) diff --git a/src/test/java/ghidra/DelinkerIntegrationTest.java b/src/test/java/ghidra/DelinkerIntegrationTest.java index e516124..5007eb8 100644 --- a/src/test/java/ghidra/DelinkerIntegrationTest.java +++ b/src/test/java/ghidra/DelinkerIntegrationTest.java @@ -18,14 +18,13 @@ import static org.junit.Assert.assertTrue; import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.file.AccessMode; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; @@ -36,6 +35,8 @@ import ghidra.app.analyzers.RelocationTableSynthesizerAnalyzer; import ghidra.app.util.DomainObjectService; import ghidra.app.util.Option; +import ghidra.app.util.bin.FileByteProvider; +import ghidra.app.util.bin.format.elf.ElfHeader; import ghidra.app.util.exporter.ElfRelocatableObjectExporter; import ghidra.app.util.exporter.Exporter; import ghidra.app.util.importer.MessageLog; @@ -172,42 +173,26 @@ public DomainObject getDomainObject() { return exportedFile; } - private byte[] extractElfSectionBytes(String inputFormat, File file, String sectionName) - throws Exception { - File outputFile = - createTempFileForTest(String.format("%s.%s.bin", file.getName(), sectionName)); - - List objcopyCmdline = List.of( - "objcopy", - "-I", inputFormat, - "-O", "binary", - "-j", sectionName, - "--set-section-flags", String.format("%s=alloc,load,content", sectionName), - file.getAbsolutePath(), - outputFile.getAbsolutePath()); - - Process process = new ProcessBuilder(objcopyCmdline).start(); - assertTrue("objdump invocation completes", process.waitFor(10, TimeUnit.SECONDS)); - assertEquals("objdump invocation succeeded", 0, process.exitValue()); - - try (FileInputStream fis = new FileInputStream(outputFile)) { - return fis.readAllBytes(); + private byte[] extractElfSectionBytes(File file, String sectionName) throws Exception { + try (FileByteProvider byteProvider = new FileByteProvider(file, null, AccessMode.READ)) { + ElfHeader header = new ElfHeader(byteProvider, s -> {}); + header.parse(); + return header.getSection(sectionName).getRawInputStream().readAllBytes(); } } - protected void compareElfSectionBytes(String inputFormat, File referenceFile, - String referenceSectionName, File exportedFile, String exportedSectionName) - throws Exception { - compareElfSectionBytes(inputFormat, referenceFile, referenceSectionName, exportedFile, + protected void compareElfSectionBytes(File referenceFile, String referenceSectionName, + File exportedFile, String exportedSectionName) throws Exception { + compareElfSectionBytes(referenceFile, referenceSectionName, exportedFile, exportedSectionName, Collections.emptyMap()); } - protected void compareElfSectionBytes(String inputFormat, File referenceFile, - String referenceSectionName, File exportedFile, String exportedSectionName, + protected void compareElfSectionBytes(File referenceFile, String referenceSectionName, + File exportedFile, String exportedSectionName, Map patches) throws Exception { byte[] expectedBytes = - extractElfSectionBytes(inputFormat, referenceFile, referenceSectionName); - byte[] actualBytes = extractElfSectionBytes(inputFormat, exportedFile, exportedSectionName); + extractElfSectionBytes(referenceFile, referenceSectionName); + byte[] actualBytes = extractElfSectionBytes(exportedFile, exportedSectionName); for (Map.Entry entry : patches.entrySet()) { byte[] patch = entry.getValue(); @@ -217,12 +202,12 @@ protected void compareElfSectionBytes(String inputFormat, File referenceFile, assertArrayEquals(expectedBytes, actualBytes); } - protected void compareElfSectionSizes(String inputFormat, File referenceFile, - String referenceSectionName, File exportedFile, String exportedSectionName) + protected void compareElfSectionSizes(File referenceFile, String referenceSectionName, + File exportedFile, String exportedSectionName) throws Exception { byte[] expectedBytes = - extractElfSectionBytes(inputFormat, referenceFile, referenceSectionName); - byte[] actualBytes = extractElfSectionBytes(inputFormat, exportedFile, exportedSectionName); + extractElfSectionBytes(referenceFile, referenceSectionName); + byte[] actualBytes = extractElfSectionBytes(exportedFile, exportedSectionName); assertEquals(expectedBytes.length, actualBytes.length); } diff --git a/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/I386_ctype_o_IntegrationTest.java b/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/I386_ctype_o_IntegrationTest.java index 813a1b0..80b0744 100644 --- a/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/I386_ctype_o_IntegrationTest.java +++ b/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/I386_ctype_o_IntegrationTest.java @@ -22,8 +22,6 @@ import ghidra.program.model.address.AddressSetView; public class I386_ctype_o_IntegrationTest extends DelinkerIntegrationTest { - private static final String INPUT_FORMAT = "elf32-little"; - private static final File ctypeFile = new File("src/test/resources/ascii-table/reference/freestanding/i386/ctype.o"); @@ -39,8 +37,8 @@ public void testExport_ctype_o() throws Exception { .union(af.getAddressSet(af.getAddress("0804a060"), af.getAddress("0804a160"))); // .rodata File exportedFile = exportElfObjectFile(set, null); - compareElfSectionBytes(INPUT_FORMAT, ctypeFile, ".text", exportedFile, ".text"); - compareElfSectionSizes(INPUT_FORMAT, ctypeFile, ".rel.text", exportedFile, ".rel.text"); - compareElfSectionBytes(INPUT_FORMAT, ctypeFile, ".rodata", exportedFile, ".rodata"); + compareElfSectionBytes(ctypeFile, ".text", exportedFile, ".text"); + compareElfSectionSizes(ctypeFile, ".rel.text", exportedFile, ".rel.text"); + compareElfSectionBytes(ctypeFile, ".rodata", exportedFile, ".rodata"); } } diff --git a/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/I386_main_o_IntegrationTest.java b/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/I386_main_o_IntegrationTest.java index 4ab6b0d..032289e 100644 --- a/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/I386_main_o_IntegrationTest.java +++ b/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/I386_main_o_IntegrationTest.java @@ -23,8 +23,6 @@ import ghidra.program.model.address.AddressSetView; public class I386_main_o_IntegrationTest extends DelinkerIntegrationTest { - private static final String INPUT_FORMAT = "elf32-little"; - private static final File ctypeFile = new File("src/test/resources/ascii-table/reference/freestanding/i386/main.o"); @@ -48,9 +46,8 @@ public void testExport_main_o() throws Exception { Map.entry(0x163, new byte[] { 0x67, -24, -4, -1, -1, -1 }), Map.entry(0x21e, new byte[] { 0x1d, -1, -1, -1 })); - compareElfSectionBytes(INPUT_FORMAT, ctypeFile, ".text", exportedFile, ".text", - text_patches); - compareElfSectionBytes(INPUT_FORMAT, ctypeFile, ".rodata", exportedFile, ".rodata"); - compareElfSectionSizes(INPUT_FORMAT, ctypeFile, ".rel.rodata", exportedFile, ".rel.rodata"); + compareElfSectionBytes(ctypeFile, ".text", exportedFile, ".text", text_patches); + compareElfSectionBytes(ctypeFile, ".rodata", exportedFile, ".rodata"); + compareElfSectionSizes(ctypeFile, ".rel.rodata", exportedFile, ".rel.rodata"); } } diff --git a/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/Mipsel_ctype_o_IntegrationTest.java b/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/Mipsel_ctype_o_IntegrationTest.java index f8d655d..6e85add 100644 --- a/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/Mipsel_ctype_o_IntegrationTest.java +++ b/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/Mipsel_ctype_o_IntegrationTest.java @@ -22,8 +22,6 @@ import ghidra.program.model.address.AddressSetView; public class Mipsel_ctype_o_IntegrationTest extends DelinkerIntegrationTest { - private static final String INPUT_FORMAT = "elf32-little"; - private static final File ctypeFile = new File("src/test/resources/ascii-table/reference/freestanding/mipsel/ctype.o"); @@ -39,8 +37,8 @@ public void testExport_ctype_o() throws Exception { .union(af.getAddressSet(af.getAddress("00400a00"), af.getAddress("00400b0f"))); // .rodata File exportedFile = exportElfObjectFile(set, null); - compareElfSectionBytes(INPUT_FORMAT, ctypeFile, ".text", exportedFile, ".text"); - compareElfSectionSizes(INPUT_FORMAT, ctypeFile, ".rel.text", exportedFile, ".rel.text"); - compareElfSectionBytes(INPUT_FORMAT, ctypeFile, ".rodata", exportedFile, ".rodata"); + compareElfSectionBytes(ctypeFile, ".text", exportedFile, ".text"); + compareElfSectionSizes(ctypeFile, ".rel.text", exportedFile, ".rel.text"); + compareElfSectionBytes(ctypeFile, ".rodata", exportedFile, ".rodata"); } } diff --git a/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/Mipsel_main_o_IntegrationTest.java b/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/Mipsel_main_o_IntegrationTest.java index 8b70caa..1d6539d 100644 --- a/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/Mipsel_main_o_IntegrationTest.java +++ b/src/test/java/ghidra/app/util/exporter/asciitable/freestanding/Mipsel_main_o_IntegrationTest.java @@ -23,8 +23,6 @@ import ghidra.program.model.address.AddressSetView; public class Mipsel_main_o_IntegrationTest extends DelinkerIntegrationTest { - private static final String INPUT_FORMAT = "elf32-little"; - private static final File mainFile = new File("src/test/resources/ascii-table/reference/freestanding/mipsel/main.o"); @@ -61,20 +59,19 @@ public void testExport_main_o() throws Exception { Map.entry(0x3ac, new byte[2]), Map.entry(0x404, new byte[2])); - compareElfSectionBytes(INPUT_FORMAT, mainFile, ".text", exportedFile, ".text", - text_patches); - compareElfSectionSizes(INPUT_FORMAT, mainFile, ".rel.text", exportedFile, ".rel.text"); - //compareElfSectionBytes(INPUT_FORMAT, mainFile, exportedFile, ".text.nolibc_raise"); - //compareElfSectionSizes(INPUT_FORMAT, mainFile, exportedFile, ".rel.text.nolibc_raise"); - //compareElfSectionSizes(INPUT_FORMAT, mainFile, exportedFile, ".text.nolibc_memove"); - //compareElfSectionBytes(INPUT_FORMAT, mainFile, exportedFile, ".text.nolibc_memcpy"); - //compareElfSectionSizes(INPUT_FORMAT, mainFile, exportedFile, ".rel.text.nolibc_memcpy"); - //compareElfSectionSizes(INPUT_FORMAT, mainFile, exportedFile, ".text.nolibc_memset"); - //compareElfSectionBytes(INPUT_FORMAT, mainFile, exportedFile, ".text.nolibc_abort"); - //compareElfSectionSizes(INPUT_FORMAT, mainFile, exportedFile, ".rel.text.nolibc_abort"); - compareElfSectionBytes(INPUT_FORMAT, mainFile, ".sdata", exportedFile, ".sdata"); - compareElfSectionBytes(INPUT_FORMAT, mainFile, ".rodata", exportedFile, ".rodata"); - compareElfSectionSizes(INPUT_FORMAT, mainFile, ".rel.rodata", exportedFile, ".rel.rodata"); - compareElfSectionBytes(INPUT_FORMAT, mainFile, ".sbss", exportedFile, ".sbss"); + compareElfSectionBytes(mainFile, ".text", exportedFile, ".text", text_patches); + compareElfSectionSizes(mainFile, ".rel.text", exportedFile, ".rel.text"); + //compareElfSectionBytes(mainFile, exportedFile, ".text.nolibc_raise"); + //compareElfSectionSizes(mainFile, exportedFile, ".rel.text.nolibc_raise"); + //compareElfSectionSizes(mainFile, exportedFile, ".text.nolibc_memove"); + //compareElfSectionBytes(mainFile, exportedFile, ".text.nolibc_memcpy"); + //compareElfSectionSizes(mainFile, exportedFile, ".rel.text.nolibc_memcpy"); + //compareElfSectionSizes(mainFile, exportedFile, ".text.nolibc_memset"); + //compareElfSectionBytes(mainFile, exportedFile, ".text.nolibc_abort"); + //compareElfSectionSizes(mainFile, exportedFile, ".rel.text.nolibc_abort"); + compareElfSectionBytes(mainFile, ".sdata", exportedFile, ".sdata"); + compareElfSectionBytes(mainFile, ".rodata", exportedFile, ".rodata"); + compareElfSectionSizes(mainFile, ".rel.rodata", exportedFile, ".rel.rodata"); + compareElfSectionBytes(mainFile, ".sbss", exportedFile, ".sbss"); } }