Home | History | Annotate | Download | only in common
      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 *
    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;
    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 	/*
    370 	 * .dynsym and .SUNW_ldynsym sections.
    371 	 *
    372 	 * The string table section used for the symbol table and
    373 	 * dynamic sections lies immediately after the dynsym, so the
    374 	 * presence of SUNW_ldynsym changes the dynstr section index.
    375 	 */
    376 	if (d[DI_SUNW_SYMTAB] != NULL) {
    377 		size += sizeof (Shdr);	/* SUNW_ldynsym shdr */
    378 		ldynsym_size = (size_t)d[DI_SUNW_SYMSZ]->d_un.d_val;
    379 		dynsym_size = ldynsym_size - (d[DI_SYMTAB]->d_un.d_ptr
    380 		    - d[DI_SUNW_SYMTAB]->d_un.d_ptr);
    381 		ldynsym_size -= dynsym_size;
    382 		dynstr_shndx = 4;
    383 	} else {
    384 		dynsym_size = sizeof (Sym) * hnchains;
    385 		ldynsym_size = 0;
    386 		dynstr_shndx = 3;
    387 	}
    388 	size += sizeof (Shdr) + ldynsym_size + dynsym_size;
    389 
    390 	/* .dynstr section */
    391 	size += sizeof (Shdr);
    392 	size += roundup(d[DI_STRSZ]->d_un.d_val, SH_ADDRALIGN);
    393 
    394 	/* .dynamic section */
    395 	size += sizeof (Shdr);
    396 	size += roundup(phdr->p_filesz, SH_ADDRALIGN);
    397 
    398 	/* .plt section */
    399 	if (d[DI_PLTGOT] != NULL && d[DI_JMPREL] != NULL &&
    400 	    d[DI_PLTRELSZ] != NULL && d[DI_PLTREL] != NULL) {
    401 		size_t pltrelsz = d[DI_PLTRELSZ]->d_un.d_val;
    402 
    403 		if (d[DI_PLTREL]->d_un.d_val == DT_RELA) {
    404 			pltentries = pltrelsz / sizeof (Rela);
    405 		} else if (d[DI_PLTREL]->d_un.d_val == DT_REL) {
    406 			pltentries = pltrelsz / sizeof (Rel);
    407 		} else {
    408 			/* fall back to the platform default */
    409 #if ((defined(__i386) || defined(__amd64)) && !defined(_ELF64))
    410 			pltentries = pltrelsz / sizeof (Rel);
    411 			dprintf("DI_PLTREL not found, defaulting to Rel");
    412 #else /* (!(__i386 || __amd64)) || _ELF64 */
    413 			pltentries = pltrelsz / sizeof (Rela);
    414 			dprintf("DI_PLTREL not found, defaulting to Rela");
    415 #endif /* (!(__i386 || __amd64) || _ELF64 */
    416 		}
    417 
    418 		if (pltentries < PLTREL_MIN_ENTRIES) {
    419 			dprintf("too few PLT relocation entries "
    420 			    "(found %lu, expected at least %d)\n",
    421 			    (long)pltentries, PLTREL_MIN_ENTRIES);
    422 			goto bad;
    423 		}
    424 		if (pltentries < PLTREL_MIN_ENTRIES + 2)
    425 			goto done_with_plt;
    426 
    427 		/*
    428 		 * Now that we know the number of plt relocation entries
    429 		 * we can calculate the size of the plt.
    430 		 */
    431 		pltsz = (pltentries + M_PLT_XNumber) * M_PLT_ENTSIZE;
    432 #if defined(__sparc)
    433 		/* The sparc PLT always has a (delay slot) nop at the end */
    434 		pltsz += 4;
    435 #endif /* __sparc */
    436 
    437 		size += sizeof (Shdr);
    438 		size += roundup(pltsz, SH_ADDRALIGN);
    439 	}
    440 done_with_plt:
    441 
    442 	if ((elfdata = calloc(1, size)) == NULL)
    443 		goto bad;
    444 
    445 	/* LINTED - alignment */
    446 	ep = (Ehdr *)elfdata;
    447 	(void) memcpy(ep, ehdr, offsetof(Ehdr, e_phoff));
    448 
    449 	ep->e_ehsize = sizeof (Ehdr);
    450 	ep->e_phoff = sizeof (Ehdr);
    451 	ep->e_phentsize = ehdr->e_phentsize;
    452 	ep->e_phnum = phnum;
    453 	ep->e_shoff = ep->e_phoff + phnum * ep->e_phentsize;
    454 	ep->e_shentsize = sizeof (Shdr);
    455 	/*
    456 	 * Plt and SUNW_ldynsym sections are optional. C logical
    457 	 * binary operators return a 0 or 1 value, so the following
    458 	 * adds 1 for each optional section present.
    459 	 */
    460 	ep->e_shnum = 5 + (pltsz != 0) + (d[DI_SUNW_SYMTAB] != NULL);
    461 	ep->e_shstrndx = 1;
    462 
    463 	/* LINTED - alignment */
    464 	sp = (Shdr *)(elfdata + ep->e_shoff);
    465 	off = ep->e_shoff + ep->e_shentsize * ep->e_shnum;
    466 
    467 	/*
    468 	 * Copying the program headers directly from the process's
    469 	 * address space is a little suspect, but since we only
    470 	 * use them for their address and size values, this is fine.
    471 	 */
    472 	if (Pread(P, &elfdata[ep->e_phoff], phnum * ep->e_phentsize,
    473 	    addr + ehdr->e_phoff) != phnum * ep->e_phentsize) {
    474 		dprintf("failed to read program headers\n");
    475 		goto bad;
    476 	}
    477 
    478 	/*
    479 	 * The first elf section is always skipped.
    480 	 */
    481 	sp++;
    482 
    483 	/*
    484 	 * Section Header: .shstrtab
    485 	 */
    486 	sp->sh_name = SHSTR_NDX_shstrtab;
    487 	sp->sh_type = SHT_STRTAB;
    488 	sp->sh_flags = SHF_STRINGS;
    489 	sp->sh_addr = 0;
    490 	sp->sh_offset = off;
    491 	sp->sh_size = sizeof (shstr);
    492 	sp->sh_link = 0;
    493 	sp->sh_info = 0;
    494 	sp->sh_addralign = 1;
    495 	sp->sh_entsize = 0;
    496 
    497 	(void) memcpy(&elfdata[off], shstr, sizeof (shstr));
    498 	off += roundup(sp->sh_size, SH_ADDRALIGN);
    499 	sp++;
    500 
    501 	/*
    502 	 * Section Header: .SUNW_ldynsym
    503 	 */
    504 	if (d[DI_SUNW_SYMTAB] != NULL) {
    505 		sp->sh_name = SHSTR_NDX_SUNW_ldynsym;
    506 		sp->sh_type = SHT_SUNW_LDYNSYM;
    507 		sp->sh_flags = SHF_ALLOC;
    508 		sp->sh_addr = d[DI_SUNW_SYMTAB]->d_un.d_ptr;
    509 		if (ehdr->e_type == ET_DYN)
    510 			sp->sh_addr += addr;
    511 		sp->sh_offset = off;
    512 		sp->sh_size = ldynsym_size;
    513 		sp->sh_link = dynstr_shndx;
    514 		/* Index of 1st global in table that has none == # items */
    515 		sp->sh_info = sp->sh_size / sizeof (Sym);
    516 		sp->sh_addralign = SH_ADDRALIGN;
    517 		sp->sh_entsize = sizeof (Sym);
    518 
    519 		if (Pread(P, &elfdata[off], sp->sh_size,
    520 		    sp->sh_addr) != sp->sh_size) {
    521 			dprintf("failed to read .SUNW_ldynsym at %lx\n",
    522 			    (long)sp->sh_addr);
    523 			goto bad;
    524 		}
    525 		off += sp->sh_size;
    526 		/* No need to round up ldynsym data. Dynsym data is same type */
    527 		sp++;
    528 	}
    529 
    530 	/*
    531 	 * Section Header: .dynsym
    532 	 */
    533 	sp->sh_name = SHSTR_NDX_dynsym;
    534 	sp->sh_type = SHT_DYNSYM;
    535 	sp->sh_flags = SHF_ALLOC;
    536 	sp->sh_addr = d[DI_SYMTAB]->d_un.d_ptr;
    537 	if (ehdr->e_type == ET_DYN)
    538 		sp->sh_addr += addr;
    539 	sp->sh_offset = off;
    540 	sp->sh_size = dynsym_size;
    541 	sp->sh_link = dynstr_shndx;
    542 	sp->sh_info = 1;	/* Index of 1st global in table */
    543 	sp->sh_addralign = SH_ADDRALIGN;
    544 	sp->sh_entsize = sizeof (Sym);
    545 
    546 	if (Pread(P, &elfdata[off], sp->sh_size,
    547 	    sp->sh_addr) != sp->sh_size) {
    548 		dprintf("failed to read .dynsym at %lx\n",
    549 		    (long)sp->sh_addr);
    550 		goto bad;
    551 	}
    552 
    553 	off += roundup(sp->sh_size, SH_ADDRALIGN);
    554 	sp++;
    555 
    556 	/*
    557 	 * Section Header: .dynstr
    558 	 */
    559 	sp->sh_name = SHSTR_NDX_dynstr;
    560 	sp->sh_type = SHT_STRTAB;
    561 	sp->sh_flags = SHF_ALLOC | SHF_STRINGS;
    562 	sp->sh_addr = d[DI_STRTAB]->d_un.d_ptr;
    563 	if (ehdr->e_type == ET_DYN)
    564 		sp->sh_addr += addr;
    565 	sp->sh_offset = off;
    566 	sp->sh_size = d[DI_STRSZ]->d_un.d_val;
    567 	sp->sh_link = 0;
    568 	sp->sh_info = 0;
    569 	sp->sh_addralign = 1;
    570 	sp->sh_entsize = 0;
    571 
    572 	if (Pread(P, &elfdata[off], sp->sh_size,
    573 	    sp->sh_addr) != sp->sh_size) {
    574 		dprintf("failed to read .dynstr\n");
    575 		goto bad;
    576 	}
    577 	off += roundup(sp->sh_size, SH_ADDRALIGN);
    578 	sp++;
    579 
    580 	/*
    581 	 * Section Header: .dynamic
    582 	 */
    583 	sp->sh_name = SHSTR_NDX_dynamic;
    584 	sp->sh_type = SHT_DYNAMIC;
    585 	sp->sh_flags = SHF_WRITE | SHF_ALLOC;
    586 	sp->sh_addr = phdr->p_vaddr;
    587 	if (ehdr->e_type == ET_DYN)
    588 		sp->sh_addr -= addr;
    589 	sp->sh_offset = off;
    590 	sp->sh_size = phdr->p_filesz;
    591 	sp->sh_link = dynstr_shndx;
    592 	sp->sh_info = 0;
    593 	sp->sh_addralign = SH_ADDRALIGN;
    594 	sp->sh_entsize = sizeof (Dyn);
    595 
    596 	(void) memcpy(&elfdata[off], dp, sp->sh_size);
    597 	off += roundup(sp->sh_size, SH_ADDRALIGN);
    598 	sp++;
    599 
    600 	/*
    601 	 * Section Header: .plt
    602 	 */
    603 	if (pltsz != 0) {
    604 		ulong_t		plt_symhash;
    605 		uint_t		htmp, ndx;
    606 		uintptr_t	strtabptr, strtabname;
    607 		Sym		sym, *symtabptr;
    608 		uint_t		*hash;
    609 		char		strbuf[sizeof ("_PROCEDURE_LINKAGE_TABLE_")];
    610 
    611 		/*
    612 		 * Now we need to find the address of the plt by looking
    613 		 * up the "_PROCEDURE_LINKAGE_TABLE_" symbol.
    614 		 */
    615 
    616 		/* get the address of the symtab and strtab sections */
    617 		strtabptr = d[DI_STRTAB]->d_un.d_ptr;
    618 		symtabptr = (Sym *)(uintptr_t)d[DI_SYMTAB]->d_un.d_ptr;
    619 		if (ehdr->e_type == ET_DYN) {
    620 			strtabptr += addr;
    621 			symtabptr = (Sym*)((uintptr_t)symtabptr + addr);
    622 		}
    623 
    624 		/* find the .hash bucket address for this symbol */
    625 		plt_symhash = elf_hash("_PROCEDURE_LINKAGE_TABLE_");
    626 		htmp = plt_symhash % hnbuckets;
    627 		hash = &((uint_t *)hptr)[2 + htmp];
    628 
    629 		/* read the elf hash bucket index */
    630 		if (Pread(P, &ndx, sizeof (ndx), (uintptr_t)hash) !=
    631 		    sizeof (ndx)) {
    632 			dprintf("Pread of .hash at %lx failed\n", (long)hash);
    633 			goto bad;
    634 		}
    635 
    636 		while (ndx) {
    637 			if (Pread(P, &sym, sizeof (sym),
    638 			    (uintptr_t)&symtabptr[ndx]) != sizeof (sym)) {
    639 				dprintf("Pread of .symtab at %lx failed\n",
    640 				    (long)&symtabptr[ndx]);
    641 				goto bad;
    642 			}
    643 
    644 			strtabname = strtabptr + sym.st_name;
    645 			if (Pread_string(P, strbuf, sizeof (strbuf),
    646 			    strtabname) < 0) {
    647 				dprintf("Pread of .strtab at %lx failed\n",
    648 				    (long)strtabname);
    649 				goto bad;
    650 			}
    651 
    652 			if (strcmp("_PROCEDURE_LINKAGE_TABLE_", strbuf) == 0)
    653 				break;
    654 
    655 			hash = &((uint_t *)hptr)[2 + hnbuckets + ndx];
    656 			if (Pread(P, &ndx, sizeof (ndx), (uintptr_t)hash) !=
    657 			    sizeof (ndx)) {
    658 				dprintf("Pread of .hash at %lx failed\n",
    659 				    (long)hash);
    660 				goto bad;
    661 			}
    662 		}
    663 
    664 #if defined(__sparc)
    665 		if (sym.st_value != d[DI_PLTGOT]->d_un.d_ptr) {
    666 			dprintf("warning: DI_PLTGOT (%lx) doesn't match "
    667 			    ".plt symbol pointer (%lx)",
    668 			    (long)d[DI_PLTGOT]->d_un.d_ptr,
    669 			    (long)sym.st_value);
    670 		}
    671 #endif /* __sparc */
    672 
    673 		if (ndx == 0) {
    674 			dprintf(
    675 			    "Failed to find \"_PROCEDURE_LINKAGE_TABLE_\"\n");
    676 			goto bad;
    677 		}
    678 
    679 		sp->sh_name = SHSTR_NDX_plt;
    680 		sp->sh_type = SHT_PROGBITS;
    681 		sp->sh_flags = SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR;
    682 		sp->sh_addr = sym.st_value;
    683 		if (ehdr->e_type == ET_DYN)
    684 			sp->sh_addr += addr;
    685 		sp->sh_offset = off;
    686 		sp->sh_size = pltsz;
    687 		sp->sh_link = 0;
    688 		sp->sh_info = 0;
    689 		sp->sh_addralign = SH_ADDRALIGN;
    690 		sp->sh_entsize = M_PLT_ENTSIZE;
    691 
    692 		if (Pread(P, &elfdata[off], sp->sh_size, sp->sh_addr) !=
    693 		    sp->sh_size) {
    694 			dprintf("failed to read .plt at %lx\n",
    695 			    (long)sp->sh_addr);
    696 			goto bad;
    697 		}
    698 		off += roundup(sp->sh_size, SH_ADDRALIGN);
    699 		sp++;
    700 	}
    701 
    702 	/* make sure we didn't write past the end of allocated memory */
    703 	sp++;
    704 	assert(((uintptr_t)(sp) - 1) < ((uintptr_t)elfdata + size));
    705 
    706 	free(dp);
    707 	if ((elf = elf_memory(elfdata, size)) == NULL) {
    708 		free(elfdata);
    709 		return (NULL);
    710 	}
    711 
    712 	fptr->file_elfmem = elfdata;
    713 
    714 	return (elf);
    715 
    716 bad:
    717 	if (dp != NULL)
    718 		free(dp);
    719 	if (elfdata != NULL)
    720 		free(elfdata);
    721 	return (NULL);
    722 }
    723