diff options
author | Stefan Kristiansson <stefan.kristiansson@saunalahti.fi> | 2014-07-17 22:09:10 +0300 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2014-07-18 14:10:23 -0400 |
commit | 200d15479c0bc48471ee7b8e538ce33af990f82e (patch) | |
tree | 864cc38895b9277384ed3a956f4ad324de2c4455 /arch/or1k/reloc.h | |
parent | 7bece9c2095ee81f14b1088f6b0ba2f37fecb283 (diff) | |
download | musl-200d15479c0bc48471ee7b8e538ce33af990f82e.tar.gz |
add or1k (OpenRISC 1000) architecture port
With the exception of a fenv implementation, the port is fully featured.
The port has been tested in or1ksim, the golden reference functional
simulator for OpenRISC 1000.
It passes all libc-test tests (except the math tests that
requires a fenv implementation).
The port assumes an or1k implementation that has support for
atomic instructions (l.lwa/l.swa).
Although it passes all the libc-test tests, the port is still
in an experimental state, and has yet experienced very little
'real-world' use.
Diffstat (limited to 'arch/or1k/reloc.h')
-rw-r--r-- | arch/or1k/reloc.h | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/arch/or1k/reloc.h b/arch/or1k/reloc.h new file mode 100644 index 00000000..830a800a --- /dev/null +++ b/arch/or1k/reloc.h @@ -0,0 +1,47 @@ +#include <string.h> +#include <elf.h> +#include <endian.h> + +#define LDSO_ARCH "or1k" + +#define TPOFF_K 0 + +static int remap_rel(int type) +{ + switch(type) { + case R_OR1K_32: + return REL_SYMBOLIC; + case R_OR1K_GLOB_DAT: + return REL_GOT; + case R_OR1K_JMP_SLOT: + return REL_PLT; + case R_OR1K_RELATIVE: + return REL_RELATIVE; + case R_OR1K_COPY: + return REL_COPY; + case R_OR1K_TLS_DTPMOD: + return REL_DTPMOD; + case R_OR1K_TLS_DTPOFF: + return REL_DTPOFF; + case R_OR1K_TLS_TPOFF: + return REL_TPOFF; + } + return 0; +} + +#include "syscall.h" +void __reloc_self(int c, size_t *a, size_t *dynv) +{ + char dot = '.', ex = 'x'; + char *base; + size_t t[20], n; + for (a+=c+1; *a; a++); + for (a++; *a; a+=2) if (*a<20) t[*a] = a[1]; + base = (char *)t[AT_BASE]; + if (!base) base = (char *)(t[AT_PHDR] & -t[AT_PAGESZ]); + for (a=dynv; *a; a+=2) if (*a<20) t[*a] = a[1]; + n = t[DT_RELASZ]; + for (a=(void *)(base+t[DT_RELA]); n; a+=3, n-=12) + if (a[1]%256 == R_OR1K_RELATIVE) + *(size_t *)(base+a[0]) = (size_t)base + a[2]; +} |