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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27/* Copyright (c) 1988 AT&T */ 28/* All Rights Reserved */ 29 30#pragma ident "@(#)clscook.c 1.11 08/05/31 SMI" 31 32/* 33 * This stuff used to live in cook.c, but was moved out to 34 * facilitate dual (Elf32 and Elf64) compilation. See block 35 * comment in cook.c for more info. 36 */ 37 38#include <string.h> 39#include <ar.h> 40#include <stdlib.h> 41#include <errno.h> 42#include "decl.h" 43#include "member.h" 44#include "msg.h" 45 46#if defined(__APPLE__) 47#include <mach-o/fat.h> 48#include <mach-o/loader.h> 49#include <mach-o/nlist.h> 50#include <mach-o/stab.h> 51#include <sys/mman.h> 52 53static struct xSectName 54{ 55 const char *MachoName; 56 const char *PrimaryElfName; 57 const char *SecondaryElfName; 58} 59xTab[] = 60{ 61 {SECT_TEXT, ".text", "non-SEG_TEXT .text" }, 62 {SECT_DATA, ".data", "non-SEG_DATA .data" }, 63 {SECT_BSS, ".bss", "non-SEG_DATA .bss" }, 64 {SECT_CTF, ".SUNW_ctf", 0}, 65 {"__symbol_table", ".symtab", 0 }, 66 {"__debug_info", ".debug_info", 0 }, 67 {"__debug_abbrev", ".debug_abbrev", 0 }, 68 {"__debug_aranges", ".debug_aranges", 0 }, 69 {"__debug_ranges", ".debug_ranges", 0 }, 70 {"__debug_line", ".debug_line", 0 }, 71 {"__debug_frame", ".debug_frame", 0 }, 72 {"__debug_loc", ".debug_loc", 0 }, 73 {"__debug_pubnames", ".debug_pubnames", 0 }, 74 {"__debug_str", ".debug_str", 0 }, 75 {"__debug_funcnames", ".debug_funcnames", 0 }, 76 {"__debug_typenames", ".debug_typenames", 0 }, 77 {"__debug_pubtypes", ".debug_pubtypes", 0 }, 78 {"__debug_varnames", ".debug_varnames", 0 }, 79 {"__debug_weaknames", ".debug_weaknames", 0 }, 80 {"__debug_macinfo", ".debug_macinfo", 0 }, 81 {"__eh_frame", ".eh_frame", 0 }, 82 {"__dir_str_table", ".dir_str_table", 0 } /* Directly addressed Mach-o string table. */ 83}; 84#define SIZE_XTAB (sizeof(xTab)/sizeof(xTab[0])) 85#define LOADER_H_NAME_LENGTH 16 86 87static 88int elf_macho_str_cookie(const char *name, int primary) 89{ 90 int j; 91 int ret = SIZE_XTAB << 1; 92 93 for (j = 0; j < SIZE_XTAB && name; j++) { 94 if (0 == strncmp(name, xTab[j].MachoName, LOADER_H_NAME_LENGTH)) { 95 if (!primary && xTab[j].SecondaryElfName) 96 ret = (j << 1) + 1; 97 else 98 ret = j << 1; 99 break; 100 } 101 } 102 103 return ret; 104} 105 106#if defined(_ELF64) /* Want just one definition, so compile only under -D_ELF64 */ 107const char *elf_macho_str_off(size_t off) 108{ 109 if (off >= (SIZE_XTAB << 1)) 110 return ".unknown mach-o"; 111 else if (off & 1) 112 return xTab[off>>1].SecondaryElfName; 113 else 114 return xTab[off>>1].PrimaryElfName; 115} 116#endif 117 118static 119Elf32_Word STTSect(const char *sectname) 120{ 121 if (0 == strcmp(sectname, SECT_TEXT)) 122 return STT_FUNC; 123 else if (0 == strcmp(sectname, SECT_DATA)) 124 return STT_OBJECT; 125 else if (0 == strcmp(sectname, SECT_BSS)) 126 return STT_OBJECT; 127 else 128 return STT_OBJECT; 129} 130#endif /* __APPLE__ */ 131 132/* 133 * This module is compiled twice, the second time having 134 * -D_ELF64 defined. The following set of macros, along 135 * with machelf.h, represent the differences between the 136 * two compilations. Be careful *not* to add any class- 137 * dependent code (anything that has elf32 or elf64 in the 138 * name) to this code without hiding it behind a switch- 139 * able macro like these. 140 */ 141#if defined(_ELF64) 142#define Snode Snode64 143#define ELFCLASS ELFCLASS64 144#define ElfField Elf64 145#define _elf_snode_init _elf64_snode_init 146#define _elf_prepscan _elf64_prepscan 147#define _elf_cookscn _elf64_cookscn 148#define _elf_mtype _elf64_mtype 149#define _elf_msize _elf64_msize 150#define elf_fsize elf64_fsize 151#define _elf_snode _elf64_snode 152#define _elf_ehdr _elf64_ehdr 153#define elf_xlatetom elf64_xlatetom 154#define _elf_phdr _elf64_phdr 155#define _elf_shdr _elf64_shdr 156#define _elf_prepscn _elf64_prepscn 157 158#if defined(__APPLE__) 159#define _mach_header mach_header_64 160#define _MH_CIGAM MH_CIGAM_64 161#define _swap_mh __swap_mach_header_64 162#define _elf_word Elf64_Word 163#define _elf_addr Elf64_Addr 164#define _elf_off Elf64_Off 165#define _SHN_MACHO SHN_MACHO_64 166#define _nlist nlist_64 167#define _addralign 8 168#define _SWAPVAL SWAP64 169 170#define _LC_SEGMENT LC_SEGMENT_64 171#define _segcmd segment_command_64 172#define _sect section_64 173#define _swapsegcmd __swap_segment_command_64 174#define _swapsect __swap_section_64 175 176#endif /* __APPLE__ */ 177 178#else /* Elf32 */ 179#define Snode Snode32 180#define ELFCLASS ELFCLASS32 181#define ElfField Elf32 182#define _elf_snode_init _elf32_snode_init 183#define _elf_prepscan _elf32_prepscan 184#define _elf_cookscn _elf32_cookscn 185#define _elf_mtype _elf32_mtype 186#define _elf_msize _elf32_msize 187#define elf_fsize elf32_fsize 188#define _elf_snode _elf32_snode 189#define _elf_ehdr _elf32_ehdr 190#define elf_xlatetom elf32_xlatetom 191#define _elf_phdr _elf32_phdr 192#define _elf_shdr _elf32_shdr 193#define _elf_prepscn _elf32_prepscn 194 195#if defined(__APPLE__) 196#define _mach_header mach_header 197#define _MH_CIGAM MH_CIGAM 198#define _swap_mh __swap_mach_header 199#define _elf_word Elf32_Word 200#define _elf_addr Elf32_Addr 201#define _elf_off Elf32_Off 202#define _SHN_MACHO SHN_MACHO 203#define _nlist nlist 204#define _addralign 4 205#define _SWAPVAL SWAP32 206 207#define _LC_SEGMENT LC_SEGMENT 208#define _segcmd segment_command 209#define _sect section 210#define _swapsegcmd __swap_segment_command 211#define _swapsect __swap_section 212 213#endif /* __APPLE__ */ 214 215#endif /* _ELF64 */ 216 217 218static Okay 219_elf_prepscn(Elf *elf, size_t cnt) 220{ 221 NOTE(ASSUMING_PROTECTED(*elf)) 222 Elf_Scn * s; 223 Elf_Scn * end; 224 225 if (cnt == 0) 226 return (OK_YES); 227 228 if ((s = malloc(cnt * sizeof (Elf_Scn))) == 0) { 229 _elf_seterr(EMEM_SCN, errno); 230 return (OK_NO); 231 } 232 NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*s)) 233 elf->ed_scntabsz = cnt; 234 end = s + cnt; 235 elf->ed_hdscn = s; 236 do { 237 *s = _elf_snode_init.sb_scn; 238 s->s_elf = elf; 239 s->s_next = s + 1; 240 s->s_index = s - elf->ed_hdscn; 241 s->s_shdr = (Shdr*)s->s_elf->ed_shdr + s->s_index; 242 ELFMUTEXINIT(&s->s_mutex); 243 244 /* 245 * Section has not yet been cooked! 246 * 247 * We don't cook a section until it's data is actually 248 * referenced. 249 */ 250 s->s_myflags = 0; 251 } while (++s < end); 252 253 elf->ed_tlscn = --s; 254 s->s_next = 0; 255 256 /* 257 * Section index SHN_UNDEF (0) does not and cannot 258 * have a data buffer. Fix it here. Also mark the 259 * initial section as being allocated for the block 260 */ 261 262 s = elf->ed_hdscn; 263 s->s_myflags = SF_ALLOC; 264 s->s_hdnode = 0; 265 s->s_tlnode = 0; 266 NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*s)) 267 return (OK_YES); 268} 269 270 271Okay 272_elf_cookscn(Elf_Scn * s) 273{ 274 NOTE(ASSUMING_PROTECTED(*s, *(s->s_elf))) 275 Elf * elf; 276 Shdr * sh; 277 register Dnode * d = &s->s_dnode; 278 size_t fsz, msz; 279 unsigned work; 280 281 NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*d)) 282 s->s_hdnode = s->s_tlnode = d; 283 s->s_err = 0; 284 s->s_shflags = 0; 285 s->s_uflags = 0; 286 287 288 /* 289 * Prepare d_data for inspection, but don't actually 290 * translate data until needed. Leave the READY 291 * flag off. NOBITS sections see zero size. 292 */ 293 elf = s->s_elf; 294 sh = s->s_shdr; 295 296 d->db_scn = s; 297 d->db_off = sh->sh_offset; 298 d->db_data.d_align = sh->sh_addralign; 299 d->db_data.d_version = elf->ed_version; 300 ELFACCESSDATA(work, _elf_work) 301 d->db_data.d_type = _elf_mtype(elf, sh->sh_type, work); 302 d->db_data.d_buf = 0; 303 d->db_data.d_off = 0; 304 fsz = elf_fsize(d->db_data.d_type, 1, elf->ed_version); 305 msz = _elf_msize(d->db_data.d_type, elf->ed_version); 306 d->db_data.d_size = (sh->sh_size / fsz) * msz; 307 d->db_shsz = sh->sh_size; 308 d->db_raw = 0; 309 d->db_buf = 0; 310 d->db_uflags = 0; 311 d->db_myflags = 0; 312 d->db_next = 0; 313 314 if (sh->sh_type != SHT_NOBITS) 315 d->db_fsz = sh->sh_size; 316 else 317 d->db_fsz = 0; 318 319 s->s_myflags |= SF_READY; 320 321 NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*d)) 322 return (OK_YES); 323} 324 325 326 327Snode * 328_elf_snode() 329{ 330 register Snode *s; 331 332 if ((s = malloc(sizeof (Snode))) == 0) { 333 _elf_seterr(EMEM_SNODE, errno); 334 return (0); 335 } 336 *s = _elf_snode_init; 337 ELFMUTEXINIT(&s->sb_scn.s_mutex); 338 s->sb_scn.s_myflags = SF_ALLOC | SF_READY; 339 s->sb_scn.s_shdr = &s->sb_shdr; 340 return (s); 341} 342 343 344 345int 346_elf_ehdr(Elf * elf, int inplace) 347{ 348 NOTE(ASSUMING_PROTECTED(*elf)) 349 register size_t fsz; /* field size */ 350 Elf_Data dst, src; 351 352 fsz = elf_fsize(ELF_T_EHDR, 1, elf->ed_version); 353 if (fsz > elf->ed_fsz) { 354 _elf_seterr(EFMT_EHDRSZ, 0); 355 return (-1); 356 } 357 if (inplace && (fsz >= sizeof (Ehdr))) { 358 /* 359 * The translated Ehdr will fit over the original Ehdr. 360 */ 361 /* LINTED */ 362 elf->ed_ehdr = (Ehdr *)elf->ed_ident; 363 elf->ed_status = ES_COOKED; 364 } else { 365 elf->ed_ehdr = malloc(sizeof (Ehdr)); 366 if (elf->ed_ehdr == 0) { 367 _elf_seterr(EMEM_EHDR, errno); 368 return (-1); 369 } 370 elf->ed_myflags |= EDF_EHALLOC; 371 } 372 373 /* 374 * Memory size >= fsz, because otherwise the memory version 375 * loses information and cannot accurately implement the 376 * file. 377 */ 378 379 src.d_buf = (Elf_Void *)elf->ed_ident; 380 src.d_type = ELF_T_EHDR; 381 src.d_size = fsz; 382 src.d_version = elf->ed_version; 383 dst.d_buf = (Elf_Void *)elf->ed_ehdr; 384 dst.d_size = sizeof (Ehdr); 385 dst.d_version = EV_CURRENT; 386 387 if ((_elf_vm(elf, (size_t)0, fsz) != OK_YES) || 388 (elf_xlatetom(&dst, &src, elf->ed_encode) == 0)) { 389 if (elf->ed_myflags & EDF_EHALLOC) { 390 elf->ed_myflags &= ~EDF_EHALLOC; 391 free(elf->ed_ehdr); 392 } 393 elf->ed_ehdr = 0; 394 return (-1); 395 } 396 397 if (((Ehdr*)elf->ed_ehdr)->e_ident[EI_CLASS] != ELFCLASS) { 398 _elf_seterr(EREQ_CLASS, 0); 399 if (elf->ed_myflags & EDF_EHALLOC) { 400 elf->ed_myflags &= ~EDF_EHALLOC; 401 free(elf->ed_ehdr); 402 } 403 elf->ed_ehdr = 0; 404 return (-1); 405 } 406 407 if (((Ehdr*)elf->ed_ehdr)->e_version != elf->ed_version) { 408 _elf_seterr(EFMT_VER2, 0); 409 if (elf->ed_myflags & EDF_EHALLOC) { 410 elf->ed_myflags &= ~EDF_EHALLOC; 411 free(elf->ed_ehdr); 412 } 413 elf->ed_ehdr = 0; 414 return (-1); 415 } 416 417 return (0); 418} 419 420 421 422int 423_elf_phdr(Elf * elf, int inplace) 424{ 425 NOTE(ASSUMING_PROTECTED(*elf)) 426 register size_t fsz, msz; 427 Elf_Data dst, src; 428 Ehdr * eh = elf->ed_ehdr; /* must be present */ 429 unsigned work; 430 431 if (eh->e_phnum == 0) 432 return (0); 433 434 fsz = elf_fsize(ELF_T_PHDR, 1, elf->ed_version); 435 if (eh->e_phentsize != fsz) { 436 _elf_seterr(EFMT_PHDRSZ, 0); 437 return (-1); 438 } 439 440 fsz *= eh->e_phnum; 441 ELFACCESSDATA(work, _elf_work) 442 msz = _elf_msize(ELF_T_PHDR, work) * eh->e_phnum; 443 if ((eh->e_phoff == 0) || 444 ((fsz + eh->e_phoff) > elf->ed_fsz)) { 445 _elf_seterr(EFMT_PHTAB, 0); 446 return (-1); 447 } 448 449 if (inplace && fsz >= msz && eh->e_phoff % sizeof (ElfField) == 0) { 450 elf->ed_phdr = (Elf_Void *)(elf->ed_ident + eh->e_phoff); 451 elf->ed_status = ES_COOKED; 452 } else { 453 if ((elf->ed_phdr = malloc(msz)) == 0) { 454 _elf_seterr(EMEM_PHDR, errno); 455 return (-1); 456 } 457 elf->ed_myflags |= EDF_PHALLOC; 458 } 459 src.d_buf = (Elf_Void *)(elf->ed_ident + eh->e_phoff); 460 src.d_type = ELF_T_PHDR; 461 src.d_size = fsz; 462 src.d_version = elf->ed_version; 463 dst.d_buf = elf->ed_phdr; 464 dst.d_size = msz; 465 dst.d_version = work; 466 if ((_elf_vm(elf, (size_t)eh->e_phoff, fsz) != OK_YES) || 467 (elf_xlatetom(&dst, &src, elf->ed_encode) == 0)) { 468 if (elf->ed_myflags & EDF_PHALLOC) { 469 elf->ed_myflags &= ~EDF_PHALLOC; 470 free(elf->ed_phdr); 471 } 472 elf->ed_phdr = 0; 473 return (-1); 474 } 475 elf->ed_phdrsz = msz; 476 return (0); 477} 478 479 480 481int 482_elf_shdr(Elf * elf, int inplace) 483{ 484 NOTE(ASSUMING_PROTECTED(*elf)) 485 register size_t fsz, msz; 486 size_t scncnt; 487 Elf_Data dst, src; 488 register Ehdr *eh = elf->ed_ehdr; /* must be present */ 489 490 if ((eh->e_shnum == 0) && (eh->e_shoff == 0)) 491 return (0); 492 493 fsz = elf_fsize(ELF_T_SHDR, 1, elf->ed_version); 494 if (eh->e_shentsize != fsz) { 495 _elf_seterr(EFMT_SHDRSZ, 0); 496 return (-1); 497 } 498 /* 499 * If we are dealing with a file with 'extended section 500 * indexes' - then we need to load the first section 501 * header. The actual section count is stored in 502 * Shdr[0].sh_size. 503 */ 504 if ((scncnt = eh->e_shnum) == 0) { 505 Shdr sh; 506 if ((eh->e_shoff == 0) || 507 (elf->ed_fsz <= eh->e_shoff) || 508 (elf->ed_fsz - eh->e_shoff < fsz)) { 509 _elf_seterr(EFMT_SHTAB, 0); 510 return (-1); 511 } 512 src.d_buf = (Elf_Void *)(elf->ed_ident + eh->e_shoff); 513 src.d_type = ELF_T_SHDR; 514 src.d_size = fsz; 515 src.d_version = elf->ed_version; 516 dst.d_buf = (Elf_Void *)&sh; 517 dst.d_size = sizeof (Shdr); 518 dst.d_version = EV_CURRENT; 519 if ((_elf_vm(elf, (size_t)eh->e_shoff, fsz) != OK_YES) || 520 (elf_xlatetom(&dst, &src, elf->ed_encode) == 0)) { 521 return (-1); 522 } 523 scncnt = sh.sh_size; 524 } 525 526 fsz *= scncnt; 527 msz = scncnt * sizeof (Shdr); 528 if ((eh->e_shoff == 0) || 529 (elf->ed_fsz <= eh->e_shoff) || 530 (elf->ed_fsz - eh->e_shoff < fsz)) { 531 _elf_seterr(EFMT_SHTAB, 0); 532 return (-1); 533 } 534 535 if (inplace && (fsz >= msz) && 536 ((eh->e_shoff % sizeof (ElfField)) == 0)) { 537 /* LINTED */ 538 elf->ed_shdr = (Shdr *)(elf->ed_ident + eh->e_shoff); 539 elf->ed_status = ES_COOKED; 540 } else { 541 if ((elf->ed_shdr = malloc(msz)) == 0) { 542 _elf_seterr(EMEM_SHDR, errno); 543 return (-1); 544 } 545 elf->ed_myflags |= EDF_SHALLOC; 546 } 547 src.d_buf = (Elf_Void *)(elf->ed_ident + eh->e_shoff); 548 src.d_type = ELF_T_SHDR; 549 src.d_size = fsz; 550 src.d_version = elf->ed_version; 551 dst.d_buf = (Elf_Void *)elf->ed_shdr; 552 dst.d_size = msz; 553 dst.d_version = EV_CURRENT; 554 555#if defined(__APPLE__) 556 if (elf->ed_kind == ELF_K_MACHO) { 557 struct _mach_header hdr, *mh = (struct _mach_header *)(elf->ed_image); 558 struct load_command *thisLC = (struct load_command *)(&(mh[1])); 559 int needSwap = (_MH_CIGAM == mh->magic); 560 int i,j; 561 562 Shdr *pShdr = (Shdr *)(elf->ed_shdr); 563 Shdr *SectionToShdrMap[scncnt]; /* small stack allocated array */ 564 Shdr **pMap = SectionToShdrMap; 565 Shdr *pSymTab = NULL; 566 567 bzero(pShdr, sizeof(Shdr)); 568 SectionToShdrMap[0] = pShdr; 569 pMap++; /* By Mach-o convention the n_sect ordinal index is one-based */ 570 pShdr++; /* By ELF convention the first section header is unused */ 571 572 if (needSwap) { 573 hdr = *mh; 574 mh = &hdr; 575 _swap_mh(mh); 576 } 577 578 for (i = 0; i < mh->ncmds; i++) { 579 int cmd = thisLC->cmd, cmdsize = thisLC->cmdsize; 580 581 if (needSwap) { 582 SWAP32(cmd); 583 SWAP32(cmdsize); 584 } 585 586 switch(cmd) { 587 case _LC_SEGMENT: 588 { 589 struct _segcmd seg, *thisSG = (struct _segcmd *)thisLC; 590 struct _sect sect, *section_ptr, *thisSect = (struct _sect *)(&(thisSG[1])); 591 592 if (needSwap) { 593 seg = *thisSG; 594 thisSG = &seg; 595 _swapsegcmd(thisSG); 596 } 597 598 for (j = 0; j < thisSG->nsects; ++j) { 599 int primary; 600 601 section_ptr = thisSect + j; 602 603 if (needSwap) { 604 sect = *section_ptr; 605 section_ptr = § 606 _swapsect(section_ptr); 607 } 608 609 primary = (0 == strcmp(thisSG->segname, SEG_TEXT)) || 610 (0 == strcmp(thisSG->segname, SEG_DATA)); 611 612 pShdr->sh_name = (_elf_word)elf_macho_str_cookie(section_ptr->sectname, primary); 613 pShdr->sh_type = SHT_UNKNOWN12; 614 pShdr->sh_flags = 0; 615 pShdr->sh_addr = (_elf_addr)section_ptr->addr; 616 pShdr->sh_offset = (_elf_off)section_ptr->offset; 617 pShdr->sh_size = section_ptr->size; 618 pShdr->sh_link = _SHN_MACHO; 619 pShdr->sh_info = STTSect(section_ptr->sectname); 620 pShdr->sh_addralign = section_ptr->align; 621 pShdr->sh_entsize = 0; 622 *pMap = pShdr; 623 pMap++; 624 pShdr++; 625 } 626 break; 627 } 628 629 case LC_SYMTAB: 630 { 631 struct symtab_command symt, *thisST = (struct symtab_command *)thisLC; 632 633 if (needSwap) { 634 symt = *thisST; 635 thisST = &symt; 636 __swap_symtab_command(thisST); 637 } 638 639 pShdr->sh_name = (_elf_word)elf_macho_str_cookie("__symbol_table", 1); 640 pShdr->sh_type = SHT_STRTAB; /* Must yield ELF_T_BYTE to allow the sh_entsize used below! */ 641 pShdr->sh_flags = 0; 642 pShdr->sh_addr = (_elf_addr)(thisST->symoff); 643 pShdr->sh_offset = (_elf_off)(thisST->symoff); 644 pShdr->sh_size = thisST->nsyms * sizeof (struct _nlist); 645 pShdr->sh_link = _SHN_MACHO; 646 pShdr->sh_info = 0; 647 pShdr->sh_addralign = _addralign; 648 pShdr->sh_entsize = sizeof(struct _nlist); 649 pSymTab = pShdr; 650 pShdr++; 651 652 pShdr->sh_name = (_elf_word)elf_macho_str_cookie("__dir_str_table", 1); 653 pShdr->sh_type = SHT_STRTAB; /* Must yield ELF_T_BYTE to allow the sh_entsize used below! */ 654 pShdr->sh_flags = 0; 655 pShdr->sh_addr = (_elf_addr)(thisST->stroff); 656 pShdr->sh_offset = (_elf_off)(thisST->stroff); 657 pShdr->sh_size = thisST->strsize; 658 pShdr->sh_link = _SHN_MACHO; 659 pShdr->sh_info = 0; 660 pShdr->sh_addralign = 1; 661 pShdr->sh_entsize = 0; 662 pShdr++; 663 break; 664 } 665 666 default: 667 break; 668 } 669 670 thisLC = (struct load_command *) ((caddr_t) thisLC + cmdsize); 671 } 672 673 src.d_buf = (Elf_Void *)elf->ed_shdr; 674 src.d_type = ELF_T_SHDR; 675 src.d_size = fsz; 676 677 if (NULL != pSymTab) { 678 struct _nlist *nsym = (struct _nlist *)(elf->ed_image + pSymTab->sh_addr); 679 struct _nlist *pEnd = nsym + (pSymTab->sh_size/pSymTab->sh_entsize); 680 pMap = SectionToShdrMap; 681 682 if (mprotect((char *)elf->ed_image, elf->ed_imagesz, 683 PROT_READ|PROT_WRITE) == -1) { 684 _elf_seterr(EIO_VM, errno); 685 return (-1); 686 } 687 688 while (nsym < pEnd) { 689 690 if (needSwap) { 691 SWAP32(nsym->n_un.n_strx); 692 SWAP16(nsym->n_desc); 693 _SWAPVAL(nsym->n_value); 694 } 695 696 if (nsym->n_type & N_STAB) { /* Detect C++ methods */ 697 698 switch(nsym->n_type) { 699 case N_FUN: 700 nsym->n_desc = STT_FUNC; 701 break; 702 case N_GSYM: 703 nsym->n_desc = STT_OBJECT; 704 break; 705 default: 706 break; 707 } 708 709 } else if ((N_ABS | N_EXT) == (nsym->n_type & (N_TYPE | N_EXT)) || 710 (N_SECT | N_EXT) == (nsym->n_type & (N_TYPE | N_EXT))) { 711 nsym->n_desc = SectionToShdrMap[nsym->n_sect]->sh_info; 712 } else if ((N_UNDF | N_EXT) == (nsym->n_type & (N_TYPE | N_EXT)) && 713 nsym->n_sect == NO_SECT) { 714 nsym->n_desc = STT_OBJECT; /* Common symbol */ 715 } else { 716 /* NOTHING don't mess with other types of symbols */ 717 } 718 nsym++; 719 } 720 } 721 } 722#endif /* __APPLE__ */ 723 724 if ((_elf_vm(elf, (size_t)eh->e_shoff, fsz) != OK_YES) || 725 (elf_xlatetom(&dst, &src, elf->ed_encode) == 0) || 726 (_elf_prepscn(elf, scncnt) != OK_YES)) { 727 if (elf->ed_myflags & EDF_SHALLOC) { 728 elf->ed_myflags &= ~EDF_SHALLOC; 729 free(elf->ed_shdr); 730 } 731 elf->ed_shdr = 0; 732 return (-1); 733 } 734 return (0); 735} 736