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