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