mdreloc.c revision 1.3 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
21 for (rel = obj->rel; rel < obj->rellim; rel++) {
22 Elf_Addr *where;
23 const Elf_Sym *def;
24 const Obj_Entry *defobj;
25 Elf_Addr tmp;
26
27 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
28
29 switch (ELF_R_TYPE(rel->r_info)) {
30 case R_TYPE(NONE):
31 break;
32
33 #if 1 /* XXX should not occur */
34 case R_TYPE(PC32):
35 def = _rtld_find_symdef(rel->r_info, obj, &defobj,
36 false);
37 if (def == NULL)
38 return -1;
39
40 *where += (Elf_Addr)(defobj->relocbase + def->st_value) -
41 (Elf_Addr)where;
42 rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
43 defobj->strtab + def->st_name, obj->path,
44 (void *)*where, defobj->path));
45 break;
46
47 case R_TYPE(GOT32):
48 #endif
49 case R_TYPE(32):
50 case R_TYPE(GLOB_DAT):
51 def = _rtld_find_symdef(rel->r_info, obj, &defobj,
52 false);
53 if (def == NULL)
54 return -1;
55
56 tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
57 *where);
58 if (*where != tmp)
59 *where = tmp;
60 rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
61 defobj->strtab + def->st_name, obj->path,
62 (void *)*where, defobj->path));
63 break;
64
65 case R_TYPE(RELATIVE):
66 *where += (Elf_Addr)obj->relocbase;
67 rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
68 (void *)*where));
69 break;
70
71 case R_TYPE(COPY):
72 /*
73 * These are deferred until all other relocations have
74 * been done. All we do here is make sure that the
75 * COPY relocation is not in a shared library. They
76 * are allowed only in executable files.
77 */
78 if (!obj->mainprog) {
79 _rtld_error(
80 "%s: Unexpected R_COPY relocation in shared library",
81 obj->path);
82 return -1;
83 }
84 rdbg(dodebug, ("COPY (avoid in main)"));
85 break;
86
87 default:
88 def = _rtld_find_symdef(rel->r_info, obj, &defobj,
89 true);
90 rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
91 "contents = %p, symbol = %s",
92 (u_long)ELF_R_SYM(rel->r_info),
93 (u_long)ELF_R_TYPE(rel->r_info),
94 (void *)rel->r_offset, (void *)*where,
95 def ? defobj->strtab + def->st_name : "??"));
96 _rtld_error("%s: Unsupported relocation type %ld "
97 "in non-PLT relocations\n",
98 obj->path, (u_long) ELF_R_TYPE(rel->r_info));
99 return -1;
100 }
101 }
102 return 0;
103 }
104