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 /* 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