+#define R_PPC64_PLTSEQ 119 /*FIXME not in elf.h*/
+#define R_PPC64_PLTCALL 120
+
#define ha(x_) ((((x_) >> 16) + (((x_) & 0x8000) ? 1 : 0)) & 0xffff)
#define lo(x_) ((x_) & 0xffff)
case R_PPC64_REL16_HA:
store_val(where,MASK(16),ha(s+a-p));
break;
+ case R_PPC64_PLT16_HA:
+ gote=got+sym->st_size-1;
+ *gote=s+a;
+ store_val(where,MASK(16),ha((ul)gote-toc->st_value));
+ break;
+ case R_PPC64_PLT16_LO_DS:
+ gote=got+sym->st_size-1;
+ *gote=s+a;
+ store_val(where,MASK(16),lo((ul)gote-toc->st_value));/*>>2*/
+ break;
+ case R_PPC64_PLTSEQ:
+ case R_PPC64_PLTCALL:
+ break;
case R_PPC64_TOC16_HA:
store_val(where,MASK(16),ha(s+a-toc->st_value));
break;
};
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) {
-
- Shdr *sec;
+load_trampolines(void *v,Shdr *sec,Sym *ds1) {
+
Rela *r;
void *ve;
ul *u,j;
- massert((sec=get_section(".rela.dyn",sec1,sece,sn)));
-
v+=sec->sh_offset;
ve=v+sec->sh_size;
}
+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) {
+
+ Shdr *sec;
+
+ massert((sec=get_section(".rela.dyn",sec1,sece,sn)));
+ massert(!load_trampolines(v,sec,ds1));
+ if ((sec=get_section(".rela.plt",sec1,sece,sn)))
+ massert(!load_trampolines(v,sec,ds1));
+
+ 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;
+ void *v,*ve;
Shdr *sec;
Sym *sym;
}
}
+ for (sym=sym1;sym<syme;sym++)
+ 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_PPC64_PLT16_HA||
+ ELF_R_TYPE(r->r_info)==R_PPC64_PLT16_LO_DS) {
+
+ sym=sym1+ELF_R_SYM(r->r_info);
+
+ if (!sym->st_size)
+ sym->st_size=++*gs;
+
+ }
+
return 0;
}