From ee92c0fe5c1b9d59508273916e2c9a75b68dbc13 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Thu, 21 Apr 2016 01:25:29 +0200 Subject: nds32: add support for new architecture Add support for Andes Technology NDS32 architecture. See here http://www.andestech.com/en/index/index.htm for more informaton. Verification of the port from an older uClibc port was done on a sponsored AG101p board. The testsuite only has 5 errors, three are related to an existing bug in dlclose() with LT.old, also happening on cris32 and m68k. Failures to fallocate/posix_fallocate are unresolved. Thanks to Andes Technology sponsoring the hardware and being very helpful while doing the uClibc-ng porting. Signed-off-by: Waldemar Brodkorb --- ldso/ldso/nds32/dl-sysdep.h | 99 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 ldso/ldso/nds32/dl-sysdep.h (limited to 'ldso/ldso/nds32/dl-sysdep.h') diff --git a/ldso/ldso/nds32/dl-sysdep.h b/ldso/ldso/nds32/dl-sysdep.h new file mode 100644 index 000000000..c4a32ca71 --- /dev/null +++ b/ldso/ldso/nds32/dl-sysdep.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2016 Andes Technology, Inc. + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +/* Define this if the system uses RELOCA. */ +#define ELF_USES_RELOCA +#include +/* Initialization sequence for the GOT. */ +#define INIT_GOT(GOT_BASE,MODULE) \ +{ \ + GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ + GOT_BASE[1] = (unsigned long) MODULE; \ +} + +static __inline__ unsigned long nds32_modulus(unsigned long m, unsigned long p) +{ + unsigned long i,t,inc; + i=p; t=0; + while (!(i&(1<<31))) { + i<<=1; + t++; + } + t--; + for (inc=t;inc>2;inc--) { + i=p<=i) { + m-=i; + i<<=1; + if (i&(1<<31)) + break; + if (i=p) { + m-=p; + } + return m; +} +#define do_rem(result, n, base) ((result) = nds32_modulus(n, base)) + +/* Here we define the magic numbers that this dynamic loader should accept */ +#define MAGIC1 EM_NDS32 +#undef MAGIC2 + +/* Used for error messages */ +#define ELF_TARGET "NDS32" + +struct elf_resolve; +unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); + +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so + PLT entries should not be allowed to define the value. + ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one + of the main executable's symbols, as for a COPY reloc. */ +#define elf_machine_type_class(type) \ + ((((type) == R_NDS32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_NDS32_COPY) * ELF_RTYPE_CLASS_COPY)) + +/* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. We used to use the PIC register to do this + without a constant pool reference, but GCC 4.2 will use a pseudo-register + for the PIC base, so it may not be in r10. */ +static __inline__ Elf32_Addr __attribute__ ((unused)) +elf_machine_dynamic (void) +{ + Elf32_Addr link_addr; + __asm__ ( "l.w %0, _GLOBAL_OFFSET_TABLE_@GOTOFF": "=r" (link_addr) ); + return link_addr; +} + +/* Return the run-time load address of the shared object. */ +static __inline__ Elf32_Addr __attribute__ ((unused)) +elf_machine_load_address (void) +{ + /* It doesn't matter what variable this is, the reference never makes + it to assembly. We need a dummy reference to some global variable + via the GOT to make sure the compiler initialized %ebx in time. */ + + Elf32_Addr addr; + __asm__ ("la %0, _dl_start@GOTOFF\n" : "=r" (addr) ); + return addr - elf_machine_dynamic(); +} + +static __inline__ void +elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) +{ + Elf32_Rela * rpnt = (void *) rel_addr; + --rpnt; + do { + Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset); + + *reloc_addr = load_off + rpnt->r_addend; + } while (--relative_count); +} -- cgit v1.2.3