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
757eccd1d2
commit
5aba20f270
6 changed files with 46 additions and 23 deletions
16
arm-gen.c
16
arm-gen.c
|
@ -1717,8 +1717,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;
|
||||
}
|
||||
}
|
||||
|
@ -1728,8 +1732,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
|
||||
|
@ -133,7 +133,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;
|
||||
|
@ -159,10 +159,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,6 +379,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:
|
||||
if (s1->output_type == TCC_OUTPUT_DLL) {
|
||||
|
|
8
tcc.h
8
tcc.h
|
@ -94,6 +94,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
|
||||
|
|
8
tccelf.c
8
tccelf.c
|
@ -47,10 +47,6 @@ struct sym_version {
|
|||
/* section is dynsymtab_section */
|
||||
#define SHF_DYNSYM 0x40000000
|
||||
|
||||
#ifndef PAGESIZE
|
||||
# define PAGESIZE 4096
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
ST_FUNC void tccelf_new(TCCState *s)
|
||||
|
@ -1036,6 +1032,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:
|
||||
|
@ -1452,6 +1449,9 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
|
|||
tcc_add_dll(s1, TCC_LIBGCC, 0);
|
||||
}
|
||||
#endif
|
||||
#if TCC_TARGET_ARM && 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");
|
||||
|
|
17
tccrun.c
17
tccrun.c
|
@ -63,10 +63,6 @@ static void *win64_add_function_table(TCCState *s1);
|
|||
static void win64_del_function_table(void *);
|
||||
#endif
|
||||
|
||||
#ifndef PAGESIZE
|
||||
# define PAGESIZE 4096
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/* Do all relocations (needed before using tcc_get_symbol())
|
||||
Returns -1 on error. */
|
||||
|
@ -333,7 +329,10 @@ static void set_pages_executable(TCCState *s1, void *ptr, unsigned long length)
|
|||
if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | 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)
|
||||
__clear_cache(ptr, (char *)ptr + length);
|
||||
# endif
|
||||
#endif
|
||||
|
@ -667,6 +666,9 @@ static void rt_getcontext(ucontext_t *uc, rt_context *rc)
|
|||
#elif defined(__arm__) && defined(__OpenBSD__)
|
||||
rc->ip = uc->sc_pc;
|
||||
rc->fp = uc->sc_fpreg[29];
|
||||
#elif defined(__arm__) && defined(__FreeBSD__)
|
||||
rc->ip = uc->uc_mcontext.__gregs[_REG_PC];
|
||||
rc->fp = uc->uc_mcontext.__gregs[_REG_FP];
|
||||
#elif defined(__arm__)
|
||||
rc->ip = uc->uc_mcontext.arm_pc;
|
||||
rc->fp = uc->uc_mcontext.arm_fp;
|
||||
|
@ -830,8 +832,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 a new issue