From 98efc72c4ca20b60c80dd16e2c88af114b8b2ae7 Mon Sep 17 00:00:00 2001 From: Ivan Fratric Date: Fri, 30 Jun 2023 17:28:39 +0200 Subject: [PATCH] Hexagon support (#25) * Hexagon support * Fix typo --- linux-user/elfload.c | 35 +++++++++++++++++++++++++++++++++++ linux-user/hexagon/cpu_loop.c | 17 +++++++++++++++++ target/hexagon/cpu-param.h | 11 ++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 418ad92598..82aa74bb70 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2213,7 +2213,25 @@ static void zero_bss(abi_ulong elf_bss, abi_ulong last_bss, int prot) } if (host_start < host_map_start) { + //// --- Begin LibAFL code --- + /* We are doing a memset to a destination that might not be writable. + Temporary change permissions and restore below. */ + int tmp_prot = prot; + if(!(tmp_prot & PROT_WRITE)) { + tmp_prot ^= PROT_WRITE; + mprotect((void *)(host_map_start - qemu_real_host_page_size()), + qemu_real_host_page_size(), tmp_prot); + } + //// --- End LibAFL code --- + memset((void *)host_start, 0, host_map_start - host_start); + + //// --- Begin LibAFL code --- + if(tmp_prot != prot) { + mprotect((void *)(host_map_start - qemu_real_host_page_size()), + qemu_real_host_page_size(), prot); + } + //// --- End LibAFL code --- } } @@ -3021,6 +3039,10 @@ static void load_elf_image(const char *image_name, int image_fd, loaddr = a; } a = eppnt->p_vaddr + eppnt->p_memsz - 1; + //// --- Begin LibAFL code --- + /* Fix a case where eppnt->p_memsz is zero */ + if(eppnt->p_memsz == 0) a++; + //// --- End LibAFL code --- if (a > hiaddr) { hiaddr = a; } @@ -3173,6 +3195,15 @@ static void load_elf_image(const char *image_name, int image_fd, for (i = 0; i < ehdr->e_phnum; i++) { struct elf_phdr *eppnt = phdr + i; + + //// --- Begin LibAFL code --- + #ifdef TARGET_HEXAGON + /* Encountered cases where p_type was PT_NULL + but the segment should still be loaded. */ + if((eppnt->p_type == PT_NULL) && eppnt->p_vaddr) eppnt->p_type = PT_LOAD; + #endif + //// --- End LibAFL code --- + if (eppnt->p_type == PT_LOAD) { abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em, vaddr_len; int elf_prot = 0; @@ -3570,6 +3601,10 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) exit(-1); } + //// --- Begin LibAFL code --- + if(elf_interpreter && !elf_interpreter[0]) elf_interpreter = NULL; + //// --- End LibAFL code --- + if (elf_interpreter) { load_elf_interp(elf_interpreter, &interp_info, bprm->buf); diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c index 7f1499ed28..d97df6cc07 100644 --- a/linux-user/hexagon/cpu_loop.c +++ b/linux-user/hexagon/cpu_loop.c @@ -33,12 +33,29 @@ void cpu_loop(CPUHexagonState *env) target_ulong ret; for (;;) { + +//// --- Begin LibAFL code --- + + if (libafl_qemu_break_asap) return; + +//// --- End LibAFL code --- + cpu_exec_start(cs); trapnr = cpu_exec(cs); cpu_exec_end(cs); process_queued_cpu_work(cs); switch (trapnr) { + +//// --- Begin LibAFL code --- + +#define EXCP_LIBAFL_BP 0xf4775747 + + case EXCP_LIBAFL_BP: + return; + +//// --- End LibAFL code --- + case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ break; diff --git a/target/hexagon/cpu-param.h b/target/hexagon/cpu-param.h index 71b4a9b83e..2eb442ef86 100644 --- a/target/hexagon/cpu-param.h +++ b/target/hexagon/cpu-param.h @@ -18,7 +18,16 @@ #ifndef HEXAGON_CPU_PARAM_H #define HEXAGON_CPU_PARAM_H -#define TARGET_PAGE_BITS 16 /* 64K pages */ +//// --- Begin LibAFL code --- + +/* Binaries that assume 4k page size were observed. + Unless TARGET_PAGE_BITS is reduced, Qemu elf loader + will error out for such binaries. */ +//#define TARGET_PAGE_BITS 16 /* 64K pages */ +#define TARGET_PAGE_BITS 12 /* 4K pages */ + +//// --- End LibAFL code --- + #define TARGET_LONG_BITS 32 #define TARGET_PHYS_ADDR_SPACE_BITS 36