mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
6a6cfff17d
This commit introduces support for dynamic objects. We do not support translating dynamic libraries yet, therefore this commit introduces support for PIE programs. At the current stage, QEMU does not provide us explicit information about an instruction using the program counter, but introduces its value as an immediate. As a consequence, we cannot support arbitrary relocation. For this reason, we statically relocate the program to a fixed address (`0x50000000` by default, but it can be customized through the `--base` argument). Therefore, all the addresses read from ELF data structure need to be relocated. Code compiled with `-fPIC` cannot store in global data the address of a function, since it will be relocated at run-time. This means that the global data harvesting won't bring any benefit. On the other hand, going through dynamic symbols can be hugely beneficial. Same argument for `*_RELATIVE` relocations. The `merge-dynamic.py` script has been improved to find the appropriate spot to put the rewritten program/section and headers and the dynamic sections (the kernel is peeky on them). Finally the `setRegister` function has been introduced in the module produced by `revamb`. This function allows to keep CSVs static and, at the same time, it allow `support.c` to set them. This is particularly useful when we want to call the `root` function with specific values in the registers (e.g., during for fuzzing purposes) or, as it's the case for PIE, to synchronize the value of the FS register, which is initialized by the dynamic loader, before execution gets to the `main` function in `support.c`.
100 lines
2.0 KiB
C
100 lines
2.0 KiB
C
#ifndef _SUPPORT_H
|
|
#define _SUPPORT_H
|
|
|
|
/*
|
|
* This file is distributed under the MIT License. See LICENSE.md for details.
|
|
*/
|
|
|
|
#include <setjmp.h>
|
|
#include <signal.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
// Handle target specific information:
|
|
//
|
|
// * Register size
|
|
// * Macro to swap endianess from the host one
|
|
#if defined(TARGET_arm)
|
|
|
|
typedef uint32_t target_reg;
|
|
#define SWAP(x) (htole32(x))
|
|
#define TARGET_REG_FORMAT PRIx32
|
|
|
|
#elif defined(TARGET_x86_64)
|
|
|
|
typedef uint64_t target_reg;
|
|
#define SWAP(x) (htole64(x))
|
|
#define TARGET_REG_FORMAT PRIx64
|
|
|
|
// TODO: these have been recovered by hand
|
|
enum {
|
|
REGISTER_RAX = 0x8250,
|
|
REGISTER_RCX = 0x8258,
|
|
REGISTER_RDX = 0x8260,
|
|
REGISTER_RBX = 0x8268,
|
|
REGISTER_RSP = 0x8270,
|
|
REGISTER_RBP = 0x8278,
|
|
REGISTER_RSI = 0x8280,
|
|
REGISTER_RDI = 0x8288,
|
|
REGISTER_R8 = 0x8290,
|
|
REGISTER_R9 = 0x8298,
|
|
REGISTER_R12 = 0x82b0,
|
|
REGISTER_R13 = 0x82b8,
|
|
REGISTER_R14 = 0x82c0,
|
|
REGISTER_R15 = 0x82c8,
|
|
|
|
REGISTER_FS = 0x8370,
|
|
|
|
REGISTER_XMM0 = 0x8558,
|
|
REGISTER_XMM1 = 0x8598,
|
|
REGISTER_XMM2 = 0x85d8,
|
|
REGISTER_XMM3 = 0x8618,
|
|
REGISTER_XMM4 = 0x8658,
|
|
REGISTER_XMM5 = 0x8698,
|
|
REGISTER_XMM6 = 0x86d8,
|
|
REGISTER_XMM7 = 0x8718
|
|
};
|
|
|
|
#elif defined(TARGET_i386)
|
|
|
|
typedef uint32_t target_reg;
|
|
#define SWAP(x) (htole32(x))
|
|
#define TARGET_REG_FORMAT PRIx32
|
|
|
|
#elif defined(TARGET_mips)
|
|
|
|
typedef uint32_t target_reg;
|
|
#define SWAP(x) (htobe32(x))
|
|
#define TARGET_REG_FORMAT PRIx32
|
|
|
|
#elif defined(TARGET_s390x)
|
|
|
|
typedef uint64_t target_reg;
|
|
#define SWAP(x) (htobe64(x))
|
|
#define TARGET_REG_FORMAT PRIx64
|
|
|
|
#else
|
|
|
|
#error "Architecture not supported"
|
|
|
|
#endif
|
|
|
|
// Register values before the signal was triggered
|
|
extern target_reg *saved_registers;
|
|
|
|
extern uint64_t *segment_boundaries;
|
|
extern uint64_t segments_count;
|
|
|
|
// Variables used to initialize the stack
|
|
extern target_reg phdr_address;
|
|
extern target_reg e_phentsize;
|
|
extern target_reg e_phnum;
|
|
|
|
// Setjmp/longjmp buffer
|
|
extern jmp_buf jmp_buffer;
|
|
|
|
bool is_executable(uint64_t pc);
|
|
void set_register(uint32_t register_id, uint64_t value);
|
|
|
|
#endif // _SUPPORT_H
|