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:
herman ten brugge 2021-01-16 07:01:59 +01:00
parent 757eccd1d2
commit 5aba20f270
6 changed files with 46 additions and 23 deletions

View file

@ -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)

View file

@ -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
View file

@ -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

View file

@ -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");

View file

@ -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) {

View file

@ -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