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