Skip to content

Commit

Permalink
tests: remove dependency on objcopy
Browse files Browse the repository at this point in the history
  • Loading branch information
boricj committed Jun 2, 2024
1 parent 1ff8ced commit e69f1f5
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 67 deletions.
53 changes: 19 additions & 34 deletions src/test/java/ghidra/DelinkerIntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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<String> 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<Integer, byte[]> 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<Integer, byte[]> entry : patches.entrySet()) {
byte[] patch = entry.getValue();
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -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");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -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");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -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");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -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");
}
}

0 comments on commit e69f1f5

Please sign in to comment.