mirror of
https://github.com/frida/tinycc
synced 2024-11-23 16:19:35 +03:00
BSD: arm support
Support OpenBSD/FreeBSD/NetBSD on asm. move PAGESIZE to tcc.h and use _SC_PAGESIZE (netbsd/arm has 8192 pagesize) arm: - fix cmp instruction for qemu (raspberry pi works without patch?) - increase start address/size - use large plt size - add return R_ARM_PREL31 - add R_ARM_TARGET1 to prepare_dynamic_rel - add gcc_s to FreeBSD (unwind code) - do not use __clear_cache on bsd (sometimes bad system call) - do stack unwinding on bsd - test/tcctest.c: use %lld %llu on bsd
This commit is contained in:
parent
48bc44c5e6
commit
aefbb5274d
16
arm-gen.c
16
arm-gen.c
@ -1674,8 +1674,12 @@ void gen_opi(int op)
|
||||
uint32_t x;
|
||||
x=stuff_const(opc|0x2000000|(c<<16),vtop->c.i);
|
||||
if(x) {
|
||||
r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
|
||||
o(x|(r<<12));
|
||||
if ((x & 0xfff00000) == 0xe3500000) // cmp rx,#c
|
||||
o(x);
|
||||
else {
|
||||
r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
|
||||
o(x|(r<<12));
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -1685,8 +1689,12 @@ void gen_opi(int op)
|
||||
c=intr(gv(RC_INT));
|
||||
vswap();
|
||||
}
|
||||
r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
|
||||
o(opc|(c<<16)|(r<<12)|fr);
|
||||
if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry
|
||||
o(opc|(c<<16)|fr);
|
||||
else {
|
||||
r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
|
||||
o(opc|(c<<16)|(r<<12)|fr);
|
||||
}
|
||||
done:
|
||||
vtop--;
|
||||
if (op >= TOK_ULT && op <= TOK_GT)
|
||||
|
16
arm-link.c
16
arm-link.c
@ -12,8 +12,8 @@
|
||||
|
||||
#define R_NUM R_ARM_NUM
|
||||
|
||||
#define ELF_START_ADDR 0x00008000
|
||||
#define ELF_PAGE_SIZE 0x1000
|
||||
#define ELF_START_ADDR 0x00010000
|
||||
#define ELF_PAGE_SIZE 0x10000
|
||||
|
||||
#define PCRELATIVE_DLLPLT 1
|
||||
#define RELOCATE_DLLPLT 1
|
||||
@ -127,7 +127,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_
|
||||
write32le(p, 0x4778); /* bx pc */
|
||||
write32le(p+2, 0x46c0); /* nop */
|
||||
}
|
||||
p = section_ptr_add(plt, 12);
|
||||
p = section_ptr_add(plt, 16);
|
||||
/* save GOT offset for relocate_plt */
|
||||
write32le(p + 4, got_offset);
|
||||
return plt_offset;
|
||||
@ -153,10 +153,11 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
unsigned off = x + read32le(p + 4) + (s1->plt->data - p) + 4;
|
||||
if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
|
||||
p += 4;
|
||||
write32le(p, 0xe28fc600 | ((off >> 20) & 0xff)); // add ip, pc, #0xNN00000
|
||||
write32le(p + 4, 0xe28cca00 | ((off >> 12) & 0xff)); // add ip, ip, #0xNN000
|
||||
write32le(p + 8, 0xe5bcf000 | (off & 0xfff)); // ldr pc, [ip, #0xNNN]!
|
||||
p += 12;
|
||||
write32le(p, 0xe28fc200 | ((off >> 28) & 0xf)); // add ip, pc, #0xN0000000
|
||||
write32le(p + 4, 0xe28cc600 | ((off >> 20) & 0xff)); // add ip, pc, #0xNN00000
|
||||
write32le(p + 8, 0xe28cca00 | ((off >> 12) & 0xff)); // add ip, ip, #0xNN000
|
||||
write32le(p + 12, 0xe5bcf000 | (off & 0xfff)); // ldr pc, [ip, #0xNNN]!
|
||||
p += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -346,6 +347,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
|
||||
tcc_error("can't relocate value at %x,%d",addr, type);
|
||||
(*(int *)ptr) |= x & 0x7fffffff;
|
||||
}
|
||||
return;
|
||||
case R_ARM_ABS32:
|
||||
// case R_ARM_TARGET1: /* ??? as seen on NetBSD - FIXME! */
|
||||
if (s1->output_type == TCC_OUTPUT_DLL) {
|
||||
|
8
tcc.h
8
tcc.h
@ -86,6 +86,14 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||
# undef CONFIG_TCC_STATIC
|
||||
#endif
|
||||
|
||||
#ifndef PAGESIZE
|
||||
# ifdef _SC_PAGESIZE
|
||||
# define PAGESIZE sysconf(_SC_PAGESIZE)
|
||||
# else
|
||||
# define PAGESIZE 4096
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef O_BINARY
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
4
tccelf.c
4
tccelf.c
@ -1055,6 +1055,7 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
||||
case R_X86_64_64:
|
||||
#elif defined(TCC_TARGET_ARM)
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_TARGET1:
|
||||
#elif defined(TCC_TARGET_ARM64)
|
||||
case R_AARCH64_ABS32:
|
||||
case R_AARCH64_ABS64:
|
||||
@ -1445,6 +1446,9 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
|
||||
tcc_add_dll(s1, TCC_LIBGCC, 0);
|
||||
}
|
||||
#endif
|
||||
#if defined(TCC_TARGET_ARM) && defined(TARGETOS_FreeBSD)
|
||||
tcc_add_library_err(s1, "gcc_s"); // unwind code
|
||||
#endif
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
|
||||
tcc_add_library_err(s1, "pthread");
|
||||
|
16
tccrun.c
16
tccrun.c
@ -352,7 +352,10 @@ static void set_pages_executable(TCCState *s1, void *ptr, unsigned long length)
|
||||
if (mprotect((void *)start, end - start, PROT_READ | PROT_EXEC))
|
||||
tcc_error("mprotect failed: did you mean to configure --with-selinux?");
|
||||
# endif
|
||||
# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
|
||||
/* XXX: BSD sometimes dump core with bad system call */
|
||||
# if (defined(TCC_TARGET_ARM) && \
|
||||
!defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)) || \
|
||||
defined(TCC_TARGET_ARM64)
|
||||
# ifdef __APPLE__
|
||||
sys_icache_invalidate(ptr, length);
|
||||
sys_dcache_flush(ptr, length);
|
||||
@ -691,6 +694,12 @@ static void rt_getcontext(ucontext_t *uc, rt_context *rc)
|
||||
# if defined(__APPLE__)
|
||||
rc->ip = uc->uc_mcontext->__ss.__pc;
|
||||
rc->fp = uc->uc_mcontext->__ss.__r[11];
|
||||
# elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
rc->ip = uc->uc_mcontext.__gregs[_REG_PC];
|
||||
rc->fp = uc->uc_mcontext.__gregs[_REG_FP];
|
||||
# elif defined(__OpenBSD__)
|
||||
rc->ip = uc->sc_pc;
|
||||
rc->fp = uc->sc_fpreg[29];
|
||||
# elif defined(__QNX__)
|
||||
rc->ip = uc->uc_mcontext.cpu.gpr[15];
|
||||
rc->fp = uc->uc_mcontext.cpu.gpr[11];
|
||||
@ -860,8 +869,9 @@ static int rt_get_caller_pc(addr_t *paddr, rt_context *rc, int level)
|
||||
#elif defined(__arm__)
|
||||
static int rt_get_caller_pc(addr_t *paddr, rt_context *rc, int level)
|
||||
{
|
||||
/* XXX: only supports linux */
|
||||
#if !defined(__linux__)
|
||||
/* XXX: only supports linux/bsd */
|
||||
#if !defined(__linux__) && \
|
||||
!defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
|
||||
return -1;
|
||||
#else
|
||||
if (level == 0) {
|
||||
|
@ -21,7 +21,9 @@
|
||||
typedef __SIZE_TYPE__ uintptr_t;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(_WIN32) || \
|
||||
(defined(__arm__) && \
|
||||
(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)))
|
||||
#define LONG_LONG_FORMAT "%lld"
|
||||
#define ULONG_LONG_FORMAT "%llu"
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user