1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <assert.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stddef.h>
31 #include <string.h>
32 #include <memory.h>
33 #include <sys/sysmacros.h>
34 #include <sys/machelf.h>
35
36 #include "Pcontrol.h"
37 #include "Psymtab_machelf.h"
38
39
40 /*
41 * This file contains code for use by Psymtab.c that is compiled once
42 * for each supported ELFCLASS.
43 *
44 * When processing ELF files, it is common to encounter a situation where
45 * a program with one ELFCLASS (32 or 64-bit) is required to examine a
46 * file with a different ELFCLASS. For example, the 32-bit linker (ld) may
47 * be used to link a 64-bit program. The simplest solution to this problem
48 * is to duplicate each such piece of code, modifying only the data types,
49 * and to use if statements to select the code to run. The problem with
50 * doing it that way is that the resulting code is difficult to maintain.
51 * It is inevitable that the copies will not always get modified identically,
52 * and will drift apart. The only robust solution is to generate the
53 * multiple instances of code automatically from a single piece of code.
54 *
55 * The solution used within the Solaris linker is to write the code once,
56 * using the data types defined in sys/machelf.h, and then to compile that
57 * code twice, once with _ELF64 defined (to generate ELFCLASS64 code) and
58 * once without (to generate ELFCLASS32). We use the same approach here.
59 *
60 * Note that the _ELF64 definition does not refer to the ELFCLASS of
61 * the resulting code, but rather, to the ELFCLASS of the data it
62 * examines. By repeating the above double-compilation for both 32-bit
63 * and 64-bit builds, we end up with 4 instances, which collectively
64 * can handle any combination of program and ELF data class:
65 *
66 * \ Compilation class
67 * \ 32 64
68 * \------------------
69 * |
70 * 32 | X X
71 * ELF Data Class |
72 * 64 | X X
73 */
74
75
76
77 /*
78 * Read data from the specified process and construct an in memory
79 * image of an ELF file that will let us use libelf for most of the
80 * work we need to later (e.g. symbol table lookups). This is used
81 * in cases where no usable on-disk image for the process is available.
82 * We need sections for the dynsym, dynstr, and plt, and we need
83 * the program headers from the text section. The former is used in
84 * Pbuild_file_symtab(); the latter is used in several functions in
85 * Pcore.c to reconstruct the origin of each mapping from the load
86 * object that spawned it.
87 *
88 * Here are some useful pieces of elf trivia that will help
89 * to elucidate this code.
90 *
91 * All the information we need about the dynstr can be found in these
92 * two entries in the dynamic section:
93 *
94 * DT_STRTAB base of dynstr
95 * DT_STRSZ size of dynstr
96 *
97 * So deciphering the dynstr is pretty straightforward.
98 *
99 * The dynsym is a little trickier.
100 *
101 * DT_SYMTAB base of dynsym
102 * DT_SYMENT size of a dynstr entry (Elf{32,64}_Sym)
103 * DT_HASH base of hash table for dynamic lookups
104 *
105 * The DT_SYMTAB entry gives us any easy way of getting to the base
106 * of the dynsym, but getting the size involves rooting around in the
107 * dynamic lookup hash table. Here's the layout of the hash table:
108 *
109 * +-------------------+
110 * | nbucket | All values are 32-bit
111 * +-------------------+ (Elf32_Word or Elf64_Word)
112 * | nchain |
113 * +-------------------+
114 * | bucket[0] |
115 * | . . . |
116 * | bucket[nbucket-1] |
117 * +-------------------+
118 * | chain[0] |
119 * | . . . |
120 * | chain[nchain-1] |
121 * +-------------------+
122 * (figure 5-12 from the SYS V Generic ABI)
123 *
124 * Symbols names are hashed into a particular bucket which contains
125 * an index into the symbol table. Each entry in the symbol table
126 * has a corresponding entry in the chain table which tells the
127 * consumer where the next entry in the hash chain is. We can use
128 * the nchain field to find out the size of the dynsym.
129 *
130 * If there is a dynsym present, there may also be an optional
131 * section called the SUNW_ldynsym that augments the dynsym by
132 * providing local function symbols. When the Solaris linker lays
133 * out a file that has both of these sections, it makes sure that
134 * the data for the two sections is adjacent with the SUNW_ldynsym
135 * in front. This allows the runtime linker to treat these two
136 * symbol tables as being a single larger table. There are two
137 * items in the dynamic section for this:
138 *
139 * DT_SUNW_SYMTAB base of the SUNW_ldynsym
140 * DT_SUNW_SYMSZ total size of SUNW_ldynsym and dynsym
141 * added together. We can figure out the
142 * size of the SUNW_ldynsym section by
143 * subtracting the size of the dynsym
144 * (described above) from this value.
145 *
146 * We can figure out the size of the .plt section, but it takes some
147 * doing. We need to use the following information:
148 *
149 * DT_PLTGOT GOT PLT entry offset (on x86) or PLT offset (on sparc)
150 * DT_JMPREL base of the PLT's relocation section
151 * DT_PLTRELSZ size of the PLT's relocation section
152 * DT_PLTREL type of the PLT's relocation section
153 *
154 * We can use the number of relocation entries to calculate the size of
155 * the PLT. We get the address of the PLT by looking up the
156 * _PROCEDURE_LINKAGE_TABLE_ symbol.
157 *
158 * For more information, check out the System V Generic ABI.
159 */
160
161
162 /*
163 * The fake_elfXX() function generated by this file uses the following
164 * string as the string table for the section names. Since it is critical
165 * to count correctly, and to improve readability, the SHSTR_NDX_ macros
166 * supply the proper offset for each name within the string.
167 */
168 static char shstr[] =
169 ".shstrtab\0.dynsym\0.dynstr\0.dynamic\0.plt\0.SUNW_ldynsym";
170
171 /* Offsets within shstr for each name */
172 #define SHSTR_NDX_shstrtab 0
173 #define SHSTR_NDX_dynsym 10
174 #define SHSTR_NDX_dynstr 18
175 #define SHSTR_NDX_dynamic 26
176 #define SHSTR_NDX_plt 35
177 #define SHSTR_NDX_SUNW_ldynsym 40
178
179
180 /*
181 * Section header alignment for 32 and 64-bit ELF files differs
182 */
183 #ifdef _ELF64
184 #define SH_ADDRALIGN 8
185 #else
186 #define SH_ADDRALIGN 4
187 #endif
188
189 /*
190 * This is the smallest number of PLT relocation entries allowed in a proper
191 * .plt section.
192 */
193 #ifdef __sparc
194 #define PLTREL_MIN_ENTRIES 4 /* SPARC psABI 3.0 and SCD 2.4 */
195 #else
196 #ifdef __lint
197 /*
198 * On x86, lint would complain about unsigned comparison with
199 * PLTREL_MIN_ENTRIES. This define fakes up the value of PLTREL_MIN_ENTRIES
200 * and silences lint. On SPARC, there is no such issue.
201 */
202 #define PLTREL_MIN_ENTRIES 1
203 #else
204 #define PLTREL_MIN_ENTRIES 0
205 #endif
206 #endif
207
208 #ifdef _ELF64
209 Elf *
fake_elf64(struct ps_prochandle * P,file_info_t * fptr,uintptr_t addr,Ehdr * ehdr,uint_t phnum,Phdr * phdr)210 fake_elf64(struct ps_prochandle *P, file_info_t *fptr, uintptr_t addr,
211 Ehdr *ehdr, uint_t phnum, Phdr *phdr)
212 #else
213 Elf *
214 fake_elf32(struct ps_prochandle *P, file_info_t *fptr, uintptr_t addr,
215 Ehdr *ehdr, uint_t phnum, Phdr *phdr)
216 #endif
217 {
218 enum {
219 DI_PLTGOT,
220 DI_JMPREL,
221 DI_PLTRELSZ,
222 DI_PLTREL,
223 DI_SYMTAB,
224 DI_HASH,
225 DI_SYMENT,
226 DI_STRTAB,
227 DI_STRSZ,
228 DI_SUNW_SYMTAB,
229 DI_SUNW_SYMSZ,
230 DI_NENT
231 };
232 /*
233 * Mask of dynamic options that must be present in a well
234 * formed dynamic section. We need all of these in order to
235 * put together a complete set of elf sections. They are
236 * mandatory in both executables and shared objects so if one
237 * of them is missing, we're in some trouble and should abort.
238 * The PLT items are expected, but we will let them slide if
239 * need be. The DI_SUNW_SYM* items are completely optional, so
240 * we use them if they are present and ignore them otherwise.
241 */
242 const int di_req_mask = (1 << DI_SYMTAB) | (1 << DI_HASH) |
243 (1 << DI_SYMENT) | (1 << DI_STRTAB) | (1 << DI_STRSZ);
244 int di_mask = 0;
245 size_t size = 0;
246 caddr_t elfdata = NULL;
247 Elf *elf;
248 size_t dynsym_size = 0, ldynsym_size;
249 int dynstr_shndx;
250 Ehdr *ep;
251 Shdr *sp;
252 Dyn *dp = NULL;
253 Dyn *d[DI_NENT] = { 0 };
254 uint_t i;
255 Off off;
256 size_t pltsz = 0, pltentries = 0;
257 uintptr_t hptr = NULL;
258 Word hnchains, hnbuckets;
259
260 if (ehdr->e_type == ET_DYN)
261 phdr->p_vaddr += addr;
262
263 if (P->rap != NULL) {
264 if (rd_get_dyns(P->rap, addr, (void **)&dp, NULL) != RD_OK)
265 goto bad;
266 } else {
267 if ((dp = malloc(phdr->p_filesz)) == NULL)
268 goto bad;
269 if (Pread(P, dp, phdr->p_filesz, phdr->p_vaddr) !=
270 phdr->p_filesz)
271 goto bad;
272 }
273
274 /*
275 * Iterate over the items in the dynamic section, grabbing
276 * the address of items we want and saving them in dp[].
277 */
278 for (i = 0; i < phdr->p_filesz / sizeof (Dyn); i++) {
279 switch (dp[i].d_tag) {
280 /* For the .plt section */
281 case DT_PLTGOT:
282 d[DI_PLTGOT] = &dp[i];
283 break;
284 case DT_JMPREL:
285 d[DI_JMPREL] = &dp[i];
286 break;
287 case DT_PLTRELSZ:
288 d[DI_PLTRELSZ] = &dp[i];
289 break;
290 case DT_PLTREL:
291 d[DI_PLTREL] = &dp[i];
292 break;
293
294 /* For the .dynsym section */
295 case DT_SYMTAB:
296 d[DI_SYMTAB] = &dp[i];
297 di_mask |= (1 << DI_SYMTAB);
298 break;
299 case DT_HASH:
300 d[DI_HASH] = &dp[i];
301 di_mask |= (1 << DI_HASH);
302 break;
303 case DT_SYMENT:
304 d[DI_SYMENT] = &dp[i];
305 di_mask |= (1 << DI_SYMENT);
306 break;
307 case DT_SUNW_SYMTAB:
308 d[DI_SUNW_SYMTAB] = &dp[i];
309 break;
310 case DT_SUNW_SYMSZ:
311 d[DI_SUNW_SYMSZ] = &dp[i];
312 break;
313
314 /* For the .dynstr section */
315 case DT_STRTAB:
316 d[DI_STRTAB] = &dp[i];
317 di_mask |= (1 << DI_STRTAB);
318 break;
319 case DT_STRSZ:
320 d[DI_STRSZ] = &dp[i];
321 di_mask |= (1 << DI_STRSZ);
322 break;
323 }
324 }
325
326 /* Ensure all required entries were collected */
327 if ((di_mask & di_req_mask) != di_req_mask) {
328 dprintf("text section missing required dynamic entries\n");
329 goto bad;
330 }
331
332 /* SUNW_ldynsym must be adjacent to dynsym. Ignore if not */
333 if ((d[DI_SUNW_SYMTAB] != NULL) && (d[DI_SUNW_SYMSZ] != NULL) &&
334 ((d[DI_SYMTAB]->d_un.d_ptr <= d[DI_SUNW_SYMTAB]->d_un.d_ptr) ||
335 (d[DI_SYMTAB]->d_un.d_ptr >= (d[DI_SUNW_SYMTAB]->d_un.d_ptr +
336 d[DI_SUNW_SYMSZ]->d_un.d_val)))) {
337 d[DI_SUNW_SYMTAB] = NULL;
338 d[DI_SUNW_SYMSZ] = NULL;
339 }
340
341 /* elf header */
342 size = sizeof (Ehdr);
343
344 /* program headers from in-core elf fragment */
345 size += phnum * ehdr->e_phentsize;
346
347 /* unused shdr, and .shstrtab section */
348 size += sizeof (Shdr);
349 size += sizeof (Shdr);
350 size += roundup(sizeof (shstr), SH_ADDRALIGN);
351
352 if (d[DI_HASH] != NULL) {
353 Word hash[2];
354
355 hptr = d[DI_HASH]->d_un.d_ptr;
356 if (ehdr->e_type == ET_DYN)
357 hptr += addr;
358
359 if (Pread(P, hash, sizeof (hash), hptr) != sizeof (hash)) {
360 dprintf("Pread of .hash at %lx failed\n",
361 (long)(hptr));
362 goto bad;
363 }
364
365 hnbuckets = hash[0];
366 hnchains = hash[1];
367 }
368
369 if ((d[DI_HASH] == NULL) || (hnbuckets == 0) || (hnchains == 0)) {
370 dprintf("empty or missing .hash\n");
371 goto bad;
372 }
373
374 /*
375 * .dynsym and .SUNW_ldynsym sections.
376 *
377 * The string table section used for the symbol table and
378 * dynamic sections lies immediately after the dynsym, so the
379 * presence of SUNW_ldynsym changes the dynstr section index.
380 */
381 if (d[DI_SUNW_SYMTAB] != NULL) {
382 size += sizeof (Shdr); /* SUNW_ldynsym shdr */
383 ldynsym_size = (size_t)d[DI_SUNW_SYMSZ]->d_un.d_val;
384 dynsym_size = ldynsym_size - (d[DI_SYMTAB]->d_un.d_ptr
385 - d[DI_SUNW_SYMTAB]->d_un.d_ptr);
386 ldynsym_size -= dynsym_size;
387 dynstr_shndx = 4;
388 } else {
389 dynsym_size = sizeof (Sym) * hnchains;
390 ldynsym_size = 0;
391 dynstr_shndx = 3;
392 }
393 size += sizeof (Shdr) + ldynsym_size + dynsym_size;
394
395 /* .dynstr section */
396 size += sizeof (Shdr);
397 size += roundup(d[DI_STRSZ]->d_un.d_val, SH_ADDRALIGN);
398
399 /* .dynamic section */
400 size += sizeof (Shdr);
401 size += roundup(phdr->p_filesz, SH_ADDRALIGN);
402
403 /* .plt section */
404 if (d[DI_PLTGOT] != NULL && d[DI_JMPREL] != NULL &&
405 d[DI_PLTRELSZ] != NULL && d[DI_PLTREL] != NULL) {
406 size_t pltrelsz = d[DI_PLTRELSZ]->d_un.d_val;
407
408 if (d[DI_PLTREL]->d_un.d_val == DT_RELA) {
409 pltentries = pltrelsz / sizeof (Rela);
410 } else if (d[DI_PLTREL]->d_un.d_val == DT_REL) {
411 pltentries = pltrelsz / sizeof (Rel);
412 } else {
413 /* fall back to the platform default */
414 #if ((defined(__i386) || defined(__amd64)) && !defined(_ELF64))
415 pltentries = pltrelsz / sizeof (Rel);
416 dprintf("DI_PLTREL not found, defaulting to Rel");
417 #else /* (!(__i386 || __amd64)) || _ELF64 */
418 pltentries = pltrelsz / sizeof (Rela);
419 dprintf("DI_PLTREL not found, defaulting to Rela");
420 #endif /* (!(__i386 || __amd64) || _ELF64 */
421 }
422
423 if (pltentries < PLTREL_MIN_ENTRIES) {
424 dprintf("too few PLT relocation entries "
425 "(found %lu, expected at least %d)\n",
426 (long)pltentries, PLTREL_MIN_ENTRIES);
427 goto bad;
428 }
429 if (pltentries < PLTREL_MIN_ENTRIES + 2)
430 goto done_with_plt;
431
432 /*
433 * Now that we know the number of plt relocation entries
434 * we can calculate the size of the plt.
435 */
436 pltsz = (pltentries + M_PLT_XNumber) * M_PLT_ENTSIZE;
437 #if defined(__sparc)
438 /* The sparc PLT always has a (delay slot) nop at the end */
439 pltsz += 4;
440 #endif /* __sparc */
441
442 size += sizeof (Shdr);
443 size += roundup(pltsz, SH_ADDRALIGN);
444 }
445 done_with_plt:
446
447 if ((elfdata = calloc(1, size)) == NULL)
448 goto bad;
449
450 /* LINTED - alignment */
451 ep = (Ehdr *)elfdata;
452 (void) memcpy(ep, ehdr, offsetof(Ehdr, e_phoff));
453
454 ep->e_ehsize = sizeof (Ehdr);
455 ep->e_phoff = sizeof (Ehdr);
456 ep->e_phentsize = ehdr->e_phentsize;
457 ep->e_phnum = phnum;
458 ep->e_shoff = ep->e_phoff + phnum * ep->e_phentsize;
459 ep->e_shentsize = sizeof (Shdr);
460 /*
461 * Plt and SUNW_ldynsym sections are optional. C logical
462 * binary operators return a 0 or 1 value, so the following
463 * adds 1 for each optional section present.
464 */
465 ep->e_shnum = 5 + (pltsz != 0) + (d[DI_SUNW_SYMTAB] != NULL);
466 ep->e_shstrndx = 1;
467
468 /* LINTED - alignment */
469 sp = (Shdr *)(elfdata + ep->e_shoff);
470 off = ep->e_shoff + ep->e_shentsize * ep->e_shnum;
471
472 /*
473 * Copying the program headers directly from the process's
474 * address space is a little suspect, but since we only
475 * use them for their address and size values, this is fine.
476 */
477 if (Pread(P, &elfdata[ep->e_phoff], phnum * ep->e_phentsize,
478 addr + ehdr->e_phoff) != phnum * ep->e_phentsize) {
479 dprintf("failed to read program headers\n");
480 goto bad;
481 }
482
483 /*
484 * The first elf section is always skipped.
485 */
486 sp++;
487
488 /*
489 * Section Header: .shstrtab
490 */
491 sp->sh_name = SHSTR_NDX_shstrtab;
492 sp->sh_type = SHT_STRTAB;
493 sp->sh_flags = SHF_STRINGS;
494 sp->sh_addr = 0;
495 sp->sh_offset = off;
496 sp->sh_size = sizeof (shstr);
497 sp->sh_link = 0;
498 sp->sh_info = 0;
499 sp->sh_addralign = 1;
500 sp->sh_entsize = 0;
501
502 (void) memcpy(&elfdata[off], shstr, sizeof (shstr));
503 off += roundup(sp->sh_size, SH_ADDRALIGN);
504 sp++;
505
506 /*
507 * Section Header: .SUNW_ldynsym
508 */
509 if (d[DI_SUNW_SYMTAB] != NULL) {
510 sp->sh_name = SHSTR_NDX_SUNW_ldynsym;
511 sp->sh_type = SHT_SUNW_LDYNSYM;
512 sp->sh_flags = SHF_ALLOC;
513 sp->sh_addr = d[DI_SUNW_SYMTAB]->d_un.d_ptr;
514 if (ehdr->e_type == ET_DYN)
515 sp->sh_addr += addr;
516 sp->sh_offset = off;
517 sp->sh_size = ldynsym_size;
518 sp->sh_link = dynstr_shndx;
519 /* Index of 1st global in table that has none == # items */
520 sp->sh_info = sp->sh_size / sizeof (Sym);
521 sp->sh_addralign = SH_ADDRALIGN;
522 sp->sh_entsize = sizeof (Sym);
523
524 if (Pread(P, &elfdata[off], sp->sh_size,
525 sp->sh_addr) != sp->sh_size) {
526 dprintf("failed to read .SUNW_ldynsym at %lx\n",
527 (long)sp->sh_addr);
528 goto bad;
529 }
530 off += sp->sh_size;
531 /* No need to round up ldynsym data. Dynsym data is same type */
532 sp++;
533 }
534
535 /*
536 * Section Header: .dynsym
537 */
538 sp->sh_name = SHSTR_NDX_dynsym;
539 sp->sh_type = SHT_DYNSYM;
540 sp->sh_flags = SHF_ALLOC;
541 sp->sh_addr = d[DI_SYMTAB]->d_un.d_ptr;
542 if (ehdr->e_type == ET_DYN)
543 sp->sh_addr += addr;
544 sp->sh_offset = off;
545 sp->sh_size = dynsym_size;
546 sp->sh_link = dynstr_shndx;
547 sp->sh_info = 1; /* Index of 1st global in table */
548 sp->sh_addralign = SH_ADDRALIGN;
549 sp->sh_entsize = sizeof (Sym);
550
551 if (Pread(P, &elfdata[off], sp->sh_size,
552 sp->sh_addr) != sp->sh_size) {
553 dprintf("failed to read .dynsym at %lx\n",
554 (long)sp->sh_addr);
555 goto bad;
556 }
557
558 off += roundup(sp->sh_size, SH_ADDRALIGN);
559 sp++;
560
561 /*
562 * Section Header: .dynstr
563 */
564 sp->sh_name = SHSTR_NDX_dynstr;
565 sp->sh_type = SHT_STRTAB;
566 sp->sh_flags = SHF_ALLOC | SHF_STRINGS;
567 sp->sh_addr = d[DI_STRTAB]->d_un.d_ptr;
568 if (ehdr->e_type == ET_DYN)
569 sp->sh_addr += addr;
570 sp->sh_offset = off;
571 sp->sh_size = d[DI_STRSZ]->d_un.d_val;
572 sp->sh_link = 0;
573 sp->sh_info = 0;
574 sp->sh_addralign = 1;
575 sp->sh_entsize = 0;
576
577 if (Pread(P, &elfdata[off], sp->sh_size,
578 sp->sh_addr) != sp->sh_size) {
579 dprintf("failed to read .dynstr\n");
580 goto bad;
581 }
582 off += roundup(sp->sh_size, SH_ADDRALIGN);
583 sp++;
584
585 /*
586 * Section Header: .dynamic
587 */
588 sp->sh_name = SHSTR_NDX_dynamic;
589 sp->sh_type = SHT_DYNAMIC;
590 sp->sh_flags = SHF_WRITE | SHF_ALLOC;
591 sp->sh_addr = phdr->p_vaddr;
592 if (ehdr->e_type == ET_DYN)
593 sp->sh_addr -= addr;
594 sp->sh_offset = off;
595 sp->sh_size = phdr->p_filesz;
596 sp->sh_link = dynstr_shndx;
597 sp->sh_info = 0;
598 sp->sh_addralign = SH_ADDRALIGN;
599 sp->sh_entsize = sizeof (Dyn);
600
601 (void) memcpy(&elfdata[off], dp, sp->sh_size);
602 off += roundup(sp->sh_size, SH_ADDRALIGN);
603 sp++;
604
605 /*
606 * Section Header: .plt
607 */
608 if (pltsz != 0) {
609 ulong_t plt_symhash;
610 uint_t htmp, ndx;
611 uintptr_t strtabptr, strtabname;
612 Sym sym, *symtabptr;
613 uint_t *hash;
614 char strbuf[sizeof ("_PROCEDURE_LINKAGE_TABLE_")];
615
616 /*
617 * Now we need to find the address of the plt by looking
618 * up the "_PROCEDURE_LINKAGE_TABLE_" symbol.
619 */
620
621 /* get the address of the symtab and strtab sections */
622 strtabptr = d[DI_STRTAB]->d_un.d_ptr;
623 symtabptr = (Sym *)(uintptr_t)d[DI_SYMTAB]->d_un.d_ptr;
624 if (ehdr->e_type == ET_DYN) {
625 strtabptr += addr;
626 symtabptr = (Sym*)((uintptr_t)symtabptr + addr);
627 }
628
629 /* find the .hash bucket address for this symbol */
630 plt_symhash = elf_hash("_PROCEDURE_LINKAGE_TABLE_");
631 htmp = plt_symhash % hnbuckets;
632 hash = &((uint_t *)hptr)[2 + htmp];
633
634 /* read the elf hash bucket index */
635 if (Pread(P, &ndx, sizeof (ndx), (uintptr_t)hash) !=
636 sizeof (ndx)) {
637 dprintf("Pread of .hash at %lx failed\n", (long)hash);
638 goto bad;
639 }
640
641 while (ndx) {
642 if (Pread(P, &sym, sizeof (sym),
643 (uintptr_t)&symtabptr[ndx]) != sizeof (sym)) {
644 dprintf("Pread of .symtab at %lx failed\n",
645 (long)&symtabptr[ndx]);
646 goto bad;
647 }
648
649 strtabname = strtabptr + sym.st_name;
650 if (Pread_string(P, strbuf, sizeof (strbuf),
651 strtabname) < 0) {
652 dprintf("Pread of .strtab at %lx failed\n",
653 (long)strtabname);
654 goto bad;
655 }
656
657 if (strcmp("_PROCEDURE_LINKAGE_TABLE_", strbuf) == 0)
658 break;
659
660 hash = &((uint_t *)hptr)[2 + hnbuckets + ndx];
661 if (Pread(P, &ndx, sizeof (ndx), (uintptr_t)hash) !=
662 sizeof (ndx)) {
663 dprintf("Pread of .hash at %lx failed\n",
664 (long)hash);
665 goto bad;
666 }
667 }
668
669 #if defined(__sparc)
670 if (sym.st_value != d[DI_PLTGOT]->d_un.d_ptr) {
671 dprintf("warning: DI_PLTGOT (%lx) doesn't match "
672 ".plt symbol pointer (%lx)",
673 (long)d[DI_PLTGOT]->d_un.d_ptr,
674 (long)sym.st_value);
675 }
676 #endif /* __sparc */
677
678 if (ndx == 0) {
679 dprintf(
680 "Failed to find \"_PROCEDURE_LINKAGE_TABLE_\"\n");
681 goto bad;
682 }
683
684 sp->sh_name = SHSTR_NDX_plt;
685 sp->sh_type = SHT_PROGBITS;
686 sp->sh_flags = SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR;
687 sp->sh_addr = sym.st_value;
688 if (ehdr->e_type == ET_DYN)
689 sp->sh_addr += addr;
690 sp->sh_offset = off;
691 sp->sh_size = pltsz;
692 sp->sh_link = 0;
693 sp->sh_info = 0;
694 sp->sh_addralign = SH_ADDRALIGN;
695 sp->sh_entsize = M_PLT_ENTSIZE;
696
697 if (Pread(P, &elfdata[off], sp->sh_size, sp->sh_addr) !=
698 sp->sh_size) {
699 dprintf("failed to read .plt at %lx\n",
700 (long)sp->sh_addr);
701 goto bad;
702 }
703 off += roundup(sp->sh_size, SH_ADDRALIGN);
704 sp++;
705 }
706
707 /* make sure we didn't write past the end of allocated memory */
708 sp++;
709 assert(((uintptr_t)(sp) - 1) < ((uintptr_t)elfdata + size));
710
711 free(dp);
712 if ((elf = elf_memory(elfdata, size)) == NULL) {
713 free(elfdata);
714 return (NULL);
715 }
716
717 fptr->file_elfmem = elfdata;
718
719 return (elf);
720
721 bad:
722 if (dp != NULL)
723 free(dp);
724 if (elfdata != NULL)
725 free(elfdata);
726 return (NULL);
727 }
728