author | Camm Maguire <camm@debian.org> | 2014年08月13日 20:49:07 +0000 |
---|---|---|
committer | Camm Maguire <camm@debian.org> | 2014年08月13日 20:49:07 +0000 |
commit | d3829c238aeb952354a8b0afe703ac8eecf35849 (patch) | |
tree | 2ff34d1194d76edbc0d3e53e6946a200489c324b | |
parent | f46550fb17719515b2947e4d48abe3ac51085bcd (diff) | |
download | gcl-d3829c238aeb952354a8b0afe703ac8eecf35849.tar.gz |
-rw-r--r-- | gcl/h/elf64_aarch64_reloc.h | 45 | ||||
-rw-r--r-- | gcl/h/elf64_aarch64_reloc_special.h | 43 |
diff --git a/gcl/h/elf64_aarch64_reloc.h b/gcl/h/elf64_aarch64_reloc.h index 33bd60d24..9f9311195 100644 --- a/gcl/h/elf64_aarch64_reloc.h +++ b/gcl/h/elf64_aarch64_reloc.h @@ -1,43 +1,36 @@ -/* .xword: (S+A) */ -#define R_AARCH64_ABS64 257 -/* .word: (S+A) */ -#define R_AARCH64_ABS32 258 -/* B: ((S+A-P) >> 2) & 0x3ffffff. */ -#define R_AARCH64_JUMP26 282 -/* BL: ((S+A-P) >> 2) & 0x3ffffff. */ -#define R_AARCH64_CALL26 283 -/* ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */ -#define R_AARCH64_ADR_PREL_PG_HI21 275 -/* ADD: (S+A) & 0xfff */ -#define R_AARCH64_ADD_ABS_LO12_NC 277 -/* LD/ST32: (S+A) & 0xffc */ -#define R_AARCH64_LDST32_ABS_LO12_NC 285 -/* LD/ST64: (S+A) & 0xff8 */ -#define R_AARCH64_LDST64_ABS_LO12_NC 286 - - case R_AARCH64_ABS64: + case R_AARCH64_ABS64: /* .xword: (S+A) */ store_val(where,~0L,s+a); break; - case R_AARCH64_ABS32: + case R_AARCH64_ABS32: /* .word: (S+A) */ store_val(where,MASK(32),s+a); break; - case R_AARCH64_JUMP26: - case R_AARCH64_CALL26: - store_vals(where,MASK(26),((long)(s+a-p)) / 4); + case R_AARCH64_JUMP26: /* B: ((S+A-P) >> 2) & 0x3ffffff. */ + case R_AARCH64_CALL26: /* BL: ((S+A-P) >> 2) & 0x3ffffff. */ + { + long x=((long)(s+a-p))/4; + if (abs(x)&(~MASK(26))) { + *(ul *)tramp=s+a; + got+=gotp; + gotp+=sizeof(tramp)/sizeof(*got); + memcpy(got,tramp,sizeof(tramp)); + x=((long)(got+1))/4; + } + store_vals(where,MASK(26),x); + } break; - case R_AARCH64_ADR_PREL_PG_HI21: + case R_AARCH64_ADR_PREL_PG_HI21: /* ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */ #define PG(x) ((x) & ~0xfff) s = ((long)(PG(s+a)-PG(p))) / 0x1000; store_val(where,MASK(2) << 29, (s & 0x3) << 29); store_val(where,MASK(19) << 5, (s & 0x1ffffc) << 3); #undef PG break; - case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_ADD_ABS_LO12_NC: /* ADD: (S+A) & 0xfff */ store_val(where,MASK(12) << 10,(s+a) << 10); break; - case R_AARCH64_LDST32_ABS_LO12_NC: + case R_AARCH64_LDST32_ABS_LO12_NC: /* LD/ST32: (S+A) & 0xffc */ store_val(where,MASK(12) << 10,((s+a) & 0xffc) << 8); break; - case R_AARCH64_LDST64_ABS_LO12_NC: + case R_AARCH64_LDST64_ABS_LO12_NC: /* LD/ST64: (S+A) & 0xff8 */ store_val(where,MASK(12) << 10,((s+a) & 0xff8) << 7); break; diff --git a/gcl/h/elf64_aarch64_reloc_special.h b/gcl/h/elf64_aarch64_reloc_special.h new file mode 100644 index 000000000..e6a8341c9 --- /dev/null +++ b/gcl/h/elf64_aarch64_reloc_special.h @@ -0,0 +1,43 @@ +/* #define R_AARCH64_TRAMP 1 */ +ul gotp; + +static int tramp[]={0x0, /*64bit absolute address*/ + 0x0, /*64bit absolute address*/ + 0x58ffffd0, /*ldr 19bit pc relative x16*/ + 0xd61f0200};/*br x16*/ + +static int +find_special_params(void *v,Shdr *sec1,Shdr *sece,const char *sn, + const char *st1,Sym *ds1,Sym *dse,Sym *sym,Sym *syme) { + + return 0; + +} + +static int +label_got_symbols(void *v1,Shdr *sec1,Shdr *sece,Sym *sym1,Sym *syme,const char *st1,const char *sn,ul *gs) { + + Rela *r; + Sym *sym; + Shdr *sec; + void *v,*ve; + + gotp=0; + for (sym=sym1;sym<syme;sym++) + sym->st_other=sym->st_size=0; + + for (*gs=0,sec=sec1;sec<sece;sec++) + if (sec->sh_type==SHT_RELA) + for (v=v1+sec->sh_offset,ve=v+sec->sh_size,r=v;v<ve;v+=sec->sh_entsize,r=v) + if (ELF_R_TYPE(r->r_info)==R_AARCH64_JUMP26 || + ELF_R_TYPE(r->r_info)==R_AARCH64_CALL26) { + + /*FIXME try to figure out earlier if this space is needed*/ + (*gs)+=sizeof(tramp)/sizeof(*gs); + /* r->r_info=ELF_R_INFO(ELF_R_SYM(r->r_info),R_AARCH64_TRAMP); */ + + } + + return 0; + +} |