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 = 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 }