headers.c revision 1.62.4.3 1 1.62.4.3 pgoyette /* $NetBSD: headers.c,v 1.62.4.3 2019/01/18 08:50:11 pgoyette Exp $ */
2 1.1 cgd
3 1.1 cgd /*
4 1.1 cgd * Copyright 1996 John D. Polstra.
5 1.1 cgd * Copyright 1996 Matt Thomas <matt (at) 3am-software.com>
6 1.17 mycroft * Copyright 2002 Charles M. Hannum <root (at) ihack.net>
7 1.1 cgd * All rights reserved.
8 1.1 cgd *
9 1.1 cgd * Redistribution and use in source and binary forms, with or without
10 1.1 cgd * modification, are permitted provided that the following conditions
11 1.1 cgd * are met:
12 1.1 cgd * 1. Redistributions of source code must retain the above copyright
13 1.1 cgd * notice, this list of conditions and the following disclaimer.
14 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 cgd * notice, this list of conditions and the following disclaimer in the
16 1.1 cgd * documentation and/or other materials provided with the distribution.
17 1.1 cgd * 3. All advertising materials mentioning features or use of this software
18 1.1 cgd * must display the following acknowledgement:
19 1.1 cgd * This product includes software developed by John Polstra.
20 1.1 cgd * 4. The name of the author may not be used to endorse or promote products
21 1.1 cgd * derived from this software without specific prior written permission.
22 1.1 cgd *
23 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 1.1 cgd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 1.1 cgd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 1.1 cgd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 1.1 cgd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 1.1 cgd * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 1.1 cgd * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 1.1 cgd * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 1.1 cgd * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 1.1 cgd * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 1.1 cgd */
34 1.1 cgd
35 1.1 cgd /*
36 1.1 cgd * Dynamic linker for ELF.
37 1.1 cgd *
38 1.1 cgd * John Polstra <jdp (at) polstra.com>.
39 1.1 cgd */
40 1.1 cgd
41 1.19 skrll #include <sys/cdefs.h>
42 1.19 skrll #ifndef lint
43 1.62.4.3 pgoyette __RCSID("$NetBSD: headers.c,v 1.62.4.3 2019/01/18 08:50:11 pgoyette Exp $");
44 1.19 skrll #endif /* not lint */
45 1.19 skrll
46 1.1 cgd #include <err.h>
47 1.1 cgd #include <errno.h>
48 1.1 cgd #include <fcntl.h>
49 1.1 cgd #include <stdarg.h>
50 1.1 cgd #include <stdio.h>
51 1.1 cgd #include <stdlib.h>
52 1.1 cgd #include <string.h>
53 1.1 cgd #include <unistd.h>
54 1.1 cgd #include <sys/types.h>
55 1.1 cgd #include <sys/mman.h>
56 1.29 joerg #include <sys/bitops.h>
57 1.1 cgd #include <dirent.h>
58 1.1 cgd
59 1.1 cgd #include "debug.h"
60 1.1 cgd #include "rtld.h"
61 1.1 cgd
62 1.1 cgd /*
63 1.1 cgd * Process a shared object's DYNAMIC section, and save the important
64 1.1 cgd * information in its Obj_Entry structure.
65 1.1 cgd */
66 1.1 cgd void
67 1.22 christos _rtld_digest_dynamic(const char *execname, Obj_Entry *obj)
68 1.1 cgd {
69 1.4 christos Elf_Dyn *dynp;
70 1.4 christos Needed_Entry **needed_tail = &obj->needed;
71 1.51 christos const Elf_Dyn *dyn_soname = NULL;
72 1.4 christos const Elf_Dyn *dyn_rpath = NULL;
73 1.30 joerg bool use_pltrel = false;
74 1.30 joerg bool use_pltrela = false;
75 1.8 mycroft Elf_Addr relsz = 0, relasz = 0;
76 1.13 mycroft Elf_Addr pltrel = 0, pltrelsz = 0;
77 1.58 christos #ifdef RTLD_LOADER
78 1.10 fredette Elf_Addr init = 0, fini = 0;
79 1.58 christos #endif
80 1.4 christos
81 1.49 skrll dbg(("headers: digesting PT_DYNAMIC at %p", obj->dynamic));
82 1.5 kleink for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; ++dynp) {
83 1.49 skrll dbg((" d_tag %ld at %p", (long)dynp->d_tag, dynp));
84 1.4 christos switch (dynp->d_tag) {
85 1.4 christos
86 1.5 kleink case DT_REL:
87 1.4 christos obj->rel = (const Elf_Rel *)
88 1.4 christos (obj->relocbase + dynp->d_un.d_ptr);
89 1.4 christos break;
90 1.4 christos
91 1.5 kleink case DT_RELSZ:
92 1.4 christos relsz = dynp->d_un.d_val;
93 1.4 christos break;
94 1.4 christos
95 1.5 kleink case DT_RELENT:
96 1.4 christos assert(dynp->d_un.d_val == sizeof(Elf_Rel));
97 1.4 christos break;
98 1.4 christos
99 1.5 kleink case DT_JMPREL:
100 1.13 mycroft pltrel = dynp->d_un.d_ptr;
101 1.4 christos break;
102 1.4 christos
103 1.5 kleink case DT_PLTRELSZ:
104 1.8 mycroft pltrelsz = dynp->d_un.d_val;
105 1.4 christos break;
106 1.4 christos
107 1.5 kleink case DT_RELA:
108 1.9 kleink obj->rela = (const Elf_Rela *)
109 1.4 christos (obj->relocbase + dynp->d_un.d_ptr);
110 1.4 christos break;
111 1.4 christos
112 1.5 kleink case DT_RELASZ:
113 1.4 christos relasz = dynp->d_un.d_val;
114 1.4 christos break;
115 1.4 christos
116 1.5 kleink case DT_RELAENT:
117 1.9 kleink assert(dynp->d_un.d_val == sizeof(Elf_Rela));
118 1.4 christos break;
119 1.4 christos
120 1.5 kleink case DT_PLTREL:
121 1.30 joerg use_pltrel = dynp->d_un.d_val == DT_REL;
122 1.30 joerg use_pltrela = dynp->d_un.d_val == DT_RELA;
123 1.30 joerg assert(use_pltrel || use_pltrela);
124 1.4 christos break;
125 1.4 christos
126 1.5 kleink case DT_SYMTAB:
127 1.4 christos obj->symtab = (const Elf_Sym *)
128 1.4 christos (obj->relocbase + dynp->d_un.d_ptr);
129 1.4 christos break;
130 1.4 christos
131 1.5 kleink case DT_SYMENT:
132 1.4 christos assert(dynp->d_un.d_val == sizeof(Elf_Sym));
133 1.4 christos break;
134 1.4 christos
135 1.5 kleink case DT_STRTAB:
136 1.4 christos obj->strtab = (const char *)
137 1.4 christos (obj->relocbase + dynp->d_un.d_ptr);
138 1.4 christos break;
139 1.4 christos
140 1.5 kleink case DT_STRSZ:
141 1.4 christos obj->strsize = dynp->d_un.d_val;
142 1.4 christos break;
143 1.4 christos
144 1.41 nonaka case DT_VERNEED:
145 1.41 nonaka obj->verneed = (const Elf_Verneed *)
146 1.41 nonaka (obj->relocbase + dynp->d_un.d_ptr);
147 1.41 nonaka break;
148 1.41 nonaka
149 1.41 nonaka case DT_VERNEEDNUM:
150 1.41 nonaka obj->verneednum = dynp->d_un.d_val;
151 1.41 nonaka break;
152 1.41 nonaka
153 1.41 nonaka case DT_VERDEF:
154 1.41 nonaka obj->verdef = (const Elf_Verdef *)
155 1.41 nonaka (obj->relocbase + dynp->d_un.d_ptr);
156 1.41 nonaka break;
157 1.41 nonaka
158 1.41 nonaka case DT_VERDEFNUM:
159 1.41 nonaka obj->verdefnum = dynp->d_un.d_val;
160 1.41 nonaka break;
161 1.41 nonaka
162 1.41 nonaka case DT_VERSYM:
163 1.41 nonaka obj->versyms = (const Elf_Versym *)
164 1.41 nonaka (obj->relocbase + dynp->d_un.d_ptr);
165 1.41 nonaka break;
166 1.41 nonaka
167 1.5 kleink case DT_HASH:
168 1.4 christos {
169 1.31 skrll const Elf_Symindx *hashtab = (const Elf_Symindx *)
170 1.31 skrll (obj->relocbase + dynp->d_un.d_ptr);
171 1.4 christos
172 1.29 joerg if (hashtab[0] > UINT32_MAX)
173 1.29 joerg obj->nbuckets = UINT32_MAX;
174 1.29 joerg else
175 1.29 joerg obj->nbuckets = hashtab[0];
176 1.4 christos obj->nchains = hashtab[1];
177 1.4 christos obj->buckets = hashtab + 2;
178 1.4 christos obj->chains = obj->buckets + obj->nbuckets;
179 1.29 joerg /*
180 1.29 joerg * Should really be in _rtld_relocate_objects,
181 1.29 joerg * but _rtld_symlook_obj might be used before.
182 1.29 joerg */
183 1.29 joerg if (obj->nbuckets) {
184 1.29 joerg fast_divide32_prepare(obj->nbuckets,
185 1.29 joerg &obj->nbuckets_m,
186 1.29 joerg &obj->nbuckets_s1,
187 1.29 joerg &obj->nbuckets_s2);
188 1.29 joerg }
189 1.4 christos }
190 1.4 christos break;
191 1.4 christos
192 1.5 kleink case DT_NEEDED:
193 1.4 christos {
194 1.4 christos Needed_Entry *nep = NEW(Needed_Entry);
195 1.4 christos
196 1.4 christos nep->name = dynp->d_un.d_val;
197 1.4 christos nep->obj = NULL;
198 1.4 christos nep->next = NULL;
199 1.4 christos
200 1.4 christos *needed_tail = nep;
201 1.4 christos needed_tail = &nep->next;
202 1.4 christos }
203 1.4 christos break;
204 1.4 christos
205 1.5 kleink case DT_PLTGOT:
206 1.4 christos obj->pltgot = (Elf_Addr *)
207 1.4 christos (obj->relocbase + dynp->d_un.d_ptr);
208 1.4 christos break;
209 1.4 christos
210 1.5 kleink case DT_TEXTREL:
211 1.4 christos obj->textrel = true;
212 1.4 christos break;
213 1.4 christos
214 1.5 kleink case DT_SYMBOLIC:
215 1.4 christos obj->symbolic = true;
216 1.4 christos break;
217 1.4 christos
218 1.5 kleink case DT_RPATH:
219 1.62.4.3 pgoyette case DT_RUNPATH:
220 1.4 christos /*
221 1.4 christos * We have to wait until later to process this, because
222 1.4 christos * we might not have gotten the address of the string
223 1.4 christos * table yet.
224 1.4 christos */
225 1.4 christos dyn_rpath = dynp;
226 1.4 christos break;
227 1.4 christos
228 1.5 kleink case DT_SONAME:
229 1.51 christos dyn_soname = dynp;
230 1.4 christos break;
231 1.4 christos
232 1.5 kleink case DT_INIT:
233 1.58 christos #ifdef RTLD_LOADER
234 1.10 fredette init = dynp->d_un.d_ptr;
235 1.58 christos #endif
236 1.4 christos break;
237 1.4 christos
238 1.43 matt #ifdef HAVE_INITFINI_ARRAY
239 1.43 matt case DT_INIT_ARRAY:
240 1.59 joerg obj->init_array =
241 1.59 joerg (Elf_Addr *)(obj->relocbase + dynp->d_un.d_ptr);
242 1.49 skrll dbg(("headers: DT_INIT_ARRAY at %p",
243 1.49 skrll obj->init_array));
244 1.43 matt break;
245 1.43 matt
246 1.43 matt case DT_INIT_ARRAYSZ:
247 1.43 matt obj->init_arraysz = dynp->d_un.d_val / sizeof(fptr_t);
248 1.49 skrll dbg(("headers: DT_INIT_ARRAYZ %zu",
249 1.49 skrll obj->init_arraysz));
250 1.43 matt break;
251 1.43 matt #endif
252 1.43 matt
253 1.5 kleink case DT_FINI:
254 1.58 christos #ifdef RTLD_LOADER
255 1.10 fredette fini = dynp->d_un.d_ptr;
256 1.58 christos #endif
257 1.4 christos break;
258 1.1 cgd
259 1.43 matt #ifdef HAVE_INITFINI_ARRAY
260 1.43 matt case DT_FINI_ARRAY:
261 1.43 matt obj->fini_array =
262 1.55 joerg (Elf_Addr *)(obj->relocbase + dynp->d_un.d_ptr);
263 1.49 skrll dbg(("headers: DT_FINI_ARRAY at %p",
264 1.49 skrll obj->fini_array));
265 1.43 matt break;
266 1.43 matt
267 1.43 matt case DT_FINI_ARRAYSZ:
268 1.50 skrll obj->fini_arraysz = dynp->d_un.d_val / sizeof(fptr_t);
269 1.49 skrll dbg(("headers: DT_FINI_ARRAYZ %zu",
270 1.49 skrll obj->fini_arraysz));
271 1.43 matt break;
272 1.43 matt #endif
273 1.43 matt
274 1.20 simonb /*
275 1.20 simonb * Don't process DT_DEBUG on MIPS as the dynamic section
276 1.20 simonb * is mapped read-only. DT_MIPS_RLD_MAP is used instead.
277 1.20 simonb * XXX: n32/n64 may use DT_DEBUG, not sure yet.
278 1.20 simonb */
279 1.20 simonb #ifndef __mips__
280 1.5 kleink case DT_DEBUG:
281 1.1 cgd #ifdef RTLD_LOADER
282 1.4 christos dynp->d_un.d_ptr = (Elf_Addr)&_rtld_debug;
283 1.1 cgd #endif
284 1.4 christos break;
285 1.20 simonb #endif
286 1.2 mhitch
287 1.14 mycroft #ifdef __mips__
288 1.4 christos case DT_MIPS_LOCAL_GOTNO:
289 1.4 christos obj->local_gotno = dynp->d_un.d_val;
290 1.4 christos break;
291 1.4 christos
292 1.4 christos case DT_MIPS_SYMTABNO:
293 1.4 christos obj->symtabno = dynp->d_un.d_val;
294 1.4 christos break;
295 1.4 christos
296 1.4 christos case DT_MIPS_GOTSYM:
297 1.4 christos obj->gotsym = dynp->d_un.d_val;
298 1.4 christos break;
299 1.2 mhitch
300 1.4 christos case DT_MIPS_RLD_MAP:
301 1.2 mhitch #ifdef RTLD_LOADER
302 1.4 christos *((Elf_Addr *)(dynp->d_un.d_ptr)) = (Elf_Addr)
303 1.4 christos &_rtld_debug;
304 1.2 mhitch #endif
305 1.4 christos break;
306 1.2 mhitch #endif
307 1.39 matt #ifdef __powerpc__
308 1.53 matt #ifdef _LP64
309 1.53 matt case DT_PPC64_GLINK:
310 1.54 matt obj->glink = (Elf_Addr)(uintptr_t)obj->relocbase + dynp->d_un.d_ptr;
311 1.53 matt break;
312 1.53 matt #else
313 1.39 matt case DT_PPC_GOT:
314 1.39 matt obj->gotptr = (Elf_Addr *)(obj->relocbase + dynp->d_un.d_ptr);
315 1.39 matt break;
316 1.39 matt #endif
317 1.53 matt #endif
318 1.23 ad case DT_FLAGS_1:
319 1.38 skrll obj->z_now =
320 1.62.4.1 pgoyette ((dynp->d_un.d_val & DF_1_NOW) != 0);
321 1.38 skrll obj->z_nodelete =
322 1.38 skrll ((dynp->d_un.d_val & DF_1_NODELETE) != 0);
323 1.38 skrll obj->z_initfirst =
324 1.23 ad ((dynp->d_un.d_val & DF_1_INITFIRST) != 0);
325 1.38 skrll obj->z_noopen =
326 1.38 skrll ((dynp->d_un.d_val & DF_1_NOOPEN) != 0);
327 1.23 ad break;
328 1.4 christos }
329 1.1 cgd }
330 1.1 cgd
331 1.28 lukem obj->rellim = (const Elf_Rel *)((const uint8_t *)obj->rel + relsz);
332 1.28 lukem obj->relalim = (const Elf_Rela *)((const uint8_t *)obj->rela + relasz);
333 1.30 joerg if (use_pltrel) {
334 1.13 mycroft obj->pltrel = (const Elf_Rel *)(obj->relocbase + pltrel);
335 1.13 mycroft obj->pltrellim = (const Elf_Rel *)(obj->relocbase + pltrel + pltrelsz);
336 1.13 mycroft obj->pltrelalim = 0;
337 1.13 mycroft /* On PPC and SPARC, at least, REL(A)SZ may include JMPREL.
338 1.13 mycroft Trim rel(a)lim to save time later. */
339 1.13 mycroft if (obj->rellim && obj->pltrel &&
340 1.13 mycroft obj->rellim > obj->pltrel &&
341 1.13 mycroft obj->rellim <= obj->pltrellim)
342 1.11 mycroft obj->rellim = obj->pltrel;
343 1.30 joerg } else if (use_pltrela) {
344 1.13 mycroft obj->pltrela = (const Elf_Rela *)(obj->relocbase + pltrel);
345 1.13 mycroft obj->pltrellim = 0;
346 1.13 mycroft obj->pltrelalim = (const Elf_Rela *)(obj->relocbase + pltrel + pltrelsz);
347 1.13 mycroft /* On PPC and SPARC, at least, REL(A)SZ may include JMPREL.
348 1.13 mycroft Trim rel(a)lim to save time later. */
349 1.13 mycroft if (obj->relalim && obj->pltrela &&
350 1.13 mycroft obj->relalim > obj->pltrela &&
351 1.13 mycroft obj->relalim <= obj->pltrelalim)
352 1.11 mycroft obj->relalim = obj->pltrela;
353 1.8 mycroft }
354 1.10 fredette
355 1.57 joerg #ifdef RTLD_LOADER
356 1.10 fredette if (init != 0)
357 1.57 joerg obj->init = (Elf_Addr) obj->relocbase + init;
358 1.10 fredette if (fini != 0)
359 1.57 joerg obj->fini = (Elf_Addr) obj->relocbase + fini;
360 1.57 joerg #endif
361 1.4 christos
362 1.4 christos if (dyn_rpath != NULL) {
363 1.22 christos _rtld_add_paths(execname, &obj->rpaths, obj->strtab +
364 1.12 mycroft dyn_rpath->d_un.d_val);
365 1.4 christos }
366 1.51 christos if (dyn_soname != NULL) {
367 1.51 christos _rtld_object_add_name(obj, obj->strtab +
368 1.51 christos dyn_soname->d_un.d_val);
369 1.51 christos }
370 1.1 cgd }
371 1.1 cgd
372 1.1 cgd /*
373 1.1 cgd * Process a shared object's program header. This is used only for the
374 1.1 cgd * main program, when the kernel has already loaded the main program
375 1.1 cgd * into memory before calling the dynamic linker. It creates and
376 1.1 cgd * returns an Obj_Entry structure.
377 1.1 cgd */
378 1.1 cgd Obj_Entry *
379 1.18 skrll _rtld_digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry)
380 1.1 cgd {
381 1.6 mycroft Obj_Entry *obj;
382 1.4 christos const Elf_Phdr *phlimit = phdr + phnum;
383 1.4 christos const Elf_Phdr *ph;
384 1.62 joerg bool first_seg = true;
385 1.62 joerg Elf_Addr vaddr;
386 1.62 joerg size_t size;
387 1.4 christos
388 1.6 mycroft obj = _rtld_obj_new();
389 1.36 skrll
390 1.36 skrll for (ph = phdr; ph < phlimit; ++ph) {
391 1.36 skrll if (ph->p_type != PT_PHDR)
392 1.36 skrll continue;
393 1.50 skrll
394 1.60 joerg obj->relocbase = (caddr_t)((uintptr_t)phdr - (uintptr_t)ph->p_vaddr);
395 1.60 joerg obj->phdr = phdr; /* Equivalent to relocbase + p_vaddr. */
396 1.46 matt obj->phsize = ph->p_memsz;
397 1.49 skrll dbg(("headers: phdr %p (%p) phsize %zu relocbase %p",
398 1.49 skrll obj->phdr, phdr, obj->phsize, obj->relocbase));
399 1.36 skrll break;
400 1.36 skrll }
401 1.50 skrll
402 1.4 christos for (ph = phdr; ph < phlimit; ++ph) {
403 1.37 skrll vaddr = (Elf_Addr)(uintptr_t)(obj->relocbase + ph->p_vaddr);
404 1.4 christos switch (ph->p_type) {
405 1.4 christos
406 1.6 mycroft case PT_INTERP:
407 1.27 mrg obj->interp = (const char *)(uintptr_t)vaddr;
408 1.52 skrll dbg(("headers: %s %p phsize %" PRImemsz,
409 1.49 skrll "PT_INTERP", (void *)(uintptr_t)vaddr,
410 1.49 skrll ph->p_memsz));
411 1.4 christos break;
412 1.4 christos
413 1.5 kleink case PT_LOAD:
414 1.62 joerg size = round_up(vaddr + ph->p_memsz) - obj->vaddrbase;
415 1.62 joerg if (first_seg) { /* First load segment */
416 1.24 christos obj->vaddrbase = round_down(vaddr);
417 1.27 mrg obj->mapbase = (caddr_t)(uintptr_t)obj->vaddrbase;
418 1.62 joerg obj->textsize = size;
419 1.62 joerg obj->mapsize = size;
420 1.62 joerg first_seg = false;
421 1.4 christos } else { /* Last load segment */
422 1.62 joerg obj->mapsize = MAX(obj->mapsize, size);
423 1.4 christos }
424 1.52 skrll dbg(("headers: %s %p phsize %" PRImemsz,
425 1.49 skrll "PT_LOAD", (void *)(uintptr_t)vaddr,
426 1.49 skrll ph->p_memsz));
427 1.4 christos break;
428 1.4 christos
429 1.5 kleink case PT_DYNAMIC:
430 1.27 mrg obj->dynamic = (Elf_Dyn *)(uintptr_t)vaddr;
431 1.52 skrll dbg(("headers: %s %p phsize %" PRImemsz,
432 1.49 skrll "PT_DYNAMIC", (void *)(uintptr_t)vaddr,
433 1.49 skrll ph->p_memsz));
434 1.4 christos break;
435 1.40 joerg
436 1.61 christos #ifdef GNU_RELRO
437 1.61 christos case PT_GNU_RELRO:
438 1.61 christos obj->relro_page = obj->relocbase
439 1.61 christos + round_down(ph->p_vaddr);
440 1.61 christos obj->relro_size = round_up(ph->p_memsz);
441 1.61 christos dbg(("headers: %s %p phsize %" PRImemsz,
442 1.61 christos "PT_GNU_RELRO", (void *)(uintptr_t)vaddr,
443 1.61 christos ph->p_memsz));
444 1.61 christos break;
445 1.61 christos #endif
446 1.61 christos
447 1.40 joerg #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
448 1.40 joerg case PT_TLS:
449 1.40 joerg obj->tlsindex = 1;
450 1.40 joerg obj->tlssize = ph->p_memsz;
451 1.40 joerg obj->tlsalign = ph->p_align;
452 1.40 joerg obj->tlsinitsize = ph->p_filesz;
453 1.62.4.2 pgoyette obj->tlsinit = (void *)(obj->relocbase +
454 1.62.4.2 pgoyette (uintptr_t)ph->p_vaddr);
455 1.52 skrll dbg(("headers: %s %p phsize %" PRImemsz,
456 1.49 skrll "PT_TLS", (void *)(uintptr_t)vaddr,
457 1.49 skrll ph->p_memsz));
458 1.40 joerg break;
459 1.40 joerg #endif
460 1.44 matt #ifdef __ARM_EABI__
461 1.44 matt case PT_ARM_EXIDX:
462 1.44 matt obj->exidx_start = (void *)(uintptr_t)vaddr;
463 1.44 matt obj->exidx_sz = ph->p_memsz;
464 1.52 skrll dbg(("headers: %s %p phsize %" PRImemsz,
465 1.49 skrll "PT_ARM_EXIDX", (void *)(uintptr_t)vaddr,
466 1.49 skrll ph->p_memsz));
467 1.44 matt break;
468 1.44 matt #endif
469 1.4 christos }
470 1.1 cgd }
471 1.1 cgd
472 1.4 christos obj->entry = entry;
473 1.4 christos return obj;
474 1.1 cgd }
475