mdreloc.c revision 1.5 1 #include <sys/types.h>
2 #include <sys/stat.h>
3
4 #include "debug.h"
5 #include "rtld.h"
6
7 void
8 _rtld_setup_pltgot(const Obj_Entry *obj)
9 {
10 obj->pltgot[1] = (Elf_Addr) obj;
11 obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
12 }
13
14 int
15 _rtld_relocate_nonplt_objects(obj, dodebug)
16 Obj_Entry *obj;
17 bool dodebug;
18 {
19 const Elf_Rel *rel;
20 #ifdef COMBRELOC
21 unsigned long lastsym = -1;
22 #endif
23 Elf_Addr target;
24
25 for (rel = obj->rel; rel < obj->rellim; rel++) {
26 Elf_Addr *where;
27 const Elf_Sym *def;
28 const Obj_Entry *defobj;
29 Elf_Addr tmp;
30 unsigned long symnum;
31
32 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
33 symnum = ELF_R_SYM(rel->r_info);
34
35 switch (ELF_R_TYPE(rel->r_info)) {
36 case R_TYPE(NONE):
37 break;
38
39 #if 1 /* XXX should not occur */
40 case R_TYPE(PC32):
41 #ifdef COMBRELOC
42 if (symnum != lastsym) {
43 #endif
44 def = _rtld_find_symdef(symnum, obj, &defobj,
45 false);
46 if (def == NULL)
47 return -1;
48 target = (Elf_Addr)(defobj->relocbase +
49 def->st_value);
50 #ifdef COMBRELOC
51 lastsym = symnum;
52 }
53 #endif
54
55 *where += target - (Elf_Addr)where;
56 rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
57 obj->strtab + obj->symtab[symnum].st_name,
58 obj->path, (void *)*where, defobj->path));
59 break;
60
61 case R_TYPE(GOT32):
62 #endif
63 case R_TYPE(32):
64 case R_TYPE(GLOB_DAT):
65 #ifdef COMBRELOC
66 if (symnum != lastsym) {
67 #endif
68 def = _rtld_find_symdef(symnum, obj, &defobj,
69 false);
70 if (def == NULL)
71 return -1;
72 target = (Elf_Addr)(defobj->relocbase +
73 def->st_value);
74 #ifdef COMBRELOC
75 lastsym = symnum;
76 }
77 #endif
78
79 tmp = target + *where;
80 if (*where != tmp)
81 *where = tmp;
82 rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
83 obj->strtab + obj->symtab[symnum].st_name,
84 obj->path, (void *)*where, defobj->path));
85 break;
86
87 case R_TYPE(RELATIVE):
88 *where += (Elf_Addr)obj->relocbase;
89 rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
90 (void *)*where));
91 break;
92
93 case R_TYPE(COPY):
94 /*
95 * These are deferred until all other relocations have
96 * been done. All we do here is make sure that the
97 * COPY relocation is not in a shared library. They
98 * are allowed only in executable files.
99 */
100 if (!obj->mainprog) {
101 _rtld_error(
102 "%s: Unexpected R_COPY relocation in shared library",
103 obj->path);
104 return -1;
105 }
106 rdbg(dodebug, ("COPY (avoid in main)"));
107 break;
108
109 default:
110 rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
111 "contents = %p, symbol = %s",
112 symnum, (u_long)ELF_R_TYPE(rel->r_info),
113 (void *)rel->r_offset, (void *)*where,
114 obj->strtab + obj->symtab[symnum].st_name));
115 _rtld_error("%s: Unsupported relocation type %ld "
116 "in non-PLT relocations\n",
117 obj->path, (u_long) ELF_R_TYPE(rel->r_info));
118 return -1;
119 }
120 }
121 return 0;
122 }
123