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