~ubuntu-branches/ubuntu/vivid/gcl/vivid

« back to all changes in this revision

Viewing changes to .pc/init_is_in_.opd_on_ppc64/h/elf64_mips_reloc_special.h

  • Committer: Package Import Robot
  • Author(s): Camm Maguire
  • Date: 2014-06-14 13:43:57 UTC
  • mfrom: (13.1.114 sid)
  • Revision ID: package-import@ubuntu.com-20140614134357-viaqd4x69dx4hhlz
Tags: 2.6.10-14
2.6.11preĀ testĀ 13

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
static ul ggot,ggote; static Rela *hr;
 
2
 
 
3
#undef ELF_R_SYM 
 
4
#define ELF_R_SYM(a_) (a_&0xffffffff) 
 
5
#undef ELF_R_TYPE 
 
6
#define ELF_R_TYPE(a_) (((a_>>40)&0xff) ? ((a_>>40)&0xff) : ((a_>>56)&0xff)) 
 
7
#define ELF_R_FTYPE(a_) ((a_>>56)&0xff)
 
8
 
 
9
static int
 
10
write_stub(ul s,ul *got,ul *gote) {
 
11
 
 
12
  int *goti;
 
13
  
 
14
 
 
15
  *gote=(ul)(goti=(void *)(gote+2));
 
16
  *++gote=s;
 
17
  s=((void *)gote-(void *)got);
 
18
  *goti++=(0x37<<26)|(0x1c<<21)|(0x19<<16)|s;
 
19
  *goti++=(0x37<<26)|(0x19<<21)|(0x19<<16)|0;
 
20
  *goti++=0x03200008;
 
21
  *goti++=0x00200825;
 
22
 
 
23
  return 0;
 
24
  
 
25
}
 
26
 
 
27
static int
 
28
make_got_room_for_stub(Shdr *sec1,Shdr *sece,Sym *sym,const char *st1,ul *gs) {
 
29
 
 
30
  Shdr *ssec=sec1+sym->st_shndx;
 
31
  struct node *a;
 
32
  if ((ssec>=sece || !ALLOC_SEC(ssec)) && 
 
33
      (a=find_sym_ptable(st1+sym->st_name)) &&
 
34
      a->address>=ggot && a->address<ggote)
 
35
    (*gs)+=3;
 
36
 
 
37
  return 0;
 
38
 
 
39
}
 
40
 
 
41
static int
 
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) {
 
44
  
 
45
  Shdr *sec;
 
46
  ul *q,gotsym=0,locgotno=0,stub,stube;
 
47
  void *p,*pe;
 
48
 
 
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) {
 
51
    q=p;
 
52
    if (q[0]==DT_MIPS_GOTSYM)
 
53
      gotsym=q[1];
 
54
    if (q[0]==DT_MIPS_LOCAL_GOTNO)
 
55
      locgotno=q[1];
 
56
    
 
57
  }
 
58
  massert(gotsym && locgotno);
 
59
 
 
60
  massert(sec=get_section(".MIPS.stubs",sec1,sece,sn));
 
61
  stub=sec->sh_addr;
 
62
  stube=sec->sh_addr+sec->sh_size;
 
63
      
 
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;
 
67
 
 
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;
 
71
 
 
72
  return 0;
 
73
 
 
74
}
 
75
 
 
76
static int
 
77
label_got_symbols(void *v1,Shdr *sec1,Shdr *sece,Sym *sym1,Sym *syme,const char *st1,ul *gs) {
 
78
 
 
79
  Rela *r;
 
80
  Sym *sym;
 
81
  Shdr *sec;
 
82
  void *v,*ve;
 
83
  ul q=0,a,b;
 
84
 
 
85
  for (sym=sym1;sym<syme;sym++)
 
86
    sym->st_size=0;
 
87
 
 
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) {
 
94
 
 
95
          sym=sym1+ELF_R_SYM(r->r_info);
 
96
 
 
97
          a=r->r_addend>>15;
 
98
 
 
99
          if (2*a>=sizeof(sym->st_size) || !((sym->st_size>>(a*16))&0xffff)) {
 
100
 
 
101
            q=++*gs;
 
102
            if (2*a<sizeof(sym->st_size)) {
 
103
              massert(q<=0xffff);
 
104
              sym->st_size|=(q<<(a*16));
 
105
            }
 
106
            
 
107
            massert(!make_got_room_for_stub(sec1,sece,sym,st1,gs));
 
108
 
 
109
          }
 
110
 
 
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); 
 
115
 
 
116
        }
 
117
  
 
118
  return 0;
 
119
  
 
120
}