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 }