1
static ul ggot,ggote; static Rela *hr;
4
#define ELF_R_SYM(a_) (a_&0xffffffff)
6
#define ELF_R_TYPE(a_) (((a_>>40)&0xff) ? ((a_>>40)&0xff) : ((a_>>56)&0xff))
7
#define ELF_R_FTYPE(a_) ((a_>>56)&0xff)
10
write_stub(ul s,ul *got,ul *gote) {
15
*gote=(ul)(goti=(void *)(gote+2));
17
s=((void *)gote-(void *)got);
18
*goti++=(0x37<<26)|(0x1c<<21)|(0x19<<16)|s;
19
*goti++=(0x37<<26)|(0x19<<21)|(0x19<<16)|0;
28
make_got_room_for_stub(Shdr *sec1,Shdr *sece,Sym *sym,const char *st1,ul *gs) {
30
Shdr *ssec=sec1+sym->st_shndx;
32
if ((ssec>=sece || !ALLOC_SEC(ssec)) &&
33
(a=find_sym_ptable(st1+sym->st_name)) &&
34
a->address>=ggot && a->address<ggote)
42
find_special_params(void *v,Shdr *sec1,Shdr *sece,const char *sn,
43
const char *st1,Sym *ds1,Sym *dse,Sym *sym,Sym *syme) {
46
ul *q,gotsym=0,locgotno=0,stub,stube;
49
massert(sec=get_section(".dynamic",sec1,sece,sn));
50
for (p=(void *)sec->sh_addr,pe=p+sec->sh_size;p<pe;p+=sec->sh_entsize) {
52
if (q[0]==DT_MIPS_GOTSYM)
54
if (q[0]==DT_MIPS_LOCAL_GOTNO)
58
massert(gotsym && locgotno);
60
massert(sec=get_section(".MIPS.stubs",sec1,sece,sn));
62
stube=sec->sh_addr+sec->sh_size;
64
massert(sec=get_section(".got",sec1,sece,sn));
65
ggot=sec->sh_addr+locgotno*sec->sh_entsize;
66
ggote=sec->sh_addr+sec->sh_size;
68
for (ds1+=gotsym,sym=ds1;sym<dse;sym++)
69
if (!sym->st_value || (sym->st_value>=stub && sym->st_value<stube))
70
sym->st_value=ggot+(sym-ds1)*sec->sh_entsize;
77
label_got_symbols(void *v1,Shdr *sec1,Shdr *sece,Sym *sym1,Sym *syme,const char *st1,ul *gs) {
85
for (sym=sym1;sym<syme;sym++)
88
for (*gs=0,sec=sec1;sec<sece;sec++)
89
if (sec->sh_type==SHT_RELA)
90
for (v=v1+sec->sh_offset,ve=v+sec->sh_size,r=v;v<ve;v+=sec->sh_entsize,r=v)
91
if (ELF_R_TYPE(r->r_info)==R_MIPS_CALL16||
92
ELF_R_TYPE(r->r_info)==R_MIPS_GOT_DISP||
93
ELF_R_TYPE(r->r_info)==R_MIPS_GOT_PAGE) {
95
sym=sym1+ELF_R_SYM(r->r_info);
99
if (2*a>=sizeof(sym->st_size) || !((sym->st_size>>(a*16))&0xffff)) {
102
if (2*a<sizeof(sym->st_size)) {
104
sym->st_size|=(q<<(a*16));
107
massert(!make_got_room_for_stub(sec1,sece,sym,st1,gs));
111
b=sizeof(r->r_addend)*4;
112
massert(!(r->r_addend>>b));
113
q=2*a>=sizeof(sym->st_size) ? q : (sym->st_size>>(a*16))&0xffff;
114
r->r_addend|=(q<<=b);