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 committed by Ole André Vadla Ravnås
parent 48bc44c5e6
commit aefbb5274d
6 changed files with 49 additions and 15 deletions

View File

@ -1674,8 +1674,12 @@ void gen_opi(int op)
uint32_t x;
x=stuff_const(opc|0x2000000|(c<<16),vtop->c.i);
if(x) {
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();
}
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
@ -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
View File

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

View File

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

View File

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

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