thixotropist / ghidra_import_tests

Experimental framework for testing Ghidra binary import support
1 stars 0 forks source link

Generate new riscv-64 objects from source code #1

Closed thixotropist closed 10 months ago

thixotropist commented 10 months ago

The first set of Ghidra import test cases relied on external packages. Add new import test cases compiled (or assembled) from source code with an imported cross-platform toolchain.

Initially, the test cases will use a riscv-64, gcc 12 linux toolchain with C, C++, and possibly assembly sources. The build options should try to model a mix of normal user process, user sharable library, and loadable kernel module elements.

The first tests are limited to exercise features involving riscv-64 relocation and concurrency controls.

Example:

Compile the following with a riscv-64 toolchain with PIE enabled and PIC disabled.

char bssString[4096];
#include <stdio.h>
int
main (void)
{
  // exercise store into .bss with small offset
  bssString[8] = 0;
  // exercise store into .bss with 12 bit offset
  bssString[2049] = 0;
  // reference bssString to prevent optimization erasure and pass a bss address as a parameter
  printf(bssString);
  return 0;
}

Readelf shows that this generates an object file with multiple relocation types - more relocations than lines of actual code!

0000000000000004  0000000e00000017 R_RISCV_PCREL_HI20     0000000000000000 bssString + 0
0000000000000004  0000000000000033 R_RISCV_RELAX                             0
0000000000000008  0000000900000018 R_RISCV_PCREL_LO12_I   0000000000000004 .L0  + 0
0000000000000008  0000000000000033 R_RISCV_RELAX                             0
0000000000000010  0000000e00000017 R_RISCV_PCREL_HI20     0000000000000000 bssString + 801
0000000000000010  0000000000000033 R_RISCV_RELAX                             801
0000000000000014  0000000a00000019 R_RISCV_PCREL_LO12_S   0000000000000010 .L0  + 0
0000000000000014  0000000000000033 R_RISCV_RELAX                             0
0000000000000018  0000000f00000013 R_RISCV_CALL_PLT       0000000000000000 printf + 0
0000000000000018  0000000000000033 R_RISCV_RELAX                             0

A successful test case will bundle:

RISCV has a lot of different relocation codes. To get started, we will ignore any RISCV relocation codes that aren't known to the binutils-2_40 assembler. So we will care about relocations to GOT and BSS, but ignore relocations into things like task-local storage. Debugging relocations and frame tables are similarly out of scope.

thixotropist commented 10 months ago

closed with b06f08b