1/* 2 * Copyright (c) 1999-2007 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23#ifdef SHLIB 24#include "shlib.h" 25#endif /* SHLIB */ 26/* 27 * This file contains the routines to manage the merging of the symbols. 28 * It builds a merged symbol table and string table for external symbols. 29 * It also contains all other routines that deal with symbols. 30 */ 31#include <sys/param.h> 32#include <sys/types.h> 33#include <sys/stat.h> 34#include <stdlib.h> 35#if !(defined(KLD) && defined(__STATIC__)) 36#include <stdio.h> 37#include <ctype.h> 38#include <mach/mach.h> 39#else /* defined(KLD) && defined(__STATIC__) */ 40#include <mach/kern_return.h> 41#endif /* !(defined(KLD) && defined(__STATIC__)) */ 42#include <stdarg.h> 43#include <string.h> 44#include <mach-o/loader.h> 45#include <mach-o/nlist.h> 46#include <mach-o/stab.h> 47#include <mach-o/ldsyms.h> 48#include <ar.h> 49#include "stuff/bool.h" 50#include "stuff/bytesex.h" 51#include "stuff/macosx_deployment_target.h" 52#ifndef RLD 53#include "stuff/symbol_list.h" 54#endif 55 56#include "ld.h" 57#include "specs.h" 58#include "live_refs.h" 59#include "objects.h" 60#include "sections.h" 61#include "pass1.h" 62#include "symbols.h" 63#include "layout.h" 64#include "pass2.h" 65#include "sets.h" 66#include "hash_string.h" 67#include "dylibs.h" 68#include "mod_sections.h" 69 70#ifdef RLD 71__private_extern__ char *base_name; 72#endif 73 74/* 75 * The head of the symbol list and the total count of all external symbols 76 * in the list. The total count of private externals is included in the total 77 * count of the merged symbols. The private externals may end up as global or 78 * static depending on the -keep_private_externs flag. The count of merged 79 * symbols referenced only from dylibs will not be in the output file. 80 */ 81__private_extern__ struct merged_symbol_root *merged_symbol_root = NULL; 82__private_extern__ unsigned long nmerged_symbols = 0; 83__private_extern__ unsigned long nmerged_private_symbols = 0; 84__private_extern__ unsigned long nmerged_symbols_referenced_only_from_dylibs =0; 85 86/* 87 * nstripped_merged_symbols is set to the number of merged symbol being stripped 88 * out when -dead_strip is specified or the strip_level is 89 * STRIP_DYNAMIC_EXECUTABLE. 90 */ 91__private_extern__ unsigned long nstripped_merged_symbols = 0; 92/* 93 * When -dead_strip is specified some of these the merged private symbols may 94 * get stripped. To allow assign_output_symbol_indexes() to recalculate the 95 * value of nstripped_merged_symbols when it sets the strip_level to 96 * STRIP_DYNAMIC_EXECUTABLE it starts with this value and then adds the 97 * additional merged symbols to strip. This value is also used to do its 98 * consistency check after assigning local symbol indexes. 99 * nstripped_merged_private_symbols is set in count_live_symbols(). 100 */ 101static unsigned long nstripped_merged_private_symbols = 0; 102 103/* 104 * The head of the list of the blocks that store the strings for the merged 105 * symbols and the total size of all the strings. 106 */ 107__private_extern__ struct string_block *merged_string_blocks = NULL; 108__private_extern__ unsigned long merged_string_size = 0; 109 110/* 111 * To order the merged symbol table these arrays are allocated and filled in by 112 * assign_output_symbol_indexes() to assign the output symbol indexes and then 113 * used by output_merged_symbols() to put the symbols out in that order. 114 */ 115static struct merged_symbol **undefsyms_order = NULL; 116static struct merged_symbol **extdefsyms_order = NULL; 117/* 118 * The current order of an undefined symbol. This is set into the merged_symbol 119 * and later used if bind_at_load is set to sort the undefined symbols by so 120 * they are in the order the were seen by the static linker. 121 */ 122static int undef_order = 0; 123#ifndef SA_RLD 124/* 125 * The qsort routines used by assign_output_symbol_indexes() to order the merged 126 * symbol table. 127 */ 128static int qsort_by_module( 129 const struct merged_symbol **ms1, 130 const struct merged_symbol **ms2); 131static int qsort_by_name( 132 const struct merged_symbol **ms1, 133 const struct merged_symbol **ms2); 134static int qsort_by_undef_order( 135 const struct merged_symbol **ms1, 136 const struct merged_symbol **ms2); 137#endif /* !defined(SA_RLD) */ 138 139/* 140 * The number of local symbols that will appear in the output file and the 141 * size of their strings. 142 */ 143__private_extern__ unsigned long nlocal_symbols = 0; 144__private_extern__ unsigned long local_string_size = 0; 145 146/* 147 * The things to deal with creating local symbols with the object file's name 148 * for a given section. If the section name is (__TEXT,__text) these are the 149 * same as a UNIX link editor's file.o symbols for the text section. 150 */ 151__private_extern__ struct sect_object_symbols sect_object_symbols = { FALSE }; 152 153/* 154 * The head of the undefined list and the list of free undefined structures. 155 * These are circular lists so they can be searched from start to end and so 156 * new items can be put on the end. These two structure never has their 157 * merged_symbol filled in but they only serve as the heads and tails of there 158 * lists. 159 */ 160__private_extern__ struct undefined_list undefined_list = { 161 NULL, &undefined_list, &undefined_list 162}; 163static struct undefined_list free_list = { 164 NULL, &free_list, &free_list 165}; 166/* 167 * The structures for the undefined list are allocated in blocks and placed on 168 * a free list. They are allocated in blocks so they can be free()'ed quickly. 169 */ 170#define NUNDEF_BLOCKS 680 171static struct undefined_block { 172 struct undefined_list undefineds[NUNDEF_BLOCKS]; 173 struct undefined_block *next; 174} *undefined_blocks; 175 176#ifndef RLD 177/* 178 * The common symbol load map. Only allocated and filled in if load map is 179 * requested. 180 */ 181__private_extern__ struct common_load_map common_load_map = { 0 }; 182 183/* 184 * These symbols are used by the routines command_line_symbol(), 185 * command_line_indr_symbol() and merge_dylib_symbols() to create symbols from 186 * the command line options (-u and -i) and from dylibs. 187 */ 188static struct nlist undefined_symbol = { 189 {0}, /* n_un.n_strx */ 190 N_UNDF | N_EXT, /* n_type */ 191 NO_SECT, /* n_sect */ 192 0, /* n_desc */ 193 0 /* n_value */ 194}; 195static struct nlist indr_symbol = { 196 {0}, /* n_un.n_strx */ 197 N_INDR | N_EXT, /* n_type */ 198 NO_SECT, /* n_sect */ 199 0, /* n_desc */ 200 0 /* n_value */ 201}; 202static struct nlist pbud_symbol = { 203 {0}, /* n_un.n_strx */ 204 N_PBUD | N_EXT, /* n_type */ 205 NO_SECT, /* n_sect */ 206 REFERENCE_FLAG_UNDEFINED_LAZY, /* n_desc */ 207 0 /* n_value */ 208}; 209static struct nlist pbud_weak_def_symbol = { 210 {0}, /* n_un.n_strx */ 211 N_PBUD | N_EXT, /* n_type */ 212 NO_SECT, /* n_sect */ 213 REFERENCE_FLAG_UNDEFINED_LAZY | N_WEAK_DEF, /* n_desc */ 214 0 /* n_value */ 215}; 216 217/* 218 * This symbol is used by the routines that define link editor defined symbols. 219 * And the routine sets it up. 220 */ 221static struct object_file *link_edit_symbols_object = NULL; 222static void setup_link_edit_symbols_object( 223 void); 224 225/* 226 * Most of the time there are no local symbols marked with the NO_DEAD_STRIP 227 * flag. Since it is time consuming to mark those blocks we check to see if 228 * when have any of them in merge_symbols. 229 */ 230static enum bool local_NO_DEAD_STRIP_symbols = FALSE; 231static void mark_N_NO_DEAD_STRIP_local_symbols_in_section_live( 232 struct merged_section *ms); 233static void removed_dead_local_symbols_in_section( 234 struct merged_section *ms); 235static void remove_dead_N_GSYM_stabs( 236 void); 237static void setup_link_editor_symbol( 238 char *symbol_name); 239static void define_link_editor_dylib_symbol( 240 unsigned long header_address, 241 char *symbol_name); 242static void exports_list_processing( 243 char *symbol_name, 244 struct nlist *symbol); 245static char * find_stab_name_end( 246 char *name); 247static char * find_stab_type_end( 248 char *name_end); 249#endif /* !defined(RLD) */ 250static enum bool is_type_stab( 251 unsigned char n_type, 252 char *symbol_name); 253 254/* 255 * These symbols are used when defining common symbols. In the RLD case they 256 * are templates and thus const and the real versions of these symbols are in 257 * the sets array. 258 */ 259static 260#if defined(RLD) && !defined(__DYNAMIC__) 261const 262#endif 263struct section link_edit_common_section = { 264 SECT_COMMON, /* sectname */ 265 SEG_DATA, /* segname */ 266 0, /* addr */ 267 0, /* size */ 268 0, /* offset */ 269 0, /* align */ 270 0, /* reloff */ 271 0, /* nreloc */ 272 S_ZEROFILL, /* flags */ 273 0, /* reserved1 */ 274 0, /* reserved2 */ 275}; 276 277static 278#if defined(RLD) && !defined(__DYNAMIC__) 279const 280#endif 281struct section_map link_edit_section_maps = { 282#ifdef RLD 283 NULL, /* struct section *s */ 284#else 285 &link_edit_common_section, /* struct section *s */ 286#endif /* RLD */ 287 NULL, /* output_section */ 288 0, /* offset */ 289 0, /* flush_offset */ 290 NULL, /* fine_relocs */ 291 0, /* nfine_relocs */ 292 FALSE, /* no_load_order */ 293 0, /* order */ 294 NULL, /* load_orders */ 295 0 /* nload_orders */ 296}; 297 298#ifndef RLD 299__private_extern__ 300struct symtab_command link_edit_common_symtab = { 301 LC_SYMTAB, /* cmd */ 302 sizeof(struct symtab_command), /* cmdsize */ 303 0, /* symoff */ 304 0, /* nsyms */ 305 0, /* stroff */ 306 1 /* strsize */ 307}; 308#endif /* !defined(RLD) */ 309 310__private_extern__ 311struct object_file link_edit_common_object = { 312 "\"link editor\"", /* file_name */ 313 NULL, /* obj_addr */ 314 0, /* obj_size */ 315 FALSE, /* swapped */ 316 FALSE, /* fvmlib_stuff */ 317 FALSE, /* dylib */ 318 FALSE, /* dylib_stuff */ 319 FALSE, /* bundle_loader */ 320 0, /* library_ordinal */ 321 0, /* isub_image */ 322 0, /* nload_dylibs */ 323 FALSE, /* dylinker */ 324 FALSE, /* command_line */ 325 NULL, /* ar_hdr */ 326 NULL, /* ar_name */ 327 0, /* ar_name_size */ 328 NULL, /* dylib_module */ 329 1, /* nsection_maps */ 330#ifdef RLD 331 NULL, /* section_maps */ 332 NULL, /* symtab */ 333#else 334 &link_edit_section_maps, /* section_maps */ 335 &link_edit_common_symtab, /* symtab */ 336#endif /* RLD */ 337 NULL, /* dysymtab */ 338 NULL, /* rc */ 339 0, /* nundefineds */ 340 NULL, /* undefined_maps */ 341 0, /* nextdefsym */ 342 0, /* iextdefsym */ 343 0, /* nprivatesym */ 344 0, /* iprivatesym */ 345 0, /* cprivatesym */ 346 0, /* nlocalsym */ 347 0, /* ilocalsym */ 348 NULL, /* localsym_blocks */ 349 NULL /* cur_section_map */ 350#ifdef RLD 351 ,0, /* set_num */ 352 FALSE /* user_obj_addr */ 353#endif /* RLD */ 354}; 355 356/* 357 * This is the list of multiply defined symbol names. It is used to make sure 358 * an error message for each name is only printed once and it is traced only 359 * once. 360 */ 361static char **multiple_defs = NULL; 362static unsigned long nmultiple_defs = 0; 363 364/* 365 * This is the count of indirect symbols in the merged symbol table. It is used 366 * as the size of an array that needed to be allocated to reduce chains of 367 * indirect symbols to their final symbol and to detect circular chains. 368 */ 369static unsigned long nindr_symbols = 0; 370 371/* 372 * The indr_symbol_pair structure is used when there are chains of N_INDR 373 * that have symbols both from dylibs and not from dylibs. The routine 374 * reduce_indr_symbols() creates this and the routines output_merged_symbols() 375 * and indirect_section_merge() both use it. What is going on is that when 376 * producing an output file the N_INDR symbols from a dylib can't be used in 377 * a chain of N_INDR symbols. So this structure contains merged_symbols which 378 * are N_INDR which should use the matching indr_symbol from the table instead 379 * of going through (struct merged_symbol *)(merged_symbol->nlist.n_value). 380 */ 381__private_extern__ struct indr_symbol_pair *indr_symbol_pairs = NULL; 382__private_extern__ unsigned long nindr_symbol_pairs = 0; 383 384/* 385 * commons_exist is set and used in define_common_symbols(). noundefs is set 386 * and used in process_undefineds(). These are then used in 387 * layout_merged_symbols() to properly set the MH_NOUNDEFS flag (which in turn 388 * properly set the execute bits of the file). 389 */ 390static enum bool commons_exist = FALSE; 391static enum bool noundefs = TRUE; 392 393/* 394 * merged_symbols_relocated is set when the merged symbols are relocated to 395 * have addresses and section numbers as they would in the output file. 396 */ 397__private_extern__ enum bool merged_symbols_relocated = FALSE; 398 399static struct merged_symbol *enter_symbol( 400 struct merged_symbol *hash_pointer, 401 struct nlist *object_symbol, 402 char *object_strings, 403 struct object_file *definition_object); 404static void enter_indr_symbol( 405 struct merged_symbol *merged_symbol, 406 struct nlist *object_symbol, 407 char *object_strings, 408 struct object_file *definition_object); 409static char *enter_string( 410 char *symbol_name, 411 unsigned long *len_ret); 412static void add_to_undefined_list( 413 struct merged_symbol *merged_symbol); 414static void multiply_defined( 415 struct merged_symbol *merged_symbol, 416 struct nlist *object_symbol, 417 char *object_strings); 418static void trace_object_symbol( 419 struct nlist *symbol, 420 char *strings); 421static void trace_symbol( 422 char *symbol_name, 423 struct nlist *nlist, 424 struct object_file *object_file, 425 char *indr_symbol_name); 426#ifndef RLD 427static void define_link_editor_symbol( 428 char *symbol_name, 429 unsigned char type, 430 unsigned char sect, 431 short desc, 432 unsigned long value); 433static void remove_dead_N_GSYM_stabs_for_cur_obj( 434 struct nlist *object_symbols, 435 char *object_strings); 436#endif /* !defined(RLD) */ 437static unsigned long merged_symbol_string_index( 438 char *symbol_name); 439static struct string_block *get_string_block( 440 char *symbol_name); 441static void get_stroff_and_mtime_for_N_OSO( 442 unsigned long *stroff_for_N_OSO, 443 unsigned long *mtime); 444 445/* 446 * Check all the fields of the given symbol in the current object to make sure 447 * it is valid. This is required to that the rest of the code can assume that 448 * use the values in the symbol without futher checks and without causing an 449 * error. 450 */ 451static 452inline 453void 454check_symbol( 455struct nlist *symbol, 456char *strings, 457unsigned long index) 458{ 459 unsigned long section_type, library_ordinal; 460 461 /* check the n_strx field of this symbol */ 462 if(symbol->n_un.n_strx < 0 || 463 (uint32_t)symbol->n_un.n_strx >= cur_obj->symtab->strsize){ 464 error_with_cur_obj("bad string table index (%d) for symbol %lu", 465 symbol->n_un.n_strx, index); 466 return; 467 } 468 469 /* check the n_type field of this symbol */ 470 switch(symbol->n_type & N_TYPE){ 471 case N_UNDF: 472 if((symbol->n_type & N_STAB) == 0 && 473 (symbol->n_type & N_EXT) == 0){ 474 error_with_cur_obj("undefined symbol %lu (%s) is not also " 475 "external symbol (N_EXT)", index, 476 symbol->n_un.n_strx == 0 ? "NULL name" : 477 strings + symbol->n_un.n_strx); 478 return; 479 } 480 if(symbol->n_type & N_PEXT && symbol->n_value == 0){ 481 error_with_cur_obj("undefined symbol %lu (%s) can't be " 482 "private external symbol (N_PEXT)", index, 483 symbol->n_un.n_strx == 0 ? "NULL name" : 484 strings + symbol->n_un.n_strx); 485 return; 486 } 487 if((symbol->n_type & N_STAB) == 0 && 488 (((struct mach_header *)(cur_obj->obj_addr))->flags & 489 MH_TWOLEVEL) == MH_TWOLEVEL){ 490 library_ordinal = GET_LIBRARY_ORDINAL(symbol->n_desc); 491 if((library_ordinal == EXECUTABLE_ORDINAL && 492 ((struct mach_header *)(cur_obj->obj_addr))->filetype != 493 MH_BUNDLE) || 494 (library_ordinal != SELF_LIBRARY_ORDINAL && 495 (library_ordinal != DYNAMIC_LOOKUP_ORDINAL || 496 cur_obj->nload_dylibs != DYNAMIC_LOOKUP_ORDINAL) && 497 library_ordinal-1 >= cur_obj->nload_dylibs) ){ 498 error_with_cur_obj("undefined symbol %lu (%s) has bad " 499 "library oridinal %lu", index, 500 symbol->n_un.n_strx == 0 ? "NULL name" : 501 strings + symbol->n_un.n_strx, 502 library_ordinal); 503 return; 504 } 505 } 506 /* fall through to the check below */ 507 case N_ABS: 508 if((symbol->n_type & N_STAB) == 0 && 509 symbol->n_sect != NO_SECT){ 510 error_with_cur_obj("symbol %lu (%s) must have NO_SECT for " 511 "its n_sect field given its type", index, 512 symbol->n_un.n_strx == 0 ? "NULL name" : 513 strings + symbol->n_un.n_strx); 514 return; 515 } 516 break; 517 case N_PBUD: 518 if((symbol->n_type & N_STAB) == 0 && 519 (symbol->n_type & N_EXT) == 0){ 520 error_with_cur_obj("undefined symbol %lu (%s) is not also " 521 "external symbol (N_EXT)", index, 522 symbol->n_un.n_strx == 0 ? "NULL name" : 523 strings + symbol->n_un.n_strx); 524 return; 525 } 526 if((symbol->n_type & N_STAB) == 0 && 527 symbol->n_sect != NO_SECT){ 528 error_with_cur_obj("symbol %lu (%s) must have NO_SECT for " 529 "its n_sect field given its type", index, 530 symbol->n_un.n_strx == 0 ? "NULL name" : 531 strings + symbol->n_un.n_strx); 532 return; 533 } 534 break; 535 case N_SECT: 536 if((symbol->n_type & N_STAB) == 0 && 537 symbol->n_sect == NO_SECT){ 538 error_with_cur_obj("symbol %lu (%s) must not have NO_SECT " 539 "for its n_sect field given its type (N_SECT)", 540 index, symbol->n_un.n_strx == 0 ? "NULL name" : 541 strings + symbol->n_un.n_strx); 542 return; 543 } 544 break; 545 case N_INDR: 546 if(symbol->n_type & N_EXT){ 547 /* note n_value is unsigned and can't be < 0 */ 548 if(symbol->n_value >= cur_obj->symtab->strsize){ 549 error_with_cur_obj("bad string table index (%u) for " 550 "indirect name for symbol %lu (%s)", 551 symbol->n_value, index, symbol->n_un.n_strx == 0 ? 552 "NULL name" : strings + symbol->n_un.n_strx); 553 return; 554 } 555 } 556 else if((symbol->n_type & N_STAB) == 0){ 557 error_with_cur_obj("indirect symbol %lu (%s) is not also " 558 "external symbol (N_EXT)", index, 559 symbol->n_un.n_strx == 0 ? "NULL name" : 560 strings + symbol->n_un.n_strx); 561 return; 562 } 563 if(symbol->n_type & N_PEXT){ 564 error_with_cur_obj("indirect symbol %lu (%s) can't be " 565 "private external symbol (N_PEXT)", index, 566 symbol->n_un.n_strx == 0 ? "NULL name" : 567 strings + symbol->n_un.n_strx); 568 return; 569 } 570 break; 571 default: 572 if((symbol->n_type & N_STAB) == 0){ 573 error_with_cur_obj("symbol %lu (%s) has unknown n_type field " 574 "(0x%x)", index, symbol->n_un.n_strx == 0 ? 575 "NULL name" : strings + symbol->n_un.n_strx, 576 (unsigned int)(symbol->n_type)); 577 return; 578 } 579 break; 580 } 581 582 /* 583 * Check the n_sect field, note sections are numbered from 1 up to and 584 * including the total number of sections (that is the test is > not 585 * >= ). 586 */ 587 if((unsigned long)(symbol->n_sect) > cur_obj->nsection_maps){ 588 error_with_cur_obj("symbol %lu (%s)'s n_sect field (%d) is " 589 "greater than the number of sections in this object (%lu)", 590 index, symbol->n_un.n_strx == 0 ? "NULL name" : strings + 591 symbol->n_un.n_strx, symbol->n_sect, cur_obj->nsection_maps); 592 return; 593 } 594 595 /* 596 * Check to make sure this is not an enternal symbol defined in an 597 * indirect section. 598 */ 599 if((symbol->n_type & N_EXT) != 0 && 600 (symbol->n_type & N_TYPE) == N_SECT){ 601 section_type = (cur_obj->section_maps[symbol->n_sect - 1].s->flags) 602 & SECTION_TYPE; 603 if(section_type == S_NON_LAZY_SYMBOL_POINTERS || 604 section_type == S_LAZY_SYMBOL_POINTERS || 605 section_type == S_SYMBOL_STUBS){ 606 error_with_cur_obj("external symbol %lu (%s) not allowed in an " 607 "indirect section", index, symbol->n_un.n_strx == 0 ? 608 "NULL name" : strings + symbol->n_un.n_strx); 609 return; 610 } 611 } 612 613 /* 614 * Check to see that any symbol that is marked as a weak_definition 615 * is a global symbol defined in a coalesced section. 616 */ 617 if((symbol->n_type & N_STAB) == 0 && 618 (symbol->n_desc & N_WEAK_DEF) == N_WEAK_DEF){ 619 if((symbol->n_type & N_EXT) == 0 && 620 (symbol->n_type & N_PEXT) != N_PEXT){ 621 error_with_cur_obj("non-external symbol %lu (%s) can't be a" 622 " weak definition", index, symbol->n_un.n_strx == 0 ? 623 "NULL name" : strings + symbol->n_un.n_strx); 624 return; 625 } 626 if((symbol->n_type & N_TYPE) == N_UNDF || 627 (symbol->n_type & N_TYPE) == N_PBUD){ 628 error_with_cur_obj("undefined symbol %lu (%s) can't be a " 629 "weak definition", index, symbol->n_un.n_strx == 0 ? 630 "NULL name" : strings + symbol->n_un.n_strx); 631 return; 632 } 633 if((symbol->n_type & N_TYPE) != N_SECT){ 634 error_with_cur_obj("symbol %lu (%s) can't be a weak " 635 "definition (currently only supported in section of " 636 "type S_COALESCED)", index, symbol->n_un.n_strx == 0 ? 637 "NULL name" : strings + symbol->n_un.n_strx); 638 return; 639 } 640 else{ 641 section_type = (cur_obj->section_maps[symbol->n_sect - 1]. 642 s->flags) & SECTION_TYPE; 643 if(section_type != S_COALESCED){ 644 error_with_cur_obj("symbol %lu (%s) can't be a weak " 645 "definition (currently only supported in section " 646 "of type S_COALESCED)", index, symbol->n_un.n_strx 647 == 0 ? "NULL name" : strings + symbol->n_un.n_strx); 648 return; 649 } 650 } 651 } 652 653 /* 654 * Check to make sure this symbols is not in a debug section. 655 */ 656 if((symbol->n_type & N_TYPE) == N_SECT && 657 ((cur_obj->section_maps[symbol->n_sect - 1].s->flags) 658 & S_ATTR_DEBUG) == S_ATTR_DEBUG){ 659 error_with_cur_obj("malformed object, symbols not allowed in debug " 660 "sections (symbol %lu (%s) is in debug section (%.16s,%.16s)", 661 index, symbol->n_un.n_strx == 0 ? "NULL name" : 662 strings + symbol->n_un.n_strx, 663 cur_obj->section_maps[symbol->n_sect - 1].s->segname, 664 cur_obj->section_maps[symbol->n_sect - 1].s->sectname); 665 return; 666 } 667} 668 669/* 670 * relocate_symbol() relocates the specified symbol pointed to by nlist in the 671 * object file pointed to by object file. It modifies the section number of 672 * the symbol and the value of the symbol to what it should be in the output 673 * file. 674 */ 675static 676inline 677void 678relocate_symbol( 679struct nlist *nlist, 680struct object_file *object_file) 681{ 682 struct section_map *section_map; 683 684 /* 685 * If this symbol is not in a section then it is not changed. 686 */ 687 if(nlist->n_sect == NO_SECT) 688 return; 689#ifdef RLD 690 /* 691 * If this symbol is not in the current set of objects being linked 692 * and loaded it does not get relocated. 693 */ 694 if(object_file->set_num != cur_set) 695 return; 696#endif /* RLD */ 697 698 /* 699 * Change the section number of this symbol to the section number it 700 * will have in the output file. For RLD all section numbers are left 701 * as they are in the input file they came from so that a future call 702 * to trace_symbol() will work. If they are are written to an output 703 * file then they are updated in the output memory buffer by the 704 * routines that output the symbols so to leave the merged symbol table 705 * data structure the way it is. 706 */ 707 section_map = &(object_file->section_maps[nlist->n_sect - 1]); 708#ifndef RLD 709 nlist->n_sect = section_map->output_section->output_sectnum; 710#endif /* RLD */ 711 712 /* 713 * If this symbol comes from base file of an incremental load 714 * then it's value is not adjusted. 715 */ 716 if(object_file == base_obj) 717 return; 718 /* 719 * Adjust the value of this symbol by it's section. The base 720 * of the section in the object file it came from is subtracted 721 * the base of the section in the output file is added and the 722 * offset this section appears in the output section is added. 723 * 724 * value += - old_section_base_address 725 * + new_section_base_address 726 * + offset_in_the_output_section; 727 * 728 * If the symbol is in a section that has fine relocation then 729 * it's value is set to where the value is in the output file 730 * by using the offset in the input file's section and getting 731 * the offset in the output file's section (via the fine 732 * relocation structures) and adding the address of that section 733 * in the output file. 734 */ 735 if(section_map->nfine_relocs == 0) 736 nlist->n_value += - section_map->s->addr 737 + section_map->output_section->s.addr 738 + section_map->offset; 739 else 740 nlist->n_value = fine_reloc_output_offset(section_map, 741 nlist->n_value - 742 section_map->s->addr) 743 + section_map->output_section->s.addr; 744} 745 746#ifndef RLD 747/* 748 * When removing stabs from duplicate include files this hash table and 749 * structure keeps the list of ones we have already seen. 750 */ 751struct include_file { 752 char *include_file_name; 753 unsigned long sum; 754#ifdef DEBUG 755 char *object_file_name; 756 unsigned long index; 757#endif 758 struct include_file *next; 759}; 760#define INCLUDE_HASH_SIZE 1000 761static struct include_file *include_file_hash_table[INCLUDE_HASH_SIZE] = { 0 }; 762 763/* 764 * lookup_and_enter_include() looks up the include file name to see if we have 765 * seen it with this sum before. If it has not been seen before we return 766 * TRUE indicating this is new and record the name and sum in the hash table. 767 * If it is not new we return FALSE indicating we have seen this before. 768 */ 769static 770enum bool 771lookup_and_enter_include( 772char *include_file_name, 773unsigned long sum, 774unsigned long index, 775enum bool next_eincl) 776{ 777 unsigned long hash_index; 778 struct include_file *include_file, *p, *q; 779 780 hash_index = hash_string(include_file_name, NULL) % INCLUDE_HASH_SIZE; 781 if(include_file_hash_table[hash_index] == NULL){ 782 include_file = allocate(sizeof(struct include_file)); 783 memset(include_file, '\0', sizeof(struct include_file)); 784 include_file_hash_table[hash_index] = include_file; 785 include_file->include_file_name = include_file_name; 786 include_file->sum = sum; 787#ifdef DEBUG 788 include_file->object_file_name = cur_obj->file_name; 789 include_file->index = index; 790#endif 791 include_file_hash_table[hash_index] = include_file; 792 return(TRUE); 793 } 794 /* 795 * Look through the hash buckets and see if this is the same include 796 * file name with the same sum is found. If so return FALSE indicating 797 * this is not new. 798 */ 799 p = include_file_hash_table[hash_index]; 800 for(;;){ 801 if(p->sum == sum && 802 strcmp(p->include_file_name, include_file_name) == 0) 803#ifdef OPTIMISTIC 804 /* 805 * Be very very optimistic and assume if the names match and 806 * as long as neither sum is zero or they are zero and they 807 * match the header really should be the same. 808 */ 809 if(strcmp(p->include_file_name, include_file_name) == 0 && 810 (p->sum == sum || (p->sum != 0 && sum != 0))) 811#endif /* OPTIMISTIC */ 812 { 813#ifdef DEBUG 814 if(debug & (1 << 24)) 815 printf("include file = %s in object file = %s has same " 816 "sum as previous object file = %s\n", 817 include_file_name, cur_obj->file_name, 818 p->object_file_name); 819#endif /* DEBUG */ 820 return(FALSE); 821 } 822 if(p->next == NULL){ 823#ifdef DEBUG 824 q = include_file_hash_table[hash_index]; 825 for(;;){ 826 if(debug & (1 << 23) && 827 strcmp(q->include_file_name, include_file_name) == 0 && 828 q->sum != sum && sum != 0 && q->sum != 0 && 829 next_eincl == FALSE){ 830 if(debug & (1 << 23)) 831 printf("include file = %s in object file = %s at " 832 "index %lu with different sum than previous " 833 "object file = %s at index %lu\n", 834 include_file_name, cur_obj->file_name, index, 835 q->object_file_name, q->index); 836 break; 837 } 838 if(q->next == NULL) 839 break; 840 else 841 q = q->next; 842 } 843#endif /* DEBUG */ 844 break; 845 } 846 else 847 p = p->next; 848 } 849 850 /* 851 * We did not find this include file with the same sum. So create a new 852 * entry for this one and hang it off the hash chain. 853 */ 854 include_file = allocate(sizeof(struct include_file)); 855 memset(include_file, '\0', sizeof(struct include_file)); 856 p = include_file_hash_table[hash_index]; 857 include_file_hash_table[hash_index] = include_file; 858 include_file->include_file_name = include_file_name; 859 include_file->sum = sum; 860#ifdef DEBUG 861 include_file->object_file_name = cur_obj->file_name; 862 include_file->index = index; 863#endif 864 include_file->next = p; 865 return(TRUE); 866} 867#endif /* !defined(RLD) */ 868 869/* 870 * count_dwarf_symbols() returns the number of DWARF symbols that would 871 * be generated by SYM, which must be in the current object. It is the 872 * pass1 counterpart of add_dwarf_map_for_sym. 873 */ 874static size_t 875count_dwarf_symbols(const struct nlist *sym, 876 size_t i, const size_t * debug_ptr) 877{ 878 size_t cnt; 879 880 /* The debug map only represents symbols which are defined in 881 a particular section or which are global common symbols. */ 882 if ((sym->n_type & (N_TYPE | N_STAB)) != N_SECT 883 && ((sym->n_type & (N_TYPE | N_STAB)) != N_UNDF 884 || sym->n_value == 0)) 885 return 0; 886 /* If S_ATTR_STRIP_STATIC_SYMS is set on this symbol's section, 887 we don't need a debug symbol for this symbol. */ 888 if ((sym->n_type & (N_TYPE | N_STAB)) == N_SECT 889 && (cur_obj->section_maps[sym->n_sect - 1].s->flags & 890 S_ATTR_STRIP_STATIC_SYMS)) 891 return 0; 892 if (! debug_ptr || *debug_ptr != i) 893 return 1; 894 for (cnt = 0; debug_ptr[cnt + 2] & 0x80000000; cnt++) 895 ; 896 return cnt + 4; 897} 898 899/* 900 * 'merged_symbol' is about to have its defining object changed. If the 901 * symbol was from a .o file with DWARF, remove the corresponding 902 * DWARF symbols. 903 */ 904static void 905maybe_remove_dwarf_symbol (struct merged_symbol *merged_symbol) 906{ 907 struct object_file * mo = merged_symbol->definition_object; 908 struct object_file * cur_o = cur_obj; 909 size_t * debug_ptr = mo->dwarf_source_data; 910 size_t n; 911 struct nlist * obj_symbols; 912 char * obj_strings; 913 size_t i; 914 915 if (! merged_symbol->definition_object->dwarf_name) 916 return; 917 918 obj_symbols = (struct nlist *) (mo->obj_addr + mo->symtab->symoff); 919 obj_strings = mo->obj_addr + mo->symtab->stroff; 920 i = 0; 921 while (strcmp (obj_strings + obj_symbols[i].n_un.n_strx, 922 merged_symbol->nlist.n_un.n_name) != 0) 923 i++; 924 if (debug_ptr) 925 while (*debug_ptr < i) 926 for (debug_ptr += 2; *debug_ptr & 0x80000000; debug_ptr++) 927 ; 928 cur_obj = mo; 929 n = count_dwarf_symbols (obj_symbols + i, i, debug_ptr); 930 cur_obj = cur_o; 931 merged_symbol->definition_object->nlocalsym -= n; 932 nlocal_symbols -= n; 933} 934 935/* 936 * merge_symbols() merges the symbols from the current object (cur_obj) into 937 * the merged symbol table. 938 */ 939__private_extern__ 940void 941merge_symbols(void) 942{ 943 unsigned long i, j, object_undefineds, nrefsym, output_strlen; 944 struct nlist *object_symbols; 945 char *object_strings; 946 struct merged_symbol *hash_pointer, *merged_symbol; 947 enum bool discarded_coalesced_symbol; 948 enum bool discarded_multiply_defined_symbol; 949 unsigned short n_desc; 950 size_t * debug_ptr; 951 952#ifndef RLD 953 unsigned long nest, sum, k; 954 enum bool no_exclusion; 955 char *stab_string, *include_file_name; 956 struct localsym_block *localsym_block, *temp_localsym_block, 957 **next_localsym_block, *cur_localsym_block; 958#endif 959 960#if defined(DEBUG) || defined(RLD) 961 /* The compiler "warning: `merged_symbol' may be used uninitialized */ 962 /* in this function" can safely be ignored */ 963 merged_symbol = NULL; 964#endif 965 966 /* If this object file has no symbols then just return */ 967 if(cur_obj->symtab == NULL) 968 return; 969 970 /* setup pointers to the symbol table and string table */ 971 object_symbols = (struct nlist *)(cur_obj->obj_addr + 972 cur_obj->symtab->symoff); 973 object_strings = (char *)(cur_obj->obj_addr + cur_obj->symtab->stroff); 974 if(cur_obj->swapped && 975 (((struct mach_header *)cur_obj->obj_addr)->filetype != MH_DYLIB || 976 ((struct mach_header *)cur_obj->obj_addr)->filetype != 977 MH_DYLIB_STUB)) 978 swap_nlist(object_symbols, cur_obj->symtab->nsyms, host_byte_sex); 979 980 981 /* 982 * For all the strings of the symbols to be valid the string table must 983 * end with a '\0'. 984 */ 985 if(cur_obj->symtab->strsize > 0 && 986 object_strings[cur_obj->symtab->strsize - 1] != '\0'){ 987 error_with_cur_obj("string table does not end with a '\\0'"); 988 return; 989 } 990 991 /* 992 * If this object is not the base file count the number of undefined 993 * externals and commons in this object so that an undefined external 994 * map for this object can be allocated and then it will be filled in 995 * as these undefined external symbols are looked up in the merged 996 * symbol table. This map will be used when doing relocation for 997 * external relocation entries in pass2 (and is not needed for the base 998 * file because that is not relocated or copied in to the output). 999 */ 1000 object_undefineds = 0; 1001 for(i = 0; i < cur_obj->symtab->nsyms; i++){ 1002 check_symbol(&(object_symbols[i]), object_strings, i); 1003 if(errors) 1004 return; 1005 if((object_symbols[i].n_type & N_EXT) == N_EXT && 1006 (object_symbols[i].n_type & N_TYPE) == N_UNDF) 1007 object_undefineds++; 1008 /* 1009 * Note: coalesced symbols are always defined symbols in each object 1010 * file but referenced with external relocation entries. Since they 1011 * are always defined they are not in the count of undefined 1012 * symbols or in the undefined map. 1013 */ 1014#ifndef RLD 1015 /* 1016 * If we have an -export_symbols_list or -unexport_symbol_list 1017 * option set the private extern bit on symbols that are not to 1018 * be exported for global symbols that are not undefined. 1019 */ 1020 if((object_symbols[i].n_type & N_EXT) == N_EXT && 1021 object_symbols[i].n_type != (N_EXT | N_UNDF)) 1022 exports_list_processing(object_strings + 1023 object_symbols[i].n_un.n_strx, 1024 object_symbols + i); 1025#endif /* !defined(RLD) */ 1026 /* 1027 * If this is a private external defined symbol (but not a common) 1028 * increment the count of private exterals for this object and the 1029 * total in the output file. 1030 */ 1031 if((object_symbols[i].n_type & N_EXT) && 1032 (object_symbols[i].n_type & N_PEXT) && 1033 (object_symbols[i].n_type & N_TYPE) != N_UNDF){ 1034 cur_obj->nprivatesym++; 1035 nmerged_private_symbols++; 1036 } 1037 } 1038 if(cur_obj != base_obj){ 1039 cur_obj->nundefineds = object_undefineds; 1040 if(cur_obj->nundefineds != 0) 1041 cur_obj->undefined_maps = allocate(object_undefineds * 1042 sizeof(struct undefined_map)); 1043 } 1044 1045#ifndef RLD 1046 /* 1047 * If the output file type is a multi module dynamic shared library then 1048 * count the number of defined externals. And using this count, the 1049 * count of undefined symbols and the count of private externs then 1050 * reference map, to build the reference table, is allocated. 1051 */ 1052 if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ 1053 /* 1054 * Note: coalesced symbols are always defined symbols in each object 1055 * file but referenced with external relocation entries. If the one 1056 * in this object is discarded then cur_obj->nextdefsym is 1057 * decremented and the reference_maps[].flags field is changed to 1058 * some REFERENCE_FLAG_*_UNDEFINED_* value. But note that even 1059 * though cur_obj->nextdefsym is decremented cur_obj->nundefineds is 1060 * NOT incremented. 1061 */ 1062 for(i = 0; i < cur_obj->symtab->nsyms; i++){ 1063 if((object_symbols[i].n_type & N_EXT) == N_EXT && 1064 (object_symbols[i].n_type & N_PEXT) != N_PEXT && 1065 (object_symbols[i].n_type & N_TYPE) != N_UNDF) 1066 cur_obj->nextdefsym++; 1067 } 1068 cur_obj->nrefsym = cur_obj->nundefineds + cur_obj->nextdefsym + 1069 cur_obj->nprivatesym; 1070 cur_obj->irefsym = 1071 output_dysymtab_info.dysymtab_command.nextrefsyms; 1072 output_dysymtab_info.dysymtab_command.nextrefsyms += 1073 cur_obj->nrefsym; 1074 if(cur_obj->nrefsym != 0) 1075 cur_obj->reference_maps = allocate(cur_obj->nrefsym * 1076 sizeof(struct reference_map)); 1077 } 1078#endif /* !defined(RLD) */ 1079 1080 /* 1081 * If local section object symbols were specified and if local symbols 1082 * are to appear in the output file see if this object file has this 1083 * section and if so account for this symbol. 1084 */ 1085 if(sect_object_symbols.specified && 1086 strip_level != STRIP_ALL && 1087 strip_level != STRIP_NONGLOBALS && 1088 (cur_obj != base_obj || strip_base_symbols == FALSE)){ 1089 if(sect_object_symbols.ms == NULL) 1090 sect_object_symbols.ms = lookup_merged_section( 1091 sect_object_symbols.segname, 1092 sect_object_symbols.sectname); 1093 if(sect_object_symbols.ms != NULL){ 1094 if((sect_object_symbols.ms->s.flags & SECTION_TYPE) == 1095 S_CSTRING_LITERALS || 1096 (sect_object_symbols.ms->s.flags & SECTION_TYPE) == 1097 S_4BYTE_LITERALS || 1098 (sect_object_symbols.ms->s.flags & SECTION_TYPE) == 1099 S_8BYTE_LITERALS || 1100 (sect_object_symbols.ms->s.flags & SECTION_TYPE) == 1101 S_LITERAL_POINTERS){ 1102 warning("section (%s,%s) is a literal section " 1103 "and can't be used with -sectobjectsymbols", 1104 sect_object_symbols.segname, 1105 sect_object_symbols.sectname); 1106 sect_object_symbols.specified = FALSE; 1107 sect_object_symbols.ms = NULL; 1108 } 1109 else if((sect_object_symbols.ms->s.flags & S_ATTR_DEBUG) == 1110 S_ATTR_DEBUG){ 1111 warning("section (%s,%s) is a debug section " 1112 "and can't be used with -sectobjectsymbols", 1113 sect_object_symbols.segname, 1114 sect_object_symbols.sectname); 1115 sect_object_symbols.specified = FALSE; 1116 sect_object_symbols.ms = NULL; 1117 } 1118 else{ 1119 /* 1120 * See if this object file has the section that the section 1121 * object symbols are being created for. 1122 */ 1123 for(i = 0; i < cur_obj->nsection_maps; i++){ 1124 if(sect_object_symbols.ms == 1125 cur_obj->section_maps[i].output_section){ 1126 cur_obj->nlocalsym++; 1127 nlocal_symbols++; 1128 if(cur_obj->ar_hdr == NULL) 1129 local_string_size += 1130 strlen(cur_obj->file_name) + 1; 1131 else 1132 local_string_size += cur_obj->ar_name_size + 1; 1133 break; 1134 } 1135 } 1136 } 1137 } 1138 } 1139 1140 /* Allocate space for per-object-file DWARF debug map symbols. */ 1141 if(cur_obj->dwarf_name){ 1142 /* There are 3 symbols for every .o, two SOs and one OSO. */ 1143 nlocal_symbols += 3; 1144 cur_obj->nlocalsym += 3; 1145 local_string_size += 1 + strlen (cur_obj->dwarf_name); 1146 /* If there's a compilation directory, there's an extra SO. */ 1147 if (cur_obj->dwarf_comp_dir) { 1148 /* The compilation directory has a '/' appended. */ 1149 local_string_size += 2 + strlen (cur_obj->dwarf_comp_dir); 1150 nlocal_symbols++; 1151 cur_obj->nlocalsym++; 1152 } 1153 if(cur_obj->resolved_path == NULL) 1154 set_obj_resolved_path(cur_obj); 1155 local_string_size += 1 + cur_obj->resolved_path_len; 1156 /* Allocate space for the strings for SOL DWARF debug map symbols. */ 1157 for (i = 0; i < cur_obj->dwarf_num_paths; i++) 1158 if (cur_obj->dwarf_paths[i]) 1159 local_string_size += 1 + strlen (cur_obj->dwarf_paths[i]); 1160 } 1161 1162 /* 1163 * Now merge the external symbols are looked up and merged based 1164 * what was found if anything. Locals are counted if they will 1165 * appear in the output file based on the strip level. 1166 */ 1167 nrefsym = 0; 1168 object_undefineds = 0; 1169 debug_ptr = cur_obj->dwarf_source_data; 1170 for(i = 0; i < cur_obj->symtab->nsyms; i++){ 1171 discarded_coalesced_symbol = FALSE; 1172 discarded_multiply_defined_symbol = FALSE; 1173 if (debug_ptr && *debug_ptr < i) { 1174 for (debug_ptr += 2; *debug_ptr & 0x80000000; debug_ptr++) ; 1175 } 1176 1177 if(object_symbols[i].n_type & N_EXT){ 1178 /* 1179 * Do the trace of this symbol if specified. 1180 */ 1181 if(ntrace_syms != 0){ 1182 for(j = 0; j < ntrace_syms; j++){ 1183 if(strcmp(trace_syms[j], object_strings + 1184 object_symbols[i].n_un.n_strx) == 0){ 1185 trace_object_symbol(&(object_symbols[i]), 1186 object_strings); 1187 break; 1188 } 1189 } 1190 } 1191 /* lookup the symbol and see if it has already been seen */ 1192 hash_pointer = lookup_symbol(object_strings + 1193 object_symbols[i].n_un.n_strx); 1194 if(hash_pointer->name_len == 0){ 1195 /* 1196 * If this is the basefile and the symbol is not a 1197 * definition of a symbol (or an indirect) then don't enter 1198 * this symbol into the symbol table. 1199 */ 1200 if(cur_obj != base_obj || 1201 (object_symbols[i].n_type != (N_EXT | N_UNDF) && 1202 object_symbols[i].n_type != (N_EXT | N_INDR) ) ){ 1203 /* the symbol has not been seen yet so just enter it */ 1204 merged_symbol = enter_symbol(hash_pointer, 1205 &(object_symbols[i]), 1206 object_strings, cur_obj); 1207 merged_symbol->referenced_in_non_dylib = TRUE; 1208 if(merged_symbol->non_dylib_referenced_obj == NULL) 1209 merged_symbol->non_dylib_referenced_obj = cur_obj; 1210 } 1211 } 1212 /* the symbol has been seen so merge it */ 1213 else{ 1214 merged_symbol = hash_pointer; 1215 /* 1216 * If this symbol has only been referenced by a dylib up to 1217 * this point re-enter the symbol name so it is in a string 1218 * block that will be in the output file and set 1219 * referenced_in_non_dylib to TRUE now. 1220 */ 1221 if(merged_symbol->referenced_in_non_dylib == FALSE){ 1222 merged_symbol->nlist.n_un.n_name = 1223 enter_string(object_strings + 1224 object_symbols[i].n_un.n_strx, NULL); 1225 merged_symbol->referenced_in_non_dylib = TRUE; 1226 if(merged_symbol->non_dylib_referenced_obj == NULL) 1227 merged_symbol->non_dylib_referenced_obj = cur_obj; 1228 } 1229 /* 1230 * If the object's symbol was undefined ignore it and just 1231 * use the merged symbol. 1232 */ 1233 if(object_symbols[i].n_type == (N_EXT | N_UNDF) && 1234 object_symbols[i].n_value == 0){ 1235 /* 1236 * If the merged symbol was a lazy reference and the 1237 * object's symbol is not then remove the lazy reference 1238 * mark from the symbol. 1239 */ 1240 if(((merged_symbol->nlist.n_type == (N_EXT | N_UNDF) && 1241 merged_symbol->nlist.n_value == 0) || 1242 merged_symbol->nlist.n_type == (N_EXT | N_PBUD)) && 1243 (merged_symbol->nlist.n_desc & REFERENCE_TYPE) == 1244 REFERENCE_FLAG_UNDEFINED_LAZY && 1245 (object_symbols[i].n_desc & REFERENCE_TYPE) != 1246 REFERENCE_FLAG_UNDEFINED_LAZY) 1247 merged_symbol->nlist.n_desc = 1248 (merged_symbol->nlist.n_desc & ~REFERENCE_TYPE) | 1249 REFERENCE_FLAG_UNDEFINED_NON_LAZY; 1250 1251 /* 1252 * If the undefined symbol is marked as 1253 * REFERENCED_DYNAMICALLY keep this mark. 1254 */ 1255 merged_symbol->nlist.n_desc |= 1256 (object_symbols[i].n_desc & REFERENCED_DYNAMICALLY); 1257 1258 /* 1259 * This is part of the cctools_aek-thumb-hack branch. 1260 * It seems to think undefined symbols would be marked 1261 * as symbols that are definitions of Thumb symbols. 1262 * But since undefined symbols are not definitions I 1263 * don't see how this code would ever be used. 1264 merged_symbol->nlist.n_desc |= 1265 (object_symbols[i].n_desc & N_ARM_THUMB_DEF); 1266 */ 1267 1268 /* 1269 * If the merged symbol is also an undefined deal with 1270 * weak reference mismatches if any. 1271 */ 1272 if((merged_symbol->nlist.n_type == (N_EXT | N_UNDF) && 1273 merged_symbol->nlist.n_value == 0) || 1274 merged_symbol->nlist.n_type == (N_EXT | N_PBUD)){ 1275 /* 1276 * The merged symbol may be from an dylib and we 1277 * haven't yet seen any undefined symbols before 1278 * this object. If so just set the N_WEAK_REF bit 1279 * in the merged symbol to be that in this object 1280 * file. 1281 */ 1282 if(merged_symbol->seen_undef == FALSE){ 1283 merged_symbol->nlist.n_desc = 1284 (merged_symbol->nlist.n_desc & ~N_WEAK_REF) | 1285 (object_symbols[i].n_desc & N_WEAK_REF); 1286 } 1287 else 1288 /* 1289 * We have seen an undefined symbol before so 1290 * if the N_WEAK_REF bits don't match resolve it 1291 * based on the -weak_reference_mismatches 1292 * setting. 1293 */ 1294 if(((merged_symbol->nlist.n_desc & N_WEAK_REF) == 1295 N_WEAK_REF && 1296 (object_symbols[i].n_desc & N_WEAK_REF) != 1297 N_WEAK_REF) || 1298 ((merged_symbol->nlist.n_desc & N_WEAK_REF) != 1299 N_WEAK_REF && 1300 (object_symbols[i].n_desc & N_WEAK_REF) == 1301 N_WEAK_REF)){ 1302 if(weak_reference_mismatches == 1303 WEAK_REFS_MISMATCH_ERROR) 1304 merged_symbol->weak_reference_mismatch = 1305 TRUE; 1306 else if(weak_reference_mismatches == 1307 WEAK_REFS_MISMATCH_WEAK) 1308 merged_symbol->nlist.n_desc |= N_WEAK_REF; 1309 else if(weak_reference_mismatches == 1310 WEAK_REFS_MISMATCH_NON_WEAK) 1311 merged_symbol->nlist.n_desc &= 1312 ~(N_WEAK_REF); 1313 } 1314 merged_symbol->seen_undef = TRUE; 1315 } 1316 } 1317 /* 1318 * See if the object's symbol is a common. 1319 */ 1320 else if((object_symbols[i].n_type & N_EXT) == N_EXT && 1321 (object_symbols[i].n_type & N_TYPE) == N_UNDF && 1322 object_symbols[i].n_value != 0){ 1323 /* 1324 * See if the merged symbol is a common or undefined. 1325 */ 1326 if((merged_symbol->nlist.n_type & N_EXT) == N_EXT && 1327 (merged_symbol->nlist.n_type & N_TYPE) == N_UNDF){ 1328 /* 1329 * If the merged symbol is a common use the larger 1330 * of the two commons. Else the merged symbol is 1331 * a common so use the common symbol. 1332 */ 1333 if(merged_symbol->nlist.n_value != 0){ 1334 if((merged_symbol->nlist.n_type & N_PEXT) != 1335 (object_symbols[i].n_type & N_PEXT)){ 1336 warning("common symbol: %s both as an " 1337 "external symbol and a private " 1338 "external symbol", merged_symbol-> 1339 nlist.n_un.n_name); 1340 trace_merged_symbol(merged_symbol); 1341 trace_object_symbol(&(object_symbols[i]), 1342 object_strings); 1343 } 1344 if(object_symbols[i].n_value > 1345 merged_symbol->nlist.n_value){ 1346 merged_symbol->nlist.n_value = 1347 object_symbols[i].n_value; 1348 merged_symbol->definition_object = cur_obj; 1349 /* 1350 * Since we are "using" this common then 1351 * "use" the private extern bit from this 1352 * object's symbol for the merged symbol. 1353 */ 1354 merged_symbol->nlist.n_type = 1355 (merged_symbol->nlist.n_type & ~N_PEXT) | 1356 (object_symbols[i].n_type & N_PEXT); 1357 } 1358 } 1359 else{ 1360 merged_symbol->nlist.n_value = 1361 object_symbols[i].n_value; 1362 merged_symbol->definition_object = cur_obj; 1363 } 1364 } 1365 /* 1366 * The merged symbol is not a common or undefined and 1367 * the object symbol is a common so just ignore the 1368 * object's common symbol and use the merged defined 1369 * symbol. 1370 */ 1371 } 1372 /* 1373 * If the merged symbol is undefined or common (and at this 1374 * point the object's symbol is known not to be undefined 1375 * or common) then use the object's symbol. 1376 */ 1377 else if((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF){ 1378 /* one could also say: 1379 * && merged_symbol->nlist.n_value == 0 && 1380 * merged_symbol->nlist.n_value != 0 1381 * if the above test but that is always true. 1382 */ 1383 merged_symbol->nlist.n_type = object_symbols[i].n_type; 1384 merged_symbol->nlist.n_sect = object_symbols[i].n_sect; 1385 n_desc = 0; 1386 /* 1387 * If this symbol was previously referenced dynamically 1388 * then keep this information. 1389 */ 1390 n_desc |= (merged_symbol->nlist.n_desc & 1391 REFERENCED_DYNAMICALLY); 1392 /* 1393 * If the object symbol is a symbol defined as Thumb 1394 * symbol then keep this information. 1395 */ 1396 n_desc |= (object_symbols[i].n_desc & N_ARM_THUMB_DEF); 1397 1398 /* 1399 * If the object symbol is a weak definition it may be 1400 * later discarded for a non-weak symbol from a dylib so 1401 * if the undefined symbol is a weak reference keep that 1402 * information. 1403 */ 1404 if((object_symbols[i].n_desc & N_WEAK_DEF) == 1405 N_WEAK_DEF) 1406 n_desc |= (merged_symbol->nlist.n_desc & 1407 N_WEAK_REF); 1408 merged_symbol->nlist.n_desc = 1409 object_symbols[i].n_desc | n_desc; 1410 if(merged_symbol->nlist.n_type == (N_EXT | N_INDR)) 1411 enter_indr_symbol(merged_symbol, 1412 &(object_symbols[i]), 1413 object_strings, cur_obj); 1414 else 1415 merged_symbol->nlist.n_value = 1416 object_symbols[i].n_value; 1417 merged_symbol->definition_object = cur_obj; 1418 } 1419 /* 1420 * If the object symbol is a weak definition then 1421 * it is discarded and the merged symbol is kept, 1422 * unless the merged symbol is a weak symbol in a 1423 * dylib. Note currently only symbols in 1424 * coalesced sections can have this set and it is 1425 * checked for in check_symbol() so it is assumed 1426 * it is a coalesced symbol here. 1427 */ 1428 else if((object_symbols[i].n_desc & N_WEAK_DEF) == 1429 N_WEAK_DEF && 1430 (merged_symbol->defined_in_dylib == FALSE || 1431 ! merged_symbol->weak_def_in_dylib)){ 1432 discarded_coalesced_symbol = TRUE; 1433 if((object_symbols[i].n_type & N_EXT) && 1434 (object_symbols[i].n_type & N_PEXT)){ 1435 cur_obj->nprivatesym--; 1436 nmerged_private_symbols--; 1437 } 1438 else{ 1439 cur_obj->nextdefsym--; 1440 } 1441 } 1442 /* 1443 * Otherwise, if the merged symbol is a weak 1444 * definition then it is discarded and the object 1445 * symbol is used. 1446 */ 1447 else if((merged_symbol->nlist.n_desc & N_WEAK_DEF) == 1448 N_WEAK_DEF || 1449 (merged_symbol->defined_in_dylib == TRUE && 1450 merged_symbol->weak_def_in_dylib)){ 1451 if(merged_symbol->defined_in_dylib == FALSE){ 1452 if((merged_symbol->nlist.n_type & N_EXT) && 1453 (merged_symbol->nlist.n_type & N_PEXT)){ 1454 merged_symbol->definition_object->nprivatesym--; 1455 nmerged_private_symbols--; 1456 } 1457 else{ 1458 merged_symbol->definition_object->nextdefsym--; 1459 } 1460 maybe_remove_dwarf_symbol (merged_symbol); 1461 } 1462#ifndef RLD 1463 /* 1464 * If the output file is a multi module MH_DYLIB type 1465 * reset the reference map for the merged external 1466 * symbol that is being discarded. 1467 */ 1468 if(filetype == MH_DYLIB && 1469 multi_module_dylib == TRUE && 1470 merged_symbol->defined_in_dylib == FALSE){ 1471 /* 1472 * Discared coalesced symbols are referenced as 1473 * undefined. TODO: to determine if the reference is 1474 * lazy or non-lazy we would have to look at all the 1475 * relocation entries in this object. For now just 1476 * assume non-lazy to be safe. 1477 */ 1478 for(j = 0; 1479 j < merged_symbol->definition_object->nrefsym; 1480 j++){ 1481 if(merged_symbol->definition_object-> 1482 reference_maps[j].merged_symbol == 1483 merged_symbol){ 1484 if(object_symbols[i].n_type & N_PEXT) 1485 merged_symbol->definition_object-> 1486 reference_maps[j].flags = 1487 REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY; 1488 else 1489 merged_symbol->definition_object-> 1490 reference_maps[j].flags = 1491 REFERENCE_FLAG_UNDEFINED_NON_LAZY; 1492 break; 1493 } 1494 } 1495 } 1496#endif /* RLD */ 1497 merged_symbol->defined_in_dylib = FALSE; 1498 merged_symbol->coalesced_defined_in_dylib = FALSE; 1499 merged_symbol->weak_def_in_dylib = FALSE; 1500 merged_symbol->nlist.n_type = object_symbols[i].n_type; 1501 merged_symbol->nlist.n_sect = object_symbols[i].n_sect; 1502 /* 1503 * If this symbol was previously referenced 1504 * dynamically then keep this information. 1505 */ 1506 if(merged_symbol->nlist.n_desc & 1507 REFERENCED_DYNAMICALLY) 1508 merged_symbol->nlist.n_desc = 1509 object_symbols[i].n_desc | 1510 REFERENCED_DYNAMICALLY 1511 /* 1512 * This was part of the cctools_aek-thumb-hack 1513 * branch. It seems to think if the discarded 1514 * weak merged symbol was marked as Thumb 1515 * definition then that should be preserved. 1516 * But since the object symbol is being used 1517 * instead it may not be a Thumb definition. 1518 | (merged_symbol->nlist.n_desc & 1519 N_ARM_THUMB_DEF) 1520 */ 1521 ; 1522 else 1523 merged_symbol->nlist.n_desc = 1524 object_symbols[i].n_desc 1525 /* 1526 * This was part of the cctools_aek-thumb-hack 1527 * branch. It seems to think if the discarded 1528 * weak merged symbol was marked as Thumb 1529 * definition then that should be preserved. 1530 * But since the object symbol is being used 1531 * instead it may not be a Thumb definition. 1532 | (merged_symbol->nlist.n_desc & 1533 N_ARM_THUMB_DEF) 1534 */ 1535 ; 1536 if(merged_symbol->nlist.n_type == (N_EXT | N_INDR)) 1537 enter_indr_symbol(merged_symbol, 1538 &(object_symbols[i]), 1539 object_strings, cur_obj); 1540 else 1541 merged_symbol->nlist.n_value = 1542 object_symbols[i].n_value; 1543 merged_symbol->definition_object = cur_obj; 1544 } 1545 /* 1546 * If both symbols are coalesced symbols then the this 1547 * symbol is discarded. 1548 */ 1549 else if(( 1550 ((merged_symbol->nlist.n_type & N_TYPE) == N_SECT && 1551 ((merged_symbol->definition_object->section_maps[ 1552 merged_symbol->nlist.n_sect - 1].s->flags) & 1553 SECTION_TYPE) == S_COALESCED) || 1554 (merged_symbol->defined_in_dylib == TRUE && 1555 merged_symbol->coalesced_defined_in_dylib) ) 1556 && 1557 (object_symbols[i].n_type & N_TYPE) == N_SECT && 1558 ((cur_obj->section_maps[object_symbols[i].n_sect - 1]. 1559 s->flags) & SECTION_TYPE) == S_COALESCED){ 1560 1561 discarded_coalesced_symbol = TRUE; 1562 if((object_symbols[i].n_type & N_EXT) && 1563 (object_symbols[i].n_type & N_PEXT)){ 1564 cur_obj->nprivatesym--; 1565 nmerged_private_symbols--; 1566 } 1567 else{ 1568 cur_obj->nextdefsym--; 1569 } 1570#ifdef COALESCE_DEBUG 1571printf("symbol: %s is coalesced\n", merged_symbol->nlist.n_un.n_name); 1572#endif 1573 } 1574#ifdef KLD 1575 /* 1576 * For KLD if both symbols are absolute symbols with the 1577 * value the symbol is discarded. 1578 */ 1579 else if((merged_symbol->nlist.n_type & N_TYPE) == N_ABS && 1580 (object_symbols[i].n_type & N_TYPE) == N_ABS && 1581 merged_symbol->nlist.n_value == 1582 object_symbols[i].n_value){ 1583 if((object_symbols[i].n_type & N_EXT) && 1584 (object_symbols[i].n_type & N_PEXT)){ 1585 cur_obj->nprivatesym--; 1586 nmerged_private_symbols--; 1587 } 1588 else{ 1589 cur_obj->nextdefsym--; 1590 } 1591 } 1592#endif /* KLD */ 1593 else{ 1594 discarded_multiply_defined_symbol = TRUE; 1595 multiply_defined(merged_symbol, &(object_symbols[i]), 1596 object_strings); 1597 if(allow_multiply_defined_symbols == TRUE){ 1598 /* 1599 * If this is a private external then decrement 1600 * the previous incremented the count of private 1601 * exterals for this object and the total in the 1602 * output file since we are going to ignore this 1603 * this multiply defined symbol. 1604 */ 1605 if((object_symbols[i].n_type & N_EXT) && 1606 (object_symbols[i].n_type & N_PEXT)){ 1607 cur_obj->nprivatesym--; 1608 nmerged_private_symbols--; 1609 } 1610 } 1611 } 1612 } 1613 /* 1614 * If this symbol was undefined or a common in this object 1615 * and the object is not the basefile enter a pointer to the 1616 * merged symbol and its index in the object file's undefined 1617 * map. 1618 */ 1619 if((object_symbols[i].n_type & N_EXT) == N_EXT && 1620 (object_symbols[i].n_type & N_TYPE) == N_UNDF && 1621 cur_obj != base_obj){ 1622 cur_obj->undefined_maps[object_undefineds].index = i; 1623 cur_obj->undefined_maps[object_undefineds].merged_symbol = 1624 merged_symbol; 1625 object_undefineds++; 1626 /* 1627 * Note: coalesced symbols are always defined symbols in 1628 * each object file but referenced with external relocation 1629 * entries. Since they are always defined they are not in 1630 * in the undefined map. 1631 */ 1632 } 1633#ifndef RLD 1634 /* 1635 * If the output file is a multi module MH_DYLIB type set the 1636 * reference map for this external symbol. 1637 */ 1638 if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ 1639 cur_obj->reference_maps[nrefsym].merged_symbol = 1640 merged_symbol; 1641 /* 1642 * Discared coalesced symbols are referenced as undefined. 1643 * TODO: to determine if the reference is lazy or non-lazy 1644 * we would have to look at all the relocation entries in 1645 * this object. For now just assume non-lazy to be safe. 1646 */ 1647 if(discarded_coalesced_symbol == TRUE){ 1648 if(merged_symbol->nlist.n_type & N_PEXT) 1649 cur_obj->reference_maps[nrefsym].flags = 1650 REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY; 1651 else 1652 cur_obj->reference_maps[nrefsym].flags = 1653 REFERENCE_FLAG_UNDEFINED_NON_LAZY; 1654 } 1655 else if(object_symbols[i].n_type == (N_EXT | N_UNDF)) 1656 cur_obj->reference_maps[nrefsym].flags = 1657 object_symbols[i].n_desc & REFERENCE_TYPE; 1658 else if(object_symbols[i].n_type & N_PEXT) 1659 cur_obj->reference_maps[nrefsym].flags = 1660 REFERENCE_FLAG_PRIVATE_DEFINED; 1661 else 1662 cur_obj->reference_maps[nrefsym].flags = 1663 REFERENCE_FLAG_DEFINED; 1664 nrefsym++; 1665 } 1666#endif /* !defined(RLD) */ 1667 } 1668 else if(cur_obj != base_obj || strip_base_symbols == FALSE){ 1669#ifndef RLD 1670 if(dead_strip && 1671 (object_symbols[i].n_type & N_STAB) == 0 && 1672 (object_symbols[i].n_type & N_TYPE) == N_SECT && 1673 object_symbols[i].n_desc & N_NO_DEAD_STRIP) 1674 local_NO_DEAD_STRIP_symbols = TRUE; 1675#endif /* !defined(RLD) */ 1676 1677 if(strip_level != STRIP_DUP_INCLS && 1678 is_output_local_symbol(object_symbols[i].n_type, 1679 object_symbols[i].n_sect, object_symbols[i].n_desc, 1680 cur_obj, 1681 object_symbols[i].n_un.n_strx == 0 ? "" : 1682 object_strings + object_symbols[i].n_un.n_strx, 1683 &output_strlen)){ 1684 cur_obj->nlocalsym++; 1685 nlocal_symbols++; 1686 local_string_size += object_symbols[i].n_un.n_strx == 0 ? 0: 1687 output_strlen + 1; 1688 } 1689 } 1690 1691 /* If this file had DWARF, account for the extra debug_map 1692 symbols. */ 1693 if (cur_obj->dwarf_name && ! discarded_coalesced_symbol && 1694 ! discarded_multiply_defined_symbol){ 1695 size_t n = count_dwarf_symbols (object_symbols + i, i, 1696 debug_ptr); 1697 cur_obj->nlocalsym += n; 1698 nlocal_symbols += n; 1699 } 1700 } 1701 1702#ifndef RLD 1703 /* 1704 * If we are stripping STABS from duplicate includes then go through the 1705 * symbol table determining which local symbols (STABS and non-stabs) 1706 * which are to be in the output file. 1707 * 1708 * The stabs for each N_BINCL/N_EINCL are parsed out as a group. Since 1709 * there can be intermixed nested groups the parsing is a bit strange 1710 * as we create blocks for the symbols that have been parsed out and 1711 * then restart parsing at the inter nesting level. This allows outer 1712 * groups to be excluded when inter groups can't. The blocks must be 1713 * put and kept on the list in order of their symbol table index. 1714 */ 1715 if(strip_level == STRIP_DUP_INCLS){ 1716 localsym_block = cur_obj->localsym_blocks; 1717 next_localsym_block = &(cur_obj->localsym_blocks); 1718 for(i = 0; i < cur_obj->symtab->nsyms; i++){ 1719 /* skip blocks of symbols that have already been parsed */ 1720 if(localsym_block != NULL && localsym_block->index == i){ 1721 i += localsym_block->count - 1; /* the loop will do i++ */ 1722 next_localsym_block = &(localsym_block->next); 1723 localsym_block = localsym_block->next; 1724 continue; 1725 } 1726 if(object_symbols[i].n_type & N_EXT) 1727 continue; 1728 if((object_symbols[i].n_type & N_STAB) == 0 || 1729 object_symbols[i].n_type != N_BINCL){ 1730 cur_obj->nlocalsym++; 1731 nlocal_symbols++; 1732 /* 1733 * Even though strip_level is STRIP_DUP_INCLS and we know 1734 * we are keeping this symbol, it might be an N_OSO which 1735 * we maybe changing the name of so is_output_local_symbol() 1736 * is still called to get the output_strlen. 1737 */ 1738 (void)is_output_local_symbol(object_symbols[i].n_type, 1739 object_symbols[i].n_sect, object_symbols[i].n_desc, 1740 cur_obj, 1741 object_symbols[i].n_un.n_strx == 0 ? "" : 1742 object_strings + object_symbols[i].n_un.n_strx, 1743 &output_strlen); 1744 local_string_size += 1745 object_symbols[i].n_un.n_strx == 0 ? 0: 1746 output_strlen + 1; 1747 continue; 1748 } 1749 /* 1750 * We now have a N_BINCL stab. We will now see if we can 1751 * exclude this stab through its closing N_EINCL stab. 1752 * To exclude this group it must not have any non-stabs in it 1753 * and must not have any stabs that need relocation (stabs for 1754 * definitions of symbols in header files, N_FUN, N_SLINE, etc). 1755 * 1756 * An N_BINCL symbol indicates the start of the stabs entries 1757 * for a header file. We need to scan ahead to the next N_EINCL 1758 * symbol, ignoring nesting, adding up all the characters in the 1759 * symbol names, not including the file numbers in types (the 1760 * first number after an open parenthesis). 1761 */ 1762 no_exclusion = FALSE; 1763 nest = 0; 1764 sum = 0; 1765 /* 1766 * Create the first block for this bincl, 1767 * then after parsing out the incl's stabs, 1768 * the outer loop will start again just after this block 1769 */ 1770 localsym_block = allocate(sizeof(struct localsym_block)); 1771 memset(localsym_block, '\0', sizeof(struct localsym_block)); 1772 localsym_block->index = i; 1773 localsym_block->state = PARSE_SYMBOLS; 1774 localsym_block->count = 1; 1775 localsym_block->input_N_BINCL_n_value = 1776 object_symbols[i].n_value; 1777 if(localsym_block->input_N_BINCL_n_value != 0) 1778 sum = localsym_block->input_N_BINCL_n_value; 1779 1780 /* insert the first block in the list */ 1781 localsym_block->next = *next_localsym_block; 1782 *next_localsym_block = localsym_block; 1783 next_localsym_block = &(localsym_block->next); 1784 1785 /* 1786 * The current block on the chain for the group starts out 1787 * as the first block. 1788 */ 1789 cur_localsym_block = localsym_block; 1790 1791 for(j = i + 1; j < cur_obj->symtab->nsyms; j++){ 1792 if(object_symbols[j].n_type == N_EINCL){ 1793 if(nest == 0){ 1794 /* count this symbol as the part of this block */ 1795 cur_localsym_block->count++; 1796 break; 1797 } 1798 else{ 1799 nest--; 1800 if(nest == 0){ 1801 /* 1802 * If we are going back to nest level zero 1803 * we can now set the index to where the 1804 * current block starts. 1805 */ 1806 cur_localsym_block->index = j + 1; 1807 } 1808 } 1809 } 1810 else if(object_symbols[j].n_type == N_BINCL || 1811 object_symbols[j].n_type == N_EXCL){ 1812 nest++; 1813 /* 1814 * End the current block and create a new one if we 1815 * haven't already. We don't know the index yet, but 1816 * we do know we need a new block as we are nesting 1817 * down and expect to come back. 1818 */ 1819 if(cur_localsym_block->count != 0){ 1820 temp_localsym_block = allocate( 1821 sizeof(struct localsym_block)); 1822 memset(temp_localsym_block, '\0', 1823 sizeof(struct localsym_block)); 1824 temp_localsym_block->state = PARSE_SYMBOLS; 1825 1826 /* insert it after the current block */ 1827 temp_localsym_block->next = 1828 cur_localsym_block->next; 1829 cur_localsym_block->next = temp_localsym_block; 1830 1831 /* now make it the current block */ 1832 cur_localsym_block = temp_localsym_block; 1833 } 1834 if(object_symbols[j].n_type == N_EXCL){ 1835 nest--; 1836 if(nest == 0){ 1837 /* 1838 * If we are going back to nest level zero 1839 * we can now set the index to where the 1840 * current block starts. 1841 */ 1842 cur_localsym_block->index = j + 1; 1843 } 1844 } 1845 } 1846 else if(nest == 0){ 1847 if((object_symbols[j].n_type & N_STAB) == 0 || 1848 object_symbols[j].n_sect != NO_SECT){ 1849 no_exclusion = TRUE; 1850 } 1851 /* 1852 * If this is a local symbol count it as the part of 1853 * the current block. 1854 */ 1855 if((object_symbols[j].n_type & N_STAB) != 0){ 1856 cur_localsym_block->count++; 1857 1858 if(localsym_block->input_N_BINCL_n_value == 0 && 1859 object_symbols[j].n_un.n_strx != 0){ 1860 stab_string = object_strings + 1861 object_symbols[j].n_un.n_strx; 1862 for( ; *stab_string != '\0'; stab_string++){ 1863 sum += *stab_string; 1864 if(*stab_string == '('){ 1865 /* skip the file number */ 1866 stab_string++; 1867 while(isdigit((unsigned char) 1868 *stab_string)) 1869 stab_string++; 1870 stab_string--; 1871 } 1872 else if(*stab_string == '.' && 1873 stab_string[1] != '\0' && 1874 stab_string[1] == '_'){ 1875 stab_string++; /* one for the '.' */ 1876 sum += *stab_string; 1877 stab_string++; /* and one for the '_' */ 1878 while(isdigit((unsigned char) 1879 *stab_string)) 1880 stab_string++; 1881 stab_string--; 1882 } 1883 } 1884 } 1885 } 1886 } 1887 } 1888 /* 1889 * If we did not succesfully parsed a N_BINCL/N_EINCL pair or 1890 * the group has symbols that can't be excluded, then just add 1891 * these symbols to the count of local symbols and the sizes of 1892 * the strings in this group. Leave the blocks that were 1893 * created in the PARSE_SYMBOLS state so they won't be looked 1894 * at again and the symbols won't be removed. 1895 */ 1896 if(j == cur_obj->symtab->nsyms || no_exclusion == TRUE){ 1897 temp_localsym_block = localsym_block; 1898 while(temp_localsym_block != NULL){ 1899 cur_obj->nlocalsym += temp_localsym_block->count; 1900 nlocal_symbols += temp_localsym_block->count; 1901 for(k = temp_localsym_block->index; 1902 k < temp_localsym_block->index + 1903 temp_localsym_block->count; 1904 k++){ 1905 /* 1906 * Even though strip_level is STRIP_DUP_INCLS and 1907 * we know we are keeping this symbol, it might be 1908 * an N_OSO which we maybe changing the name of. 1909 * So is_output_local_symbol() is still called to 1910 * get the output_strlen. 1911 */ 1912 (void)is_output_local_symbol( 1913 object_symbols[k].n_type, 1914 object_symbols[k].n_sect, 1915 object_symbols[k].n_desc, 1916 cur_obj, 1917 object_symbols[k].n_un.n_strx == 0 ? "" : 1918 object_strings + object_symbols[k].n_un.n_strx, 1919 &output_strlen); 1920 local_string_size += 1921 object_symbols[k].n_un.n_strx == 0 ? 0: 1922 output_strlen + 1; 1923 } 1924 if(temp_localsym_block == cur_localsym_block) 1925 break; 1926 else 1927 temp_localsym_block = temp_localsym_block->next; 1928 } 1929 i = i + localsym_block->count 1930 - 1; /* the loop will do i++ */ 1931 localsym_block = localsym_block->next; 1932 } 1933 else{ 1934 /* 1935 * We succesfully parsed out a set of stabs between a 1936 * N_BINCL/N_EINCL pair that now can be considered for 1937 * exclusion if we have seen the same include file with 1938 * the same sum of its stab strings without file numbers. 1939 * lookup_and_enter_include() will return TRUE if this is 1940 * new and we have not seen this group before. 1941 */ 1942 include_file_name = object_strings + 1943 object_symbols[i].n_un.n_strx; 1944 if(lookup_and_enter_include(include_file_name, sum, i, 1945 object_symbols[i+1].n_type == N_EINCL)){ 1946 /* 1947 * This is the first time this group is seen, so count 1948 * the symbols in the blocks of this include file as to 1949 * be in the output (all known to be local symbols) and 1950 * add up the sizes of their strings. 1951 */ 1952 temp_localsym_block = localsym_block; 1953 while(temp_localsym_block != NULL){ 1954 cur_obj->nlocalsym += temp_localsym_block->count; 1955 nlocal_symbols += temp_localsym_block->count; 1956 for(k = temp_localsym_block->index; 1957 k < temp_localsym_block->index + 1958 temp_localsym_block->count; 1959 k++){ 1960 /* 1961 * Even though strip_level is STRIP_DUP_INCLS 1962 * and we know we are keeping this symbol, it 1963 * might be an N_OSO which we maybe changing 1964 * the name of. So is_output_local_symbol() is 1965 * still called to get the output_strlen. 1966 */ 1967 (void)is_output_local_symbol( 1968 object_symbols[k].n_type, 1969 object_symbols[k].n_sect, 1970 object_symbols[k].n_desc, 1971 cur_obj, 1972 object_symbols[k].n_un.n_strx == 0 ? "" : 1973 object_strings + 1974 object_symbols[k].n_un.n_strx, 1975 &output_strlen); 1976 local_string_size += 1977 object_symbols[k].n_un.n_strx == 0 ? 0: 1978 output_strlen + 1; 1979 } 1980 if(temp_localsym_block == cur_localsym_block) 1981 break; 1982 else 1983 temp_localsym_block = temp_localsym_block->next; 1984 } 1985 /* 1986 * The sum for the N_BINCL needs to be set so use the 1987 * the first block for this bincl group for this, 1988 * resetting its count to 1 after resetting the outer 1989 * loop to start after the original size of the block. 1990 * The other blocks for this bincl group continue to 1991 * have their state set to PARSE_SYMBOLS and will be 1992 * removed from the list after all symbols are parsed. 1993 * Then the symbols from this include will be in the 1994 * output. 1995 */ 1996 localsym_block->state = BEGIN_INCLUDE; 1997 localsym_block->sum = sum; 1998 i = i + localsym_block->count 1999 - 1; /* the loop will do i++ */ 2000 localsym_block->count = 1; 2001 localsym_block = localsym_block->next; 2002 } 2003 else{ 2004 /* 2005 * This group of stabs has been seen before so it will 2006 * be excluded from the output. Use the the first 2007 * block for this bincl group for this marking it as 2008 * EXCLUDED_INCLUDE, then set the other blocks in this 2009 * group to DISCARD. Then account for the one N_EXCL 2010 * stab and it's sting. Finally reset the outer loop to 2011 * start after the first block. 2012 */ 2013 localsym_block->state = EXCLUDED_INCLUDE; 2014 localsym_block->sum = sum; 2015 if(localsym_block != cur_localsym_block){ 2016 temp_localsym_block = localsym_block->next; 2017 while(temp_localsym_block != NULL){ 2018 temp_localsym_block->state = DISCARD_SYMBOLS; 2019 if(temp_localsym_block == cur_localsym_block) 2020 break; 2021 else 2022 temp_localsym_block = 2023 temp_localsym_block->next; 2024 } 2025 } 2026 2027 /* account for the one N_EXCL replacing this group */ 2028 cur_obj->nlocalsym += 1; 2029 nlocal_symbols += 1; 2030 /* 2031 The path string for an EXCL always re-uses 2032 the path from the matching BINCL 2033 local_string_size += strlen(include_file_name) + 1; 2034 */ 2035 i = i + localsym_block->count - 1; 2036 /* the loop will do i++ */ 2037 /* 2038 * Note the count field of an EXCLUDED_INCLUDE block 2039 * contains the #of symbols to that were replaced with 2040 * the N_EINCL not a count of 1. So the count is not 2041 * changed. 2042 */ 2043 localsym_block = localsym_block->next; 2044 } 2045 } 2046 } 2047 /* 2048 * Go through the list of blocks and remove any blocks that were 2049 * just needed for parsing. 2050 */ 2051 localsym_block = cur_obj->localsym_blocks; 2052 next_localsym_block = &(cur_obj->localsym_blocks); 2053 while(localsym_block != NULL){ 2054 if(localsym_block->state == PARSE_SYMBOLS){ 2055 temp_localsym_block = localsym_block; 2056 localsym_block = localsym_block->next; 2057 *next_localsym_block = localsym_block; 2058 free(temp_localsym_block); 2059 } 2060 else{ 2061 next_localsym_block = &(localsym_block->next); 2062 localsym_block = localsym_block->next; 2063 } 2064 } 2065 } 2066#endif /* !defined(RLD) */ 2067 2068} 2069 2070#ifndef RLD 2071/* 2072 * exports_list_processing() takes a symbol_name and a defined symbol from an 2073 * object file and sets the private extern bit is it is not to be exported. And 2074 * also marks the symbol in the list as seen. 2075 */ 2076static 2077void 2078exports_list_processing( 2079char *symbol_name, 2080struct nlist *symbol) 2081{ 2082 struct symbol_list *sp; 2083 2084 if(save_symbols != NULL){ 2085 sp = bsearch(symbol_name, save_symbols, nsave_symbols, 2086 sizeof(struct symbol_list), 2087 (int (*)(const void *, const void *)) 2088 symbol_list_bsearch); 2089 if(sp != NULL){ 2090 sp->seen = TRUE; 2091 } 2092 else{ 2093 if(symbol->n_desc & REFERENCED_DYNAMICALLY){ 2094 warning("symbol: %s referenced dynamically and must be " 2095 "exported", symbol_name); 2096 } 2097 else{ 2098 symbol->n_type |= N_PEXT; 2099 } 2100 } 2101 } 2102 if(remove_symbols != NULL){ 2103 sp = bsearch(symbol_name, remove_symbols, nremove_symbols, 2104 sizeof(struct symbol_list), 2105 (int (*)(const void *, const void *)) 2106 symbol_list_bsearch); 2107 if(sp != NULL){ 2108 sp->seen = TRUE; 2109 if(symbol->n_desc & REFERENCED_DYNAMICALLY){ 2110 warning("symbol: %s referenced dynamically and must be " 2111 "exported", symbol_name); 2112 } 2113 else{ 2114 symbol->n_type |= N_PEXT; 2115 } 2116 } 2117 } 2118} 2119 2120/* 2121 * command_line_symbol() looks up a symbol name that comes from a command line 2122 * argument (like -u symbol_name) and returns a pointer to the merged symbol 2123 * table entry for it. If the symbol doesn't exist it enters an undefined 2124 * symbol for it. 2125 */ 2126__private_extern__ 2127struct merged_symbol * 2128command_line_symbol( 2129char *symbol_name) 2130{ 2131 unsigned long i; 2132 struct merged_symbol *hash_pointer, *merged_symbol; 2133 struct object_file *command_line_object; 2134 2135 command_line_object = new_object_file(); 2136 command_line_object->file_name = "command line"; 2137 command_line_object->command_line = TRUE; 2138 /* 2139 * Do the trace of this symbol if specified. 2140 */ 2141 if(ntrace_syms != 0){ 2142 for(i = 0; i < ntrace_syms; i++){ 2143 if(strcmp(trace_syms[i], symbol_name) == 0){ 2144 trace_symbol(symbol_name, &(undefined_symbol), 2145 command_line_object, "error in trace_symbol()"); 2146 break; 2147 } 2148 } 2149 } 2150 /* lookup the symbol and see if it has already been seen */ 2151 hash_pointer = lookup_symbol(symbol_name); 2152 if(hash_pointer->name_len == 0){ 2153 /* 2154 * The symbol has not been seen yet so just enter it as an 2155 * undefined symbol and it will be returned. 2156 */ 2157 merged_symbol = enter_symbol(hash_pointer, &(undefined_symbol), 2158 symbol_name, command_line_object); 2159 if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ 2160 command_line_object->reference_maps = 2161 reallocate(command_line_object->reference_maps, 2162 (command_line_object->nrefsym + 1) * 2163 sizeof(struct reference_map)); 2164 command_line_object->reference_maps[ 2165 command_line_object->nrefsym].flags = 2166 REFERENCE_FLAG_UNDEFINED_NON_LAZY; 2167 command_line_object->reference_maps[ 2168 command_line_object->nrefsym].merged_symbol = 2169 merged_symbol; 2170 command_line_object->irefsym = 2171 output_dysymtab_info.dysymtab_command.nextrefsyms; 2172 command_line_object->nrefsym += 1; 2173 output_dysymtab_info.dysymtab_command.nextrefsyms += 1; 2174 } 2175 } 2176 /* the symbol has been seen so just use it */ 2177 else{ 2178 merged_symbol = hash_pointer; 2179 /* 2180 * If this symbol has only been referenced by a dylib up to 2181 * this point re-enter the symbol name so it is in a string 2182 * block that will be in the output file. 2183 */ 2184 if(merged_symbol->referenced_in_non_dylib == FALSE) 2185 merged_symbol->nlist.n_un.n_name = enter_string(symbol_name, 2186 NULL); 2187 } 2188 merged_symbol->referenced_in_non_dylib = TRUE; 2189 if(merged_symbol->non_dylib_referenced_obj == NULL) 2190 merged_symbol->non_dylib_referenced_obj = command_line_object; 2191 return(merged_symbol); 2192} 2193 2194/* 2195 * command_line_indr_symbol() creates an indirect symbol for symbol_name to 2196 * indr_symbol_name. It is used for -i command line options. Since this is 2197 * a defining symbol the problems of multiply defined symbols can happen. This 2198 * and the tracing is not too neat as far as the code goes but it does exactly 2199 * what is intended. That is exactly one error message for each symbol and 2200 * exactly one trace for each object or command line option for each symbol. 2201 */ 2202__private_extern__ 2203void 2204command_line_indr_symbol( 2205char *symbol_name, 2206char *indr_symbol_name) 2207{ 2208 unsigned long i, j; 2209 enum bool was_traced; 2210 struct merged_symbol *hash_pointer, *merged_symbol, *merged_indr_symbol; 2211 struct object_file *command_line_object; 2212 2213 command_line_object = new_object_file(); 2214 command_line_object->file_name = "command line"; 2215 command_line_object->command_line = TRUE; 2216 /* 2217 * Do the trace of the symbol_name if specified. 2218 */ 2219 was_traced = FALSE; 2220 if(ntrace_syms != 0){ 2221 for(i = 0; i < ntrace_syms; i++){ 2222 if(strcmp(trace_syms[i], symbol_name) == 0){ 2223 trace_symbol(symbol_name, &(indr_symbol), 2224 command_line_object, indr_symbol_name); 2225 was_traced = TRUE; 2226 break; 2227 } 2228 } 2229 } 2230 /* lookup the symbol_name and see if it has already been seen */ 2231 hash_pointer = lookup_symbol(symbol_name); 2232 if(hash_pointer->name_len == 0){ 2233 /* 2234 * The symbol has not been seen yet so just enter it as an 2235 * undefined and it will be changed to a proper merged indirect 2236 * symbol. 2237 */ 2238 merged_symbol = enter_symbol(hash_pointer, &(undefined_symbol), 2239 symbol_name, command_line_object); 2240 merged_symbol->referenced_in_non_dylib = TRUE; 2241 if(merged_symbol->non_dylib_referenced_obj == NULL) 2242 merged_symbol->non_dylib_referenced_obj = command_line_object; 2243 } 2244 else{ 2245 /* 2246 * The symbol exist. So if the symbol is anything but a common or 2247 * undefined then it is multiply defined. 2248 */ 2249 merged_symbol = hash_pointer; 2250 /* 2251 * If this symbol has only been referenced by a dylib up to 2252 * this point re-enter the symbol name so it is in a string 2253 * block that will be in the output file. 2254 */ 2255 if(merged_symbol->referenced_in_non_dylib == FALSE) 2256 merged_symbol->nlist.n_un.n_name = enter_string(symbol_name, 2257 NULL); 2258 merged_symbol->referenced_in_non_dylib = TRUE; 2259 if(merged_symbol->non_dylib_referenced_obj == NULL) 2260 merged_symbol->non_dylib_referenced_obj = command_line_object; 2261 if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF){ 2262 /* 2263 * It is multiply defined so the logic of the routine 2264 * multiply_defined() is copied here so that tracing a symbol 2265 * from the command line can be done. 2266 */ 2267 for(i = 0; i < nmultiple_defs; i++){ 2268 if(strcmp(multiple_defs[i], 2269 merged_symbol->nlist.n_un.n_name) == 0) 2270 break; 2271 } 2272 for(j = 0; j < ntrace_syms; j++){ 2273 if(strcmp(trace_syms[j], 2274 merged_symbol->nlist.n_un.n_name) == 0) 2275 break; 2276 } 2277 if(i == nmultiple_defs){ 2278 if(allow_multiply_defined_symbols == TRUE) 2279 warning("multiple definitions of symbol %s", 2280 merged_symbol->nlist.n_un.n_name); 2281 else 2282 error("multiple definitions of symbol %s", 2283 merged_symbol->nlist.n_un.n_name); 2284 multiple_defs = reallocate(multiple_defs, (nmultiple_defs + 2285 1) * sizeof(char *)); 2286 multiple_defs[nmultiple_defs++] = 2287 merged_symbol->nlist.n_un.n_name; 2288 if(j == ntrace_syms) 2289 trace_merged_symbol(merged_symbol); 2290 } 2291 if(was_traced == FALSE) 2292 trace_symbol(symbol_name, &(indr_symbol), 2293 command_line_object, indr_symbol_name); 2294 return; 2295 } 2296 } 2297 nindr_symbols++; 2298 /* Now change this symbol to an indirect symbol type */ 2299 merged_symbol->nlist.n_type = N_INDR | N_EXT; 2300 merged_symbol->nlist.n_sect = NO_SECT; 2301 merged_symbol->nlist.n_desc = 0; 2302 2303 /* lookup the indr_symbol_name and see if it has already been seen */ 2304 hash_pointer = lookup_symbol(indr_symbol_name); 2305 if(hash_pointer->name_len == 0){ 2306 /* 2307 * The symbol has not been seen yet so just enter it after tracing 2308 * if the symbol is specified. 2309 */ 2310 for(i = 0; i < ntrace_syms; i++){ 2311 if(strcmp(trace_syms[i], indr_symbol_name) == 0){ 2312 trace_symbol(indr_symbol_name, &(undefined_symbol), 2313 command_line_object, "error in trace_symbol()"); 2314 break; 2315 } 2316 } 2317 merged_indr_symbol = enter_symbol(hash_pointer, &(undefined_symbol), 2318 indr_symbol_name, command_line_object); 2319 merged_indr_symbol->referenced_in_non_dylib = TRUE; 2320 if(merged_indr_symbol->non_dylib_referenced_obj == NULL) 2321 merged_indr_symbol->non_dylib_referenced_obj = 2322 command_line_object; 2323 } 2324 else{ 2325 merged_indr_symbol = hash_pointer; 2326 /* 2327 * If this symbol has only been referenced by a dylib up to 2328 * this point re-enter the symbol name so it is in a string 2329 * block that will be in the output file. 2330 */ 2331 if(merged_indr_symbol->referenced_in_non_dylib == FALSE) 2332 merged_indr_symbol->nlist.n_un.n_name = 2333 enter_string(indr_symbol_name, NULL); 2334 merged_indr_symbol->referenced_in_non_dylib = TRUE; 2335 if(merged_indr_symbol->non_dylib_referenced_obj == NULL) 2336 merged_indr_symbol->non_dylib_referenced_obj = 2337 command_line_object; 2338 } 2339 merged_symbol->nlist.n_value = (unsigned long)merged_indr_symbol; 2340 2341 if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ 2342 command_line_object->nextdefsym = 1; 2343 command_line_object->reference_maps = 2344 reallocate(command_line_object->reference_maps, 2345 (command_line_object->nrefsym + 2) * 2346 sizeof(struct reference_map)); 2347 command_line_object->reference_maps[ 2348 command_line_object->nrefsym + 0].flags = 2349 REFERENCE_FLAG_DEFINED; 2350 command_line_object->reference_maps[ 2351 command_line_object->nrefsym + 0].merged_symbol = 2352 merged_symbol; 2353 command_line_object->reference_maps[ 2354 command_line_object->nrefsym + 1].flags = 2355 REFERENCE_FLAG_UNDEFINED_NON_LAZY; 2356 command_line_object->reference_maps[ 2357 command_line_object->nrefsym + 1].merged_symbol = 2358 merged_indr_symbol; 2359 command_line_object->irefsym = 2360 output_dysymtab_info.dysymtab_command.nextrefsyms; 2361 command_line_object->nrefsym += 2; 2362 output_dysymtab_info.dysymtab_command.nextrefsyms += 2; 2363 } 2364} 2365 2366/* 2367 * merge_dylib_module_symbols() merges the symbols from the current object 2368 * (cur_obj) which represents a module from a dynamic shared library into 2369 * the merged symbol table. The parameter dynamic_library is the dynamic 2370 * library struct the current object is from. 2371 */ 2372__private_extern__ 2373void 2374merge_dylib_module_symbols( 2375struct dynamic_library *dynamic_library) 2376{ 2377 unsigned long i, j, k, l, nundefineds, module_index, library_ordinal; 2378 char *strings, *symbol_name, *name; 2379 struct nlist *symbols, *fake_trace_symbol; 2380 struct dylib_reference *refs; 2381 unsigned long flags; 2382 enum bool was_traced, resolve_flat; 2383 struct merged_symbol *hash_pointer, *merged_symbol; 2384 struct object_file *obj; 2385 struct dylib_table_of_contents *toc; 2386 struct dynamic_library *dep; 2387 2388 strings = cur_obj->obj_addr + cur_obj->symtab->stroff; 2389 symbols = (struct nlist *)(cur_obj->obj_addr + 2390 cur_obj->symtab->symoff); 2391 refs = (struct dylib_reference *)(cur_obj->obj_addr + 2392 cur_obj->dysymtab->extrefsymoff); 2393 2394 /* 2395 * First loop through the symbols defined by this module and merge them 2396 * into the merged symbol table. 2397 */ 2398 for(i = 0; i < cur_obj->dylib_module->nextdefsym; i++){ 2399 j = i + cur_obj->dylib_module->iextdefsym; 2400 symbol_name = strings + symbols[j].n_un.n_strx; 2401 /* 2402 * Do the trace of the symbol_name if specified. 2403 */ 2404 if((symbols[j].n_desc & N_WEAK_DEF) == N_WEAK_DEF) 2405 fake_trace_symbol = &pbud_weak_def_symbol; 2406 else 2407 fake_trace_symbol = &pbud_symbol; 2408 was_traced = FALSE; 2409 if(ntrace_syms != 0){ 2410 for(k = 0; k < ntrace_syms; k++){ 2411 if(strcmp(trace_syms[k], symbol_name) == 0){ 2412 trace_symbol(symbol_name, fake_trace_symbol, cur_obj, 2413 "error in trace_symbol()"); 2414 was_traced = TRUE; 2415 break; 2416 } 2417 } 2418 } 2419 /* lookup the symbol_name and see if it has already been seen */ 2420 hash_pointer = lookup_symbol(symbol_name); 2421 if(hash_pointer->name_len == 0){ 2422 /* 2423 * The symbol has not been seen yet so just enter it as a 2424 * prebound undefined. 2425 */ 2426 merged_symbol = enter_symbol(hash_pointer, &(pbud_symbol), 2427 symbol_name, cur_obj); 2428 } 2429 else{ 2430 merged_symbol = hash_pointer; 2431 /* 2432 * If the merged symbol is not undefined and if this symbol is 2433 * a weak definition then it is simply ignored and the merged 2434 * symbol is used. Note currently only coalesced sections can 2435 * have this attribute and this is checked for in 2436 * check_symbol() so it is assumed it is a coalesced symbol 2437 * here. 2438 */ 2439 if((merged_symbol->nlist.n_type != (N_UNDF | N_EXT) || 2440 merged_symbol->nlist.n_value != 0) && 2441 (symbols[j].n_desc & N_WEAK_DEF) == N_WEAK_DEF){ 2442 continue; 2443 } 2444 /* 2445 * If the merged symbol is a weak definition then it is 2446 * discarded and this symbol definition from this dylib is used. 2447 */ 2448 if((merged_symbol->nlist.n_desc & N_WEAK_DEF) == N_WEAK_DEF || 2449 (merged_symbol->defined_in_dylib == TRUE && 2450 merged_symbol->weak_def_in_dylib)){ 2451 if(merged_symbol->defined_in_dylib == FALSE){ 2452 if((merged_symbol->nlist.n_type & N_EXT) && 2453 (merged_symbol->nlist.n_type & N_PEXT)){ 2454 merged_symbol->definition_object->nprivatesym--; 2455 nmerged_private_symbols--; 2456 } 2457 else{ 2458 merged_symbol->definition_object->nextdefsym--; 2459 } 2460 } 2461 /* 2462 * If the output file is a multi module MH_DYLIB type reset 2463 * the reference map for the merged external symbol that 2464 * is being discarded. 2465 */ 2466 if(filetype == MH_DYLIB && 2467 multi_module_dylib == TRUE && 2468 merged_symbol->defined_in_dylib == FALSE){ 2469 /* 2470 * Discared coalesced symbols are referenced as 2471 * undefined. TODO: to determine if the reference is 2472 * lazy or non-lazy we would have to look at all the 2473 * relocation entries in this object. For now just 2474 * assume non-lazy to be safe. 2475 */ 2476 for(k = 0; 2477 k < merged_symbol->definition_object->nrefsym; 2478 k++){ 2479 if(merged_symbol->definition_object-> 2480 reference_maps[k].merged_symbol == 2481 merged_symbol){ 2482 if(symbols[k].n_type & N_PEXT) 2483 merged_symbol->definition_object-> 2484 reference_maps[k].flags = 2485 REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY; 2486 else 2487 merged_symbol->definition_object-> 2488 reference_maps[k].flags = 2489 REFERENCE_FLAG_UNDEFINED_NON_LAZY; 2490 break; 2491 } 2492 } 2493 } 2494 merged_symbol->coalesced_defined_in_dylib = FALSE; 2495 merged_symbol->weak_def_in_dylib = FALSE; 2496 goto use_symbol_definition_from_this_dylib; 2497 } 2498 /* 2499 * If both symbols are coalesced symbols then the this 2500 * symbol is simply ignored. 2501 */ 2502 if((((merged_symbol->nlist.n_type & N_TYPE) == N_SECT && 2503 ((merged_symbol->definition_object->section_maps[ 2504 merged_symbol->nlist.n_sect - 1].s->flags) & 2505 SECTION_TYPE) == S_COALESCED) || 2506 merged_symbol->coalesced_defined_in_dylib == TRUE) && 2507 (symbols[j].n_type & N_TYPE) == N_SECT && 2508 ((cur_obj->section_maps[symbols[j].n_sect - 1]. 2509 s->flags) & SECTION_TYPE) == S_COALESCED){ 2510 continue; 2511 } 2512 /* 2513 * The symbol exists and both are not coalesced symbols. So if 2514 * the merged symbol is anything but a common or undefined then 2515 * it is multiply defined. 2516 */ 2517 if(merged_symbol->nlist.n_type != (N_UNDF | N_EXT)){ 2518 /* 2519 * If this is a two-level namespace link and this library is 2520 * referenced indirectly then don't issue a multiply 2521 * defined error or warning about symbols from it. 2522 */ 2523 if(twolevel_namespace == TRUE && 2524 dynamic_library->definition_obj->library_ordinal == 0) 2525 continue; 2526 /* 2527 * It is multiply defined so the logic of the routine 2528 * multiply_defined() is copied here so that tracing a 2529 * symbol from a dylib module can be done. 2530 */ 2531 for(k = 0; k < nmultiple_defs; k++){ 2532 if(strcmp(multiple_defs[k], 2533 merged_symbol->nlist.n_un.n_name) == 0) 2534 break; 2535 } 2536 for(l = 0; l < ntrace_syms; l++){ 2537 if(strcmp(trace_syms[l], 2538 merged_symbol->nlist.n_un.n_name) == 0) 2539 break; 2540 } 2541 if(k == nmultiple_defs){ 2542 if(allow_multiply_defined_symbols == TRUE){ 2543 warning("multiple definitions of symbol %s", 2544 merged_symbol->nlist.n_un.n_name); 2545 } 2546 else if((twolevel_namespace == TRUE && 2547 merged_symbol->defined_in_dylib == FALSE) || 2548 (force_flat_namespace == FALSE && 2549 ((((struct mach_header *)(cur_obj->obj_addr))-> 2550 flags & MH_TWOLEVEL) == MH_TWOLEVEL || 2551 (merged_symbol->defined_in_dylib == TRUE && 2552 (((struct mach_header *)(merged_symbol-> 2553 definition_object->obj_addr))->flags & 2554 MH_TWOLEVEL) == MH_TWOLEVEL)))){ 2555 if(multiply_defined_flag == 2556 MULTIPLY_DEFINED_WARNING){ 2557 warning("multiple definitions of symbol %s", 2558 merged_symbol->nlist.n_un.n_name); 2559 if(nowarnings == TRUE) 2560 continue; 2561 } 2562 else if(multiply_defined_flag == 2563 MULTIPLY_DEFINED_ERROR){ 2564 error("multiple definitions of symbol %s", 2565 merged_symbol->nlist.n_un.n_name); 2566 } 2567 else if(multiply_defined_flag == 2568 MULTIPLY_DEFINED_SUPPRESS) 2569 continue; 2570 } 2571 else{ 2572 error("multiple definitions of symbol %s", 2573 merged_symbol->nlist.n_un.n_name); 2574 } 2575 multiple_defs = reallocate(multiple_defs, 2576 (nmultiple_defs + 1) * sizeof(char *)); 2577 multiple_defs[nmultiple_defs++] = 2578 merged_symbol->nlist.n_un.n_name; 2579 if(l == ntrace_syms) 2580 trace_merged_symbol(merged_symbol); 2581 } 2582 if(was_traced == FALSE){ 2583 trace_symbol(symbol_name, fake_trace_symbol, cur_obj, 2584 "error in trace_symbol()"); 2585 } 2586 continue; 2587 } 2588 } 2589use_symbol_definition_from_this_dylib: 2590 maybe_remove_dwarf_symbol(merged_symbol); 2591 merged_symbol->nlist.n_type = N_PBUD | N_EXT; 2592 merged_symbol->nlist.n_sect = NO_SECT; 2593 if((symbols[j].n_type & N_TYPE) == N_SECT && 2594 ((cur_obj->section_maps[symbols[j].n_sect - 1]. 2595 s->flags) & SECTION_TYPE) == S_COALESCED){ 2596 merged_symbol->coalesced_defined_in_dylib = TRUE; 2597 if((symbols[j].n_desc & N_WEAK_DEF) == N_WEAK_DEF) 2598 merged_symbol->weak_def_in_dylib = TRUE; 2599#ifdef COALESCE_DEBUG 2600printf("merging in coalesced symbol %s\n", merged_symbol->nlist.n_un.n_name); 2601#endif 2602 } 2603 /* 2604 * If -twolevel_namespace is in effect and this symbol is referenced 2605 * from an object going into the image and will need the library 2606 * ordinal recorded check to see that this dynamic library has been 2607 * assigned an ordinal (that is it was listed on the link line or 2608 * is a sub-framework or sub-umbrella of something listed). If not 2609 * flag this as an illegal reference to an indirect dynamic library 2610 * if this library was not flagged already. 2611 */ 2612 if(save_reloc == FALSE && 2613 twolevel_namespace == TRUE && 2614 merged_symbol->referenced_in_non_dylib == TRUE && 2615 dynamic_library->definition_obj->library_ordinal == 0 && 2616 dynamic_library->indirect_twolevel_ref_flagged == FALSE){ 2617 obj = cur_obj; 2618 cur_obj = merged_symbol->definition_object; 2619 error_with_cur_obj("illegal reference to symbol: %s defined in " 2620 "indirectly referenced dynamic library %s", symbol_name, 2621 dynamic_library->dylib_file != NULL ? 2622 dynamic_library->file_name : dynamic_library->dylib_name); 2623 cur_obj = obj; 2624 dynamic_library->indirect_twolevel_ref_flagged = TRUE; 2625 } 2626 /* 2627 * Don't change the reference type bits of the n_desc field as it 2628 * contains the reference type (lazy or non-lazy). 2629 */ 2630 merged_symbol->nlist.n_value = symbols[j].n_value; 2631 if(symbols[j].n_desc & N_ARM_THUMB_DEF) 2632 merged_symbol->nlist.n_value |= 1; 2633 merged_symbol->definition_object = cur_obj; 2634 merged_symbol->defined_in_dylib = TRUE; 2635 merged_symbol->definition_library = dynamic_library; 2636 /* 2637 * If this shared library is being forced to be weak linked then 2638 * set N_WEAK_REF to make this symbol a weak reference. 2639 */ 2640 if(dynamic_library->force_weak_dylib && 2641 merged_symbol->referenced_in_non_dylib == TRUE) 2642 merged_symbol->nlist.n_desc |= N_WEAK_REF; 2643 /* 2644 * If the merged symbol we are resolving is not a weak reference 2645 * and it is referenced from a non-dylib then set 2646 * some_non_weak_refs to TRUE. 2647 */ 2648 if((merged_symbol->nlist.n_desc & N_WEAK_REF) == 0 && 2649 merged_symbol->referenced_in_non_dylib == TRUE) 2650 dynamic_library->some_non_weak_refs = TRUE; 2651 if(merged_symbol->referenced_in_non_dylib == TRUE) 2652 dynamic_library->some_symbols_referenced = TRUE; 2653 if((symbols[j].n_type & N_TYPE) == N_INDR){ 2654 merged_symbol->nlist.n_type = N_INDR | N_EXT; 2655 enter_indr_symbol(merged_symbol, symbols + j, strings, cur_obj); 2656 } 2657 /* 2658 * If -twolevel_namespace is in effect record the library ordinal 2659 * that this symbol definition is in. 2660 */ 2661 if(twolevel_namespace == TRUE){ 2662 SET_LIBRARY_ORDINAL(merged_symbol->nlist.n_desc, 2663 dynamic_library->definition_obj->library_ordinal); 2664 /* 2665 * It is possible that a common or undefined symbol could have 2666 * been in the merged symbol table and this dylib module is now 2667 * replacing it. If so we have to look it up in the table of 2668 * contents to get the correct index into the table of contents 2669 * for the hint to be recorded. 2670 */ 2671 if(merged_symbol->itoc == 0){ 2672 bsearch_strings = dynamic_library->strings; 2673 bsearch_symbols = dynamic_library->symbols; 2674 toc = bsearch(merged_symbol->nlist.n_un.n_name, 2675 dynamic_library->tocs, 2676 dynamic_library->definition_obj->dysymtab->ntoc, 2677 sizeof(struct dylib_table_of_contents), 2678 (int (*)(const void *, const void *)) 2679 dylib_bsearch); 2680 merged_symbol->itoc = toc - dynamic_library->tocs; 2681 } 2682 } 2683 } 2684 2685 /* 2686 * If the -Y flag is set (trace undefined symbols) then we create an 2687 * undefined map for this object file so process_undefineds() can use it 2688 * to do the work for -Y. 2689 */ 2690 if(Yflag && cur_obj->dylib_module->nrefsym != 0){ 2691 nundefineds = 0; 2692 for(i = 0; i < cur_obj->dylib_module->nrefsym; i++){ 2693 j = i + cur_obj->dylib_module->irefsym; 2694 flags = refs[j].flags; 2695 if(flags == REFERENCE_FLAG_UNDEFINED_NON_LAZY || 2696 flags == REFERENCE_FLAG_UNDEFINED_LAZY){ 2697 nundefineds++; 2698 } 2699 } 2700 cur_obj->undefined_maps = allocate(nundefineds * 2701 sizeof(struct undefined_map)); 2702 cur_obj->nundefineds = nundefineds; 2703 } 2704 nundefineds = 0; 2705 2706 /* 2707 * Second loop through the symbols referenced by this module and merge 2708 * undefined references into the merged symbol table. 2709 */ 2710 for(i = 0; i < cur_obj->dylib_module->nrefsym; i++){ 2711 j = i + cur_obj->dylib_module->irefsym; 2712 flags = refs[j].flags; 2713 if(flags == REFERENCE_FLAG_UNDEFINED_NON_LAZY || 2714 flags == REFERENCE_FLAG_UNDEFINED_LAZY){ 2715 symbol_name = strings + symbols[refs[j].isym].n_un.n_strx; 2716 /* 2717 * Do the trace of this symbol if specified. 2718 */ 2719 if(ntrace_syms != 0){ 2720 for(k = 0; k < ntrace_syms; k++){ 2721 if(strcmp(trace_syms[k], symbol_name) == 0){ 2722 if(force_flat_namespace == TRUE || 2723 (((struct mach_header *)(cur_obj->obj_addr))-> 2724 flags & MH_TWOLEVEL) != MH_TWOLEVEL){ 2725 trace_symbol(symbol_name, &(undefined_symbol), 2726 cur_obj, "error in trace_symbol()"); 2727 } 2728 else{ 2729 print_obj_name(cur_obj); 2730 library_ordinal = GET_LIBRARY_ORDINAL(symbols[ 2731 refs[j].isym].n_desc); 2732 if(library_ordinal != 0 && 2733 library_ordinal != DYNAMIC_LOOKUP_ORDINAL){ 2734 dep = dynamic_library->dependent_images[ 2735 library_ordinal - 1]; 2736 if(dep->umbrella_name != NULL) 2737 name = dep->umbrella_name; 2738 else if(dep->library_name != NULL) 2739 name = dep->library_name; 2740 else 2741 name = dep->dylib_name; 2742 print("reference to undefined %s (from %s)" 2743 "\n", symbol_name, name); 2744 } 2745 else 2746 print("reference to undefined %s\n", 2747 symbol_name); 2748 } 2749 break; 2750 } 2751 } 2752 } 2753 /* 2754 * Determine how this reference will be resolved. If 2755 * -force_flat_namespace is TRUE it will be resolved flat. 2756 * If this dylib is not a two-level namespace dylib it will 2757 * also be resolved flat. It it is a two-level dylib then 2758 * if the library_ordinal is DYNAMIC_LOOKUP_ORDINAL it will be 2759 * resolved flat. If it is a two-level namespace dylib and 2760 * the library_ordinal is not DYNAMIC_LOOKUP_ORDINAL it will 2761 * be resolved with two-level namespace semantics. 2762 */ 2763 if(force_flat_namespace == TRUE) 2764 resolve_flat = TRUE; 2765 else{ 2766 if((((struct mach_header *)(cur_obj->obj_addr))-> 2767 flags & MH_TWOLEVEL) == MH_TWOLEVEL){ 2768 library_ordinal = GET_LIBRARY_ORDINAL( 2769 symbols[refs[j].isym].n_desc); 2770 if(library_ordinal == DYNAMIC_LOOKUP_ORDINAL) 2771 resolve_flat = TRUE; 2772 else 2773 resolve_flat = FALSE; 2774 } 2775 else{ 2776 resolve_flat = TRUE; 2777 } 2778 } 2779 if(resolve_flat == TRUE){ 2780 /* 2781 * The new linking architecture model when building a 2782 * two-level namespace image states "with two level 2783 * namespace, there is no need to resolve undefines in 2784 * dependent dylibs". So if we are building a two-level 2785 * namespace image even when linking against a 2786 * flat-namespace dylib, that dylib's undefined references 2787 * are not to be resolved. 2788 * 2789 * This of course has the architectural flaw that error 2790 * checking is lost and we could be building a broken 2791 * binary. 2792 */ 2793 if(twolevel_namespace == TRUE && 2794 (((struct mach_header *)(cur_obj->obj_addr))-> 2795 flags & MH_TWOLEVEL) != MH_TWOLEVEL){ 2796 continue; /* with for loop */ 2797 } 2798 /* lookup the symbol and see if it has already been seen */ 2799 hash_pointer = lookup_symbol(symbol_name); 2800 if(hash_pointer->name_len == 0){ 2801 /* 2802 * The symbol has not been seen yet so just enter it as 2803 * an undefined symbol and it will be returned. 2804 */ 2805 merged_symbol = enter_symbol(hash_pointer, 2806 &(undefined_symbol), symbol_name, cur_obj); 2807 } 2808 else{ 2809 merged_symbol = hash_pointer; 2810 } 2811 merged_symbol->nlist.n_desc |= REFERENCED_DYNAMICALLY; 2812 } 2813 else{ 2814 /* 2815 * This is a two-level namespace dylib so this must be 2816 * resolved to the symbol from the referenced dylib. To do 2817 * this we fake up a merged_symbol and place it on the 2818 * undefined list with the twolevel_reference bit set and 2819 * the referencing_library field set. Then 2820 * search_dynamic_libs() in pass1.c will figure out which 2821 * dylib module is being referenced and load it. 2822 */ 2823 /* 2824 * With two level namespace, there is no need to resolve 2825 * undefines in dependent dylibs. Their location was fixed 2826 * when that dylib was built. The check here is that any 2827 * undefine which already has an ordinal and the ordinal 2828 * refers to a library that can't be accessed by the 2829 * being-linked image, then ignore it 2830 * 2831 * The comment above, from the original change, does not 2832 * consider the architectural need to resolve undefines in 2833 * dependent dylibs for error checking, and to avoid 2834 * building broken programs that could be detected at build 2835 * time instead of letting that happen at runtime. Which 2836 * could be very late do to lazy binding. 2837 * 2838 * The logic below also seems flawed in that undefined 2839 * references that are marked to be looked up dynamically 2840 * are still searched. But may not be found as the 2841 * indirectly referenced dylibs are now removed from the 2842 * list of dylibs to be searched. 2843 */ 2844 library_ordinal = GET_LIBRARY_ORDINAL( 2845 symbols[refs[j].isym].n_desc); 2846 if((library_ordinal != SELF_LIBRARY_ORDINAL) && 2847 (library_ordinal != DYNAMIC_LOOKUP_ORDINAL)){ 2848 dep = dynamic_library->dependent_images[ 2849 library_ordinal - 1]; 2850 if(dep->definition_obj->library_ordinal == 0) 2851 continue; /* with for loop */ 2852 } 2853 merged_symbol = allocate(sizeof(struct merged_symbol)); 2854 memset(merged_symbol, '\0', sizeof(struct merged_symbol)); 2855 2856 merged_symbol->nlist = symbols[refs[j].isym]; 2857 merged_symbol->nlist.n_un.n_name = symbol_name; 2858 merged_symbol->definition_object = cur_obj; 2859 merged_symbol->twolevel_reference = TRUE; 2860 merged_symbol->referencing_library = dynamic_library; 2861 add_to_undefined_list(merged_symbol); 2862 } 2863 if(Yflag){ 2864 cur_obj->undefined_maps[nundefineds++].merged_symbol = 2865 merged_symbol; 2866 } 2867 } 2868 } 2869 2870 /* 2871 * Last loop through the private symbols referenced by this module and 2872 * make sure the module is linked in. If not force it to be linked in. 2873 * Note this is doing pass1 functionality and causing modules to be 2874 * linked in. So that cur_obj can change through out this loop. 2875 */ 2876 obj = cur_obj; 2877 for(i = 0; i < obj->dylib_module->nrefsym; i++){ 2878 j = i + obj->dylib_module->irefsym; 2879 flags = refs[j].flags; 2880 if(flags == REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY || 2881 flags == REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY){ 2882 /* 2883 * Using the symbol index, refs[j].isym, figure out which 2884 * module owns this symbol and set that into module_index. 2885 */ 2886 for(k = 0; k < obj->dysymtab->nmodtab; k++){ 2887 if(refs[j].isym >= dynamic_library->mods[k].ilocalsym && 2888 refs[j].isym < dynamic_library->mods[k].ilocalsym + 2889 dynamic_library->mods[k].nlocalsym) 2890 break; 2891 } 2892 if(k >= obj->dysymtab->nmodtab){ 2893 error_with_cur_obj("isym field (%u) of reference table " 2894 "entry %lu for private reference not in the local " 2895 "symbols for any module", refs[j].isym, j); 2896 return; 2897 } 2898 module_index = k; 2899 if(is_dylib_module_loaded(dynamic_library->mods + 2900 module_index) == FALSE){ 2901 2902 cur_obj = new_object_file(); 2903 *cur_obj = *(dynamic_library->definition_obj); 2904 cur_obj->dylib_module = dynamic_library->mods + 2905 module_index; 2906 if(dynamic_library->linked_modules != NULL) 2907 dynamic_library->linked_modules[module_index / 8] |= 2908 1 << module_index % 8; 2909 if(whyload){ 2910 print_obj_name(cur_obj); 2911 symbol_name = strings + 2912 symbols[refs[j].isym].n_un.n_strx; 2913 print("loaded to resolve private symbol: %s\n", 2914 symbol_name); 2915 } 2916 merge_dylib_module_symbols(dynamic_library); 2917 cur_obj = obj; 2918 } 2919 } 2920 } 2921} 2922/* 2923 * merge_bundle_loader_symbols() merges the symbols from the current object 2924 * (cur_obj) which represents the bundle loader module into the merged symbol 2925 * table. The parameter dynamic_library is the dynamic library struct the 2926 * current object is from. 2927 */ 2928__private_extern__ 2929void 2930merge_bundle_loader_symbols( 2931struct dynamic_library *dynamic_library) 2932{ 2933 unsigned long i, j, k, l; 2934 char *strings, *symbol_name; 2935 struct nlist *symbols, *fake_trace_symbol; 2936 enum bool was_traced; 2937 struct merged_symbol *hash_pointer, *merged_symbol; 2938 2939 strings = cur_obj->obj_addr + cur_obj->symtab->stroff; 2940 symbols = (struct nlist *)(cur_obj->obj_addr + 2941 cur_obj->symtab->symoff); 2942 /* 2943 * Loop through the symbols defined by the bundle loader and merge them 2944 * into the merged symbol table. 2945 */ 2946 for(i = 0; i < cur_obj->dysymtab->nextdefsym; i++){ 2947 j = i + cur_obj->dysymtab->iextdefsym; 2948 symbol_name = strings + symbols[j].n_un.n_strx; 2949 /* 2950 * Do the trace of the symbol_name if specified. 2951 */ 2952 if((symbols[j].n_desc & N_WEAK_DEF) == N_WEAK_DEF) 2953 fake_trace_symbol = &pbud_weak_def_symbol; 2954 else 2955 fake_trace_symbol = &pbud_symbol; 2956 was_traced = FALSE; 2957 if(ntrace_syms != 0){ 2958 for(k = 0; k < ntrace_syms; k++){ 2959 if(strcmp(trace_syms[k], symbol_name) == 0){ 2960 trace_symbol(symbol_name, fake_trace_symbol, cur_obj, 2961 "error in trace_symbol()"); 2962 was_traced = TRUE; 2963 break; 2964 } 2965 } 2966 } 2967 /* lookup the symbol_name and see if it has already been seen */ 2968 hash_pointer = lookup_symbol(symbol_name); 2969 if(hash_pointer->name_len == 0){ 2970 /* 2971 * The symbol has not been seen yet so just enter it as a 2972 * prebound undefined. 2973 */ 2974 merged_symbol = enter_symbol(hash_pointer, &(pbud_symbol), 2975 symbol_name, cur_obj); 2976 } 2977 else{ 2978 merged_symbol = hash_pointer; 2979 /* 2980 * If the merged symbol is not undefined and if this symbol is 2981 * a weak definition then it is simply ignored and the merged 2982 * symbol is used. Note currently only coalesced sections can 2983 * have this attribute and this is checked for in check_symbol() 2984 * so it is assumed it is a coalesced symbol here. 2985 */ 2986 if((merged_symbol->nlist.n_type != (N_UNDF | N_EXT) || 2987 merged_symbol->nlist.n_value != 0) && 2988 (symbols[j].n_desc & N_WEAK_DEF) == N_WEAK_DEF){ 2989 continue; 2990 } 2991 /* 2992 * If the merged symbol is a weak definition then it is 2993 * discarded and this symbol definition from this bundle 2994 * loader is used. 2995 */ 2996 if(((merged_symbol->nlist.n_desc & N_WEAK_DEF) == N_WEAK_DEF) || 2997 (merged_symbol->defined_in_dylib == TRUE && 2998 merged_symbol->weak_def_in_dylib)){ 2999 if(merged_symbol->defined_in_dylib == FALSE){ 3000 if((merged_symbol->nlist.n_type & N_EXT) && 3001 (merged_symbol->nlist.n_type & N_PEXT)){ 3002 merged_symbol->definition_object->nprivatesym--; 3003 nmerged_private_symbols--; 3004 } 3005 else{ 3006 merged_symbol->definition_object->nextdefsym--; 3007 } 3008 } 3009 /* 3010 * If the output file is a multi module MH_DYLIB type reset 3011 * the reference map for the merged external symbol that 3012 * is being discarded. 3013 */ 3014 if(filetype == MH_DYLIB && 3015 multi_module_dylib == TRUE && 3016 merged_symbol->defined_in_dylib == FALSE){ 3017 /* 3018 * Discared coalesced symbols are referenced as 3019 * undefined. TODO: to determine if the reference is 3020 * lazy or non-lazy we would have to look at all the 3021 * relocation entries in this object. For now just 3022 * assume non-lazy to be safe. 3023 */ 3024 for(k = 0; 3025 k < merged_symbol->definition_object->nrefsym; 3026 k++){ 3027 if(merged_symbol->definition_object-> 3028 reference_maps[k].merged_symbol == 3029 merged_symbol){ 3030 if(symbols[k].n_type & N_PEXT) 3031 merged_symbol->definition_object-> 3032 reference_maps[k].flags = 3033 REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY; 3034 else 3035 merged_symbol->definition_object-> 3036 reference_maps[k].flags = 3037 REFERENCE_FLAG_UNDEFINED_NON_LAZY; 3038 break; 3039 } 3040 } 3041 } 3042 merged_symbol->coalesced_defined_in_dylib = FALSE; 3043 merged_symbol->weak_def_in_dylib = FALSE; 3044 goto use_symbol_definition_from_this_bundle_loader; 3045 } 3046 /* 3047 * If both symbols are coalesced symbols then the this 3048 * symbol is simply ignored. 3049 */ 3050 if((((merged_symbol->nlist.n_type & N_TYPE) == N_SECT && 3051 ((merged_symbol->definition_object->section_maps[ 3052 merged_symbol->nlist.n_sect - 1].s->flags) & 3053 SECTION_TYPE) == S_COALESCED) || 3054 merged_symbol->coalesced_defined_in_dylib == TRUE) && 3055 (symbols[j].n_type & N_TYPE) == N_SECT && 3056 ((cur_obj->section_maps[symbols[j].n_sect - 1]. 3057 s->flags) & SECTION_TYPE) == S_COALESCED){ 3058 continue; 3059 } 3060 /* 3061 * The symbol exist and both are not coalesced symbols. So if 3062 * the merged symbol is anything but a common or undefined then 3063 * it is multiply defined. 3064 */ 3065 if(merged_symbol->nlist.n_type != (N_UNDF | N_EXT)){ 3066 /* 3067 * It is multiply defined so the logic of the routine 3068 * multiply_defined() is copied here so that tracing a 3069 * symbol from a dylib module can be done. 3070 */ 3071 for(k = 0; k < nmultiple_defs; k++){ 3072 if(strcmp(multiple_defs[k], 3073 merged_symbol->nlist.n_un.n_name) == 0) 3074 break; 3075 } 3076 for(l = 0; l < ntrace_syms; l++){ 3077 if(strcmp(trace_syms[l], 3078 merged_symbol->nlist.n_un.n_name) == 0) 3079 break; 3080 } 3081 /* 3082 * If -private_bundle is used then don't worry about any 3083 * multiply defined references. 3084 */ 3085 if(private_bundle == TRUE) 3086 break; 3087 if(k == nmultiple_defs){ 3088 if(allow_multiply_defined_symbols == TRUE){ 3089 warning("multiple definitions of symbol %s", 3090 merged_symbol->nlist.n_un.n_name); 3091 } 3092 else if((twolevel_namespace == TRUE && 3093 merged_symbol->defined_in_dylib == FALSE) || 3094 (force_flat_namespace == FALSE && 3095 ((((struct mach_header *)(cur_obj->obj_addr))-> 3096 flags & MH_TWOLEVEL) == MH_TWOLEVEL || 3097 (merged_symbol->defined_in_dylib == TRUE && 3098 (((struct mach_header *)(merged_symbol-> 3099 definition_object->obj_addr))->flags & 3100 MH_TWOLEVEL) == MH_TWOLEVEL)))){ 3101 if(multiply_defined_flag == 3102 MULTIPLY_DEFINED_WARNING) 3103 warning("multiple definitions of symbol %s", 3104 merged_symbol->nlist.n_un.n_name); 3105 else if(multiply_defined_flag == 3106 MULTIPLY_DEFINED_ERROR){ 3107 error("multiple definitions of symbol %s", 3108 merged_symbol->nlist.n_un.n_name); 3109 } 3110 else if(multiply_defined_flag == 3111 MULTIPLY_DEFINED_SUPPRESS) 3112 continue; 3113 } 3114 else{ 3115 error("multiple definitions of symbol %s", 3116 merged_symbol->nlist.n_un.n_name); 3117 } 3118 multiple_defs = reallocate(multiple_defs, 3119 (nmultiple_defs + 1) * sizeof(char *)); 3120 multiple_defs[nmultiple_defs++] = 3121 merged_symbol->nlist.n_un.n_name; 3122 if(l == ntrace_syms) 3123 trace_merged_symbol(merged_symbol); 3124 } 3125 if(was_traced == FALSE) 3126 trace_symbol(symbol_name, fake_trace_symbol, cur_obj, 3127 "error in trace_symbol()"); 3128 continue; 3129 } 3130 } 3131use_symbol_definition_from_this_bundle_loader: 3132 maybe_remove_dwarf_symbol(merged_symbol); 3133 merged_symbol->nlist.n_type = N_PBUD | N_EXT; 3134 merged_symbol->nlist.n_sect = NO_SECT; 3135 if((symbols[j].n_type & N_TYPE) == N_SECT && 3136 ((cur_obj->section_maps[symbols[j].n_sect - 1]. 3137 s->flags) & SECTION_TYPE) == S_COALESCED){ 3138 merged_symbol->coalesced_defined_in_dylib = TRUE; 3139 if((symbols[j].n_desc & N_WEAK_DEF) == N_WEAK_DEF) 3140 merged_symbol->weak_def_in_dylib = TRUE; 3141#ifdef COALESCE_DEBUG 3142printf("merging in coalesced symbol %s\n", merged_symbol->nlist.n_un.n_name); 3143#endif 3144 } 3145 3146 /* 3147 * Since this is the bundle loader it always has the library 3148 * ordinal EXECUTABLE_ORDINAL assigned to it and we don't have to 3149 * worry about illegal reference to an indirect "dynamic library". 3150 */ 3151 3152 /* 3153 * Don't change the reference type bits if n_desc field as it 3154 * contains the reference type (lazy or non-lazy). 3155 */ 3156 merged_symbol->nlist.n_value = symbols[j].n_value; 3157 merged_symbol->definition_object = cur_obj; 3158 merged_symbol->defined_in_dylib = TRUE; 3159 merged_symbol->definition_library = dynamic_library; 3160 if((symbols[j].n_type & N_TYPE) == N_INDR){ 3161 merged_symbol->nlist.n_type = N_INDR | N_EXT; 3162 enter_indr_symbol(merged_symbol, symbols + j, strings, cur_obj); 3163 } 3164 /* 3165 * If -twolevel_namespace is in effect record the library ordinal 3166 * that this symbol definition is in. 3167 */ 3168 if(twolevel_namespace == TRUE){ 3169 SET_LIBRARY_ORDINAL(merged_symbol->nlist.n_desc, 3170 dynamic_library->definition_obj->library_ordinal); 3171 } 3172 } 3173 3174 /* 3175 * For the bundle loader we simply ignore any undefined references it 3176 * might have and since it is a one module image there is nothing to 3177 * do for its private symbols. 3178 */ 3179} 3180#endif /* !defined(RLD) */ 3181 3182/* 3183 * is_output_local_symbol() returns TRUE or FALSE depending if the local symbol 3184 * type, section, object and name passed to it will be in the output file's 3185 * symbol table based on the level of symbol stripping. If it returns TRUE it 3186 * also indirectly returns the size of the local string for output in 3187 * output_strlen (possibly truncated if the strip level is STRIP_MIN_DEBUG). 3188 * The obj passed must be the object this symbol came from so that the the 3189 * section can be checked for the S_ATTR_STRIP_STATIC_SYMS attribute flag. 3190 */ 3191__private_extern__ 3192enum bool 3193is_output_local_symbol( 3194unsigned char n_type, 3195unsigned char n_sect, 3196unsigned char n_desc, 3197struct object_file *obj, 3198char *symbol_name, 3199unsigned long *output_strlen) 3200{ 3201#ifndef RLD 3202 char *end; 3203#endif /* !defined(RLD) */ 3204 3205 *output_strlen = 0; 3206 switch(strip_level){ 3207 case STRIP_NONE: 3208 case STRIP_DUP_INCLS: 3209 /* 3210 * We are not stripping stabs. But if we see an N_OSO we 3211 * will change it's name in some cases. In here with just 3212 * return the lenght of the new name. In output_local_symbols() 3213 * is where the new name is set for the output file. 3214 */ 3215 if(n_type == N_OSO){ 3216 /* 3217 * When the compiler is producing dwarf debug info it 3218 * uses stabs for debug notes. And the N_OSO stabs in this 3219 * case has a n_desc field of 1. If the name is the empty 3220 * string (not NULL but a 1 character string with just a 3221 * '\0') then change the name to the full path of the 3222 * object file. If the name is not an empty string it is 3223 * left unchanged. 3224 */ 3225 if(n_desc == 1){ 3226 if(symbol_name != NULL && *symbol_name == '\0'){ 3227 if(obj->resolved_path == NULL) 3228 set_obj_resolved_path(obj); 3229 *output_strlen = cur_obj->resolved_path_len; 3230 } 3231 else{ 3232 *output_strlen = strlen(symbol_name); 3233 } 3234 } 3235 /* 3236 * When the compiler is producing stabs debug info it will 3237 * produce an N_OSO stab with an n_desc field of 0. In this 3238 * (saving all stabs an -Sp is not specified) the name gets 3239 * reset to "" (that a one character string with only a '\0' 3240 * character). Unless the input n_un.n_strx field is 0 then 3241 * it will end up as 0 in the output. 3242 */ 3243 else if(n_desc == 0){ 3244 *output_strlen = 0; 3245 } 3246 /* 3247 * If the n_desc field of this N_OSO stab is something 3248 * other than 1 or 0 leave the name unchanged. 3249 */ 3250 else{ 3251 *output_strlen = strlen(symbol_name); 3252 } 3253 } 3254 else{ 3255 *output_strlen = strlen(symbol_name); 3256 } 3257 return(TRUE); 3258 case STRIP_ALL: 3259 case STRIP_DYNAMIC_EXECUTABLE: 3260 case STRIP_NONGLOBALS: 3261 return(FALSE); 3262 case STRIP_DEBUG: 3263 if(n_type & N_STAB || 3264 (*symbol_name == 'L' && (n_type & N_STAB) == 0) || 3265 (save_reloc == FALSE && 3266 (n_type & N_TYPE) == N_SECT && 3267 (obj->section_maps[n_sect - 1].s->flags & 3268 S_ATTR_STRIP_STATIC_SYMS) == S_ATTR_STRIP_STATIC_SYMS)) 3269 return(FALSE); 3270 else{ 3271 *output_strlen = strlen(symbol_name); 3272 return(TRUE); 3273 } 3274 case STRIP_MIN_DEBUG: 3275#ifndef RLD 3276 if(n_type & N_STAB){ 3277 switch(n_type){ 3278 case N_OSO: 3279 /* 3280 * When the compiler is producing dwarf debug info it 3281 * uses stabs for debug notes. And the N_OSO stabs in 3282 * this case has a n_desc field of 1. If the name is 3283 * the empty string (not NULL but a 1 character string 3284 * with just a '\0') then change the name to the full 3285 * path of the object file. If the name is not an empty 3286 * string it is left unchanged. 3287 */ 3288 if(n_desc == 1){ 3289 if(symbol_name != NULL && *symbol_name == '\0'){ 3290 if(obj->resolved_path == NULL) 3291 set_obj_resolved_path(obj); 3292 *output_strlen = cur_obj->resolved_path_len; 3293 } 3294 else{ 3295 *output_strlen = strlen(symbol_name); 3296 } 3297 } 3298 /* 3299 * When the compiler is producing stabs debug info it 3300 * will produce an N_OSO stab with an n_desc field of 0. 3301 * In this case where -Sp is specified name is changed 3302 * to the full path of the object file. 3303 */ 3304 else if(n_desc == 0){ 3305 if(obj->resolved_path == NULL) 3306 set_obj_resolved_path(obj); 3307 *output_strlen = cur_obj->resolved_path_len; 3308 } 3309 /* 3310 * If the n_desc is not 0 or 1 then leave the name 3311 * unchanged. 3312 */ 3313 else{ 3314 *output_strlen = strlen(symbol_name); 3315 } 3316 return(TRUE); 3317 /* keep these and their full strings */ 3318 case N_SO: 3319 case N_SOL: 3320 case N_OPT: 3321 *output_strlen = strlen(symbol_name); 3322 return(TRUE); 3323 /* keep these but truncate the string to just NAME:<type> */ 3324 case N_LCSYM: 3325 case N_STSYM: 3326 case N_GSYM: 3327 case N_FUN: 3328 end = find_stab_type_end( 3329 find_stab_name_end(symbol_name)); 3330 if(end != NULL) 3331 *output_strlen = end - symbol_name; 3332 else 3333 /* 3334 * The string is not what is expected just leave 3335 * the output_strlen the size of whole string. 3336 */ 3337 *output_strlen = strlen(symbol_name); 3338 return(TRUE); 3339 /* strip all other stabs */ 3340 default: 3341 return(FALSE); 3342 } 3343 } 3344 /* it's not a stab see if we still keep it or not */ 3345 else if(*symbol_name == 'L' || 3346 (save_reloc == FALSE && 3347 (n_type & N_TYPE) == N_SECT && 3348 (obj->section_maps[n_sect - 1].s->flags & 3349 S_ATTR_STRIP_STATIC_SYMS) == S_ATTR_STRIP_STATIC_SYMS)) 3350 return(FALSE); 3351 else{ 3352 *output_strlen = strlen(symbol_name); 3353 return(TRUE); 3354 } 3355#endif /* !defined(RLD) */ 3356 case STRIP_L_SYMBOLS: 3357 if(*symbol_name == 'L' && (n_type & N_STAB) == 0) 3358 return(FALSE); 3359 else{ 3360 *output_strlen = strlen(symbol_name); 3361 return(TRUE); 3362 } 3363 } 3364 /* never gets here but shuts up a bug in -Wall */ 3365 *output_strlen = strlen(symbol_name); 3366 return(TRUE); 3367} 3368 3369/* 3370 * is_type_stab() is passed the n_type and the name of a symbol. It that is a 3371 * type stab returns TRUE else it returns FALSE. A type stab is an L_LSYM stab 3372 * of the form: 3373 * NAME:<type> 3374 * where <type> is a 'T' or 't'. 3375 */ 3376static 3377enum bool 3378is_type_stab( 3379unsigned char n_type, 3380char *symbol_name) 3381#ifdef RLD 3382{ 3383 return(FALSE); 3384} 3385#else /* !defined(RLD) */ 3386{ 3387 char *end; 3388 3389 if((n_type & N_STAB) == 0 || n_type != N_LSYM) 3390 return(FALSE); 3391 end = find_stab_name_end(symbol_name); 3392 if(end != NULL && end[1] != '\0' && (end[1] == 'T' || end[1] == 't')) 3393 return(TRUE); 3394 else 3395 return(FALSE); 3396} 3397 3398/* 3399 * find_stab_name_end() parses a stab string of the form: 3400 * NAME:<type><index> 3401 * And returns a pointer to the ':' if there is one or NULL. This is the same 3402 * way gdb(1) parses this. 3403 * 3404 * The NAME part is either a C or C++ variable/function name, or an ObjC method 3405 * name. The latter makes looking for the : a little tricky, since it can also 3406 * contain ":"'s... 3407 * The <type> field is one or more characters in the set [a-zA-Z]. 3408 * But gdb only allows any single character or the pair "Tt". 3409 * The <index> field is either an integer (positive or negative) or a comma 3410 * delimited pair of integers in parenthesis: "(<INT>,<INT>)". 3411 */ 3412static 3413char * 3414find_stab_name_end( 3415char *name) 3416{ 3417 char *first_colon, *next_colon, *s, *first_lbrac, *first_rbrac; 3418 3419 for(first_colon = strchr(name, ':'); 3420 first_colon != NULL && 3421 first_colon[1] == ':' && first_colon[2] != '\0'; 3422 /* no increment expression */){ 3423 3424 /* Check for blah::blah in a C++ name */ 3425 next_colon = strchr(&first_colon[2], ':'); 3426 if(next_colon != NULL) 3427 first_colon = next_colon; 3428 else 3429 break; 3430 } 3431 3432 if(first_colon == NULL) 3433 return(NULL); 3434 /* 3435 * It's tempting to use strchr to look for the leftmost lbrac but that 3436 * would mean scanning the whole stab string, which can be quite long. 3437 * Since we only care whether there is a left square bracket BEFORE the 3438 * first colon, restrict the search to that. 3439 */ 3440 first_lbrac = NULL; 3441 for(s = name; s < first_colon; s++){ 3442 if(*s == '['){ 3443 first_lbrac = s; 3444 break; 3445 } 3446 } 3447 if(first_lbrac == NULL || 3448 (first_lbrac == name || 3449 (first_lbrac[-1] != '-' && first_lbrac[-1] != '+'))){ 3450 return first_colon; 3451 } 3452 else{ 3453 first_rbrac = strchr(name, ']'); 3454 /* If their is no rbrac then it is really an "invalid" symbol name. 3455 so in this case just return NULL saying we could not find the 3456 colon at the end of the name. */ 3457 if(first_rbrac == NULL) 3458 return(NULL); 3459 return(strchr(first_rbrac, ':')); 3460 } 3461} 3462 3463/* 3464 * find_stab_type_end() is passed what find_stab_name_end() above returns and 3465 * then parses past the <type> in: 3466 * NAME:<type><index> 3467 * and returns a pointer to past the type or NULL. (see above in the comments 3468 * for find_stab_name_end() for more details). 3469 * 3470 * The <type> field is one or more characters in the set [a-zA-Z]. 3471 * But gdb only allows any single character or the pair "Tt". 3472 * So that is what is parsed here. 3473 */ 3474static 3475char * 3476find_stab_type_end( 3477char *name_end) 3478{ 3479 if(name_end == NULL || name_end[0] != ':') 3480 return(NULL); 3481 if(!isalpha(name_end[1])) 3482 return(NULL); 3483 if(name_end[1] == 'T' && name_end[2] == 't') 3484 return(name_end + 3); 3485 else 3486 return(name_end + 2); 3487} 3488#endif /* !defined(RLD) */ 3489 3490/* 3491 * lookup_symbol() returns a pointer to a merged_symbol struct for the symbol 3492 * name passed to it. Either the symbol is found in which case the struct 3493 * pointed to has a non-zero name_len field. If the symbol is not found the 3494 * struct pointed to is used by enter_symbol() to enter the symbol. This 3495 * is the routine that actually allocates the merged_symbol structs as part of 3496 * the merged_symbol_chunk structs. And it allocates the first of the 3497 * merged_symbol_list structs hang off the merged_symbol_root. 3498 */ 3499__private_extern__ 3500struct merged_symbol * 3501lookup_symbol( 3502char *symbol_name) 3503{ 3504 struct merged_symbol_chunk *p, *q; 3505 struct merged_symbol *sym; 3506 unsigned long hash_index, i, name_len; 3507 3508 hash_index = hash_string(symbol_name, &name_len) % 3509 SYMBOL_LIST_HASH_SIZE; 3510 if(merged_symbol_root == NULL){ 3511 merged_symbol_root = allocate(sizeof(struct merged_symbol_root)); 3512 memset(merged_symbol_root, 0, sizeof(struct merged_symbol_root)); 3513 merged_symbol_root->list = 3514 allocate(sizeof(struct merged_symbol_list)); 3515 memset(merged_symbol_root->list, 0, 3516 sizeof(struct merged_symbol_list)); 3517 merged_symbol_root->list->used = 0; 3518 merged_symbol_root->list->next = NULL; 3519 return(&merged_symbol_root->chunks[hash_index].symbols[0]); 3520 } 3521 q = NULL; 3522 for(p = &merged_symbol_root->chunks[hash_index]; p != NULL;p = p->next){ 3523 for(i = 0; i < SYMBOL_CHUNK_SIZE; i++){ 3524 sym = &p->symbols[i]; 3525 if(sym->name_len == 0){ 3526 return(sym); 3527 } 3528 if(sym->name_len == name_len && 3529 strcmp(sym->nlist.n_un.n_name, symbol_name) == 0){ 3530 return(sym); 3531 } 3532 } 3533 q = p; 3534 } 3535 q->next = allocate(sizeof(struct merged_symbol_chunk)); 3536 memset(q->next, 0, sizeof(struct merged_symbol_chunk)); 3537 return(&q->next->symbols[0]); 3538} 3539 3540#ifndef RLD 3541/* 3542 * hash_instrument() is called when -hash_instrument is specified and prints out 3543 * the info about the hash table and the merged symbols lists. 3544 */ 3545__private_extern__ 3546void 3547hash_instrument(void) 3548{ 3549 struct merged_symbol_list *merged_symbol_list; 3550 struct merged_symbol_chunk *p; 3551 unsigned long n, u, i, j, h, b, c, t; 3552 3553 n = 0; 3554 u = 0; 3555 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 3556 merged_symbol_root->list; 3557 merged_symbol_list != NULL; 3558 merged_symbol_list = merged_symbol_list->next){ 3559 u += merged_symbol_list->used; 3560 n++; 3561 } 3562 print("Number of merged_symbol_lists = %lu (containing %d pointers " 3563 "each)\n", n, SYMBOL_LIST_HASH_SIZE); 3564 print("sizeof(struct merged_symbol_list) is %lu (total %lu)\n", 3565 sizeof(struct merged_symbol_list), 3566 n * sizeof(struct merged_symbol_list)); 3567 print("Number of used pointers in the lists = %lu (%.2f%%)\n", 3568 u, ((double)u) / ((double)(SYMBOL_LIST_HASH_SIZE * n)) * 3569 100.0); 3570 3571 h = 0; 3572 b = 0; 3573 c = 0; 3574 for(i = 0; i < SYMBOL_LIST_HASH_SIZE; i++){ 3575 if(merged_symbol_root->chunks[i].symbols[0].name_len != 0) 3576 h++; 3577 for(p = &merged_symbol_root->chunks[i]; 3578 p != NULL; 3579 p = p->next){ 3580 if(p != &merged_symbol_root->chunks[i]) 3581 c++; 3582 for(j = 0; j < SYMBOL_CHUNK_SIZE; j++){ 3583 if(p->symbols[j].name_len != 0) 3584 b++; 3585 } 3586 } 3587 } 3588 print("The SYMBOL_LIST_HASH_SIZE is %d\n", SYMBOL_LIST_HASH_SIZE); 3589 print("sizeof(struct merged_symbol_root) is %lu\n", 3590 sizeof(struct merged_symbol_root)); 3591 print("Number of additional chunks: %lu (size of these %lu)\n", c, 3592 c * sizeof(struct merged_symbol_chunk)); 3593 print("Number of hash entries used: %lu (%.2f%%) average #buckets " 3594 "%.2f\n", h, ((double)h)/ ((double)SYMBOL_LIST_HASH_SIZE) * 100.0, 3595 ((double)b) / ((double)h) ); 3596 t = SYMBOL_LIST_HASH_SIZE * SYMBOL_CHUNK_SIZE + c * SYMBOL_CHUNK_SIZE; 3597 print("Number of buckets (merged symbols) used: %lu out of %lu " 3598 "(%.2f%%)\n", b, t, ((double)b)/ ((double)t) * 100.0); 3599 3600 /* print_symbol_list("from hash_instrument()", FALSE); */ 3601} 3602#endif /* !defined(RLD) */ 3603 3604/* 3605 * add_to_symbol_list() adds the passed merged_symbol to our linked list of 3606 * symbols that complements our hash table lookups. 3607 */ 3608static 3609void 3610add_to_symbol_list( 3611struct merged_symbol *merged_symbol) 3612{ 3613 struct merged_symbol_list *prev, *merged_symbol_list, *new; 3614 3615 prev = NULL; 3616 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 3617 merged_symbol_root->list; 3618 merged_symbol_list != NULL; 3619 merged_symbol_list = merged_symbol_list->next){ 3620 if(merged_symbol_list->used != SYMBOL_LIST_HASH_SIZE){ 3621 merged_symbol_list->symbols[merged_symbol_list->used] = 3622 merged_symbol; 3623 merged_symbol_list->used += 1; 3624 return; 3625 } 3626 prev = merged_symbol_list; 3627 } 3628 new = allocate(sizeof(struct merged_symbol_list)); 3629 prev->next = new; 3630 memset(new, '\0', sizeof(struct merged_symbol_list)); 3631 new->symbols[0] = merged_symbol; 3632 new->used = 1; 3633 new->next = NULL; 3634} 3635 3636/* 3637 * enter_symbol() enters the object_symbol passed to it in the merged symbol. 3638 * The object's string table and defintion object are also passed in. The 3639 * hash_pointer points to an unused merged_symbol to fill in as previously 3640 * returned by lookup_symbol(). 3641 */ 3642static 3643struct merged_symbol * 3644enter_symbol( 3645struct merged_symbol *hash_pointer, 3646struct nlist *object_symbol, 3647char *object_strings, 3648struct object_file *definition_object) 3649{ 3650 struct merged_symbol *merged_symbol; 3651 3652 if((cur_obj != base_obj || strip_base_symbols == FALSE)) 3653 nmerged_symbols++; 3654 3655 merged_symbol = hash_pointer; 3656 memset(merged_symbol, '\0', sizeof(struct merged_symbol)); 3657 merged_symbol->nlist = *object_symbol; 3658#ifdef RLD 3659 if(cur_obj == base_obj && base_name == NULL) 3660 merged_symbol->nlist.n_un.n_name = object_strings + 3661 object_symbol->n_un.n_strx; 3662 else 3663#endif 3664 merged_symbol->nlist.n_un.n_name = enter_string(object_strings + 3665 object_symbol->n_un.n_strx, 3666 &merged_symbol->name_len); 3667 merged_symbol->definition_object = definition_object; 3668 add_to_symbol_list(merged_symbol); 3669 3670 if(object_symbol->n_type == (N_UNDF | N_EXT) && 3671 object_symbol->n_value == 0) 3672 add_to_undefined_list(merged_symbol); 3673 merged_symbol->undef_order = undef_order++; 3674 3675 if(object_symbol->n_type == (N_INDR | N_EXT)) 3676 enter_indr_symbol(merged_symbol, object_symbol, object_strings, 3677 definition_object); 3678 3679 return(merged_symbol); 3680} 3681 3682/* 3683 * enter_indr_symbol() enters the indirect symbol for the object_symbol passed 3684 * to it into the merged_symbol passed to it. 3685 */ 3686static 3687void 3688enter_indr_symbol( 3689struct merged_symbol *merged_symbol, 3690struct nlist *object_symbol, 3691char *object_strings, 3692struct object_file *definition_object) 3693{ 3694 struct merged_symbol *hash_pointer, *indr_symbol; 3695 3696 nindr_symbols++; 3697 hash_pointer = lookup_symbol(object_strings + object_symbol->n_value); 3698 if(hash_pointer->name_len != 0){ 3699 indr_symbol = hash_pointer; 3700 } 3701 else{ 3702 indr_symbol = hash_pointer; 3703 add_to_symbol_list(indr_symbol); 3704 if(cur_obj != base_obj || strip_base_symbols == FALSE) 3705 nmerged_symbols++; 3706 indr_symbol->nlist.n_type = N_UNDF | N_EXT; 3707 indr_symbol->nlist.n_sect = NO_SECT; 3708 if(definition_object != NULL && 3709 definition_object->dylib_module != NULL) 3710 indr_symbol->nlist.n_desc = REFERENCE_FLAG_UNDEFINED_LAZY; 3711 else 3712 indr_symbol->nlist.n_desc = 0; 3713 indr_symbol->nlist.n_value = 0; 3714#ifdef RLD 3715 if(cur_obj == base_obj && base_name == NULL) 3716 indr_symbol->nlist.n_un.n_name = object_strings + 3717 object_symbol->n_value; 3718 else 3719#endif 3720 indr_symbol->nlist.n_un.n_name = enter_string(object_strings + 3721 object_symbol->n_value, 3722 NULL); 3723 indr_symbol->definition_object = definition_object; 3724 add_to_undefined_list(indr_symbol); 3725 } 3726 merged_symbol->nlist.n_value = (unsigned long)indr_symbol; 3727} 3728/* 3729 * enter_string() places the symbol_name passed to it in the first string block 3730 * that will hold the string. Since the string indexes will be assigned after 3731 * all the strings are entered putting the strings in the first block that fits 3732 * can be done rather than only last block. 3733 */ 3734static 3735char * 3736enter_string( 3737char *symbol_name, 3738unsigned long *len_ret) 3739{ 3740 struct string_block **p, *string_block; 3741 unsigned long len; 3742 char *r; 3743 3744 len = strlen(symbol_name) + 1; 3745 if(len_ret != NULL) 3746 *len_ret = len - 1; 3747 for(p = &(merged_string_blocks); *p; p = &(string_block->next)){ 3748 string_block = *p; 3749 if(len > string_block->size - string_block->used) 3750 continue; 3751#ifdef RLD 3752 if(string_block->set_num != cur_set) 3753 continue; 3754#endif /* RLD */ 3755 if(strip_base_symbols == TRUE && 3756 ((cur_obj == base_obj && string_block->base_strings == FALSE) || 3757 (cur_obj != base_obj && string_block->base_strings == TRUE) ) ) 3758 continue; 3759 3760 if((cur_obj != NULL && cur_obj->dylib_module != NULL && 3761 string_block->dylib_strings == FALSE) || 3762 ((cur_obj == NULL || cur_obj->dylib_module == NULL) && 3763 string_block->dylib_strings == TRUE)) 3764 continue; 3765 3766 r = strcpy(string_block->strings + string_block->used, symbol_name); 3767 string_block->used += len; 3768 if((strip_base_symbols == FALSE || 3769 string_block->base_strings == FALSE) && 3770 string_block->dylib_strings == FALSE) 3771 merged_string_size += len; 3772 return(r); 3773 } 3774 *p = allocate(sizeof(struct string_block)); 3775 string_block = *p; 3776 string_block->size = (len > host_pagesize ? len : host_pagesize); 3777 string_block->used = len; 3778 string_block->next = NULL; 3779 string_block->strings = allocate(string_block->size); 3780 string_block->base_strings = cur_obj == base_obj ? TRUE : FALSE; 3781 if(cur_obj != NULL && cur_obj->dylib_module != NULL) 3782 string_block->dylib_strings = TRUE; 3783 else 3784 string_block->dylib_strings = FALSE; 3785#ifdef RLD 3786 string_block->set_num = cur_set; 3787#endif /* RLD */ 3788 r = strcpy(string_block->strings, symbol_name); 3789 if((strip_base_symbols == FALSE || 3790 string_block->base_strings == FALSE) && 3791 string_block->dylib_strings == FALSE) 3792 merged_string_size += len; 3793 return(r); 3794} 3795 3796/* 3797 * add_to_undefined_list() adds a pointer to a merged symbol to the list of 3798 * undefined symbols. 3799 */ 3800static 3801void 3802add_to_undefined_list( 3803struct merged_symbol *merged_symbol) 3804{ 3805 struct undefined_block **p; 3806 struct undefined_list *new, *undefineds; 3807 unsigned long i; 3808 3809 if(free_list.next == &free_list){ 3810 for(p = &(undefined_blocks); *p; p = &((*p)->next)) 3811 ; 3812 *p = allocate(sizeof(struct undefined_block)); 3813 (*p)->next = 0; 3814 undefineds = (*p)->undefineds; 3815 3816 /* add the newly allocated items to the empty free_list */ 3817 free_list.next = &undefineds[0]; 3818 undefineds[0].prev = &free_list; 3819 undefineds[0].next = &undefineds[1]; 3820 for(i = 1 ; i < NUNDEF_BLOCKS - 1 ; i++){ 3821 undefineds[i].prev = &undefineds[i-1]; 3822 undefineds[i].next = &undefineds[i+1]; 3823 undefineds[i].merged_symbol = NULL; 3824 } 3825 free_list.prev = &undefineds[i]; 3826 undefineds[i].prev = &undefineds[i-1]; 3827 undefineds[i].next = &free_list; 3828 } 3829 /* take the first one off the free list */ 3830 new = free_list.next; 3831 new->next->prev = &free_list; 3832 free_list.next = new->next; 3833 3834 /* fill in the pointer to the undefined symbol */ 3835 new->merged_symbol = merged_symbol; 3836 3837 /* put this at the end of the undefined list */ 3838 new->prev = undefined_list.prev; 3839 new->next = &undefined_list; 3840 undefined_list.prev->next = new; 3841 undefined_list.prev = new; 3842} 3843 3844/* 3845 * delete_from_undefined_list() is used by pass1() after a member is loaded from 3846 * an archive that satisifies an undefined symbol. It is also called from 3847 * pass1() when it comes across a symbol on the undefined list that is no longer 3848 * undefined. 3849 */ 3850__private_extern__ 3851void 3852delete_from_undefined_list( 3853struct undefined_list *undefined) 3854{ 3855 /* take this out of the list */ 3856 undefined->prev->next = undefined->next; 3857 undefined->next->prev = undefined->prev; 3858 3859 /* put this at the end of the free list */ 3860 undefined->prev = free_list.prev; 3861 undefined->next = &free_list; 3862 free_list.prev->next = undefined; 3863 free_list.prev = undefined; 3864 undefined->merged_symbol = NULL; 3865} 3866 3867/* 3868 * multiply_defined() prints and traces the multiply defined symbol if it hasn't 3869 * been printed yet. It's slow with it linear searches and a reallocate() call 3870 * but this usually is an error case. 3871 */ 3872static 3873void 3874multiply_defined( 3875struct merged_symbol *merged_symbol, 3876struct nlist *object_symbol, 3877char *object_strings) 3878{ 3879 unsigned long i, j; 3880 3881 if(allow_multiply_defined_symbols == TRUE && nowarnings == TRUE) 3882 return; 3883 3884 for(i = 0; i < nmultiple_defs; i++){ 3885 if(strcmp(multiple_defs[i], merged_symbol->nlist.n_un.n_name) == 0) 3886 break; 3887 } 3888 for(j = 0; j < ntrace_syms; j++){ 3889 if(strcmp(trace_syms[j], merged_symbol->nlist.n_un.n_name) == 0) 3890 break; 3891 } 3892 if(i == nmultiple_defs){ 3893 if(allow_multiply_defined_symbols == TRUE) 3894 warning("multiple definitions of symbol %s", 3895 merged_symbol->nlist.n_un.n_name); 3896 else{ 3897 error("multiple definitions of symbol %s", 3898 merged_symbol->nlist.n_un.n_name); 3899 } 3900 multiple_defs = reallocate(multiple_defs, 3901 (nmultiple_defs + 1) * sizeof(char *)); 3902 multiple_defs[nmultiple_defs++] = merged_symbol->nlist.n_un.n_name; 3903 if(j == ntrace_syms) 3904 trace_merged_symbol(merged_symbol); 3905 } 3906 if(j == ntrace_syms) 3907 trace_object_symbol(object_symbol, object_strings); 3908} 3909 3910/* 3911 * trace_object_symbol() traces a symbol that comes from an object file. 3912 */ 3913static 3914void 3915trace_object_symbol( 3916struct nlist *symbol, 3917char *strings) 3918{ 3919 char *indr_symbol_name; 3920 3921 if(symbol->n_type == (N_INDR | N_EXT)) 3922 indr_symbol_name = strings + symbol->n_value; 3923 else 3924 indr_symbol_name = "error in trace_symbol()"; 3925 trace_symbol(strings + symbol->n_un.n_strx, symbol, cur_obj, 3926 indr_symbol_name); 3927} 3928 3929/* 3930 * trace_merged_symbol() traces a symbol that is in the merged symbol table. 3931 */ 3932__private_extern__ 3933void 3934trace_merged_symbol( 3935struct merged_symbol *merged_symbol) 3936{ 3937 char *indr_symbol_name; 3938 3939 if(merged_symbol->nlist.n_type == (N_INDR | N_EXT)) 3940 indr_symbol_name = ((struct merged_symbol *) 3941 (merged_symbol->nlist.n_value))->nlist.n_un.n_name; 3942 else 3943 indr_symbol_name = "error in trace_symbol()"; 3944 trace_symbol(merged_symbol->nlist.n_un.n_name, &(merged_symbol->nlist), 3945 merged_symbol->definition_object, indr_symbol_name); 3946} 3947 3948/* 3949 * trace_symbol() is the routine that really does the work of printing the 3950 * symbol its type and the file it is in. 3951 */ 3952static 3953void 3954trace_symbol( 3955char *symbol_name, 3956struct nlist *nlist, 3957struct object_file *object_file, 3958char *indr_symbol_name) 3959{ 3960 print_obj_name(object_file); 3961 if(nlist->n_type & N_PEXT) 3962 print("private external "); 3963 switch(nlist->n_type & N_TYPE){ 3964 case N_UNDF: 3965 if(nlist->n_value == 0) 3966 print("%sreference to undefined %s\n", 3967 nlist->n_desc & N_WEAK_REF ? "weak " : "", symbol_name); 3968 else 3969 print("definition of common %s (size %u)\n", symbol_name, 3970 nlist->n_value); 3971 break; 3972 case N_PBUD: 3973 print("%sdefinition of %s\n", 3974 nlist->n_desc & N_WEAK_DEF ? "weak " : "", symbol_name); 3975 break; 3976 case N_ABS: 3977 print("definition of absolute %s (value 0x%x)\n", symbol_name, 3978 (unsigned int)(nlist->n_value)); 3979 break; 3980 case N_SECT: 3981 print("%sdefinition of %s in section (%.16s,%.16s)\n", 3982 nlist->n_desc & N_WEAK_DEF ? "weak " : "", symbol_name, 3983 object_file->section_maps[nlist->n_sect - 1].s->segname, 3984 object_file->section_maps[nlist->n_sect - 1].s->sectname); 3985 break; 3986 case N_INDR: 3987 print("definition of %s as indirect for %s\n", symbol_name, 3988 indr_symbol_name); 3989 break; 3990 default: 3991 print("unknown type (0x%x) of %s\n", (unsigned int)nlist->n_type, 3992 symbol_name); 3993 break; 3994 } 3995} 3996 3997#ifndef RLD 3998/* 3999 * free_pass1_symbol_data() free()'s all symbol data only used in pass1(). 4000 */ 4001__private_extern__ 4002void 4003free_pass1_symbol_data(void) 4004{ 4005 free_undefined_list(); 4006} 4007#endif /* !defined(RLD) */ 4008 4009/* 4010 * free_undefined_list() free's up the memory for the undefined list. 4011 */ 4012__private_extern__ 4013void 4014free_undefined_list(void) 4015{ 4016 struct undefined_block *up, *undefined_block; 4017 /* 4018 * Free the undefined list 4019 */ 4020 for(up = undefined_blocks; up; ){ 4021 undefined_block = up->next; 4022 free(up); 4023 up = undefined_block; 4024 } 4025 undefined_blocks = NULL; 4026 undefined_list.next = &undefined_list; 4027 undefined_list.prev = &undefined_list; 4028 free_list.next = &free_list; 4029 free_list.prev = &free_list; 4030} 4031 4032/* 4033 * define_common_symbols() defines common symbols if there are any in the merged 4034 * symbol table. The symbols are defined in the link editor reserved zero-fill 4035 * section (__DATA,__common) and the segment and section are created if needed. 4036 * The section is looked up to see it there is a section specification for it 4037 * and if so the same processing as in process_section_specs() is done here. 4038 * If there is a spec it uses the alignment if it is greater than the merged 4039 * alignment and warns if it is less. Also it checks to make sure that no 4040 * section is to be created from a file for this reserved section. 4041 */ 4042__private_extern__ 4043void 4044define_common_symbols(void) 4045{ 4046 struct section_spec *sect_spec; 4047 struct merged_section *ms; 4048 struct section *s; 4049 4050 unsigned long i, j, common_size, align; 4051 struct merged_symbol_list *merged_symbol_list; 4052 struct merged_symbol *merged_symbol; 4053 struct common_symbol *common_symbol; 4054 4055 struct object_list *object_list, **q; 4056 struct object_file *object_file; 4057 4058 struct nlist *common_nlist; 4059 char *common_names; 4060 unsigned long n_strx; 4061#ifndef RLD 4062 struct mach_header *link_edit_common_object_mach_header; 4063#endif 4064 4065#if defined(DEBUG) || defined(RLD) 4066 /* 4067 * The compiler warning that these symbols may be used uninitialized 4068 * in this function can safely be ignored. 4069 */ 4070 common_symbol = NULL; 4071 common_nlist = NULL; 4072 common_names = NULL;; 4073 n_strx = 0; 4074#endif 4075 4076#ifdef RLD 4077 *(sets[cur_set].link_edit_common_object) = 4078 link_edit_common_object; 4079 sets[cur_set].link_edit_common_object->set_num = 4080 cur_set; 4081 sets[cur_set].link_edit_common_object->section_maps = 4082 sets[cur_set].link_edit_section_maps; 4083 *(sets[cur_set].link_edit_section_maps) = 4084 link_edit_section_maps; 4085 sets[cur_set].link_edit_section_maps->s = 4086 sets[cur_set].link_edit_common_section; 4087 *(sets[cur_set].link_edit_common_section) = 4088 link_edit_common_section; 4089#endif /* RLD */ 4090 4091#ifndef RLD 4092 /* see if there is a section spec for (__DATA,__common) */ 4093 sect_spec = lookup_section_spec(SEG_DATA, SECT_COMMON); 4094 if(sect_spec != NULL){ 4095 if(sect_spec->contents_filename != NULL){ 4096 error("section (" SEG_DATA "," SECT_COMMON ") reserved for " 4097 "allocating common symbols and can't be created from the " 4098 "file: %s", sect_spec->contents_filename); 4099 return; 4100 } 4101 sect_spec->processed = TRUE; 4102 } 4103#else 4104 sect_spec = NULL; 4105#endif /* !defined(RLD) */ 4106 4107 /* see if there is a merged section for (__DATA,__common) */ 4108 ms = lookup_merged_section(SEG_DATA, SECT_COMMON); 4109 if(ms != NULL && (ms->s.flags & SECTION_TYPE) != S_ZEROFILL){ 4110 error("section (" SEG_DATA "," SECT_COMMON ") reserved for " 4111 "allocating common symbols and exists in the loaded " 4112 "objects not as a zero fill section"); 4113 /* 4114 * Loop through all the objects and report those that have this 4115 * section and then return. 4116 */ 4117 for(q = &objects; *q; q = &(object_list->next)){ 4118 object_list = *q; 4119 for(i = 0; i < object_list->used; i++){ 4120 object_file = &(object_list->object_files[i]); 4121 if(object_file->dylib) 4122 continue; 4123 if(object_file->bundle_loader) 4124 continue; 4125 if(object_file->dylinker) 4126 continue; 4127 for(j = 0; j < object_file->nsection_maps; j++){ 4128 s = object_file->section_maps[j].s; 4129 if(strcmp(s->segname, SEG_DATA) == 0 && 4130 strcmp(s->sectname, SECT_COMMON) == 0){ 4131 print_obj_name(object_file); 4132 print("contains section (" SEG_DATA "," 4133 SECT_COMMON ")\n"); 4134 } 4135 } 4136 } 4137 } 4138 return; 4139 } 4140#ifndef RLD 4141 else{ 4142 /* 4143 * This needs to be done here on the chance there is a common 4144 * section but no commons get defined. This is also done below 4145 * if the common section is created. 4146 */ 4147 if(sect_spec != NULL && sect_spec->order_filename != NULL && 4148 ms != NULL){ 4149 ms->order_filename = sect_spec->order_filename; 4150 ms->order_addr = sect_spec->order_addr; 4151 ms->order_size = sect_spec->order_size; 4152 } 4153 } 4154#endif /* !defined(RLD) */ 4155 4156 /* 4157 * Determine if there are any commons to be defined if not just return. 4158 * If a load map is requested then the number of commons to be defined 4159 * is determined so a common load map can be allocated. 4160 */ 4161 commons_exist = FALSE; 4162 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 4163 merged_symbol_root->list; 4164 merged_symbol_list != NULL; 4165 merged_symbol_list = merged_symbol_list->next){ 4166 for(i = 0; i < merged_symbol_list->used; i++){ 4167 merged_symbol = merged_symbol_list->symbols[i]; 4168 if((merged_symbol->nlist.n_type & N_EXT) == N_EXT && 4169 (merged_symbol->nlist.n_type & N_TYPE) == N_UNDF && 4170 merged_symbol->nlist.n_value != 0){ 4171 /* 4172 * If the output format is MH_FVMLIB then commons are not 4173 * allowed because it there address may not remain fixed 4174 * on sucessive link edits. Each one is traced below. 4175 */ 4176 if(filetype == MH_FVMLIB) 4177 error("common symbols not allowed with MH_FVMLIB " 4178 "output format"); 4179 /* 4180 * If the output format is multi module MH_DYLIB then * commons are not allowed because each symbol can only be 4181 * defined in at most one module. 4182 */ 4183 if(filetype == MH_DYLIB && multi_module_dylib == TRUE) 4184 error("common symbols not allowed with MH_DYLIB " 4185 "output format with the -multi_module option"); 4186 commons_exist = TRUE; 4187#ifndef RLD 4188 if((sect_spec != NULL && 4189 sect_spec->order_filename != NULL) || 4190 dead_strip == TRUE){ 4191 link_edit_common_symtab.nsyms++; 4192 link_edit_common_symtab.strsize += 4193 strlen(merged_symbol->nlist.n_un.n_name) + 1; 4194 } 4195 else if(load_map) 4196 common_load_map.ncommon_symbols++; 4197 else 4198#endif /* !defined(RLD) */ 4199 break; 4200 } 4201 } 4202 } 4203 if(commons_exist == FALSE) 4204 return; 4205 4206 /* 4207 * Now that the checks above have been done if commons are not to be 4208 * defined just return. If the output is for dyld then define common 4209 * symbols always as dyld does not define commons. 4210 */ 4211 if(define_comldsyms == FALSE && output_for_dyld == FALSE) 4212 return; 4213 4214 /* 4215 * Create the (__DATA,__common) section if needed and set the 4216 * alignment for it. 4217 */ 4218 if(ms == NULL){ 4219#ifdef RLD 4220 ms = create_merged_section(sets[cur_set].link_edit_common_section); 4221#else 4222 ms = create_merged_section(&link_edit_common_section); 4223#endif /* RLD */ 4224 if(sect_spec != NULL && sect_spec->align_specified) 4225 ms->s.align = sect_spec->align; 4226 else 4227 ms->s.align = defaultsectalign; 4228 if(sect_spec != NULL && sect_spec->order_filename != NULL){ 4229 ms->order_filename = sect_spec->order_filename; 4230 ms->order_addr = sect_spec->order_addr; 4231 ms->order_size = sect_spec->order_size; 4232 } 4233 } 4234 else{ 4235 if(sect_spec != NULL && sect_spec->align_specified){ 4236 if(ms->s.align > sect_spec->align) 4237 warning("specified alignment (0x%x) for section (" SEG_DATA 4238 "," SECT_COMMON ") not used (less than the " 4239 "required alignment in the input files (0x%x))", 4240 (unsigned int)(1 << sect_spec->align), 4241 (unsigned int)(1 << ms->s.align)); 4242 else 4243 ms->s.align = sect_spec->align; 4244 } 4245 if(ms->s.align < defaultsectalign) 4246 ms->s.align = defaultsectalign; 4247 } 4248 4249#ifndef RLD 4250 /* 4251 * If the common section has an order file then create a symbol table 4252 * and string table for it and the load map will be generated off of 4253 * these tables in layout_ordered_section() in sections.c. If not and 4254 * a load map is requested then set up the common load map. This is 4255 * used by print_load_map() in layout.c and the common_symbols allocated 4256 * here are free()'ed in there also. 4257 */ 4258 if((sect_spec != NULL && sect_spec->order_filename != NULL) || 4259 dead_strip == TRUE){ 4260 link_edit_common_symtab.strsize = 4261 rnd(link_edit_common_symtab.strsize, sizeof(long)); 4262 link_edit_common_object.obj_size = 4263 sizeof(struct mach_header) + 4264 link_edit_common_symtab.nsyms * sizeof(struct nlist) + 4265 link_edit_common_symtab.strsize; 4266 link_edit_common_object.obj_addr = 4267 allocate(link_edit_common_object.obj_size); 4268 memset(link_edit_common_object.obj_addr, 4269 '\0', 4270 link_edit_common_object.obj_size); 4271 link_edit_common_object_mach_header = (struct mach_header *) 4272 link_edit_common_object.obj_addr; 4273 link_edit_common_object_mach_header->magic = MH_MAGIC; 4274 link_edit_common_object_mach_header->filetype = MH_OBJECT; 4275 link_edit_common_object_mach_header->flags = 4276 MH_SUBSECTIONS_VIA_SYMBOLS; 4277 link_edit_common_symtab.symoff = sizeof(struct mach_header); 4278 link_edit_common_symtab.stroff = sizeof(struct mach_header) + 4279 link_edit_common_symtab.nsyms * 4280 sizeof(struct nlist); 4281 common_nlist = (struct nlist *)(link_edit_common_object.obj_addr + 4282 link_edit_common_symtab.symoff); 4283 common_names = (char *)(link_edit_common_object.obj_addr + 4284 link_edit_common_symtab.stroff); 4285 n_strx = 1; 4286 } 4287 else if(load_map){ 4288 common_load_map.common_ms = ms; 4289 common_load_map.common_symbols = allocate( 4290 common_load_map.ncommon_symbols * 4291 sizeof(struct common_symbol)); 4292 common_symbol = common_load_map.common_symbols; 4293 } 4294#endif /* !defined(RLD) */ 4295 4296 /* 4297 * Now define the commons. This is requires building a "link editor" 4298 * object file and changing these symbols to be defined in the (__DATA, 4299 * __common) section in that "file". By doing this in this way these 4300 * symbols are handled normally throught the rest of the link editor. 4301 * Also these symbols are trace as they are defined if they are to be 4302 * traced. 4303 */ 4304 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 4305 merged_symbol_root->list; 4306 merged_symbol_list != NULL; 4307 merged_symbol_list = merged_symbol_list->next){ 4308 for(i = 0; i < merged_symbol_list->used; i++){ 4309 merged_symbol = merged_symbol_list->symbols[i]; 4310 if((merged_symbol->nlist.n_type & N_EXT) == N_EXT && 4311 (merged_symbol->nlist.n_type & N_TYPE) == N_UNDF && 4312 merged_symbol->nlist.n_value != 0){ 4313 /* 4314 * Commons are not allowed with MH_FVMLIB or MH_DYLIB 4315 * formats so trace each one. An error message for this 4316 * has been printed above. 4317 */ 4318 if(filetype == MH_FVMLIB || 4319 (filetype == MH_DYLIB && multi_module_dylib == TRUE)) 4320 trace_merged_symbol(merged_symbol); 4321 /* determine the alignment of this symbol */ 4322 common_size = merged_symbol->nlist.n_value; 4323 align = 0; 4324 while((unsigned long)(1 << align) < common_size && 4325 align < ms->s.align) 4326 align++; 4327 /* round the address of the section to this alignment */ 4328#ifdef RLD 4329 sets[cur_set].link_edit_common_section->size = rnd( 4330 sets[cur_set].link_edit_common_section->size, 1<< align); 4331#else 4332 link_edit_common_section.size = rnd( 4333 link_edit_common_section.size, 1 << align); 4334#endif /* RLD */ 4335 /* 4336 * Change this symbol's type, section number, address and 4337 * object file it is defined in to be the (__DATA,__common) 4338 * of the "link editor" object file at the address for it. 4339 */ 4340 merged_symbol->nlist.n_type = N_SECT | N_EXT | 4341 (merged_symbol->nlist.n_type & N_PEXT); 4342 merged_symbol->nlist.n_sect = 1; 4343#ifdef RLD 4344 merged_symbol->nlist.n_value = 4345 sets[cur_set].link_edit_common_section->size; 4346 merged_symbol->definition_object = 4347 sets[cur_set].link_edit_common_object; 4348 /* Create the space for this symbol */ 4349 sets[cur_set].link_edit_common_section->size += common_size; 4350#else 4351 merged_symbol->nlist.n_value =link_edit_common_section.size; 4352 merged_symbol->definition_object = 4353 &link_edit_common_object; 4354 /* Create the space for this symbol */ 4355 link_edit_common_section.size += common_size; 4356 /* 4357 * If we have an -export_symbols_list or 4358 * -unexport_symbol_list option set the private extern bit 4359 * on the symbol if it is not to be exported. 4360 */ 4361 exports_list_processing(merged_symbol->nlist.n_un.n_name, 4362 &(merged_symbol->nlist)); 4363 /* 4364 * If this common symbol got made into a private extern with 4365 * the processing of the exports list increment the count of 4366 * private exterals. 4367 */ 4368 if((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT){ 4369 link_edit_common_object.nprivatesym++; 4370 nmerged_private_symbols++; 4371 } 4372#endif /* RLD */ 4373 /* 4374 * Do the trace of this symbol if specified now that it has 4375 * been defined. 4376 */ 4377 if(ntrace_syms != 0){ 4378 for(j = 0; j < ntrace_syms; j++){ 4379 if(strcmp(trace_syms[j], 4380 merged_symbol->nlist.n_un.n_name) == 0){ 4381 trace_merged_symbol(merged_symbol); 4382 break; 4383 } 4384 } 4385 } 4386#ifndef RLD 4387 /* 4388 * Set the entries in the common symbol table if the section 4389 * is to be ordered or in the load map if producing it 4390 */ 4391 if((sect_spec != NULL && 4392 sect_spec->order_filename != NULL) || 4393 dead_strip == TRUE){ 4394 common_nlist->n_un.n_strx = n_strx; 4395 common_nlist->n_type = N_SECT | N_EXT; 4396 common_nlist->n_sect = 1; 4397 common_nlist->n_desc = 0; 4398 common_nlist->n_value = merged_symbol->nlist.n_value; 4399 strcpy(common_names + n_strx, 4400 merged_symbol->nlist.n_un.n_name); 4401 common_nlist++; 4402 n_strx += strlen(merged_symbol->nlist.n_un.n_name) + 1; 4403 } 4404 else if(load_map){ 4405 common_symbol->merged_symbol = merged_symbol; 4406 common_symbol->common_size = common_size; 4407 common_symbol++; 4408 } 4409#endif /* !defined(RLD) */ 4410 } 4411 } 4412 } 4413 4414 /* 4415 * Now that this section in this "object file" is built merged it into 4416 * the merged section list (as would be done in merge_sections()). 4417 */ 4418#ifdef RLD 4419 sets[cur_set].link_edit_common_object->section_maps[0].output_section = 4420 ms; 4421 ms->s.size = rnd(ms->s.size, 1 << ms->s.align); 4422 sets[cur_set].link_edit_common_object->section_maps[0].offset = 4423 ms->s.size; 4424 ms->s.size += sets[cur_set].link_edit_common_section->size; 4425#else 4426 link_edit_common_object.section_maps[0].output_section = ms; 4427 ms->s.size = rnd(ms->s.size, 1 << ms->s.align); 4428 link_edit_common_object.section_maps[0].offset = ms->s.size; 4429 ms->s.size += link_edit_common_section.size; 4430#endif /* RLD */ 4431} 4432 4433#ifndef RLD 4434/* 4435 * define_undefined_symbols_a_way() is called to setup defining all remaining 4436 * undefined symbols as private externs. Their final value gets set by 4437 * define_link_editor_dylib_symbols(). 4438 */ 4439__private_extern__ 4440void 4441define_undefined_symbols_a_way( 4442void) 4443{ 4444 unsigned long i; 4445 struct merged_symbol_list *merged_symbol_list; 4446 struct merged_symbol *merged_symbol; 4447 4448 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 4449 merged_symbol_root->list; 4450 merged_symbol_list != NULL; 4451 merged_symbol_list = merged_symbol_list->next){ 4452 for(i = 0; i < merged_symbol_list->used; i++){ 4453 merged_symbol = merged_symbol_list->symbols[i]; 4454 if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) && 4455 merged_symbol->nlist.n_value == 0){ 4456 if(dynamic == TRUE && 4457 filetype != MH_EXECUTE && 4458 merged_segments != NULL){ 4459 define_link_editor_symbol( 4460 merged_symbol->nlist.n_un.n_name, 4461 N_SECT | N_PEXT | N_EXT, /* n_type */ 4462 1, /* n_sect */ 4463 0, /* n_desc */ 4464 0); /* n_value */ 4465 } 4466 else{ 4467 define_link_editor_symbol( 4468 merged_symbol->nlist.n_un.n_name, 4469 N_ABS | N_PEXT | N_EXT, /* n_type */ 4470 NO_SECT, /* n_sect */ 4471 0, /* n_desc */ 4472 0); /* n_value */ 4473 } 4474 /* 4475 * This symbol got made into a private extern so increment 4476 * the count of private exterals. 4477 */ 4478 if((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT){ 4479 link_edit_symbols_object->nprivatesym++; 4480 nmerged_private_symbols++; 4481 } 4482 merged_symbol->define_a_way = 1; 4483 } 4484 } 4485 } 4486} 4487 4488static 4489void 4490setup_link_edit_symbols_object( 4491void) 4492{ 4493 if(link_edit_symbols_object == NULL){ 4494 link_edit_symbols_object = new_object_file(); 4495 link_edit_symbols_object->file_name = "link editor"; 4496 } 4497} 4498 4499#ifndef RLD 4500/* 4501 * mark_globals_live() marks all merged symbol definitions which will be global 4502 * in the output (not private externs turned into statics) or symbols with the 4503 * N_NO_DEAD_STRIP bit, or symbols in sections with the S_ATTR_NO_DEAD_STRIP 4504 * section attribute live. And marks the fine_reloc (if any) for each live 4505 * symbol live. 4506 */ 4507__private_extern__ 4508void 4509mark_globals_live(void) 4510{ 4511 unsigned long i; 4512 struct merged_symbol_list *merged_symbol_list; 4513 struct merged_symbol *merged_symbol; 4514 enum bool only_referenced_dynamically; 4515 4516 /* 4517 * If the output is an MH_EXECUTE and there was no 4518 * -exported_symbols_list or -unexported_symbols_list only symbols that 4519 * are referenced dynamically are marked live and assumed to be 4520 * exported. For other outputs formats all global symbols are marked 4521 * live (note that when symbols were merged the were turned into private 4522 * externs if they were not to be exported). 4523 */ 4524 if(filetype == MH_EXECUTE && 4525 (save_symbols == NULL && remove_symbols == NULL)) 4526 only_referenced_dynamically = TRUE; 4527 else 4528 only_referenced_dynamically = FALSE; 4529 4530 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 4531 merged_symbol_root->list; 4532 merged_symbol_list != NULL; 4533 merged_symbol_list = merged_symbol_list->next){ 4534 for(i = 0; i < merged_symbol_list->used; i++){ 4535 merged_symbol = merged_symbol_list->symbols[i]; 4536 /* 4537 * If the symbol is marked REFERENCED_DYNAMICALLY or 4538 * N_NO_DEAD_STRIP or defined in a section with the attribute 4539 * S_ATTR_NO_DEAD_STRIP mark it live. Else it has to be 4540 * a defined exported symbol to be marked live. 4541 */ 4542 if((merged_symbol->nlist.n_desc & 4543 REFERENCED_DYNAMICALLY) == REFERENCED_DYNAMICALLY || 4544 4545 (merged_symbol->nlist.n_desc & 4546 N_NO_DEAD_STRIP) == N_NO_DEAD_STRIP || 4547 4548 (((merged_symbol->nlist.n_type & N_TYPE) == N_SECT) && 4549 (merged_symbol->definition_object-> 4550 section_maps[merged_symbol->nlist.n_sect - 1].s->flags & 4551 S_ATTR_NO_DEAD_STRIP) == S_ATTR_NO_DEAD_STRIP) ){ 4552 goto mark_it_live; 4553 } 4554 else{ 4555 /* 4556 * Skip symbols defined in dynamic libraries, undefined 4557 * symbols and private_extern symbols. 4558 */ 4559 if(merged_symbol->defined_in_dylib == TRUE) 4560 continue; 4561 if((merged_symbol->nlist.n_type == (N_EXT | N_UNDF) && 4562 merged_symbol->nlist.n_value == 0) || 4563 merged_symbol->nlist.n_type == (N_EXT | N_PBUD)) 4564 continue; 4565 if((merged_symbol->nlist.n_type & N_EXT) && 4566 (merged_symbol->nlist.n_type & N_PEXT)) 4567 continue; 4568 if(only_referenced_dynamically == TRUE) 4569 continue; 4570 } 4571#ifdef DEBUG 4572mark_it_live: 4573 if(((debug & (1 << 25)) || (debug & (1 << 26)))){ 4574 print("** In mark_globals_live() "); 4575 if(merged_symbol->nlist.n_desc & N_NO_DEAD_STRIP) 4576 print("no dead strip symbol "); 4577 else 4578 print("exported symbol "); 4579 print_obj_name(merged_symbol->definition_object); 4580 print("%s\n", merged_symbol->nlist.n_un.n_name); 4581 } 4582#endif /* DEBUG */ 4583 merged_symbol->live = TRUE; 4584 if(merged_symbol->fine_reloc != NULL) 4585 merged_symbol->fine_reloc->live = TRUE; 4586 } 4587 } 4588} 4589 4590/* 4591 * mark_N_NO_DEAD_STRIP_local_symbols_live() is called to cause the fine_relocs 4592 * for local symbols that have the N_NO_DEAD_STRIP bit set to be marked live. 4593 */ 4594__private_extern__ 4595void 4596mark_N_NO_DEAD_STRIP_local_symbols_live(void) 4597{ 4598 struct merged_segment *msg, **r; 4599 struct merged_section *ms, **content, **zerofill; 4600 4601 /* 4602 * In merged_symbols() this gets set to TRUE if there were any local 4603 * symbols with the N_NO_DEAD_STRIP set. If not we don't need to do 4604 * anything here. 4605 */ 4606 if(local_NO_DEAD_STRIP_symbols == FALSE) 4607 return; 4608 4609 r = &merged_segments; 4610 while(*r){ 4611 msg = *r; 4612 content = &(msg->content_sections); 4613 while(*content){ 4614 ms = *content; 4615 mark_N_NO_DEAD_STRIP_local_symbols_in_section_live(ms); 4616 content = &(ms->next); 4617 } 4618 zerofill = &(msg->zerofill_sections); 4619 while(*zerofill){ 4620 ms = *zerofill; 4621 mark_N_NO_DEAD_STRIP_local_symbols_in_section_live(ms); 4622 zerofill = &(ms->next); 4623 } 4624 r = &(msg->next); 4625 } 4626} 4627 4628/* 4629 * mark_N_NO_DEAD_STRIP_local_symbols_in_section_live() for the specified 4630 * merged section marks fine_relocs for local symbols that have the 4631 * N_NO_DEAD_STRIP bit set live. 4632 */ 4633static 4634void 4635mark_N_NO_DEAD_STRIP_local_symbols_in_section_live( 4636struct merged_section *ms) 4637{ 4638 unsigned long i, j, k, nsect, input_offset; 4639 struct object_list *object_list, **q; 4640 struct section_map *map; 4641 struct nlist *object_symbols; 4642 char *object_strings; 4643 struct fine_reloc *fine_reloc; 4644 4645 /* 4646 * For each object file that has this section process it. 4647 */ 4648 for(q = &objects; *q; q = &(object_list->next)){ 4649 object_list = *q; 4650 for(i = 0; i < object_list->used; i++){ 4651 cur_obj = &(object_list->object_files[i]); 4652 if(cur_obj == base_obj) 4653 continue; 4654 if(cur_obj->dylib) 4655 continue; 4656 if(cur_obj->bundle_loader) 4657 continue; 4658 if(cur_obj->dylinker) 4659 continue; 4660 map = NULL; 4661 for(j = 0; j < cur_obj->nsection_maps; j++){ 4662 if(cur_obj->section_maps[j].output_section != ms) 4663 continue; 4664 if(cur_obj->section_maps[j].s->size == 0) 4665 continue; 4666 map = &(cur_obj->section_maps[j]); 4667 break; 4668 } 4669 if(map == NULL) 4670 continue; 4671 object_symbols = NULL; 4672 object_strings = NULL; 4673 if(cur_obj->symtab != NULL){ 4674 object_symbols = (struct nlist *)(cur_obj->obj_addr + 4675 cur_obj->symtab->symoff); 4676 object_strings = (char *)(cur_obj->obj_addr + 4677 cur_obj->symtab->stroff); 4678 } 4679 nsect = j + 1; 4680 /* 4681 * Now look through the symbol table for local symbols in this 4682 * section that are marked with the N_NO_DEAD_STRIP bit. 4683 */ 4684 for(k = 0; k < cur_obj->symtab->nsyms; k++){ 4685 if((object_symbols[k].n_type & N_EXT) == 0 && 4686 (object_symbols[k].n_type & N_TYPE) == N_SECT && 4687 (object_symbols[k].n_type & N_STAB) == 0 && 4688 object_symbols[k].n_sect == nsect && 4689 object_symbols[k].n_desc & N_NO_DEAD_STRIP){ 4690 input_offset = object_symbols[k].n_value - map->s->addr; 4691 fine_reloc = fine_reloc_for_input_offset( 4692 map, input_offset); 4693 fine_reloc->live = TRUE; 4694 } 4695 } 4696 } 4697 } 4698} 4699 4700/* 4701 * set_fine_relocs_for_merged_symbols() is called when -dead_strip is specified 4702 * to set the fine_reloc field of the merged symbols. Most of these are set 4703 * in layout_ordered_section() but when a section from an object is linked 4704 * as one block they are not set. So this is done here. 4705 */ 4706__private_extern__ 4707void 4708set_fine_relocs_for_merged_symbols(void) 4709{ 4710 unsigned long i; 4711 struct merged_symbol_list *merged_symbol_list; 4712 struct merged_symbol *merged_symbol; 4713 4714 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 4715 merged_symbol_root->list; 4716 merged_symbol_list != NULL; 4717 merged_symbol_list = merged_symbol_list->next){ 4718 for(i = 0; i < merged_symbol_list->used; i++){ 4719 merged_symbol = merged_symbol_list->symbols[i]; 4720 /* 4721 * Skip symbols that have already had there fine_reloc set which 4722 * happens if the block was created using symbol's addresses. 4723 */ 4724 if(merged_symbol->fine_reloc != NULL) 4725 continue; 4726 /* 4727 * If this symbol is defined in a dylib or undefined then 4728 * it will not have a fine_reloc block. 4729 */ 4730 if(merged_symbol->defined_in_dylib == TRUE || 4731 merged_symbol->nlist.n_type == (N_EXT | N_UNDF) || 4732 (merged_symbol->nlist.n_type & N_TYPE) == N_PBUD) 4733 continue; 4734 /* 4735 * Skip symbols only referenced from dynamic libraries. 4736 */ 4737 if(merged_symbol->referenced_in_non_dylib == FALSE) 4738 continue; 4739 4740 /* 4741 * The remaining symbols might be in a fine_reloc so set it 4742 * up if it has one (note this still maybe NULL). 4743 */ 4744 merged_symbol->fine_reloc = get_fine_reloc_for_merged_symbol( 4745 merged_symbol, NULL); 4746 4747 } 4748 } 4749} 4750 4751/* 4752 * count_live_symbols() is called when -dead_strip is specified after things 4753 * have been marked live. It adjust the counts and reference maps of symbols 4754 * to account for just the live symbols. 4755 */ 4756__private_extern__ 4757void 4758count_live_symbols(void) 4759{ 4760 unsigned long i, j, nrefsym; 4761 struct merged_symbol_list *merged_symbol_list; 4762 struct merged_symbol *merged_symbol; 4763 struct object_list *object_list, **q; 4764 struct object_file *obj; 4765 struct merged_segment *msg, **r; 4766 struct merged_section *ms, **content, **zerofill; 4767 4768 /* 4769 * In order to not put out strings for merged symbols that are not live 4770 * we need to rebuild the merged string table for only the live symbols. 4771 * This is done by resetting these two variables and recalling 4772 * enter_string() on the live symbols. 4773 */ 4774 merged_string_blocks = NULL; 4775 merged_string_size = 0; 4776 4777 /* 4778 * The value of nstripped_merged_symbols is incremented here for each 4779 * merged symbol that would have been in the output but is not live. 4780 * Note: nstripped_merged_symbols can be reset to zero later in 4781 * assign_output_symbol_indexes() if strip_level is set to 4782 * STRIP_DYNAMIC_EXECUTABLE. This works since any symbol to be 4783 * saved with STRIP_DYNAMIC_EXECUTABLE would also be live since 4784 * it would have REFERENCED_DYNAMICALLY set. 4785 */ 4786 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 4787 merged_symbol_root->list; 4788 merged_symbol_list != NULL; 4789 merged_symbol_list = merged_symbol_list->next){ 4790 for(i = 0; i < merged_symbol_list->used; i++){ 4791 merged_symbol = merged_symbol_list->symbols[i]; 4792 /* 4793 * Because a live fine_reloc's could have multiple global 4794 * symbols, we need to check all global symbols to see if they 4795 * are in a live block. And if so mark the global symbol live. 4796 */ 4797 if(merged_symbol->live == FALSE){ 4798 if(merged_symbol->fine_reloc != NULL && 4799 merged_symbol->fine_reloc->live == TRUE) 4800 merged_symbol->live = TRUE; 4801 } 4802 /* 4803 * Skip symbols only referenced from dynamic libraries. 4804 */ 4805 if(merged_symbol->referenced_in_non_dylib == FALSE) 4806 continue; 4807 if(merged_symbol->live == TRUE){ 4808 merged_symbol->nlist.n_un.n_name = 4809 enter_string(merged_symbol->nlist.n_un.n_name, NULL); 4810 } 4811 else{ 4812 /* 4813 * This symbol is not live so account for it the number of 4814 * stripped merged symbols. 4815 */ 4816 nstripped_merged_symbols++; 4817/* 4818printf("count_live_symbols() nstripped_merged_symbols %s\n", merged_symbol->nlist.n_un.n_name); 4819*/ 4820 4821 /* 4822 * If this symbol is defined in a dylib or undefined then 4823 * we are done accounting for it being stripped. 4824 */ 4825 if(merged_symbol->defined_in_dylib == TRUE || 4826 merged_symbol->nlist.n_type == (N_EXT | N_UNDF) || 4827 (merged_symbol->nlist.n_type & N_TYPE) == N_PBUD) 4828 continue; 4829 /* 4830 * This symbol was defined in the .o files so adjust the 4831 * counts in the object_file struct. 4832 */ 4833 4834 /* 4835 * If this is a private symbol adjust the count of 4836 * private symbols in this object. Also increment the 4837 * file level static variable for the number of private 4838 * merged symbols that are being stripped so later 4839 * assign_output_symbol_indexes() can use its value do its 4840 * consistency check. 4841 */ 4842 if(merged_symbol->nlist.n_type & N_PEXT){ 4843 merged_symbol->definition_object->nprivatesym--; 4844 nstripped_merged_private_symbols++; 4845/* 4846printf("count_live_symbols() nstripped_merged_private_symbols %s\n", merged_symbol->nlist.n_un.n_name); 4847*/ 4848 } 4849 /* 4850 * This symbol is defined in the .o file and not a 4851 * private symbol, so if we are creating a multi-module 4852 * dylib this files to adjust the count of the defined 4853 * externals in this object. 4854 */ 4855 else if(filetype == MH_DYLIB && 4856 multi_module_dylib == TRUE) 4857 merged_symbol->definition_object->nextdefsym--; 4858 } 4859 } 4860 } 4861 4862 /* 4863 * If we are creating a multi-module dylib then we need to update the 4864 * reference table and the number of references for each object to only 4865 * contain live symbols. 4866 */ 4867 output_dysymtab_info.dysymtab_command.nextrefsyms = 0; 4868 if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ 4869 for(q = &objects; *q; q = &(object_list->next)){ 4870 object_list = *q; 4871 for(i = 0; i < object_list->used; i++){ 4872 obj = &(object_list->object_files[i]); 4873 if(obj->dylib) 4874 continue; 4875 if(obj->bundle_loader) 4876 continue; 4877 if(obj->dylinker) 4878 continue; 4879 nrefsym = 0; 4880 for(j = 0; j < obj->nrefsym; j++){ 4881 if(obj->reference_maps[j].merged_symbol->live){ 4882 obj->reference_maps[nrefsym] = 4883 obj->reference_maps[j]; 4884 nrefsym++; 4885 } 4886 } 4887 obj->nrefsym = nrefsym; 4888 if(nrefsym != 0) 4889 obj->irefsym = 4890 output_dysymtab_info.dysymtab_command.nextrefsyms; 4891 output_dysymtab_info.dysymtab_command.nextrefsyms += 4892 nrefsym; 4893 } 4894 } 4895 } 4896 4897 /* 4898 * To get the global variable nlocal_symbols and the nlocal_symbols 4899 * field in the object_file structs adjusted to include just live 4900 * symbols call removed_dead_local_symbols_in_section() which will call 4901 * discard_local_symbols_for_section() for each section in each object. 4902 */ 4903 r = &merged_segments; 4904 while(*r){ 4905 msg = *r; 4906 content = &(msg->content_sections); 4907 while(*content){ 4908 ms = *content; 4909 removed_dead_local_symbols_in_section(ms); 4910 content = &(ms->next); 4911 } 4912 zerofill = &(msg->zerofill_sections); 4913 while(*zerofill){ 4914 ms = *zerofill; 4915 removed_dead_local_symbols_in_section(ms); 4916 zerofill = &(ms->next); 4917 } 4918 r = &(msg->next); 4919 } 4920 4921 /* 4922 * Call remove_dead_N_GSYM_stabs() to get rid of dead N_GSYM stabs. 4923 * For common symbols this has to be done as they are not defined or 4924 * in a section and so they can't be bracked by N_BNSYM/N_ENSYM stabs. 4925 */ 4926 remove_dead_N_GSYM_stabs(); 4927} 4928 4929/* 4930 * removed_dead_local_symbols_in_section() is pass a pointer to a merged section 4931 * and then calls discard_local_symbols_for_section() for each object with that 4932 * section to get the global variable nlocal_symbols and the nlocal_symbols 4933 * field in the object_file structs adjusted to include just live symbols. 4934 */ 4935static 4936void 4937removed_dead_local_symbols_in_section( 4938struct merged_section *ms) 4939{ 4940 unsigned long i, j; 4941 struct object_list *object_list, **q; 4942 struct section_map *map; 4943 struct nlist *object_symbols; 4944 char *object_strings; 4945 4946 /* 4947 * For each object file that has this section process it. 4948 */ 4949 for(q = &objects; *q; q = &(object_list->next)){ 4950 object_list = *q; 4951 for(i = 0; i < object_list->used; i++){ 4952 cur_obj = &(object_list->object_files[i]); 4953 if(cur_obj == base_obj) 4954 continue; 4955 if(cur_obj->dylib) 4956 continue; 4957 if(cur_obj->bundle_loader) 4958 continue; 4959 if(cur_obj->dylinker) 4960 continue; 4961 map = NULL; 4962 for(j = 0; j < cur_obj->nsection_maps; j++){ 4963 if(cur_obj->section_maps[j].output_section != ms) 4964 continue; 4965 if(cur_obj->section_maps[j].s->size == 0) 4966 continue; 4967 map = &(cur_obj->section_maps[j]); 4968 break; 4969 } 4970 if(map == NULL) 4971 continue; 4972 object_symbols = NULL; 4973 object_strings = NULL; 4974 if(cur_obj->symtab != NULL){ 4975 object_symbols = (struct nlist *)(cur_obj->obj_addr + 4976 cur_obj->symtab->symoff); 4977 object_strings = (char *)(cur_obj->obj_addr + 4978 cur_obj->symtab->stroff); 4979 } 4980 discard_local_symbols_for_section(j + 1, 4981 object_symbols, object_strings, 4982 cur_obj->section_maps[j].s, map); 4983 } 4984 } 4985} 4986 4987/* 4988 * remove_dead_N_GSYM_stabs() is used by count_live_symbols() when -dead_strip 4989 * is specified to get rid of dead N_GSYM stabs. For common symbols this has 4990 * to be done as they are not defined or in a section and so they can't be 4991 * bracked by N_BNSYM/N_ENSYM stabs. 4992 */ 4993static 4994void 4995remove_dead_N_GSYM_stabs( 4996void) 4997{ 4998 unsigned long i; 4999 struct object_list *object_list, **q; 5000 struct nlist *object_symbols; 5001 char *object_strings; 5002 5003 /* 5004 * For each object that has symbols process it. 5005 */ 5006 for(q = &objects; *q; q = &(object_list->next)){ 5007 object_list = *q; 5008 for(i = 0; i < object_list->used; i++){ 5009 cur_obj = &(object_list->object_files[i]); 5010 if(cur_obj == base_obj) 5011 continue; 5012 if(cur_obj->dylib) 5013 continue; 5014 if(cur_obj->bundle_loader) 5015 continue; 5016 if(cur_obj->dylinker) 5017 continue; 5018 if(cur_obj->symtab != NULL){ 5019 object_symbols = (struct nlist *)(cur_obj->obj_addr + 5020 cur_obj->symtab->symoff); 5021 object_strings = (char *)(cur_obj->obj_addr + 5022 cur_obj->symtab->stroff); 5023 remove_dead_N_GSYM_stabs_for_cur_obj(object_symbols, 5024 object_strings); 5025 5026 } 5027 } 5028 } 5029} 5030#endif /* !defined(RLD) */ 5031 5032/* 5033 * define_link_editor_execute_symbols() is called when the output file type is 5034 * MH_EXECUTE and it sets the address of the loader defined symbols for this 5035 * file type. For the MH_EXECUTE file type there are two loader defined symbols 5036 * which are the address of the header. Since these symbols are not in a 5037 * section (it is before the first section) they are absolute symbols. 5038 */ 5039__private_extern__ 5040void 5041define_link_editor_execute_symbols( 5042unsigned long header_address) 5043{ 5044 struct merged_symbol *merged_symbol; 5045 5046 /* look up the first symbol to see if it is present */ 5047 merged_symbol = lookup_symbol(_MH_EXECUTE_SYM); 5048 /* if it is present set it's correct value */ 5049 if(merged_symbol->name_len != 0) 5050 merged_symbol->nlist.n_value = header_address; 5051 5052 /* look up the second symbol to see if it is present */ 5053 merged_symbol = lookup_symbol("___dso_handle"); 5054 /* if it is present set it's correct value */ 5055 if(merged_symbol->name_len != 0) 5056 merged_symbol->nlist.n_value = header_address; 5057} 5058 5059#ifndef RLD 5060/* 5061 * setup_link_editor_symbols() is called when the output file type can be an 5062 * output for dyld and it sets up the loader defined symbols for the file 5063 * type. These symbols have to be set up (defined and made a private extern) 5064 * before their real addresses are known so that the dylib tables and the 5065 * relocation entries can be laied out. For the MH_DYLIB, MH_BUNDLE and 5066 * MH_DYLINKER file types the loader defined symbols, which is the address of 5067 * the header, must be relative to the sections even thought it is not in a 5068 * section (it is before the first section). So it is set as the an address 5069 * relative to the first section. This is done since these output files can be 5070 * slid by the dynamic link editor. Also for these file types the symbol is 5071 * also made a private extern. 5072 */ 5073__private_extern__ 5074void 5075setup_link_editor_symbols( 5076void) 5077{ 5078 if(filetype == MH_EXECUTE){ 5079 setup_link_editor_symbol(_MH_EXECUTE_SYM); 5080 setup_link_editor_symbol("___dso_handle"); 5081 } 5082 else if(filetype == MH_BUNDLE){ 5083 setup_link_editor_symbol(_MH_BUNDLE_SYM); 5084 setup_link_editor_symbol("___dso_handle"); 5085 } 5086 else if(filetype == MH_DYLIB){ 5087 setup_link_editor_symbol(_MH_DYLIB_SYM); 5088 setup_link_editor_symbol("___dso_handle"); 5089 } 5090 else{ /* filetype == MH_DYLINKER */ 5091 setup_link_editor_symbol(_MH_DYLINKER_SYM); 5092 setup_link_editor_symbol("___dso_handle"); 5093 } 5094} 5095 5096/* 5097 * setup_link_editor_symbol() does the real work of setting up a single loader 5098 * defined symbol for the name passed to it. 5099 */ 5100static 5101void 5102setup_link_editor_symbol( 5103char *symbol_name) 5104{ 5105 struct merged_symbol *merged_symbol; 5106 unsigned long nsects, i, j, n; 5107 struct section *sections; 5108 struct section_map *section_maps; 5109 struct merged_segment **p, *msg; 5110 struct merged_section **q, *ms; 5111 5112 /* look up the symbol to see if it is present */ 5113 merged_symbol = lookup_symbol(symbol_name); 5114 /* if it is not present just return */ 5115 if(merged_symbol->name_len == 0) 5116 return; 5117 /* 5118 * For MH_BUNDLE files we need to special case the handling of the 5119 * link editor defined symbol ___dso_handle since it is allowed to 5120 * be defined in the -bundle_loader file. But it may not referenced 5121 * from any of the the objects being linked. In this case we treat it 5122 * like the symbol is not present and just return. 5123 */ 5124 if(filetype == MH_BUNDLE && 5125 strcmp(symbol_name, "___dso_handle") == 0 && 5126 merged_symbol->definition_object->bundle_loader == TRUE && 5127 merged_symbol->non_dylib_referenced_obj == NULL) 5128 return; 5129 5130 /* 5131 * For MH_EXECUTE file types the symbol is always absolute so just 5132 * defined it with a value of zero for now. 5133 */ 5134 if(filetype == MH_EXECUTE){ 5135 define_link_editor_symbol(symbol_name, N_EXT | N_ABS, NO_SECT, 5136 merged_symbol->nlist.n_desc & REFERENCED_DYNAMICALLY, 0); 5137 return; 5138 } 5139 5140 /* 5141 * For the MH_DYLIB, MH_BUNDLE and MH_DYLINKER file types set up the 5142 * defining object file with the correct values for defining one more 5143 * private external symbol. 5144 */ 5145 setup_link_edit_symbols_object(); 5146 n = link_edit_symbols_object->nprivatesym; 5147 link_edit_symbols_object->nprivatesym += 1; 5148 nmerged_private_symbols++; 5149 5150 link_edit_symbols_object->nrefsym += 1; 5151 if(n == 0) 5152 link_edit_symbols_object->irefsym = 5153 output_dysymtab_info.dysymtab_command.nextrefsyms; 5154 if(filetype == MH_DYLIB) 5155 output_dysymtab_info.dysymtab_command.nextrefsyms += 1; 5156 link_edit_symbols_object->reference_maps = 5157 reallocate(link_edit_symbols_object->reference_maps, 5158 sizeof(struct reference_map) * (n + 1)); 5159 link_edit_symbols_object->reference_maps[n].flags = 5160 REFERENCE_FLAG_PRIVATE_DEFINED; 5161 link_edit_symbols_object->reference_maps[n].merged_symbol = 5162 merged_symbol; 5163 5164 /* count the number of merged sections */ 5165 nsects = 0; 5166 p = &merged_segments; 5167 while(*p){ 5168 msg = *p; 5169 nsects += msg->sg.nsects; 5170 p = &(msg->next); 5171 } 5172 5173 if(nsects > 0 && link_edit_symbols_object->nsection_maps == 0){ 5174 /* 5175 * Create the sections and section maps for the sections in the 5176 * "link editor" object file. To make it easy all merged sections 5177 * will be in this object file. The addr in all of the sections 5178 * and the offset in all the maps will be zero so that 5179 * layout_symbols() will set the final value of these symbols 5180 * to their correct location in the output file. 5181 */ 5182 sections = allocate(nsects * sizeof(struct section)); 5183 memset(sections, '\0', nsects * sizeof(struct section)); 5184 section_maps = allocate(nsects * sizeof(struct section_map)); 5185 memset(section_maps, '\0', nsects * sizeof(struct section_map)); 5186 setup_link_edit_symbols_object(); 5187 link_edit_symbols_object->nsection_maps = nsects; 5188 link_edit_symbols_object->section_maps = section_maps; 5189 5190 i = 0; 5191 p = &merged_segments; 5192 while(*p){ 5193 msg = *p; 5194 for(j = 0; j < 2 ; j++){ 5195 if(j == 0) 5196 /* process the content sections */ 5197 q = &(msg->content_sections); 5198 else 5199 /* process the zerofill sections */ 5200 q = &(msg->zerofill_sections); 5201 while(*q){ 5202 ms = *q; 5203 /* create the section and map for this section */ 5204 strncpy(sections[i].sectname, ms->s.sectname, 5205 sizeof(ms->s.sectname)); 5206 strncpy(sections[i].segname, ms->s.segname, 5207 sizeof(ms->s.segname)); 5208 section_maps[i].s = &(sections[i]); 5209 section_maps[i].output_section = ms; 5210 i++; 5211 q = &(ms->next); 5212 } 5213 } 5214 p = &(msg->next); 5215 } 5216 } 5217 if(nsects > 0) 5218 define_link_editor_symbol(symbol_name, N_SECT | N_PEXT | N_EXT, 5219 1, merged_symbol->nlist.n_desc & REFERENCED_DYNAMICALLY, 0); 5220 else 5221 define_link_editor_symbol(symbol_name, N_ABS | N_PEXT | N_EXT, 5222 NO_SECT, merged_symbol->nlist.n_desc & REFERENCED_DYNAMICALLY, 0); 5223} 5224 5225/* 5226 * define_link_editor_dylib_symbols() is called when the output file type is 5227 * MH_DYLIB, MH_BUNDLE or MH_DYLINKER and it defines the loader defined symbols 5228 * for these file types. This routine actually sets the value of the symbols 5229 * where as the above routine defines the symbol. For these file types there are 5230 * two loader defined symbols which are the address of the header. Since these 5231 * output files can be slid this symbol must be relative to the sections even 5232 * thought it is not in a section (it is before the first section) it is set as 5233 * the an address relative to the first section. This symbol is also a private 5234 * extern. This routine also sets the define_a_way symbols to their final value. 5235 */ 5236__private_extern__ 5237void 5238define_link_editor_dylib_symbols( 5239unsigned long header_address) 5240{ 5241 struct merged_symbol *merged_symbol; 5242 struct merged_symbol_list *merged_symbol_list; 5243 unsigned long i; 5244 5245 if(filetype == MH_BUNDLE) 5246 define_link_editor_dylib_symbol(header_address, _MH_BUNDLE_SYM); 5247 else if(filetype == MH_DYLIB) 5248 define_link_editor_dylib_symbol(header_address, _MH_DYLIB_SYM); 5249 else /* filetype == MH_DYLINKER */ 5250 define_link_editor_dylib_symbol(header_address, _MH_DYLINKER_SYM); 5251 define_link_editor_dylib_symbol(header_address, "___dso_handle"); 5252 5253 /* set the correct values of the undefined symbols defined a way */ 5254 if(undefined_flag == UNDEFINED_DEFINE_A_WAY){ 5255 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 5256 merged_symbol_root->list; 5257 merged_symbol_list != NULL; 5258 merged_symbol_list = merged_symbol_list->next){ 5259 for(i = 0; i < merged_symbol_list->used; i++){ 5260 merged_symbol = merged_symbol_list->symbols[i]; 5261 if(merged_symbol->define_a_way == 1){ 5262 if(merged_symbol->nlist.n_sect == NO_SECT) 5263 merged_symbol->nlist.n_value = header_address; 5264 else 5265 merged_symbol->nlist.n_value = header_address - 5266 link_edit_symbols_object->section_maps[0]. 5267 output_section->s.addr; 5268 } 5269 } 5270 } 5271 } 5272} 5273 5274/* 5275 * define_link_editor_dylib_symbol() does the real work of setting the address 5276 * of the loader defined symbols for filetypes that can be slid. 5277 */ 5278static 5279void 5280define_link_editor_dylib_symbol( 5281unsigned long header_address, 5282char *symbol_name) 5283{ 5284 struct merged_symbol *merged_symbol; 5285 5286 /* look up the symbol to see if it is present */ 5287 merged_symbol = lookup_symbol(symbol_name); 5288 5289 /* if it is not present just return */ 5290 if(merged_symbol->name_len == 0) 5291 return; 5292 5293 /* set it's correct value */ 5294 if(merged_symbol->nlist.n_sect == NO_SECT) 5295 merged_symbol->nlist.n_value = header_address; 5296 else 5297 merged_symbol->nlist.n_value = header_address - 5298 link_edit_symbols_object->section_maps[0].output_section->s.addr; 5299 5300} 5301#endif /* !defined(RLD) */ 5302 5303/* 5304 * define_link_editor_preload_symbols() is called when the output file type is 5305 * MH_PRELOAD and it defines the loader defined symbols for this file type. 5306 * For the MH_PRELOAD file type there are loader defined symbols for the 5307 * beginning and ending of each segment and section. Their names are of the 5308 * form: <segname>{,<sectname>}{__begin,__end} . They are N_SECT symbols for 5309 * the closest section they belong to (in some cases the *__end symbols will 5310 * be outside the section). 5311 */ 5312__private_extern__ 5313void 5314define_link_editor_preload_symbols( 5315enum bool setup) 5316{ 5317 unsigned long nsects, i, j, first_section; 5318 struct section *sections; 5319 struct section_map *section_maps; 5320 struct merged_segment **p, *msg; 5321 struct merged_section **q, *ms; 5322 struct merged_symbol *merged_symbol; 5323 char symbol_name[sizeof(ms->s.segname) + sizeof(ms->s.sectname) + 5324 sizeof("__begin")]; 5325 5326 sections = NULL; 5327 section_maps = NULL; 5328 if(setup == TRUE){ 5329 /* count the number of merged sections */ 5330 nsects = 0; 5331 p = &merged_segments; 5332 while(*p){ 5333 msg = *p; 5334 nsects += msg->sg.nsects; 5335 p = &(msg->next); 5336 } 5337 5338 /* 5339 * Create the sections and section maps for the sections in the 5340 * "link editor" object file. To make it easy all merged sections 5341 * will be in this object file. The addr in all of the sections 5342 * and the offset in all the maps will be zero so that 5343 * layout_symbols() will set the final value of these symbols 5344 * to their correct location in the output file. 5345 */ 5346 sections = allocate(nsects * sizeof(struct section)); 5347 memset(sections, '\0', nsects * sizeof(struct section)); 5348 section_maps = allocate(nsects * sizeof(struct section_map)); 5349 memset(section_maps, '\0', nsects * sizeof(struct section_map)); 5350 setup_link_edit_symbols_object(); 5351 link_edit_symbols_object->nsection_maps = nsects; 5352 link_edit_symbols_object->section_maps = section_maps; 5353 } 5354 5355 i = 0; 5356 p = &merged_segments; 5357 while(*p){ 5358 msg = *p; 5359 /* create the symbol for the beginning of the segment */ 5360 strncpy(symbol_name, msg->sg.segname, sizeof(msg->sg.segname)); 5361 strcat(symbol_name, "__begin"); 5362 if(setup == TRUE) 5363 define_link_editor_symbol(symbol_name, N_EXT | N_SECT, i+1,0,0); 5364 first_section = i + 1; 5365 for(j = 0; j < 2 ; j++){ 5366 if(j == 0) 5367 /* process the content sections */ 5368 q = &(msg->content_sections); 5369 else 5370 /* process the zerofill sections */ 5371 q = &(msg->zerofill_sections); 5372 while(*q){ 5373 ms = *q; 5374 /* create the section and map for this section */ 5375 if(setup == TRUE){ 5376 strncpy(sections[i].sectname, ms->s.sectname, 5377 sizeof(ms->s.sectname)); 5378 strncpy(sections[i].segname, ms->s.segname, 5379 sizeof(ms->s.segname)); 5380 section_maps[i].s = &(sections[i]); 5381 section_maps[i].output_section = ms; 5382 } 5383 /* create the symbol for the beginning of the section */ 5384 strncpy(symbol_name, ms->s.segname, 5385 sizeof(ms->s.segname)); 5386 strncat(symbol_name, ms->s.sectname, 5387 sizeof(ms->s.sectname)); 5388 strcat(symbol_name, "__begin"); 5389 if(setup == TRUE) 5390 define_link_editor_symbol(symbol_name, N_EXT | N_SECT, 5391 i+1, 0, 0); 5392 /* create the symbol for the end of the section */ 5393 strncpy(symbol_name, ms->s.segname, 5394 sizeof(ms->s.segname)); 5395 strncat(symbol_name, ms->s.sectname, 5396 sizeof(ms->s.sectname)); 5397 strcat(symbol_name, "__end"); 5398 if(setup) 5399 define_link_editor_symbol(symbol_name, N_EXT | N_SECT, 5400 i+1, 0, 0); 5401 else{ 5402 merged_symbol = lookup_symbol(symbol_name); 5403 if(merged_symbol->name_len != 0) 5404 merged_symbol->nlist.n_value = ms->s.size; 5405 } 5406 i++; 5407 q = &(ms->next); 5408 } 5409 } 5410 5411 /* create the symbol for the end of the segment */ 5412 strncpy(symbol_name, msg->sg.segname, 5413 sizeof(msg->sg.segname)); 5414 strcat(symbol_name, "__end"); 5415 if(setup) 5416 define_link_editor_symbol(symbol_name, N_EXT | N_SECT, 5417 first_section, 0, 0); 5418 else{ 5419 merged_symbol = lookup_symbol(symbol_name); 5420 if(merged_symbol->name_len != 0) 5421 merged_symbol->nlist.n_value = msg->sg.vmsize; 5422 } 5423 p = &(msg->next); 5424 } 5425} 5426 5427/* 5428 * define_link_editor_symbol() is passed then name of a link editor defined 5429 * symbol and the information to define it. If this symbol exist it must be 5430 * undefined or it is an error. If it exist and link editor defined symbols 5431 * are being defined it is defined using the information passed to it. 5432 */ 5433static 5434void 5435define_link_editor_symbol( 5436char *symbol_name, 5437unsigned char type, 5438unsigned char sect, 5439short desc, 5440unsigned long value) 5441{ 5442 unsigned long i; 5443 struct merged_symbol *merged_symbol; 5444 5445 /* look up the symbol to see if it is present */ 5446 merged_symbol = lookup_symbol(symbol_name); 5447 /* if it is not present just return */ 5448 if(merged_symbol->name_len == 0) 5449 return; 5450 /* 5451 * The symbol is present and must be undefined unless it is defined 5452 * in the base file of an incremental link or in the -bundle_loader 5453 * file (for the case of the ___dso_handle symbol). 5454 */ 5455 if((merged_symbol->nlist.n_type & N_EXT) != N_EXT || 5456 (merged_symbol->nlist.n_type & N_TYPE) != N_UNDF || 5457 merged_symbol->nlist.n_value != 0){ 5458 if(merged_symbol->definition_object != base_obj && 5459 merged_symbol->definition_object->bundle_loader == FALSE){ 5460 error("loaded objects attempt to redefine link editor " 5461 "defined symbol %s", symbol_name); 5462 trace_merged_symbol(merged_symbol); 5463 return; 5464 } 5465 } 5466 5467 /* 5468 * Now that the checks above have been done if link editor defined 5469 * symbols are not to be defined just return. 5470 */ 5471 if(define_comldsyms == FALSE) 5472 return; 5473 5474 /* define this symbol */ 5475 setup_link_edit_symbols_object(); 5476 merged_symbol->nlist.n_type = type; 5477 merged_symbol->nlist.n_sect = sect; 5478 merged_symbol->nlist.n_desc = desc; 5479 merged_symbol->nlist.n_value = value; 5480 merged_symbol->definition_object = link_edit_symbols_object; 5481 5482#ifndef RLD 5483 /* 5484 * If this symbol is already a private extern then it does not get 5485 * processed with the export lists. 5486 */ 5487 if((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT){ 5488 /* 5489 * If we have an -export_symbols_list or 5490 * -unexport_symbol_list option set the private extern bit 5491 * on the symbol if it is not to be exported. 5492 */ 5493 exports_list_processing(merged_symbol->nlist.n_un.n_name, 5494 &(merged_symbol->nlist)); 5495 /* 5496 * If this symbol got made into a private extern with the processing 5497 * of the exports list increment the count of private exterals. 5498 */ 5499 if((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT){ 5500 merged_symbol->definition_object->nprivatesym++; 5501 nmerged_private_symbols++; 5502 } 5503 } 5504#endif 5505 5506 /* 5507 * Do the trace of this symbol if specified now that it has 5508 * been defined. 5509 */ 5510 if(ntrace_syms != 0){ 5511 for(i = 0; i < ntrace_syms; i++){ 5512 if(strcmp(trace_syms[i], symbol_name) == 0){ 5513 trace_merged_symbol(merged_symbol); 5514 break; 5515 } 5516 } 5517 } 5518} 5519#endif /* !defined(RLD) */ 5520 5521/* 5522 * reduce_indr_symbols() reduces indirect symbol chains to have all the indirect 5523 * symbols point at their leaf symbol. Also catch loops of indirect symbols. 5524 */ 5525__private_extern__ 5526void 5527reduce_indr_symbols(void) 5528{ 5529 unsigned long i, j, k, indr_depth, from_dylibs, not_from_dylibs; 5530 struct merged_symbol_list *merged_symbol_list; 5531 struct merged_symbol *merged_symbol, **indr_symbols, *indr_symbol; 5532 struct indr_symbol_pair *indr_symbol_pair; 5533 5534 indr_symbols = allocate(nindr_symbols * sizeof(struct merged_symbol *)); 5535 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 5536 merged_symbol_root->list; 5537 merged_symbol_list != NULL; 5538 merged_symbol_list = merged_symbol_list->next){ 5539 for(i = 0; i < merged_symbol_list->used; i++){ 5540 merged_symbol = merged_symbol_list->symbols[i]; 5541 5542 /* 5543 * Reduce indirect symbol chains to have all the indirect 5544 * symbols point at their leaf symbol. Also catch loops of 5545 * indirect symbols. If an indirect symbol was previously 5546 * in a loop it's n_value is set to zero so not to print the 5547 * loop more than once. 5548 */ 5549 if(merged_symbol->nlist.n_type == (N_EXT | N_INDR) && 5550 merged_symbol->nlist.n_value != 0){ 5551 if(merged_symbol->defined_in_dylib == TRUE){ 5552 from_dylibs = 1; 5553 not_from_dylibs = 0; 5554 } 5555 else{ 5556 from_dylibs = 0; 5557 not_from_dylibs = 1; 5558 } 5559 indr_symbols[0] = merged_symbol; 5560 indr_depth = 1; 5561 indr_symbol = (struct merged_symbol *) 5562 (merged_symbol->nlist.n_value); 5563 while(indr_symbol->nlist.n_type == (N_EXT | N_INDR) && 5564 indr_symbol->nlist.n_value != 0){ 5565 for(j = 0; j < indr_depth; j++){ 5566 if(indr_symbols[j] == indr_symbol) 5567 break; 5568 } 5569 if(j == indr_depth){ 5570 if(indr_symbol->defined_in_dylib == TRUE) 5571 from_dylibs++; 5572 else 5573 not_from_dylibs++; 5574 indr_symbols[indr_depth++] = indr_symbol; 5575 indr_symbol = (struct merged_symbol *) 5576 (indr_symbol->nlist.n_value); 5577 } 5578 else{ 5579 error("indirect symbol loop:"); 5580 for(k = j; k < indr_depth; k++){ 5581 trace_merged_symbol(indr_symbols[k]); 5582 indr_symbols[k]->nlist.n_value = 0; 5583 } 5584 indr_symbol->nlist.n_value = 0; 5585 } 5586 } 5587 /* 5588 * If this N_INDR chain has symbols both from dylib and 5589 * not from dylibs record a pair for each merged symbol 5590 * not defined in a dylib and the first in the chain 5591 * defined in a dylib. 5592 */ 5593 if(from_dylibs != 0 && not_from_dylibs != 0 && 5594 indr_symbol->nlist.n_type != (N_EXT | N_INDR)){ 5595 for(j = 0; j < indr_depth; j++){ 5596 if(indr_symbols[j]->defined_in_dylib == FALSE){ 5597 for(k = j + 1; k < indr_depth; k++){ 5598 if(indr_symbols[k]->defined_in_dylib) 5599 break; 5600 } 5601 indr_symbol_pairs = reallocate( 5602 indr_symbol_pairs, 5603 sizeof(struct indr_symbol_pair) * 5604 (nindr_symbol_pairs + 1)); 5605 indr_symbol_pair = indr_symbol_pairs + 5606 nindr_symbol_pairs; 5607 nindr_symbol_pairs++; 5608 indr_symbol_pair->merged_symbol = merged_symbol; 5609 if(k < indr_depth && 5610 indr_symbols[k]->defined_in_dylib) 5611 indr_symbol_pair->indr_symbol = 5612 indr_symbols[k]; 5613 else 5614 indr_symbol_pair->indr_symbol = 5615 indr_symbol; 5616 } 5617 } 5618 } 5619 if(indr_symbol->nlist.n_type != (N_EXT | N_INDR)){ 5620 for(j = 0; j < indr_depth; j++){ 5621 indr_symbols[j]->nlist.n_value = 5622 (unsigned long)indr_symbol; 5623 /* 5624 * If this indirect symbol is pointing to a 5625 * private extern then increment the count of 5626 * private exterals. 5627 */ 5628 if((indr_symbol->nlist.n_type & N_PEXT) == N_PEXT){ 5629 indr_symbols[j]->definition_object-> 5630 nprivatesym++; 5631 nmerged_private_symbols++; 5632 } 5633 } 5634 } 5635 } 5636 } 5637 } 5638 free(indr_symbols); 5639} 5640 5641/* 5642 * layout_merged_symbols() sets the values and section numbers of the merged 5643 * symbols. 5644 */ 5645__private_extern__ 5646void 5647layout_merged_symbols(void) 5648{ 5649 unsigned long i; 5650 struct merged_symbol_list *merged_symbol_list; 5651 struct merged_symbol *merged_symbol; 5652 5653 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 5654 merged_symbol_root->list; 5655 merged_symbol_list != NULL; 5656 merged_symbol_list = merged_symbol_list->next){ 5657 for(i = 0; i < merged_symbol_list->used; i++){ 5658 merged_symbol = merged_symbol_list->symbols[i]; 5659 relocate_symbol(&(merged_symbol->nlist), 5660 merged_symbol->definition_object); 5661 } 5662 } 5663 /* 5664 * Set this global variable to let routines that look at merged symbols 5665 * in both the first pass and second pass that the merged symbols are 5666 * relocated. This is need for example when looking at the n_sect value 5667 * of a merged symbol. In the first pass it can be used as an index 5668 * into definition_object->section_maps[] but in the second pass it can 5669 * not. 5670 */ 5671 merged_symbols_relocated = TRUE; 5672 5673 /* 5674 * The MH_NOUNDEFS flag is set only if there are no undefined symbols 5675 * or commons left undefined. This is only set if we think the file is 5676 * executable as the execute bits are based on this. 5677 */ 5678 if(noundefs == TRUE && 5679 (define_comldsyms == TRUE || commons_exist == FALSE)) 5680 output_mach_header.flags |= MH_NOUNDEFS; 5681} 5682 5683/* 5684 * discard_local_symbols_for_section() is used by coalesced_section_merge(), 5685 * indirect_section_merge() and removed_dead_local_symbols_in_section() (when 5686 * -dead_strip is specified) to deal with the symbol table entries for local 5687 * symbols and N_STAB symbols in this section in the current object file after 5688 * the fine relocation entries have been set up to determined for which items 5689 * the contents will be used from current object file object file. 5690 */ 5691__private_extern__ 5692void 5693discard_local_symbols_for_section( 5694unsigned long nsect, 5695struct nlist *object_symbols, 5696char *object_strings, 5697struct section *s, 5698struct section_map *section_map) 5699{ 5700 unsigned long i, j, k, output_strlen; 5701 struct localsym_block *localsym_block, **next_localsym_block; 5702 struct fine_reloc *fine_reloc; 5703 enum bool closed_last_block; 5704 size_t * debug_ptr; 5705 5706 /* 5707 * Previouly in merge_symbols(), nlocal_symbols and local_string_size 5708 * were incremented for all symbols in this section. So now we decrement 5709 * these variables for symbols in the items that will not be in the 5710 * output file. 5711 */ 5712 localsym_block = cur_obj->localsym_blocks; 5713 next_localsym_block = &(cur_obj->localsym_blocks); 5714 debug_ptr = cur_obj->dwarf_source_data; 5715 for(i = 0; i < cur_obj->symtab->nsyms; i++){ 5716 if (debug_ptr && *debug_ptr < i) { 5717 for (debug_ptr += 2; *debug_ptr & 0x80000000; debug_ptr++) ; 5718 } 5719 /* skip blocks of symbols that have already been removed */ 5720 if(localsym_block != NULL && localsym_block->index == i){ 5721 i += localsym_block->count - 1; /* the loop will do i++ */ 5722 next_localsym_block = &(localsym_block->next); 5723 localsym_block = localsym_block->next; 5724 continue; 5725 } 5726 /* 5727 * See if this is a local symbol for this section that would be in 5728 * the output file. 5729 */ 5730 if((object_symbols[i].n_type & N_EXT) == 0 && 5731 ((object_symbols[i].n_type & N_TYPE) == N_SECT || 5732 (object_symbols[i].n_type & N_STAB) != 0) && 5733 object_symbols[i].n_sect == nsect && 5734 is_output_local_symbol(object_symbols[i].n_type, 5735 object_symbols[i].n_sect, 5736 object_symbols[i].n_desc, cur_obj, 5737 object_symbols[i].n_un.n_strx == 0 ? "" : 5738 object_strings + 5739 object_symbols[i].n_un.n_strx, 5740 &output_strlen)){ 5741 /* 5742 * If this local symbol from this section that part of a 5743 * fine_reloc that is not going to be in the output then make 5744 * sure the symbol is not going to be in the output by creating 5745 * a local symbol block for it marked to discard the symbol. 5746 * Unless the symbol is an N_SO stab, which must be kept for 5747 * the debugger to work correctly. Note these stabs would have 5748 * addresses that are meaningless if the block they are in is 5749 * dead stripped, gdb(1) has code to handle this if the address 5750 * zero (see below where this is done). 5751 */ 5752 if(fine_reloc_offset_in_output(section_map, 5753 object_symbols[i].n_value - s->addr) == FALSE && 5754 object_symbols[i].n_type != N_SO){ 5755 nlocal_symbols--; 5756 cur_obj->nlocalsym--; 5757 5758 local_string_size -= 5759 object_symbols[i].n_un.n_strx == 0 ? 0: 5760 output_strlen + 1; 5761 5762 /* If this file had DWARF, the debug map symbols 5763 for this symbol will also go away. */ 5764 if (cur_obj->dwarf_name){ 5765 size_t n = count_dwarf_symbols (object_symbols + i, i, 5766 debug_ptr); 5767 cur_obj->nlocalsym -= n; 5768 nlocal_symbols -= n; 5769 } 5770 5771 /* 5772 * Create a block for this symbol which will cause it to 5773 * be discarded for the output. 5774 */ 5775 localsym_block = allocate(sizeof(struct localsym_block)); 5776 memset(localsym_block, '\0', sizeof(struct localsym_block)); 5777 localsym_block->index = i; 5778 localsym_block->state = DISCARD_SYMBOLS; 5779 localsym_block->count = 1; 5780 5781 /* insert this block in the list */ 5782 localsym_block->next = *next_localsym_block; 5783 *next_localsym_block = localsym_block; 5784 next_localsym_block = &(localsym_block->next); 5785 5786 /* 5787 * If this is a begin nsect symbol stab (N_BNSYM) scan 5788 * forward to the end nsect symbol stab (N_ENSYM) and cause 5789 * all stabs to also be removed. 5790 */ 5791 fine_reloc = fine_reloc_for_input_offset(section_map, 5792 object_symbols[i].n_value - s->addr); 5793 if(object_symbols[i].n_type == N_BNSYM && 5794 i + 1 < cur_obj->symtab->nsyms){ 5795 for(j = i + 1; j < cur_obj->symtab->nsyms; j++){ 5796 if(localsym_block->next != NULL && 5797 j >= localsym_block->next->index) 5798 break; 5799 if(object_symbols[j].n_type == N_ENSYM) 5800 break; 5801 if((object_symbols[j].n_type & N_EXT) == N_EXT) 5802 break; 5803 if((object_symbols[j].n_type & N_STAB) == 0) 5804 break; 5805 if(object_symbols[j].n_sect == NO_SECT) 5806 continue; 5807 if(object_symbols[j].n_sect != nsect) 5808 break; 5809 if(fine_reloc != fine_reloc_for_input_offset( 5810 section_map, 5811 object_symbols[j].n_value - s->addr)) 5812 break; 5813 } 5814 /* 5815 * If we really found an end nsect symbol stab (N_ENSYM) 5816 * adjust the counts of the symbols and string sizes 5817 * for the symbols being removed and add the symbols 5818 * being removed to a local symbol block. 5819 */ 5820 if(j < cur_obj->symtab->nsyms && 5821 (localsym_block->next == NULL || 5822 j < localsym_block->next->index) && 5823 object_symbols[j].n_type == N_ENSYM && 5824 object_symbols[j].n_sect == nsect){ 5825 /* 5826 * If there are type stabs in the N_BNSYM/N_ENSYM 5827 * block these must not be removed to allow 5828 * debugging to work. To do this we scan the 5829 * symbols in this block. If we find a type stab we 5830 * close the current local symbol block and 5831 * step over this stab. If we then run into another 5832 * non-type stab we create a new local block and 5833 * put that in that block. 5834 */ 5835 closed_last_block = FALSE; 5836 for(k = i + 1; k <= j; k++){ 5837 if(is_type_stab(object_symbols[k].n_type, 5838 object_symbols[k].n_un.n_strx == 0 ? "" : 5839 object_strings + 5840 object_symbols[k].n_un.n_strx)){ 5841 closed_last_block = TRUE; 5842 } 5843 else{ 5844 if(closed_last_block == TRUE){ 5845 /* 5846 * Create a block for this next group of 5847 * symbols which will cause it to be 5848 * discarded for the output. 5849 */ 5850 localsym_block = allocate( 5851 sizeof(struct localsym_block)); 5852 memset(localsym_block, '\0', 5853 sizeof(struct localsym_block)); 5854 localsym_block->index = k; 5855 localsym_block->state = DISCARD_SYMBOLS; 5856 5857 /* insert this block in the list */ 5858 localsym_block->next = 5859 *next_localsym_block; 5860 *next_localsym_block = localsym_block; 5861 next_localsym_block = 5862 &(localsym_block->next); 5863 closed_last_block = FALSE; 5864 } 5865 localsym_block->count++; 5866 nlocal_symbols--; 5867 cur_obj->nlocalsym--; 5868 local_string_size -= 5869 object_symbols[k].n_un.n_strx == 0 ? 0: 5870 strlen(object_strings + 5871 object_symbols[k].n_un.n_strx) + 1; 5872 } 5873 } 5874 i = j; 5875 } 5876 } 5877 5878 /* 5879 * Move the pointer from the block we just created to the 5880 * the next block 5881 */ 5882 localsym_block = localsym_block->next; 5883 } 5884 /* 5885 * This local symbol is from this section and is that part of a 5886 * fine_reloc that WILL be in the output. If this is a begin 5887 * nsect symbol stab (N_BNSYM) scan forward to the end nsect 5888 * symbol stab (N_ENSYM) and cause all stabs to also be kept. 5889 * This scan is needed just like the scan above for removing 5890 * symbols when to keep all the stabs for unstripped 5891 * fine_reloc's. 5892 */ 5893 else if(object_symbols[i].n_type == N_BNSYM && 5894 i + 1 < cur_obj->symtab->nsyms){ 5895 fine_reloc = fine_reloc_for_input_offset(section_map, 5896 object_symbols[i].n_value - s->addr); 5897 for(j = i + 1; j < cur_obj->symtab->nsyms; j++){ 5898 if(localsym_block != NULL && 5899 j >= localsym_block->index) 5900 break; 5901 if(object_symbols[j].n_type == N_ENSYM) 5902 break; 5903 if((object_symbols[j].n_type & N_EXT) == N_EXT) 5904 break; 5905 if((object_symbols[j].n_type & N_STAB) == 0) 5906 break; 5907 if(object_symbols[j].n_sect == NO_SECT) 5908 continue; 5909 if(object_symbols[j].n_sect != nsect) 5910 break; 5911 if(fine_reloc != fine_reloc_for_input_offset( 5912 section_map, 5913 object_symbols[j].n_value - s->addr)) 5914 break; 5915 } 5916 /* 5917 * If we really found an end nsect symbol stab (N_ENSYM) 5918 * move the index i to skip these stabs so they are kept. 5919 */ 5920 if(j < cur_obj->symtab->nsyms && 5921 (localsym_block == NULL || 5922 j < localsym_block->index) && 5923 object_symbols[j].n_type == N_ENSYM && 5924 object_symbols[j].n_sect == nsect){ 5925 i = j; 5926 } 5927 } 5928 /* 5929 * This local symbol is being kept, if it is an N_SO stab, 5930 * from this section that part of a fine_reloc that is not 5931 * going to be in the output then change it so the debugger 5932 * will work correctly. These stabs would have addresses that 5933 * are meaningless if the block they are in is dead stripped, 5934 * gdb(1) has code to handle this if the address zero. So 5935 * set the n_sect to NO_SECT and the n_value to zero. 5936 */ 5937 else if(object_symbols[i].n_type == N_SO && 5938 fine_reloc_offset_in_output(section_map, 5939 object_symbols[i].n_value - s->addr) == FALSE){ 5940 object_symbols[i].n_sect = NO_SECT; 5941 object_symbols[i].n_value = 0; 5942 } 5943 } 5944 } 5945} 5946 5947#ifndef RLD 5948/* 5949 * remove_dead_N_GSYM_stabs_for_cur_obj() is used by remove_dead_N_GSYM_stabs() 5950 * when -dead_strip is specified to get rid of dead N_GSYM stabs for the 5951 * cur_obj. For common symbols this has to be done as they are not defined or 5952 * in a section and so they can't be bracked by N_BNSYM/N_ENSYM stabs. 5953 */ 5954static 5955void 5956remove_dead_N_GSYM_stabs_for_cur_obj( 5957struct nlist *object_symbols, 5958char *object_strings) 5959{ 5960 unsigned long i, len, symbol_name_len; 5961 long output_strlen; 5962 struct localsym_block *localsym_block, **next_localsym_block; 5963 char *stab_name, *symbol_name, *p; 5964 struct merged_symbol *hash_pointer, *merged_symbol; 5965 size_t * debug_ptr; 5966 5967 /* 5968 * Previouly in merge_symbols(), nlocal_symbols and local_string_size 5969 * were incremented for all symbols in this section. So now we decrement 5970 * these variables for N_GSYM stabs that will not be in the output file. 5971 */ 5972 symbol_name_len = 0; 5973 symbol_name = NULL; 5974 localsym_block = cur_obj->localsym_blocks; 5975 next_localsym_block = &(cur_obj->localsym_blocks); 5976 debug_ptr = cur_obj->dwarf_source_data; 5977 for(i = 0; i < cur_obj->symtab->nsyms; i++){ 5978 if (debug_ptr && *debug_ptr < i) { 5979 for (debug_ptr += 2; *debug_ptr & 0x80000000; debug_ptr++) ; 5980 } 5981 5982 /* Remove the DWARF symbols that correspond to an external 5983 symbol which will not be in the output file. 5984 This has to be done here rather than in count_live_symbols 5985 (where it would be much more efficient) for the same reason 5986 that this processing has to be done for GSYM symbols: 5987 a common variable which turns out to be dead might have 5988 GSYM entries in multiple .o files. */ 5989 if (cur_obj->dwarf_name 5990 && object_symbols[i].n_type & N_EXT 5991 && object_symbols[i].n_un.n_strx != 0) { 5992 size_t cnt = count_dwarf_symbols (object_symbols + i, i, 5993 debug_ptr); 5994 if (cnt == 0) 5995 /* Avoid expensive hash lookup for symbols not actually 5996 defined in this object file. */ 5997 continue; 5998 hash_pointer = lookup_symbol(object_strings 5999 + object_symbols[i].n_un.n_strx); 6000 if (hash_pointer->name_len == 0 6001 || hash_pointer->live 6002 || (object_symbols[i].n_sect != NO_SECT 6003 && hash_pointer->definition_object != cur_obj)) 6004 continue; 6005 6006 cur_obj->nlocalsym -= cnt; 6007 nlocal_symbols -= cnt; 6008 } 6009 6010 /* skip blocks of symbols that have already been removed */ 6011 if(localsym_block != NULL && localsym_block->index == i){ 6012 i += localsym_block->count - 1; /* the loop will do i++ */ 6013 next_localsym_block = &(localsym_block->next); 6014 localsym_block = localsym_block->next; 6015 continue; 6016 } 6017 /* 6018 * See if this is a N_GSYM stab and would be in the output file. 6019 */ 6020 output_strlen = -1; 6021 if(object_symbols[i].n_type == N_GSYM && 6022 is_output_local_symbol(object_symbols[i].n_type, 6023 object_symbols[i].n_sect, 6024 object_symbols[i].n_desc, cur_obj, 6025 object_symbols[i].n_un.n_strx == 0 ? "" : 6026 object_strings + 6027 object_symbols[i].n_un.n_strx, 6028 (unsigned long *)&output_strlen)){ 6029 /* 6030 * If is_output_local_symbol() was called in the if() above then 6031 * output_strlen will not be -1. Else we need to calculate the 6032 * output string size. This is without the trailing '\0' since 6033 * if it is set by is_output_local_symbol() we could be 6034 * truncating the string. 6035 */ 6036 if(output_strlen == -1) 6037 output_strlen = object_symbols[i].n_un.n_strx == 0 ? 0: 6038 strlen(object_strings + 6039 object_symbols[i].n_un.n_strx); 6040 /* 6041 * Parse out the global symbol name from the N_GSYM stab and 6042 * look it up to see if the merged symbol symbol is live. 6043 */ 6044 if(object_symbols[i].n_un.n_strx == 0) 6045 continue; 6046 stab_name = object_strings + object_symbols[i].n_un.n_strx; 6047 p = strchr(stab_name, ':'); 6048 if(p == NULL) 6049 continue; 6050 len = p - stab_name; 6051 if(len == 0) 6052 continue; 6053 if(len + 2 > symbol_name_len){ 6054 if(len + 2 < 4096) 6055 symbol_name_len = 4096; 6056 else 6057 symbol_name_len = len + 2; 6058 symbol_name = reallocate(symbol_name, symbol_name_len); 6059 } 6060 strcpy(symbol_name, "_"); 6061 strncat(symbol_name, stab_name, len); 6062 hash_pointer = lookup_symbol(symbol_name); 6063 if(hash_pointer->name_len == 0) 6064 continue; 6065 merged_symbol = hash_pointer; 6066 if(merged_symbol->live == FALSE){ 6067 nlocal_symbols--; 6068 cur_obj->nlocalsym--; 6069 local_string_size -= output_strlen == 0 ? 0: 6070 output_strlen + 1; 6071 /* 6072 * Create a block for this symbol which will cause it to 6073 * be discarded for the output. 6074 */ 6075 localsym_block = allocate(sizeof(struct localsym_block)); 6076 memset(localsym_block, '\0', sizeof(struct localsym_block)); 6077 localsym_block->index = i; 6078 localsym_block->state = DISCARD_SYMBOLS; 6079 localsym_block->count = 1; 6080 6081 /* insert this block in the list */ 6082 localsym_block->next = *next_localsym_block; 6083 *next_localsym_block = localsym_block; 6084 next_localsym_block = &(localsym_block->next); 6085 6086 /* 6087 * Move the pointer from the block we just created to the 6088 * the next block 6089 */ 6090 localsym_block = localsym_block->next; 6091 } 6092 } 6093 } 6094 if(symbol_name != NULL) 6095 free(symbol_name); 6096} 6097#endif /* !defined(RLD) */ 6098 6099/* these keep track of BINCL strings, so they can be re-used by EXCL */ 6100struct bincl_entry { 6101 unsigned long sum; 6102 unsigned long stroffset; 6103 const char* path; 6104}; 6105static struct bincl_entry* bincl_entries = NULL; 6106static unsigned int bincl_entries_used = 0; 6107static unsigned int bincl_entry_count = 0; 6108 6109/* 6110 * record_bincl() records the string offset of a BINCL for a checksum/path pair. 6111 */ 6112static 6113void 6114record_bincl( 6115unsigned long sum, 6116const char* path, 6117unsigned long output_stroffset) 6118{ 6119 struct bincl_entry *tmp; 6120 char *path_copy; 6121 6122 if(bincl_entries == NULL){ 6123 bincl_entry_count = 8192; 6124 bincl_entries = allocate(sizeof(struct bincl_entry) * 6125 bincl_entry_count); 6126 } 6127 if(bincl_entries_used == bincl_entry_count){ 6128 bincl_entry_count *= 2; 6129 tmp = allocate(sizeof(struct bincl_entry)*bincl_entry_count); 6130 memcpy(tmp, bincl_entries, sizeof(struct bincl_entry) * 6131 bincl_entries_used); 6132 free(bincl_entries); 6133 bincl_entries = tmp; 6134 } 6135 bincl_entries[bincl_entries_used].sum = sum; 6136 bincl_entries[bincl_entries_used].stroffset = output_stroffset; 6137 path_copy = allocate(strlen(path) + 1); 6138 strcpy(path_copy, path); 6139 bincl_entries[bincl_entries_used].path = path_copy; 6140 bincl_entries_used++; 6141} 6142 6143/* 6144 * find_bincl() finds the string offset of a BINCL for a checksum/path pair. 6145 */ 6146static 6147unsigned long 6148find_bincl( 6149unsigned long sum, 6150const char* path) 6151{ 6152 unsigned long i; 6153 6154 for(i = 0; i < bincl_entries_used; i++){ 6155 if(bincl_entries[i].sum == sum && 6156 strcmp(bincl_entries[i].path, path) == 0){ 6157 return(bincl_entries[i].stroffset); 6158 } 6159 } 6160 return(0); 6161} 6162 6163 6164/* 6165 * add_dwarf_map_entry() adds a single DWARF map symbol to 'nlist'. 6166 */ 6167static void 6168add_dwarf_map_entry(struct nlist ** nlist, unsigned long *output_nsyms, 6169 int32_t n_strx, uint8_t n_type, uint8_t n_sect, 6170 int16_t n_desc, uint32_t n_value) 6171{ 6172 (*nlist)->n_un.n_strx = n_strx; 6173 (*nlist)->n_type = n_type; 6174 (*nlist)->n_sect = n_sect; 6175 (*nlist)->n_desc = n_desc; 6176 (*nlist)->n_value = n_value; 6177 (*nlist)++; 6178 (*output_nsyms)++; 6179} 6180 6181/* 6182 * add_dwarf_map_for_sym() adds the DWARF symbols for a single object file 6183 * symbol to 'nlist'. It is the pass2 counterterpart of count_dwarf_symbols. 6184 */ 6185static void 6186add_dwarf_map_for_sym(const struct nlist * sym, 6187 size_t i, const size_t * debug_ptr, uint32_t n_strx, 6188 uint16_t old_sect, 6189 struct nlist ** nlist, unsigned long *output_nsyms) 6190{ 6191 size_t j; 6192 6193 /* The debug map only represents symbols which are defined in 6194 a particular section or which are global common symbols. */ 6195 if ((sym->n_type & (N_TYPE | N_STAB)) != N_SECT 6196 && ((sym->n_type & (N_TYPE | N_STAB)) != N_UNDF 6197 || sym->n_value == 0)) 6198 return; 6199 /* If S_ATTR_STRIP_STATIC_SYMS is set on this symbol's section, 6200 we don't need a debug symbol for this symbol. */ 6201 if ((sym->n_type & (N_TYPE | N_STAB)) == N_SECT 6202 && old_sect != NO_SECT 6203 && (cur_obj->section_maps[old_sect - 1].s->flags & 6204 S_ATTR_STRIP_STATIC_SYMS)) 6205 return; 6206 6207 if (! debug_ptr || *debug_ptr != i) 6208 { 6209 if (sym->n_type & N_EXT) 6210 add_dwarf_map_entry (nlist, output_nsyms, n_strx, N_GSYM, 0, 0, 0); 6211 else 6212 add_dwarf_map_entry (nlist, output_nsyms, 6213 sym->n_un.n_strx, N_STSYM, 6214 sym->n_sect, 0, sym->n_value); 6215 return; 6216 } 6217 add_dwarf_map_entry (nlist, output_nsyms, 6218 0, N_BNSYM, sym->n_sect, 0, sym->n_value); 6219 add_dwarf_map_entry (nlist, output_nsyms, 6220 n_strx, N_FUN, sym->n_sect, 0, sym->n_value); 6221 for (j = 2; debug_ptr[j] & 0x80000000; j++) 6222 add_dwarf_map_entry (nlist, output_nsyms, 6223 (cur_obj->dwarf_paths[debug_ptr[j] & 0x7fffffff] 6224 - output_addr 6225 - output_symtab_info.symtab_command.stroff), 6226 N_SOL, 0, 0, 0); 6227 add_dwarf_map_entry (nlist, output_nsyms, 0, N_FUN, 0, 0, debug_ptr[1]); 6228 add_dwarf_map_entry (nlist, output_nsyms, 0, N_ENSYM, 6229 sym->n_sect, 0, sym->n_value); 6230} 6231 6232/* 6233 * output_local_symbols() copys the local symbols and their strings from the 6234 * current object file into the output file's memory buffer. The symbols also 6235 * get relocated. 6236 */ 6237__private_extern__ 6238void 6239output_local_symbols(void) 6240{ 6241 unsigned long i, flush_symbol_offset, output_nsyms, flush_string_offset, 6242 start_string_size, mtime, stroff_for_N_OSO; 6243 long output_strlen; 6244 struct nlist *object_symbols, *nlist; 6245 char *object_strings, *string; 6246 struct localsym_block *localsym_block; 6247 size_t * debug_ptr; 6248 6249 /* If no symbols are not to appear in the output file just return */ 6250 if(strip_level == STRIP_ALL) 6251 return; 6252 6253 /* If this object file has no symbols then just return */ 6254 if(cur_obj->symtab == NULL) 6255 return; 6256 6257 /* If this is the base file and base file symbols are stripped return */ 6258 if(cur_obj == base_obj && strip_base_symbols == TRUE) 6259 return; 6260 6261#ifdef RLD 6262 /* If this object is not from the current set then just return */ 6263 if(cur_obj->set_num != cur_set) 6264 return; 6265#endif /* RLD */ 6266 6267 /* setup pointers to the symbol table and string table */ 6268 object_symbols = (struct nlist *)(cur_obj->obj_addr + 6269 cur_obj->symtab->symoff); 6270 object_strings = (char *)(cur_obj->obj_addr + cur_obj->symtab->stroff); 6271 6272 flush_symbol_offset = output_symtab_info.symtab_command.symoff + 6273 cur_obj->ilocalsym * sizeof(struct nlist); 6274 flush_string_offset = output_symtab_info.symtab_command.stroff + 6275 output_symtab_info.output_local_strsize; 6276 start_string_size = output_symtab_info.output_local_strsize; 6277 6278 output_nsyms = 0; 6279 stroff_for_N_OSO = 0; 6280 nlist = (struct nlist *)(output_addr + flush_symbol_offset); 6281 /* If we are creating section object symbols, create one if needed */ 6282 if(sect_object_symbols.ms != NULL){ 6283 /* 6284 * See if this object file has the section that the section object 6285 * symbols are being created for. 6286 */ 6287 for(i = 0; i < cur_obj->nsection_maps; i++){ 6288 if(sect_object_symbols.ms == 6289 cur_obj->section_maps[i].output_section){ 6290 /* make the nlist entry in the output file */ 6291 nlist->n_value = 6292 cur_obj->section_maps[i].output_section->s.addr + 6293 cur_obj->section_maps[i].offset; 6294 nlist->n_sect = 6295 cur_obj->section_maps[i].output_section->output_sectnum; 6296 nlist->n_type = N_SECT; 6297 nlist->n_desc = 0; 6298 6299 nlist->n_un.n_strx = output_symtab_info. 6300 output_local_strsize; 6301 string = output_addr + 6302 output_symtab_info.symtab_command.stroff + 6303 output_symtab_info.output_local_strsize; 6304 if(cur_obj->ar_hdr == NULL){ 6305 strcpy(string, cur_obj->file_name); 6306 output_symtab_info.output_local_strsize += 6307 strlen(cur_obj->file_name) + 1; 6308 } 6309 else{ 6310 strncpy(string, cur_obj->ar_name,cur_obj->ar_name_size); 6311 string[cur_obj->ar_name_size] = '\0'; 6312 output_symtab_info.output_local_strsize += 6313 cur_obj->ar_name_size + 1; 6314 } 6315 nlist++; 6316 output_nsyms++; 6317 break; 6318 } 6319 } 6320 } 6321 6322 /* Add initial DWARF map symbols. */ 6323 if(cur_obj->dwarf_name){ 6324 size_t len = strlen (cur_obj->dwarf_name) + 1; 6325 char * strbase = (output_addr 6326 + output_symtab_info.symtab_command.stroff); 6327 6328 if (cur_obj->dwarf_comp_dir){ 6329 size_t len = strlen (cur_obj->dwarf_comp_dir); 6330 add_dwarf_map_entry (&nlist, &output_nsyms, 6331 output_symtab_info.output_local_strsize, 6332 N_SO, 0, 0, 0); 6333 memcpy (strbase + output_symtab_info.output_local_strsize, 6334 cur_obj->dwarf_comp_dir, len); 6335 output_symtab_info.output_local_strsize += len + 2; 6336 strbase[output_symtab_info.output_local_strsize - 2] = '/'; 6337 strbase[output_symtab_info.output_local_strsize - 1] = 0; 6338 } 6339 6340 add_dwarf_map_entry (&nlist, &output_nsyms, 6341 output_symtab_info.output_local_strsize, 6342 N_SO, 0, 0, 0); 6343 memcpy (strbase + output_symtab_info.output_local_strsize, 6344 cur_obj->dwarf_name, len); 6345 output_symtab_info.output_local_strsize += len; 6346 6347 get_stroff_and_mtime_for_N_OSO(&stroff_for_N_OSO, &mtime); 6348 add_dwarf_map_entry (&nlist, &output_nsyms, 6349 stroff_for_N_OSO, N_OSO, 0, 1, mtime); 6350 6351 /* Add SOL strings to the local string table, and update 6352 cur_obj->dwarf_paths to point into it. */ 6353 for (i = 0; i < cur_obj->dwarf_num_paths; i++) 6354 if (cur_obj->dwarf_paths[i]){ 6355 char * st = strbase + output_symtab_info.output_local_strsize; 6356 size_t len = strlen (cur_obj->dwarf_paths[i]) + 1; 6357 output_symtab_info.output_local_strsize += len; 6358 memcpy (st, cur_obj->dwarf_paths[i], len); 6359 cur_obj->dwarf_paths[i] = st; 6360 } 6361 } 6362 6363 /* 6364 * Loop through this object file's local symbols. 6365 */ 6366 localsym_block = cur_obj->localsym_blocks; 6367 debug_ptr = cur_obj->dwarf_source_data; 6368 for(i = 0; i < cur_obj->symtab->nsyms; i++){ 6369 if (debug_ptr && *debug_ptr < i) { 6370 for (debug_ptr += 2; *debug_ptr & 0x80000000; debug_ptr++) ; 6371 } 6372 /* 6373 * Some of the local symbols may be excluded. These have 6374 * localsym_blocks. The localsym_blocks are ordered by the index 6375 * field. For local symbol blocks marked with the state 6376 * EXCLUDED_INCLUDE are for blocks of N_BINCL/N_EINC local symbols 6377 * to be exclude and replaced with a single N_EXCL. For the state 6378 * BEGIN_INCLUDE the sum is just set into the n_value. Others are 6379 * simply excluded as the could have been local symbols for 6380 * coalesced or indirect symbols that were removed. 6381 */ 6382 if(localsym_block != NULL && localsym_block->index == i){ 6383 if(localsym_block->state == EXCLUDED_INCLUDE || 6384 localsym_block->state == BEGIN_INCLUDE){ 6385 *nlist = object_symbols[i]; 6386 if(localsym_block->state == EXCLUDED_INCLUDE) 6387 nlist->n_type = N_EXCL; 6388 nlist->n_value = localsym_block->sum; 6389 /* 6390 * set the string of the N_BINCL/N_EXCL to the output file. 6391 * (it should have one) 6392 */ 6393 if(object_symbols[i].n_un.n_strx != 0){ 6394 int doCopy = 1; 6395 /* try to re-use an existing BINCL string */ 6396 nlist->n_un.n_strx = find_bincl(nlist->n_value, 6397 object_strings + object_symbols[i].n_un.n_strx); 6398 if(nlist->n_un.n_strx != 0){ 6399 if(nlist->n_type == N_EXCL){ 6400 /* EXCL always re-uses BINCL string, 6401 n_un.n_strx already set */ 6402 doCopy = 0; 6403 } 6404 } 6405 else if(nlist->n_type == N_BINCL){ 6406 /* first time this BINCL has been seen, so add it */ 6407 record_bincl(nlist->n_value, 6408 object_strings + 6409 object_symbols[i].n_un.n_strx, 6410 output_symtab_info.output_local_strsize); 6411 } 6412 if(doCopy){ 6413 nlist->n_un.n_strx = output_symtab_info. 6414 output_local_strsize; 6415 string = output_addr + 6416 output_symtab_info.symtab_command.stroff + 6417 output_symtab_info.output_local_strsize; 6418 strcpy(string, 6419 object_strings + 6420 object_symbols[i].n_un.n_strx); 6421 output_symtab_info.output_local_strsize += 6422 strlen(object_strings + 6423 object_symbols[i].n_un.n_strx) + 1; 6424 } 6425 } 6426 output_nsyms++; 6427 nlist++; 6428 } 6429 i += localsym_block->count - 1; /* the loop will do i++ */ 6430 localsym_block = localsym_block->next; 6431 continue; 6432 } 6433 6434 /* Add debug map entries for global symbols. */ 6435 if (cur_obj->dwarf_name 6436 /* The debug map contains symbols defined in a section... */ 6437 && (((object_symbols[i].n_type & (N_TYPE | N_STAB | N_EXT)) 6438 == (N_SECT | N_EXT)) 6439 /* ... and global common symbols. */ 6440 || (((object_symbols[i].n_type & (N_TYPE | N_STAB | N_EXT)) 6441 == (N_UNDF | N_EXT)) 6442 && object_symbols[i].n_value != 0))){ 6443 struct merged_symbol *hash_pointer; 6444 hash_pointer = lookup_symbol(object_strings 6445 + object_symbols[i].n_un.n_strx); 6446 6447 /* Only those symbols whose definitions in this object 6448 were actually output get a debug_map entry. Common symbols 6449 are always 'output' if they are live. */ 6450 if (hash_pointer->name_len != 0 6451 && (! dead_strip || hash_pointer->live) 6452 && (object_symbols[i].n_sect == NO_SECT 6453 || hash_pointer->definition_object == cur_obj)){ 6454 unsigned long symbol_index; 6455 symbol_index = (output_symtab_info.output_merged_strsize 6456 + (merged_symbol_string_index 6457 (hash_pointer->nlist.n_un.n_name))); 6458 add_dwarf_map_for_sym (&hash_pointer->nlist, i, debug_ptr, 6459 symbol_index, object_symbols[i].n_sect, 6460 &nlist, &output_nsyms); 6461 } 6462 } 6463 6464 /* 6465 * If this is a local symbol and it is to be in the output file then 6466 * copy it and it's string into the output file and relocate the 6467 * symbol. 6468 */ 6469 output_strlen = -1; 6470 if((object_symbols[i].n_type & N_EXT) == 0 && 6471 is_output_local_symbol(object_symbols[i].n_type, 6472 object_symbols[i].n_sect, object_symbols[i].n_desc, cur_obj, 6473 object_symbols[i].n_un.n_strx == 0 ? "" : 6474 object_strings + object_symbols[i].n_un.n_strx, 6475 (unsigned long *)&output_strlen)){ 6476 6477 /* 6478 * If is_output_local_symbol() was called in the if() above then 6479 * output_strlen will not be -1. Else we need to calculate the 6480 * output string size. This is without the trailing '\0' since 6481 * if it is set by is_output_local_symbol() we could be 6482 * truncating the string. 6483 */ 6484 if(output_strlen == -1) 6485 output_strlen = object_symbols[i].n_un.n_strx == 0 ? 0: 6486 strlen(object_strings + 6487 object_symbols[i].n_un.n_strx); 6488 /* copy the nlist to the output file */ 6489 *nlist = object_symbols[i]; 6490 relocate_symbol(nlist, cur_obj); 6491 /* 6492 * If we are not producing a relocatable file clear the 6493 * N_NO_DEAD_STRIP bit in non-stab symbols as it is overloaded 6494 * and can't appear in a linked image. 6495 */ 6496 if(save_reloc == FALSE && 6497 (nlist->n_type & N_TYPE) == N_SECT && 6498 (nlist->n_type & N_STAB) == 0) 6499 nlist->n_desc = nlist->n_desc & ~(N_NO_DEAD_STRIP); 6500#ifdef RLD 6501 /* 6502 * Now change the section number of this symbol to the section 6503 * number it will have in the output file. For RLD all this 6504 * has to be done on for only the symbol in an output file and 6505 * not in the merged symbol table. relocate_symbol() does not 6506 * modify n_sect for RLD. 6507 */ 6508 if(nlist->n_sect != NO_SECT) 6509 nlist->n_sect = cur_obj->section_maps[nlist->n_sect - 1]. 6510 output_section->output_sectnum; 6511#endif /* RLD */ 6512 /* 6513 * Now if this is an N_OSO we may need to set the n_value 6514 * and change its name. 6515 */ 6516 if(nlist->n_type == N_OSO){ 6517 /* 6518 * When the compiler is producing dwarf debug info it 6519 * uses stabs for debug notes. And the N_OSO stabs in this 6520 * case has a n_desc field of 1. If the name is the empty 6521 * string (not NULL but a 1 character string with just a 6522 * '\0') then change the name to the full path of the 6523 * object file and set the mod time into n_value. If the 6524 * name is not an empty string it is left unchanged. 6525 */ 6526 if(nlist->n_desc == 1){ 6527 if(object_symbols[i].n_un.n_strx != 0 && 6528 object_strings[object_symbols[i].n_un.n_strx] == 6529 '\0'){ 6530/* GUESS */ 6531 /* 6532 * Copy the string (the full path name) for the 6533 * N_OSO to the output file. 6534 */ 6535 get_stroff_and_mtime_for_N_OSO( 6536 &stroff_for_N_OSO, &mtime); 6537 /* 6538 * Reset the string index and n_value of the N_OSO. 6539 */ 6540 nlist->n_un.n_strx = stroff_for_N_OSO; 6541 nlist->n_value = mtime; 6542 } 6543 /* 6544 * The name of the dwarf N_OSO debug_note is not empty 6545 * so leave it unchanged. 6546 */ 6547 else{ 6548 goto copy_string_to_output_file; 6549 } 6550 } 6551 /* 6552 * When the compiler is producing stabs debug info it will 6553 * produce an N_OSO stab with an n_desc field of 0. 6554 */ 6555 else if(nlist->n_desc == 0){ 6556 /* 6557 * When -Sp is specified then change the name to the 6558 * full path of the object file and set the mod time 6559 * into n_value. 6560 */ 6561 if(strip_level == STRIP_MIN_DEBUG){ 6562/* GUESS */ 6563 /* 6564 * Copy the string (the full path name) for the 6565 * N_OSO to the output file. 6566 */ 6567 get_stroff_and_mtime_for_N_OSO( 6568 &stroff_for_N_OSO, &mtime); 6569 /* 6570 * Reset the string index and n_value of the N_OSO. 6571 */ 6572 nlist->n_un.n_strx = stroff_for_N_OSO; 6573 nlist->n_value = mtime; 6574 } 6575 /* 6576 * When -Sp is not specified the name gets reset to "" 6577 * reset to "" (that a one character string with only a 6578 * '\0' character). Unless the input the n_un.n_strx 6579 * field is 0 then it will end up as 0 in the output. 6580 */ 6581 else{ 6582 output_strlen = 0; 6583 goto copy_string_to_output_file; 6584 } 6585 } 6586 /* 6587 * If the n_desc is not 0 or 1 then leave the name 6588 * unchanged. 6589 */ 6590 else{ 6591 goto copy_string_to_output_file; 6592 } 6593 } 6594 else{ 6595copy_string_to_output_file: 6596 /* copy the string to the output file (if it has one) */ 6597 if(object_symbols[i].n_un.n_strx != 0){ 6598 nlist->n_un.n_strx = output_symtab_info. 6599 output_local_strsize; 6600 string = output_addr + 6601 output_symtab_info.symtab_command.stroff + 6602 output_symtab_info.output_local_strsize; 6603 /* 6604 * Note, output_strlen does not include the trailing 6605 * '\0' as we could be truncating the string. But the 6606 * increment below does as the output memory contains 6607 * zeroes and we use a zero in it after the string as 6608 * the trailing '\0'. 6609 */ 6610 strncpy(string, 6611 object_strings + object_symbols[i].n_un.n_strx, 6612 output_strlen); 6613 output_symtab_info.output_local_strsize += 6614 output_strlen + 1; 6615 } 6616 } 6617 output_nsyms++; 6618 nlist++; 6619 6620 /* Add the DWARF map entry/entries for this local symbol, 6621 if necessary. */ 6622 if(cur_obj->dwarf_name) 6623 add_dwarf_map_for_sym (nlist - 1, i, debug_ptr, 6624 nlist[-1].n_un.n_strx, 6625 object_symbols[i].n_sect, 6626 &nlist, &output_nsyms); 6627 } 6628 } 6629 6630 /* Add terminal DWARF map symbol. */ 6631 if(cur_obj->dwarf_name) 6632 add_dwarf_map_entry (&nlist, &output_nsyms, 0, N_SO, 0, 0, 0); 6633 6634 if(host_byte_sex != target_byte_sex){ 6635 nlist = (struct nlist *)(output_addr + flush_symbol_offset); 6636 swap_nlist(nlist, output_nsyms, target_byte_sex); 6637 } 6638#ifndef RLD 6639 output_flush(flush_symbol_offset, output_nsyms * sizeof(struct nlist)); 6640 output_flush(flush_string_offset, output_symtab_info. 6641 output_local_strsize - 6642 start_string_size); 6643#endif /* !defined(RLD) */ 6644 /* 6645 * Check to make sure the count is consistent. 6646 */ 6647 if(output_nsyms != cur_obj->nlocalsym) 6648 fatal("internal error: output_local_symbols() inconsistent local " 6649 "symbol count"); 6650} 6651 6652/* 6653 * get_stroff_and_mtime_for_N_OSO() is used when modifying an N_OSO from the 6654 * the cur_obj. It places a string with the resolved_path in the string table 6655 * and returns the offset to it indirectly through stroff_for_N_OSO. It also 6656 * returns the modifification time indirectly through mtime. 6657 */ 6658static 6659void 6660get_stroff_and_mtime_for_N_OSO( 6661unsigned long *stroff_for_N_OSO, 6662unsigned long *mtime) 6663{ 6664 char *string, *endptr; 6665#if !(defined(KLD) && defined(__STATIC__)) 6666 struct stat stat_buf; 6667#endif /* !(defined(KLD) && defined(__STATIC__)) */ 6668 6669 *stroff_for_N_OSO = output_symtab_info.output_local_strsize; 6670 string = output_addr + 6671 output_symtab_info.symtab_command.stroff + 6672 output_symtab_info.output_local_strsize; 6673 strcpy(string, cur_obj->resolved_path); 6674 output_symtab_info.output_local_strsize += 6675 cur_obj->resolved_path_len + 1; 6676 /* 6677 * Do not cause errors if we can't get a valid timestamp to use for the 6678 * N_OSO n_value. 6679 */ 6680 if(cur_obj->ar_hdr != NULL) 6681 *mtime = strtol(cur_obj->ar_hdr->ar_date, &endptr, 10); 6682 else{ 6683#if !(defined(KLD) && defined(__STATIC__)) 6684 if(stat(cur_obj->file_name, &stat_buf) != -1) 6685 *mtime = stat_buf.st_mtime; 6686 else 6687#endif /* !(defined(KLD) && defined(__STATIC__)) */ 6688 *mtime = 0; 6689 } 6690} 6691 6692/* 6693 * local_symbol_output_index() calculates the output symbol offset for the 6694 * symbol at index in the object file obj. This is very slow and is only 6695 * called by output_indirect_symbols() when a symbol that was a private extern 6696 * that is no longer external is being used as an indirect symbol. 6697 */ 6698__private_extern__ 6699unsigned long 6700local_symbol_output_index( 6701struct object_file *obj, 6702unsigned long index) 6703{ 6704 unsigned long i, output_nsyms, output_strlen; 6705 struct nlist *object_symbols; 6706 char *object_strings; 6707 struct localsym_block *localsym_block; 6708 6709 /* setup pointers to the symbol table and string table */ 6710 object_symbols = (struct nlist *)(obj->obj_addr + 6711 obj->symtab->symoff); 6712 object_strings = (char *)(obj->obj_addr + obj->symtab->stroff); 6713 output_nsyms = 0; 6714 /* If we are creating section object symbols, count one if needed */ 6715 if(sect_object_symbols.ms != NULL){ 6716 /* 6717 * See if this object file has the section that the section object 6718 * symbols are being created for. 6719 */ 6720 for(i = 0; i < obj->nsection_maps; i++){ 6721 if(sect_object_symbols.ms == 6722 obj->section_maps[i].output_section){ 6723 output_nsyms++; 6724 break; 6725 } 6726 } 6727 } 6728 6729 localsym_block = obj->localsym_blocks; 6730 for(i = 0; i < obj->symtab->nsyms; i++){ 6731 /* skip blocks of symbols that have been removed */ 6732 if(localsym_block != NULL && localsym_block->index == i){ 6733 i += localsym_block->count - 1; /* the loop will do i++ */ 6734 localsym_block = localsym_block->next; 6735 continue; 6736 } 6737 /* 6738 * If this is a local symbol and it is to be in the output file then 6739 * count it. 6740 */ 6741 if((object_symbols[i].n_type & N_EXT) == 0 && 6742 is_output_local_symbol(object_symbols[i].n_type, 6743 object_symbols[i].n_sect, object_symbols[i].n_desc, obj, 6744 object_symbols[i].n_un.n_strx == 0 ? "" : 6745 object_strings + object_symbols[i].n_un.n_strx, 6746 &output_strlen)){ 6747 6748 /* 6749 * This symbol was in the output file if this symbol is at the 6750 * the symbol index we are looking for then we know what output 6751 * index it is. 6752 */ 6753 if(i == index) 6754 return(obj->ilocalsym + output_nsyms); 6755 output_nsyms++; 6756 } 6757 } 6758 fatal("internal error: local_symbol_output_index() could not determine " 6759 "output_index"); 6760 return(0); 6761} 6762 6763/* 6764 * set_merged_string_block_indexes() set the relitive indexes for each merged 6765 * string block. 6766 */ 6767__private_extern__ 6768void 6769set_merged_string_block_indexes( 6770void) 6771{ 6772 unsigned long index; 6773 struct string_block **q, *string_block; 6774 6775 index = 0; 6776 for(q = &(merged_string_blocks); *q; q = &(string_block->next)){ 6777 string_block = *q; 6778 if(strip_base_symbols == TRUE && string_block->base_strings == TRUE) 6779 continue; 6780 if(string_block->dylib_strings == TRUE) 6781 continue; 6782#ifdef RLD 6783 if(string_block->set_num != cur_set) 6784 continue; 6785#endif /* RLD */ 6786 string_block->index = index, 6787 index += string_block->used; 6788 } 6789} 6790 6791/* 6792 * output_merged_symbols() readies the merged symbols for the output file (sets 6793 * string indexes and handles indirect symbols) and copies the merged symbols 6794 * and their strings to the output file. This routine also copies out the 6795 * two-level namespace hints for the undefined symbols if they are to be in 6796 * the output. 6797 */ 6798__private_extern__ 6799void 6800output_merged_symbols(void) 6801{ 6802 unsigned long i, j, flush_symbol_offset, 6803 flush_string_offset, start_string_size; 6804 struct merged_symbol_list *merged_symbol_list; 6805 struct merged_symbol *merged_symbol, *indr_symbol; 6806 struct string_block **q, *string_block; 6807 struct nlist *nlist; 6808 struct twolevel_hint *hint; 6809 6810 if(strip_level == STRIP_ALL) 6811 return; 6812 6813 /* 6814 * Indirect symbols are readied for output. For indirect symbols that 6815 * the symbol they are refering to is defined (not undefined or common) 6816 * the the type, value, etc. of the refered symbol is propagated to 6817 * indirect symbol. If the indirect symbol is not defined then the 6818 * value field is set to the index of the string the symbol is refering 6819 * to. 6820 */ 6821 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 6822 merged_symbol_root->list; 6823 merged_symbol_list != NULL; 6824 merged_symbol_list = merged_symbol_list->next){ 6825 for(i = 0; i < merged_symbol_list->used; i++){ 6826 merged_symbol = merged_symbol_list->symbols[i]; 6827 if(merged_symbol->nlist.n_type == (N_EXT | N_INDR)){ 6828 /* 6829 * If this N_INDR symbol was in a chain has symbols both 6830 * from dylib and not from dylibs get then there was a 6831 * recorded a pair for the merged symbol and the first in 6832 * the chain defined in a dylib for the indr_symbol to be 6833 * used. If not then merged_symbol->nlist.n_value can be 6834 * used. 6835 */ 6836 indr_symbol = NULL; 6837 for(j = 0; j < nindr_symbol_pairs; j++){ 6838 if(indr_symbol_pairs[j].merged_symbol == merged_symbol) 6839 indr_symbol = indr_symbol_pairs[j].indr_symbol; 6840 } 6841 if(indr_symbol == NULL) 6842 indr_symbol = (struct merged_symbol *) 6843 (merged_symbol->nlist.n_value); 6844 6845 /* 6846 * Check to see if this symbol is defined (not undefined or 6847 * common) 6848 */ 6849 if(indr_symbol->nlist.n_type != (N_EXT | N_UNDF) && 6850 indr_symbol->nlist.n_type != (N_EXT | N_PBUD) && 6851 (filetype != MH_DYLIB || 6852 (filetype == MH_DYLIB && multi_module_dylib == FALSE) || 6853 merged_symbol->definition_object == 6854 indr_symbol->definition_object)){ 6855 merged_symbol->nlist.n_type = indr_symbol->nlist.n_type; 6856 merged_symbol->nlist.n_sect = indr_symbol->nlist.n_sect; 6857 merged_symbol->nlist.n_desc = indr_symbol->nlist.n_desc; 6858 merged_symbol->nlist.n_value = 6859 indr_symbol->nlist.n_value; 6860 } 6861 else{ 6862 merged_symbol->nlist.n_value = 6863 output_symtab_info.output_merged_strsize + 6864 merged_symbol_string_index( 6865 indr_symbol->nlist.n_un.n_name); 6866 } 6867 } 6868 } 6869 } 6870 6871 /* 6872 * Copy the merged symbols into the memory buffer for the output file 6873 * and set their string indexes. This is done in three groups: 6874 * the private externals (if keep_private_externs is FALSE) 6875 * the defined external symbols 6876 * the undefined externals 6877 */ 6878 6879 /* 6880 * First group of merged symbols to be copied to into the buffer for 6881 * the output file is the private externs if they are not to be kept 6882 * (that is they are to be made static and not kept as global symbols). 6883 */ 6884 if(nmerged_private_symbols != 0 && 6885 keep_private_externs == FALSE && 6886 (strip_level != STRIP_NONGLOBALS || 6887 (filetype == MH_DYLIB && multi_module_dylib == TRUE)) ){ 6888 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 6889 merged_symbol_root->list; 6890 merged_symbol_list != NULL; 6891 merged_symbol_list = merged_symbol_list->next){ 6892 for(i = 0; i < merged_symbol_list->used; i++){ 6893 merged_symbol = merged_symbol_list->symbols[i]; 6894 if(merged_symbol->referenced_in_non_dylib == FALSE) 6895 continue; 6896 if(strip_base_symbols == TRUE && 6897 merged_symbol->definition_object == base_obj) 6898 continue; 6899#ifdef RLD 6900 if(merged_symbol->definition_object->set_num != cur_set) 6901 continue; 6902#endif /* RLD */ 6903 if(strip_level == STRIP_DYNAMIC_EXECUTABLE && 6904 (((merged_symbol->nlist.n_desc & 6905 REFERENCED_DYNAMICALLY) != REFERENCED_DYNAMICALLY) || 6906 (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)) 6907 continue; 6908 if(dead_strip == TRUE && merged_symbol->live == FALSE) 6909 continue; 6910 6911 /* 6912 * See if this is a defined private extern symbol (but not 6913 * still a common private extern symbol). 6914 */ 6915 if((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT && 6916 (merged_symbol->nlist.n_type & N_TYPE) != N_UNDF){ 6917 /* 6918 * Place this symbol with the local symbols for the 6919 * object that defined this symbol. The output symbol 6920 * index for private externs was calculated by 6921 * assign_output_symbol_indexes() and recorded in 6922 * iprivatesym for the definition object. 6923 */ 6924 flush_symbol_offset = 6925 output_symtab_info.symtab_command.symoff + 6926 merged_symbol->definition_object->iprivatesym * 6927 sizeof(struct nlist); 6928 merged_symbol->definition_object->iprivatesym++; 6929 nlist = (struct nlist *)(output_addr + 6930 flush_symbol_offset); 6931 *nlist = merged_symbol->nlist; 6932 /* 6933 * Since this is a symbol definition make sure the 6934 * weak reference bit is off. 6935 */ 6936 nlist->n_desc = nlist->n_desc & ~(N_WEAK_REF); 6937 /* 6938 * If we are not producing a relocatable file clear the 6939 * N_NO_DEAD_STRIP bit as it is overloaded and can't 6940 * appear in a linked image. 6941 */ 6942 if(save_reloc == FALSE) 6943 nlist->n_desc = nlist->n_desc & ~(N_NO_DEAD_STRIP); 6944 nlist->n_un.n_strx = output_symtab_info. 6945 output_merged_strsize + 6946 merged_symbol_string_index( 6947 merged_symbol->nlist.n_un.n_name); 6948 /* make this private extern a non-external symbol */ 6949 nlist->n_type &= ~(N_EXT); 6950#ifdef RLD 6951 /* 6952 * Now change the section number of this symbol to the 6953 * section number it will have in the output file. For 6954 * RLD all this has to be done for only the symbols in 6955 * the output file and not in the merged symbol table. 6956 * relocate_symbol() does not modify n_sect for RLD. 6957 */ 6958 if(nlist->n_sect != NO_SECT) 6959 nlist->n_sect = merged_symbol->definition_object-> 6960 section_maps[nlist->n_sect - 1]. 6961 output_section->output_sectnum; 6962#endif /* RLD */ 6963 if(host_byte_sex != target_byte_sex) 6964 swap_nlist(nlist, 1, target_byte_sex); 6965#ifndef RLD 6966 output_flush(flush_symbol_offset, sizeof(struct nlist)); 6967#endif /* !defined(RLD) */ 6968 } 6969 } 6970 } 6971 } 6972 /* 6973 * Second group of merged symbols to be copied to into the buffer for 6974 * the output file is the defined externals. They are copied out in the 6975 * order creaded by assign_output_symbol_indexes() and left in the array 6976 * extdefsyms_order. 6977 */ 6978 flush_symbol_offset = output_symtab_info.symtab_command.symoff + 6979 output_dysymtab_info.dysymtab_command.iextdefsym * 6980 sizeof(struct nlist); 6981 nlist = (struct nlist *)(output_addr + flush_symbol_offset); 6982 for(i = 0; i < output_dysymtab_info.dysymtab_command.nextdefsym; i++){ 6983 merged_symbol = extdefsyms_order[i]; 6984 *nlist = merged_symbol->nlist; 6985 /* 6986 * Since this is a symbol definition make sure the weak reference 6987 * bit is off. 6988 */ 6989 nlist->n_desc = nlist->n_desc & ~(N_WEAK_REF); 6990 /* 6991 * If we are not producing a relocatable file clear the 6992 * N_NO_DEAD_STRIP bit as it is overloaded and can't appear in a 6993 * linked image. 6994 */ 6995 if(save_reloc == FALSE) 6996 nlist->n_desc = nlist->n_desc & ~(N_NO_DEAD_STRIP); 6997 nlist->n_un.n_strx = output_symtab_info.output_merged_strsize + 6998 merged_symbol_string_index( 6999 merged_symbol->nlist.n_un.n_name); 7000 /* 7001 * If this defined external symbol is also a weak definition then 7002 * set the MH_WEAK_DEFINES and MH_BINDS_TO_WEAK bits in the 7003 * mach_header. 7004 */ 7005 if(nlist->n_desc & N_WEAK_DEF) 7006 output_mach_header.flags |= MH_WEAK_DEFINES | MH_BINDS_TO_WEAK; 7007#ifdef RLD 7008 /* 7009 * Now change the section number of this symbol to the section 7010 * number it will have in the output file. For RLD all this 7011 * has to be done on for only the symbol in an output file and 7012 * not in the merged symbol table. relocate_symbol() does not 7013 * modify n_sect for RLD. 7014 */ 7015 if(nlist->n_sect != NO_SECT) 7016 nlist->n_sect = merged_symbol->definition_object-> 7017 section_maps[nlist->n_sect - 1]. 7018 output_section->output_sectnum; 7019#endif 7020 nlist++; 7021 } 7022 if(host_byte_sex != target_byte_sex){ 7023 nlist = (struct nlist *)(output_addr + flush_symbol_offset); 7024 swap_nlist(nlist, output_dysymtab_info.dysymtab_command.nextdefsym, 7025 target_byte_sex); 7026 } 7027#ifndef RLD 7028 output_flush(flush_symbol_offset, 7029 output_dysymtab_info.dysymtab_command.nextdefsym * 7030 sizeof(struct nlist)); 7031#endif 7032 if(extdefsyms_order != NULL){ 7033 free(extdefsyms_order); 7034 extdefsyms_order = NULL; 7035 } 7036 /* 7037 * Third group of merged symbols to be copied to into the buffer for 7038 * the output file is the undefined symbols. They are copied out in the 7039 * order creaded by assign_output_symbol_indexes() and left in the array 7040 * undefsyms_order. 7041 */ 7042 flush_symbol_offset = output_symtab_info.symtab_command.symoff + 7043 output_dysymtab_info.dysymtab_command.iundefsym * 7044 sizeof(struct nlist); 7045 nlist = (struct nlist *)(output_addr + flush_symbol_offset); 7046 for(i = 0; i < output_dysymtab_info.dysymtab_command.nundefsym; i++){ 7047 merged_symbol = undefsyms_order[i]; 7048 *nlist = merged_symbol->nlist; 7049 /* 7050 * Since this is an undefined symbol make sure the weak definition 7051 * bit and N_NO_DEAD_STRIP bits are off. 7052 */ 7053 nlist->n_desc = nlist->n_desc & ~(N_WEAK_DEF & N_NO_DEAD_STRIP); 7054 /* 7055 * If this undefined symbol is referencing an undefined symbol that 7056 * is a weak symbol set the N_REF_TO_WEAK bit and set the 7057 * MH_BINDS_TO_WEAK bit in the mach_header. 7058 */ 7059 if(merged_symbol->defined_in_dylib == TRUE && 7060 merged_symbol->weak_def_in_dylib == TRUE){ 7061 nlist->n_desc |= N_REF_TO_WEAK; 7062 output_mach_header.flags |= MH_BINDS_TO_WEAK; 7063 } 7064 nlist->n_un.n_strx = output_symtab_info.output_merged_strsize + 7065 merged_symbol_string_index( 7066 merged_symbol->nlist.n_un.n_name); 7067 /* note all undefined symbols have n_sect == NO_SECT */ 7068 nlist++; 7069 } 7070 if(host_byte_sex != target_byte_sex){ 7071 nlist = (struct nlist *)(output_addr + flush_symbol_offset); 7072 swap_nlist(nlist, output_dysymtab_info.dysymtab_command.nundefsym, 7073 target_byte_sex); 7074 } 7075#ifndef RLD 7076 output_flush(flush_symbol_offset, 7077 output_dysymtab_info.dysymtab_command.nundefsym * 7078 sizeof(struct nlist)); 7079#endif 7080 /* 7081 * Copy the merged strings into the memory buffer for the output file. 7082 */ 7083 flush_string_offset = output_symtab_info.symtab_command.stroff + 7084 output_symtab_info.output_merged_strsize; 7085 start_string_size = output_symtab_info.output_merged_strsize; 7086 for(q = &(merged_string_blocks); *q; q = &(string_block->next)){ 7087 string_block = *q; 7088 if(strip_base_symbols == TRUE && string_block->base_strings == TRUE) 7089 continue; 7090 if(string_block->dylib_strings == TRUE) 7091 continue; 7092#ifdef RLD 7093 if(string_block->set_num != cur_set) 7094 continue; 7095#endif /* RLD */ 7096 memcpy(output_addr + output_symtab_info.symtab_command.stroff + 7097 output_symtab_info.output_merged_strsize, 7098 string_block->strings, 7099 string_block->used); 7100 output_symtab_info.output_merged_strsize += string_block->used; 7101 } 7102 7103#ifndef RLD 7104 output_flush(flush_string_offset, output_symtab_info. 7105 output_merged_strsize - 7106 start_string_size); 7107#endif /* !defined(RLD) */ 7108 7109 /* 7110 * Lastly create and copy out the two-level namespace hints for the 7111 * undefined symbols. This must be in the same order as the undefined 7112 * symbols so the undefsyms_order array is used. 7113 */ 7114 hint = (struct twolevel_hint *)(output_addr + 7115 output_hints_info.twolevel_hints_command.offset); 7116 if(output_for_dyld && twolevel_namespace == TRUE && 7117 twolevel_namespace_hints == TRUE){ 7118 for(i = 0; i < output_dysymtab_info.dysymtab_command.nundefsym;i++){ 7119 merged_symbol = undefsyms_order[i]; 7120 hint->isub_image = merged_symbol->definition_object->isub_image; 7121 hint->itoc = merged_symbol->itoc; 7122 hint++; 7123 } 7124 if(host_byte_sex != target_byte_sex){ 7125 hint = (struct twolevel_hint *)(output_addr + 7126 output_hints_info.twolevel_hints_command.offset); 7127 swap_twolevel_hint(hint, 7128 output_dysymtab_info.dysymtab_command.nundefsym, 7129 target_byte_sex); 7130 } 7131#ifndef RLD 7132 output_flush(output_hints_info.twolevel_hints_command.offset, 7133 output_dysymtab_info.dysymtab_command.nundefsym * 7134 sizeof(struct twolevel_hint)); 7135#endif 7136 } 7137 /* 7138 * Now the undefsyms_order array is no longer needed. 7139 */ 7140 if(undefsyms_order != NULL){ 7141 free(undefsyms_order); 7142 undefsyms_order = NULL; 7143 } 7144} 7145 7146#if defined(RLD) && !defined(SA_RLD) 7147/* 7148 * output_rld_symfile_merged_symbols() copies the merged symbol table into the 7149 * output file for the rld symfile. It makes all the symbols absolute. 7150 */ 7151__private_extern__ 7152void 7153output_rld_symfile_merged_symbols( 7154void) 7155{ 7156 struct nlist *nlist; 7157 struct merged_symbol_list *merged_symbol_list; 7158 struct merged_symbol *merged_symbol; 7159 unsigned long string_offset; 7160 struct string_block **q, *string_block; 7161 unsigned long i; 7162 7163 nlist = (struct nlist *)(output_addr + 7164 output_symtab_info.symtab_command.symoff); 7165 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 7166 merged_symbol_root->list; 7167 merged_symbol_list != NULL; 7168 merged_symbol_list = merged_symbol_list->next){ 7169 for(i = 0; i < merged_symbol_list->used; i++){ 7170 merged_symbol = merged_symbol_list->symbols[i]; 7171 if(merged_symbol->definition_object->set_num != cur_set) 7172 continue; 7173 *nlist = merged_symbol->nlist; 7174 nlist->n_un.n_strx = output_symtab_info.output_merged_strsize + 7175 merged_symbol_string_index( 7176 merged_symbol->nlist.n_un.n_name); 7177 nlist->n_sect = NO_SECT; 7178 nlist->n_type = N_ABS | N_EXT; 7179 nlist++; 7180 } 7181 } 7182 7183 /* 7184 * Copy the merged strings into the memory buffer for the output file. 7185 */ 7186 string_offset = output_symtab_info.symtab_command.stroff + 7187 output_symtab_info.output_merged_strsize; 7188 for(q = &(merged_string_blocks); *q; q = &(string_block->next)){ 7189 string_block = *q; 7190 if(string_block->set_num != cur_set) 7191 continue; 7192 memcpy(output_addr + output_symtab_info.symtab_command.stroff + 7193 output_symtab_info.output_merged_strsize, 7194 string_block->strings, 7195 string_block->used); 7196 output_symtab_info.output_merged_strsize += string_block->used; 7197 } 7198} 7199#endif /* defined(RLD) && !defined(SA_RLD) */ 7200 7201/* 7202 * merged_symbol_string_index() returns the string index of a merged symbol's 7203 * name relative to the start of the merged strings. 7204 */ 7205static 7206unsigned long 7207merged_symbol_string_index( 7208char *symbol_name) 7209{ 7210#ifndef RLD 7211 static struct string_block *string_block = NULL; 7212 7213 if(string_block == NULL) 7214 string_block = merged_string_blocks; 7215 7216 if(symbol_name < string_block->strings || 7217 symbol_name >= string_block->strings + string_block->used) 7218 string_block = get_string_block(symbol_name); 7219#else 7220 struct string_block *string_block; 7221 7222 string_block = get_string_block(symbol_name); 7223#endif 7224 return(string_block->index + (symbol_name - string_block->strings)); 7225} 7226 7227/* 7228 * get_string_block() returns a pointer to the string block the specified 7229 * merged symbol name is in. 7230 */ 7231static 7232struct string_block * 7233get_string_block( 7234char *symbol_name) 7235{ 7236 struct string_block **p, *string_block; 7237 7238 for(p = &(merged_string_blocks); *p; p = &(string_block->next)){ 7239 string_block = *p; 7240 if(symbol_name >= string_block->strings && 7241 symbol_name < string_block->strings + string_block->used) 7242 return(string_block); 7243 } 7244 fatal("internal error: get_string_block() called with symbol_name (%s) " 7245 "not in the string blocks", symbol_name); 7246 return(NULL); /* to prevent warning from compiler */ 7247} 7248 7249/* 7250 * process_undefineds() is called after all the dylibs have been searched in 7251 * layout. It first checks for undefined symbols. Then it sets the value of 7252 * nmerged_symbols_referenced_only_from_dylibs which is the number of merged 7253 * symbols that are only referenced from dylibs and will not appear in the 7254 * output file. 7255 */ 7256__private_extern__ 7257void 7258process_undefineds( 7259void) 7260{ 7261 unsigned long i, j, Ycount, errors_save; 7262 struct merged_symbol_list *merged_symbol_list; 7263 struct merged_symbol *merged_symbol; 7264 enum bool printed_undef, allowed_undef, prebound_undef; 7265 struct object_list *object_list, **q; 7266#ifndef RLD 7267 unsigned long k; 7268 struct nlist *object_symbols; 7269 struct object_file *obj; 7270 struct undefined_list *undefined, *prevs; 7271 char *short_name; 7272 struct dynamic_library *dep, *lib, *prev_lib; 7273 unsigned long library_ordinal; 7274 enum bool reported, weak_ref_warning; 7275#endif 7276 7277 errors_save = 0; 7278 printed_undef = FALSE; 7279 prebound_undef = FALSE; 7280 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 7281 merged_symbol_root->list; 7282 merged_symbol_list != NULL; 7283 merged_symbol_list = merged_symbol_list->next){ 7284 for(i = 0; i < merged_symbol_list->used; i++){ 7285 merged_symbol = merged_symbol_list->symbols[i]; 7286 /* 7287 * If the output file is not relocatable check to see if this 7288 * symbol is undefined. If it is and it is not on the allowed 7289 * undefined list print it's name. 7290 */ 7291 if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) && 7292 merged_symbol->nlist.n_value == 0){ 7293 /* 7294 * If we are dead stripping and this undefined symbol is not 7295 * live just ignore it. 7296 */ 7297 if(dead_strip == TRUE && 7298 merged_symbol->live == FALSE) 7299 continue; 7300 7301 if(prebinding == TRUE){ 7302 if(ld_trace_prebinding_disabled == TRUE) 7303 print("[Logging for XBS] prebinding" 7304 " disabled for %s because of undefined " 7305 "symbols\n", final_output != NULL ? 7306 final_output : outputfile); 7307 warning("prebinding disabled because of undefined " 7308 "symbols"); 7309 prebinding = FALSE; 7310 prebound_undef = TRUE; 7311 } 7312 allowed_undef = FALSE; 7313 if(nundef_syms != 0){ 7314 for(j = 0; j < nundef_syms; j++){ 7315 if(strcmp(undef_syms[j], 7316 merged_symbol->nlist.n_un.n_name) == 0){ 7317 allowed_undef = TRUE; 7318 break; 7319 } 7320 } 7321 } 7322 if(allowed_undef == FALSE) 7323 noundefs = FALSE; 7324 if(save_reloc == FALSE && 7325 (undefined_flag == UNDEFINED_ERROR || 7326 undefined_flag == UNDEFINED_WARNING)){ 7327 if(allowed_undef == FALSE || prebound_undef == TRUE){ 7328 if(printed_undef == FALSE){ 7329 if(undefined_flag == UNDEFINED_WARNING) 7330 warning("undefined symbols:"); 7331 else{ 7332 if(allowed_undef == TRUE && 7333 prebound_undef == TRUE) 7334 errors_save = errors; 7335 error("Undefined symbols:"); 7336 if(allowed_undef == TRUE && 7337 prebound_undef == TRUE) 7338 errors = errors_save; 7339 } 7340 printed_undef = TRUE; 7341 } 7342 else if(errors == 0 && 7343 undefined_flag == UNDEFINED_ERROR && 7344 allowed_undef == FALSE){ 7345 errors = 1; 7346 } 7347 print("%s\n", merged_symbol->nlist.n_un.n_name); 7348 } 7349 } 7350 else if(save_reloc == FALSE && 7351 undefined_flag == UNDEFINED_DYNAMIC_LOOKUP && 7352 twolevel_namespace == TRUE){ 7353 SET_LIBRARY_ORDINAL(merged_symbol->nlist.n_desc, 7354 DYNAMIC_LOOKUP_ORDINAL); 7355 } 7356 } 7357#ifndef RLD 7358 else { 7359 /* 7360 * The merged symbol is not an undefined symbol. But could 7361 * be defined in a dynamic library as a coalesed symbol or 7362 * a weak symbol. Where a later symbol was discarded from a 7363 * non_dylib. If -twolevel_namespace is in effect this 7364 * symbol, now a reference from an object, is going into 7365 * the image and will need the library ordinal recorded. 7366 * We need to see that this dynamic library has been 7367 * assigned an ordinal (that is it was listed on the link 7368 * line or is a sub-framework or sub-umbrella of 7369 * something listed). If not flag this as an illegal 7370 * reference to an indirect dynamic library if this library 7371 * was not flagged already. 7372 */ 7373 if(save_reloc == FALSE && 7374 twolevel_namespace == TRUE && 7375 merged_symbol->defined_in_dylib == TRUE && 7376 merged_symbol->referenced_in_non_dylib == TRUE && 7377 merged_symbol->definition_library-> 7378 definition_obj->library_ordinal == 0 && 7379 merged_symbol->definition_library-> 7380 indirect_twolevel_ref_flagged == FALSE){ 7381 obj = cur_obj; 7382 cur_obj = merged_symbol->non_dylib_referenced_obj; 7383 error_with_cur_obj("illegal reference to symbol: %s " 7384 "defined in indirectly referenced dynamic library " 7385 "%s", merged_symbol->nlist.n_un.n_name, 7386 merged_symbol->definition_library->dylib_file 7387 != NULL ? 7388 merged_symbol->definition_library->file_name : 7389 merged_symbol->definition_library->dylib_name); 7390 cur_obj = obj; 7391 merged_symbol->definition_library-> 7392 indirect_twolevel_ref_flagged = TRUE; 7393 } 7394 } 7395#endif /* !defined(RLD) */ 7396 } 7397 } 7398 7399#ifndef RLD 7400 /* 7401 * Deal with weak references. If we have them and the target deployment 7402 * does not support them generate a warning can clear the weak reference 7403 * bit. 7404 */ 7405 if(macosx_deployment_target.major <= 1){ 7406 weak_ref_warning = FALSE; 7407 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 7408 merged_symbol_root->list; 7409 merged_symbol_list != NULL; 7410 merged_symbol_list = merged_symbol_list->next){ 7411 for(i = 0; i < merged_symbol_list->used; i++){ 7412 merged_symbol = merged_symbol_list->symbols[i]; 7413 if(((merged_symbol->nlist.n_type == (N_EXT | N_UNDF) && 7414 merged_symbol->nlist.n_value == 0) || 7415 (merged_symbol->nlist.n_type & N_TYPE) == N_PBUD) && 7416 (merged_symbol->nlist.n_desc & N_WEAK_REF) == 7417 N_WEAK_REF){ 7418 if(weak_ref_warning == FALSE){ 7419 warning("weak symbol references not set in output " 7420 "with MACOSX_DEPLOYMENT_TARGET environment " 7421 "variable set to: %s", 7422 macosx_deployment_target.name); 7423 warning("weak referenced symbols:"); 7424 weak_ref_warning = TRUE; 7425 } 7426 merged_symbol->nlist.n_desc &= ~(N_WEAK_REF); 7427 print("%s\n", merged_symbol->nlist.n_un.n_name); 7428 } 7429 } 7430 } 7431 } 7432 /* 7433 * The target deployment does support weak references. 7434 */ 7435 else{ 7436 /* 7437 * If there have been some weak reference mismatches when symbols 7438 * were merged make a pass through merged symbols and for any 7439 * symbols that had a weak reference mismatch that is still 7440 * undefined print the error for it. 7441 */ 7442 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 7443 merged_symbol_root->list; 7444 merged_symbol_list != NULL; 7445 merged_symbol_list = merged_symbol_list->next){ 7446 for(i = 0; i < merged_symbol_list->used; i++){ 7447 merged_symbol = merged_symbol_list->symbols[i]; 7448 if(merged_symbol->weak_reference_mismatch == TRUE && 7449 ((merged_symbol->nlist.n_type == (N_EXT | N_UNDF) && 7450 merged_symbol->nlist.n_value == 0) || 7451 (merged_symbol->nlist.n_type & N_TYPE) == N_PBUD) && 7452 (merged_symbol->defined_in_dylib == FALSE || 7453 merged_symbol->definition_library-> 7454 force_weak_dylib == FALSE)){ 7455 error("mismatching weak references for symbol: %s", 7456 merged_symbol->nlist.n_un.n_name); 7457 for(q = &objects; *q; q = &(object_list->next)){ 7458 object_list = *q; 7459 for(j = 0; j < object_list->used; j++){ 7460 cur_obj = &(object_list->object_files[j]); 7461 if(cur_obj->dylib && cur_obj->dylib_module == 7462 NULL) 7463 continue; 7464 if(cur_obj->bundle_loader) 7465 continue; 7466 if(cur_obj->dylinker) 7467 continue; 7468 for(k = 0; k < cur_obj->nundefineds; k++){ 7469 if(merged_symbol == cur_obj-> 7470 undefined_maps[k].merged_symbol){ 7471 print_obj_name(cur_obj); 7472 object_symbols = (struct nlist *) 7473 (cur_obj->obj_addr + 7474 cur_obj->symtab->symoff); 7475 if((object_symbols[ 7476 cur_obj->undefined_maps[ 7477 k].index].n_desc & N_WEAK_REF) == 7478 N_WEAK_REF) 7479 print("reference to weak %s\n", 7480 merged_symbol->nlist.n_un.n_name); 7481 else 7482 print("reference to non-weak %s\n", 7483 merged_symbol->nlist.n_un.n_name); 7484 } 7485 } 7486 } 7487 } 7488 } 7489 } 7490 } 7491 } 7492#endif /* !defined(RLD) */ 7493 7494#ifndef RLD 7495 lib = NULL; 7496 prev_lib = NULL; 7497 /* 7498 * There can be two-level references left on the undefined list. These 7499 * are "fake" merged symbols as they are not entered in the symbol 7500 * merged table so the will not be reported in the above loop. There 7501 * can be many references to the same symbol expected to be defined in 7502 * ( a specific library (from many different modules). 7503 */ 7504 for(undefined = undefined_list.next; 7505 undefined != &undefined_list; 7506 undefined = undefined->next){ 7507 if(undefined->merged_symbol->twolevel_reference == TRUE){ 7508 /* 7509 * Avoid printing the same undefined symbol expected from a 7510 * a specific library more then once by checking if we have 7511 * already reported this symbol before. This is very slow 7512 * method but this is an error case. 7513 */ 7514 library_ordinal = GET_LIBRARY_ORDINAL( 7515 undefined->merged_symbol->nlist.n_desc); 7516 if(library_ordinal == SELF_LIBRARY_ORDINAL) 7517 lib = undefined->merged_symbol->referencing_library; 7518 /* 7519 * Note that if library_ordinal was DYNAMIC_LOOKUP_ORDINAL then 7520 * merge_dylib_module_symbols() in symbols.c would not have 7521 * set the twolevel_reference field to TRUE in the merged_symbol 7522 * and if we get here it with this it is an internal error. 7523 */ 7524 else if(library_ordinal == DYNAMIC_LOOKUP_ORDINAL) 7525 fatal("internal error: process_undefineds() 1 with a " 7526 "merged_symbol (%s) on the undefined list with " 7527 "twolevel_reference == TRUE and library_ordinal == " 7528 "DYNAMIC_LOOKUP_ORDINAL", undefined->merged_symbol-> 7529 nlist.n_un.n_name); 7530 else 7531 lib = undefined->merged_symbol->referencing_library-> 7532 dependent_images[library_ordinal - 1]; 7533 reported = FALSE; 7534 for(prevs = undefined_list.next; 7535 prevs != undefined; 7536 prevs = prevs->next){ 7537 if(prevs->merged_symbol->twolevel_reference == FALSE) 7538 continue; 7539 library_ordinal = GET_LIBRARY_ORDINAL( 7540 prevs->merged_symbol->nlist.n_desc); 7541 if(library_ordinal == SELF_LIBRARY_ORDINAL) 7542 prev_lib = prevs->merged_symbol->referencing_library; 7543 /* 7544 * Note that if library_ordinal was DYNAMIC_LOOKUP_ORDINAL 7545 * then merge_dylib_module_symbols() in symbols.c would not 7546 * have set the twolevel_reference field to TRUE in the 7547 * merged_symbol and if we get here it with this it is an 7548 * internal error. 7549 */ 7550 else if(library_ordinal == DYNAMIC_LOOKUP_ORDINAL) 7551 fatal("internal error: process_undefineds() 2 with a " 7552 "merged_symbol (%s) on the undefined list with " 7553 "twolevel_reference == TRUE and library_ordinal " 7554 "== DYNAMIC_LOOKUP_ORDINAL", 7555 prevs->merged_symbol->nlist.n_un.n_name); 7556 else 7557 prev_lib = prevs->merged_symbol->referencing_library-> 7558 dependent_images[library_ordinal - 1]; 7559 if(lib == prev_lib && 7560 strcmp(undefined->merged_symbol->nlist.n_un.n_name, 7561 prevs->merged_symbol->nlist.n_un.n_name) == 0){ 7562 reported = TRUE; 7563 break; 7564 } 7565 } 7566 if(reported == FALSE){ 7567 /* 7568 * Since these are undefined two-level references they are 7569 * never allowed and always cause an error. 7570 */ 7571 if(printed_undef == FALSE){ 7572 error("Undefined symbols:"); 7573 printed_undef = TRUE; 7574 } 7575 print("%s ", undefined->merged_symbol->nlist.n_un.n_name); 7576 dep = undefined->merged_symbol->referencing_library; 7577 if(dep->umbrella_name != NULL) 7578 short_name = dep->umbrella_name; 7579 else if(dep->library_name != NULL) 7580 short_name = dep->library_name; 7581 else 7582 short_name = dep->dylib_name; 7583 print("referenced from %s ", short_name); 7584 if(lib->umbrella_name != NULL) 7585 short_name = lib->umbrella_name; 7586 else if(lib->library_name != NULL) 7587 short_name = lib->library_name; 7588 else 7589 short_name = lib->dylib_name; 7590 print("expected to be defined in %s\n", short_name); 7591 } 7592 } 7593 } 7594#endif /* !defined(RLD) */ 7595 7596 if(printed_undef == TRUE && Yflag != 0){ 7597 Ycount = 0; 7598 for(q = &objects; *q; q = &(object_list->next)){ 7599 object_list = *q; 7600 for(i = 0; i < object_list->used; i++){ 7601 cur_obj = &(object_list->object_files[i]); 7602 if(cur_obj->dylib) 7603 continue; 7604 if(cur_obj->bundle_loader) 7605 continue; 7606 if(cur_obj->dylinker) 7607 continue; 7608 for(j = 0; j < cur_obj->nundefineds; j++){ 7609 merged_symbol = 7610 cur_obj->undefined_maps[j].merged_symbol; 7611 if(merged_symbol == NULL || 7612 merged_symbol->twolevel_reference == TRUE) 7613 continue; 7614 if(merged_symbol->nlist.n_type == (N_EXT|N_UNDF) && 7615 merged_symbol->nlist.n_value == 0){ 7616 if(Ycount >= Yflag){ 7617 print("more references to undefined " 7618 "symbols ...\n"); 7619 goto done; 7620 } 7621 print_obj_name(cur_obj); 7622 print("%sreference to undefined %s", 7623 merged_symbol->nlist.n_desc & N_WEAK_REF ? 7624 "weak " : "", 7625 merged_symbol->nlist.n_un.n_name); 7626#ifndef RLD 7627 library_ordinal = GET_LIBRARY_ORDINAL( 7628 merged_symbol->nlist.n_desc); 7629 if(merged_symbol->twolevel_reference == TRUE && 7630 library_ordinal != DYNAMIC_LOOKUP_ORDINAL){ 7631 if(library_ordinal == SELF_LIBRARY_ORDINAL) 7632 lib = merged_symbol->referencing_library; 7633 else 7634 lib = merged_symbol->referencing_library-> 7635 dependent_images[library_ordinal - 1]; 7636 if(lib->umbrella_name != NULL) 7637 short_name = lib->umbrella_name; 7638 else if(lib->library_name != NULL) 7639 short_name = lib->library_name; 7640 else 7641 short_name = lib->dylib_name; 7642 print(" expected to be defined in %s\n", 7643 short_name); 7644 } 7645 else 7646#endif /* !defined(RLD) */ 7647 print("\n"); 7648 Ycount++; 7649 } 7650 } 7651 } 7652 } 7653 } 7654done: 7655 /* 7656 * Determine the number of merged symbols that are only referenced from 7657 * dylibs. These will not be in the output file so this count is need 7658 * so the number of merged symbols in the output file is know for 7659 * laying out the output file. 7660 */ 7661 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 7662 merged_symbol_root->list; 7663 merged_symbol_list != NULL; 7664 merged_symbol_list = merged_symbol_list->next){ 7665 for(i = 0; i < merged_symbol_list->used; i++){ 7666 merged_symbol = merged_symbol_list->symbols[i]; 7667 /* 7668 * If this symbol is only referenced from a dylib then it will 7669 * not be in the file's output. 7670 */ 7671 if(merged_symbol->referenced_in_non_dylib == FALSE) 7672 nmerged_symbols_referenced_only_from_dylibs++; 7673 } 7674 } 7675} 7676 7677#ifndef RLD 7678/* 7679 * reset_prebound_undefines() resets the prebound undefined symbols back to 7680 * undefined symbols if prebinding is not to be done. 7681 */ 7682__private_extern__ 7683void 7684reset_prebound_undefines( 7685void) 7686{ 7687 unsigned long i; 7688 struct merged_symbol_list *merged_symbol_list; 7689 struct merged_symbol *merged_symbol, *indr_symbol; 7690 7691 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 7692 merged_symbol_root->list; 7693 merged_symbol_list != NULL; 7694 merged_symbol_list = merged_symbol_list->next){ 7695 for(i = 0; i < merged_symbol_list->used; i++){ 7696 merged_symbol = merged_symbol_list->symbols[i]; 7697 if((merged_symbol->nlist.n_type & N_TYPE) == N_PBUD){ 7698 /* 7699 * If not prebinding then reset this prebound undefined 7700 * to an undefined symbol. 7701 */ 7702 if(prebinding == FALSE){ 7703 merged_symbol->nlist.n_type = N_UNDF | N_EXT; 7704 merged_symbol->nlist.n_value = 0; 7705 merged_symbol->nlist.n_desc &= ~REFERENCED_DYNAMICALLY; 7706 } 7707 } 7708 else if(merged_symbol->nlist.n_type == (N_EXT | N_INDR) && 7709 merged_symbol->defined_in_dylib == TRUE){ 7710 /* 7711 * If not prebinding then reset this indirect symbol that 7712 * was defined in a dylib back to an undefined symbol. 7713 */ 7714 if(prebinding == FALSE){ 7715 merged_symbol->nlist.n_type = N_UNDF | N_EXT; 7716 merged_symbol->nlist.n_value = 0; 7717 merged_symbol->nlist.n_desc &= ~REFERENCED_DYNAMICALLY; 7718 } 7719 else{ 7720 /* 7721 * When prebinding if the indirect symbol is defined 7722 * (not an undefined of common) then change the indirect 7723 * symbol to a prebound undefined using the value of the 7724 * indr symbol. Else make it an undefined symbol. 7725 */ 7726 indr_symbol = (struct merged_symbol *) 7727 (merged_symbol->nlist.n_value); 7728 if(indr_symbol->nlist.n_type != (N_EXT | N_UNDF)){ 7729 merged_symbol->nlist.n_type = N_PBUD | N_EXT; 7730 merged_symbol->nlist.n_sect = NO_SECT; 7731 /* 7732 * Do not change the n_desc of the symbol as it 7733 * contains the proper LAZY or NON-LAZY reference 7734 * bits as well as the REFERENCED_DYNAMICALLY bit. 7735 */ 7736 merged_symbol->nlist.n_value = 7737 indr_symbol->nlist.n_value; 7738 } 7739 else{ 7740 merged_symbol->nlist.n_type = N_UNDF | N_EXT; 7741 merged_symbol->nlist.n_value = 0; 7742 merged_symbol->nlist.n_desc &= 7743 ~REFERENCED_DYNAMICALLY; 7744 } 7745 } 7746 } 7747 } 7748 } 7749} 7750#endif /* !defined(RLD) */ 7751 7752/* 7753 * assign_output_symbol_indexes() assigns the symbol indexes to all symbols in 7754 * the output file based on the type of output file (MH_DYLIB or not). The 7755 * difference for the MH_DYLIB format is that the external symbol are grouped 7756 * by the module they are defined in instead of being sorted by symbol name. 7757 * The order of the symbol table is as follows: 7758 * Local Symbols 7759 * Grouped by the module they are defined in 7760 * sect_object_symbol (if specified) 7761 * local symbols in the same order as the input module 7762 * private_extern symbols (if -keep_private_externs is FALSE) 7763 * Exterally defined Symbols 7764 * Sorted by name for non-MH_DYLIB format 7765 * Grouped by the module they are defined in for MH_DYLIB format 7766 * Undefinded Symbols 7767 * Sorted by name 7768 */ 7769__private_extern__ 7770void 7771assign_output_symbol_indexes( 7772void) 7773{ 7774 unsigned long index, i, nextdefsym, nundefsym, n_pext; 7775 struct merged_symbol_list *merged_symbol_list; 7776 struct merged_symbol *merged_symbol, *indr_symbol; 7777 struct object_list *object_list, **q; 7778 struct object_file *last_object; 7779 enum bool rebuild_merged_string_table; 7780 7781 rebuild_merged_string_table = FALSE; 7782 if(strip_level == STRIP_ALL){ 7783 if(has_dynamic_linker_command){ 7784 strip_level = STRIP_DYNAMIC_EXECUTABLE; 7785 /* 7786 * In order to not put out strings for merged symbols that will 7787 * be discared we need to rebuild the merged string table for 7788 * only the symbols not stripped. 7789 */ 7790 merged_string_blocks = NULL; 7791 merged_string_size = 0; 7792 rebuild_merged_string_table = TRUE; 7793 /* 7794 * The value of nstripped_merged_symbols is reset here since we 7795 * are setting the strip_level to STRIP_DYNAMIC_EXECUTABLE. 7796 * This routine will then increment nstripped_merged_symbols 7797 * for the symbols to be stripped. It may have previouly held 7798 * the count of dead symbols to strip if -dead_strip was 7799 * specified. We start with the the number of dead stripped 7800 * merged private symbols then add the live merged symbols to 7801 * strip. This works since any symbol to be saved with 7802 * STRIP_DYNAMIC_EXECUTABLE would also be live since it would 7803 * have REFERENCED_DYNAMICALLY set. Except for undefined 7804 * symbols, so if -dead_strip is specified and the undefined 7805 * symbol is not live then nstripped_merged_symbols 7806 * is incremented to account for these. 7807 */ 7808 nstripped_merged_symbols = nstripped_merged_private_symbols; 7809 } 7810 else{ 7811 seglinkedit = FALSE; 7812 return; 7813 } 7814 } 7815 /* 7816 * If we are stripping non-globals and we are not keeping private 7817 * externs and we have some private externs in the merged symbol table, 7818 * and the output is not a multi-module dylib, then in order to not put 7819 * out strings for them we also need to rebuild the merged string table 7820 * without these symbols. 7821 */ 7822 else if(strip_level == STRIP_NONGLOBALS && 7823 keep_private_externs == FALSE && 7824 nmerged_private_symbols != 0 && 7825 (filetype != MH_DYLIB || multi_module_dylib == FALSE)){ 7826 merged_string_blocks = NULL; 7827 merged_string_size = 0; 7828 rebuild_merged_string_table = TRUE; 7829 } 7830 7831 /* 7832 * Add a copy of the object file for the common symbols that the link 7833 * editor allocated into the object file list. Since it is possible 7834 * that some of the common symbols are not on the export list they could 7835 * have been made into private externs. 7836 */ 7837 last_object = add_last_object_file(&link_edit_common_object); 7838 7839 /* 7840 * Private exterals are always kept when any symbols are kept (except in 7841 * the case of STRIP_DYNAMIC_EXECUTABLE). The private externals on the 7842 * merged symbol list may be kept as local symbols or external depending 7843 * on the keep_private_externs flag. Private externals that are local 7844 * symbols (no N_EXT bit set) are always counted in the 7845 * cur_obj->nlocalsym unless the strip level is STRIP_ALL. 7846 */ 7847 7848 /* 7849 * Note if -dead_strip is specified the values of the nlocalsym and 7850 * nprivatesym fields in the object_file structs were previously 7851 * adjusted to account for only the live symbols in 7852 * count_live_symbols(). 7853 */ 7854 7855 index = 0; 7856 output_dysymtab_info.dysymtab_command.ilocalsym = index; 7857 /* 7858 * Set the indexes into the symbol table for local symbols. 7859 * Private exterals are counted as local symbols if keep_private_externs 7860 * is FALSE. 7861 */ 7862 for(q = &objects; *q; q = &(object_list->next)){ 7863 object_list = *q; 7864 for(i = 0; i < object_list->used; i++){ 7865 cur_obj = &(object_list->object_files[i]); 7866 if(cur_obj->dylib) 7867 continue; 7868 if(cur_obj->bundle_loader) 7869 continue; 7870 if(cur_obj->dylinker) 7871 continue; 7872#ifdef RLD 7873 /* 7874 * If this object is not from the current set 7875 * don't count these. 7876 */ 7877 if(cur_obj->set_num != cur_set) 7878 continue; 7879#endif /* RLD */ 7880 cur_obj->ilocalsym = index; 7881/* 7882print_obj_name(cur_obj); 7883print(" cur_obj->nlocalsym %lu\n", cur_obj->nlocalsym); 7884*/ 7885 index += cur_obj->nlocalsym; 7886 7887 if(keep_private_externs == FALSE){ 7888 cur_obj->iprivatesym = index; 7889 cur_obj->cprivatesym = index; 7890 if(strip_level != STRIP_DYNAMIC_EXECUTABLE && 7891 (strip_level != STRIP_NONGLOBALS || 7892 (filetype == MH_DYLIB && multi_module_dylib == TRUE))){ 7893 index += cur_obj->nprivatesym; 7894/* 7895print(" adding cur_obj->nprivatesym %lu to index\n", cur_obj->nprivatesym); 7896*/ 7897 } 7898 else{ 7899 nstripped_merged_symbols += 7900 cur_obj->nprivatesym; 7901 nstripped_merged_private_symbols += 7902 cur_obj->nprivatesym; 7903/* 7904print("assign_output_symbol_indexes() adding cur_obj->nprivatesym %lu to nstripped_merged_symbols\n", cur_obj->nprivatesym); 7905*/ 7906 } 7907 } 7908 } 7909 } 7910 /* 7911 * Check to make sure the counts are consistent. 7912 */ 7913 if((keep_private_externs == TRUE && index != nlocal_symbols) || 7914 (keep_private_externs == FALSE && index != nlocal_symbols + 7915 nmerged_private_symbols - nstripped_merged_private_symbols)) 7916 fatal("internal error: assign_output_symbol_indexes() " 7917 "inconsistent local symbol counts"); 7918 output_dysymtab_info.dysymtab_command.nlocalsym = index; 7919 7920 /* 7921 * Copy the values that got set in the above loop back into the 7922 * object file for the the common symbols. Then remove the copy of 7923 * the object file from the object file list. 7924 */ 7925 link_edit_common_object = *last_object; 7926 remove_last_object_file(last_object); 7927 7928 7929 /* 7930 * Count the number of undefined symbols and defined external symbols. 7931 * Private exterals are counted as defined externals if 7932 * keep_private_externs is TRUE. 7933 */ 7934 nundefsym = 0; 7935 nextdefsym = 0; 7936 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 7937 merged_symbol_root->list; 7938 merged_symbol_list != NULL; 7939 merged_symbol_list = merged_symbol_list->next){ 7940 for(i = 0; i < merged_symbol_list->used; i++){ 7941 merged_symbol = merged_symbol_list->symbols[i]; 7942 if(merged_symbol->referenced_in_non_dylib == FALSE) 7943 continue; 7944 if(strip_base_symbols == TRUE && 7945 merged_symbol->definition_object == base_obj) 7946 continue; 7947#ifdef RLD 7948 if(merged_symbol->definition_object->set_num != cur_set) 7949 continue; 7950#endif /* RLD */ 7951 /* 7952 * The value of nstripped_merged_symbols is recalculated if we 7953 * set the strip_level to STRIP_DYNAMIC_EXECUTABLE in the case 7954 * -dead_strip is specified. 7955 */ 7956 if(strip_level != STRIP_DYNAMIC_EXECUTABLE && 7957 dead_strip == TRUE && merged_symbol->live == FALSE) 7958 continue; 7959 if((merged_symbol->nlist.n_type & N_EXT) == N_EXT && 7960 ((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF || 7961 (merged_symbol->nlist.n_type & N_TYPE) == N_PBUD) | 7962 (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && 7963 merged_symbol->defined_in_dylib == TRUE)){ 7964 if(dead_strip == FALSE || merged_symbol->live == TRUE){ 7965 nundefsym++; 7966 if(rebuild_merged_string_table == TRUE) 7967 merged_symbol->nlist.n_un.n_name = 7968 enter_string(merged_symbol->nlist.n_un.n_name, 7969 NULL); 7970 } 7971 else{ 7972/* 7973printf("assign_output_symbol_indexes() nstripped_merged_symbols incremented for undefined %s\n", merged_symbol->nlist.n_un.n_name); 7974*/ 7975 nstripped_merged_symbols++; 7976 } 7977 } 7978 else{ 7979 if(merged_symbol->nlist.n_type == (N_EXT | N_INDR)){ 7980 indr_symbol = (struct merged_symbol *) 7981 (merged_symbol->nlist.n_value); 7982 n_pext = indr_symbol->nlist.n_type & N_PEXT; 7983 } 7984 else{ 7985 n_pext = merged_symbol->nlist.n_type & N_PEXT; 7986 } 7987 if(keep_private_externs == TRUE || n_pext == 0){ 7988 if(strip_level != STRIP_DYNAMIC_EXECUTABLE || 7989 (merged_symbol->nlist.n_desc & 7990 REFERENCED_DYNAMICALLY) == REFERENCED_DYNAMICALLY){ 7991 nextdefsym++; 7992 if(rebuild_merged_string_table == TRUE) 7993 merged_symbol->nlist.n_un.n_name = 7994 enter_string(merged_symbol-> 7995 nlist.n_un.n_name, NULL); 7996 } 7997 else{ 7998/* 7999printf("assign_output_symbol_indexes() nstripped_merged_symbols incremented for %s\n", merged_symbol->nlist.n_un.n_name); 8000*/ 8001 nstripped_merged_symbols++; 8002 } 8003 } 8004 } 8005 } 8006 } 8007 8008 /* 8009 * Allocate arrays to order the undefined symbols and defined external 8010 * symbols. 8011 */ 8012 undefsyms_order = allocate(nundefsym * 8013 sizeof(struct merged_symbol *)); 8014 extdefsyms_order = allocate(nextdefsym * 8015 sizeof(struct merged_symbol *)); 8016 /* 8017 * Fill in the arrays with their respective symbols. 8018 */ 8019 nundefsym = 0; 8020 nextdefsym = 0; 8021 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 8022 merged_symbol_root->list; 8023 merged_symbol_list != NULL; 8024 merged_symbol_list = merged_symbol_list->next){ 8025 for(i = 0; i < merged_symbol_list->used; i++){ 8026 merged_symbol = merged_symbol_list->symbols[i]; 8027 if(merged_symbol->referenced_in_non_dylib == FALSE) 8028 continue; 8029 if(strip_base_symbols == TRUE && 8030 merged_symbol->definition_object == base_obj) 8031 continue; 8032#ifdef RLD 8033 if(merged_symbol->definition_object->set_num != cur_set) 8034 continue; 8035#endif /* RLD */ 8036 if(dead_strip == TRUE && merged_symbol->live == FALSE) 8037 continue; 8038 if(((merged_symbol->nlist.n_type & N_EXT) == N_EXT && 8039 ((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF || 8040 (merged_symbol->nlist.n_type & N_TYPE) == N_PBUD)) || 8041 (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && 8042 merged_symbol->defined_in_dylib == TRUE)) 8043 undefsyms_order[nundefsym++] = merged_symbol; 8044 else{ 8045 if(merged_symbol->nlist.n_type == (N_EXT | N_INDR)){ 8046 indr_symbol = (struct merged_symbol *) 8047 (merged_symbol->nlist.n_value); 8048 n_pext = indr_symbol->nlist.n_type & N_PEXT; 8049 } 8050 else{ 8051 n_pext = merged_symbol->nlist.n_type & N_PEXT; 8052 } 8053 if(keep_private_externs == TRUE || n_pext == 0){ 8054 if(strip_level != STRIP_DYNAMIC_EXECUTABLE || 8055 (merged_symbol->nlist.n_desc & 8056 REFERENCED_DYNAMICALLY) == REFERENCED_DYNAMICALLY){ 8057 extdefsyms_order[nextdefsym++] = merged_symbol; 8058 } 8059 else{ 8060 if((merged_symbol->nlist.n_type & N_TYPE) == N_ABS) 8061 merged_symbol->output_index = 8062 INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL; 8063 else 8064 merged_symbol->output_index = 8065 INDIRECT_SYMBOL_LOCAL; 8066 } 8067 } 8068 } 8069 } 8070 } 8071#ifndef SA_RLD 8072 /* 8073 * Sort the defined symbols by module for MH_DYLIB formats and by 8074 * name for other formats. 8075 */ 8076 if(filetype == MH_DYLIB) 8077 qsort(extdefsyms_order, nextdefsym, sizeof(struct merged_symbol *), 8078 (int (*)(const void *, const void *))qsort_by_module); 8079 else 8080 qsort(extdefsyms_order, nextdefsym, sizeof(struct merged_symbol *), 8081 (int (*)(const void *, const void *))qsort_by_name); 8082 /* 8083 * Sort the undefined symbols. If we are doing bind_at_load then sort 8084 * them by the order the symbols were seen else sort them by name. 8085 */ 8086 if(bind_at_load == TRUE) 8087 qsort(undefsyms_order, nundefsym, sizeof(struct merged_symbol **), 8088 (int (*)(const void *, const void *))qsort_by_undef_order); 8089 else 8090 qsort(undefsyms_order, nundefsym, sizeof(struct merged_symbol **), 8091 (int (*)(const void *, const void *))qsort_by_name); 8092#endif /* !defined(SA_RLD) */ 8093 8094 /* 8095 * Assign the symbol indexes to the defined symbols. 8096 */ 8097 output_dysymtab_info.dysymtab_command.iextdefsym = index; 8098 output_dysymtab_info.dysymtab_command.nextdefsym = nextdefsym; 8099 cur_obj = NULL; 8100 for(i = 0; i < nextdefsym; i++){ 8101 if(filetype == MH_DYLIB){ 8102 if(cur_obj != extdefsyms_order[i]->definition_object){ 8103 cur_obj = extdefsyms_order[i]->definition_object; 8104 cur_obj->iextdefsym = index; 8105 } 8106 } 8107 extdefsyms_order[i]->output_index = index++; 8108 } 8109 8110 /* 8111 * Assign the symbol indexes to the undefined symbols. 8112 */ 8113 output_dysymtab_info.dysymtab_command.iundefsym = index; 8114 output_dysymtab_info.dysymtab_command.nundefsym = nundefsym; 8115 for(i = 0; i < nundefsym; i++){ 8116 undefsyms_order[i]->output_index = index++; 8117 } 8118 8119 /* 8120 * If -twolevel_namespace is in effect set the number of the two-level 8121 * hints in the hints table to the number of undefined symbols. 8122 */ 8123 if(twolevel_namespace == TRUE) 8124 output_hints_info.twolevel_hints_command.nhints = nundefsym; 8125 8126 /* 8127 * Assign the symbol indexes to the private extern symbols if they are 8128 * turned into local symbols. 8129 */ 8130 if(nmerged_private_symbols != 0 && keep_private_externs == FALSE){ 8131 cur_obj = NULL; 8132 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 8133 merged_symbol_root->list; 8134 merged_symbol_list != NULL; 8135 merged_symbol_list = merged_symbol_list->next){ 8136 for(i = 0; i < merged_symbol_list->used; i++){ 8137 merged_symbol = merged_symbol_list->symbols[i]; 8138 if(merged_symbol->referenced_in_non_dylib == FALSE) 8139 continue; 8140 if(strip_base_symbols == TRUE && 8141 merged_symbol->definition_object == base_obj) 8142 continue; 8143#ifdef RLD 8144 if(merged_symbol->definition_object->set_num != cur_set) 8145 continue; 8146#endif /* RLD */ 8147 if(dead_strip == TRUE && merged_symbol->live == FALSE) 8148 continue; 8149 if(merged_symbol->nlist.n_type & N_PEXT){ 8150 merged_symbol->output_index = 8151 merged_symbol->definition_object->cprivatesym++; 8152 } 8153 } 8154 } 8155 } 8156} 8157 8158#ifndef SA_RLD 8159/* 8160 * qsort_by_module() is used by assign_output_symbol_indexes() to sort (in 8161 * this case group) the defined external symbols by the module they are defined 8162 * in for the MH_DYLIB format. 8163 */ 8164static 8165int 8166qsort_by_module( 8167const struct merged_symbol **ms1, 8168const struct merged_symbol **ms2) 8169{ 8170 return((int)((*ms1)->definition_object) - 8171 (int)((*ms2)->definition_object)); 8172} 8173 8174/* 8175 * qsort_by_name() is used by assign_output_symbol_indexes() to sort the 8176 * the defined external symbols and the undefined symbols by symbol name. 8177 */ 8178static 8179int 8180qsort_by_name( 8181const struct merged_symbol **ms1, 8182const struct merged_symbol **ms2) 8183{ 8184 return(strcmp((*ms1)->nlist.n_un.n_name, (*ms2)->nlist.n_un.n_name)); 8185} 8186 8187/* 8188 * qsort_by_undef_order() is used by assign_output_symbol_indexes() to sort the 8189 * the undefined symbols by the order the undefined symbol appeared. 8190 */ 8191static 8192int 8193qsort_by_undef_order( 8194const struct merged_symbol **ms1, 8195const struct merged_symbol **ms2) 8196{ 8197 return(((*ms1)->undef_order - (*ms2)->undef_order)); 8198} 8199 8200/* 8201 * merged_symbol_output_index() returns the index in the output file's symbol 8202 * table for the merged_symbol pointer passed to it. 8203 */ 8204__private_extern__ 8205unsigned long 8206merged_symbol_output_index( 8207struct merged_symbol *merged_symbol) 8208{ 8209 return(merged_symbol->output_index); 8210} 8211#endif /* !defined(SA_RLD) */ 8212 8213#ifndef RLD 8214/* 8215 * This is a pointer to the module name saved in the merged string table for 8216 * the one module table entry for a single module dylib. 8217 */ 8218char *dylib_single_module_name; 8219 8220/* 8221 * layout_dylib_tables() sizes and readys the tables for a dynamic library file. 8222 * The merged symbol indexes have already been assigned before this is called. 8223 * There are three tables: 8224 * The reference table 8225 * The module table 8226 * The table of contents 8227 */ 8228__private_extern__ 8229void 8230layout_dylib_tables( 8231void) 8232{ 8233 unsigned long i, j, flags; 8234 struct merged_symbol *merged_symbol; 8235 struct object_list *object_list, **q; 8236 char *p; 8237 8238 if(multi_module_dylib == TRUE){ 8239 /* 8240 * For multi module dylibs the reference table was sized as the 8241 * symbols were merged. All that is left to do for the reference 8242 * table is to adjust the flags for undefined references that ended 8243 * up referencing private externs. 8244 */ 8245 for(q = &objects; *q; q = &(object_list->next)){ 8246 object_list = *q; 8247 for(i = 0; i < object_list->used; i++){ 8248 cur_obj = &(object_list->object_files[i]); 8249 if(cur_obj->dylib) 8250 continue; 8251 if(cur_obj->bundle_loader) 8252 continue; 8253 if(cur_obj->dylinker) 8254 continue; 8255 for(j = 0; j < cur_obj->nrefsym; j++){ 8256 merged_symbol = 8257 cur_obj->reference_maps[j].merged_symbol; 8258 if(merged_symbol->nlist.n_type & N_PEXT){ 8259 flags = cur_obj->reference_maps[j].flags; 8260 if(flags == REFERENCE_FLAG_UNDEFINED_NON_LAZY) 8261 cur_obj->reference_maps[j].flags = 8262 REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY; 8263 else if(flags == REFERENCE_FLAG_UNDEFINED_LAZY) 8264 cur_obj->reference_maps[j].flags = 8265 REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY; 8266 } 8267 else{ 8268 /* 8269 * The merged symbol is not a private extern. So it 8270 * might be a non-weak symbol that is being used and 8271 * some weak private externs refs were discarded. 8272 * If so we need to make the refs non-weak. 8273 */ 8274 flags = cur_obj->reference_maps[j].flags; 8275 if(flags == 8276 REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY) 8277 cur_obj->reference_maps[j].flags = 8278 REFERENCE_FLAG_UNDEFINED_NON_LAZY; 8279 else if(flags == 8280 REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY) 8281 cur_obj->reference_maps[j].flags = 8282 REFERENCE_FLAG_UNDEFINED_LAZY; 8283 } 8284 } 8285 } 8286 } 8287 } 8288 else{ 8289 /* 8290 * For single module dylibs the reference table size is reset here 8291 * from the defined and undefined merged symbols. The contents of 8292 * the reference table for single module dylibs will be filled in 8293 * output_dylib_tables() from the merged symbol table. 8294 */ 8295 output_dysymtab_info.dysymtab_command.nextrefsyms = 8296 output_dysymtab_info.dysymtab_command.nextdefsym + 8297 output_dysymtab_info.dysymtab_command.nundefsym; 8298 } 8299 8300 if(multi_module_dylib == TRUE){ 8301 /* 8302 * For multi module dylibs the module table is sized from the number 8303 * of modules loaded. The module_name of each module in the dynamic 8304 * shared library is set from base name or archive member name of 8305 * the object loaded. The string for the module_name is then saved 8306 * with the merged strings so that it can be converted to a string 8307 * table index on output. 8308 */ 8309 output_dysymtab_info.dysymtab_command.nmodtab = 0; 8310 for(q = &objects; *q; q = &(object_list->next)){ 8311 object_list = *q; 8312 for(i = 0; i < object_list->used; i++){ 8313 cur_obj = &(object_list->object_files[i]); 8314 if(cur_obj->dylib == TRUE) 8315 continue; 8316 if(cur_obj->bundle_loader == TRUE) 8317 continue; 8318 cur_obj->imodtab = 8319 output_dysymtab_info.dysymtab_command.nmodtab; 8320 output_dysymtab_info.dysymtab_command.nmodtab++; 8321 if(cur_obj->ar_hdr){ 8322 p = allocate(cur_obj->ar_name_size + 1); 8323 memcpy(p, cur_obj->ar_name, cur_obj->ar_name_size); 8324 p[cur_obj->ar_name_size] = '\0'; 8325 cur_obj->module_name = enter_string(p, NULL); 8326 free(p); 8327 } 8328 else{ 8329 p = strrchr(cur_obj->file_name, '/'); 8330 if(p != NULL) 8331 p++; 8332 else 8333 p = cur_obj->file_name; 8334 cur_obj->module_name = enter_string(p, NULL); 8335 } 8336 } 8337 } 8338 } 8339 else{ 8340 /* 8341 * For single module dylibs there is one module table entry. 8342 * The module_name is set to "single module". The string for the 8343 * module_name is then saved with the merged strings so that it can 8344 * be converted to a string table index on output. 8345 */ 8346 output_dysymtab_info.dysymtab_command.nmodtab = 1; 8347 dylib_single_module_name = enter_string("single module", NULL); 8348 } 8349 8350 /* 8351 * The table of contents is sized from the number of defined external 8352 * symbols. 8353 */ 8354 output_dysymtab_info.dysymtab_command.ntoc = 8355 output_dysymtab_info.dysymtab_command.nextdefsym; 8356} 8357 8358/* 8359 * output_dylib_tables() outputs the tables for a dynamic library file. 8360 * There are three tables: 8361 * The reference table 8362 * The module table 8363 * The table of contents 8364 */ 8365__private_extern__ 8366void 8367output_dylib_tables( 8368void) 8369{ 8370 unsigned long i, j, flush_offset, ntoc; 8371 struct object_list *object_list, **q; 8372 struct dylib_reference *ref, *refs; 8373 struct dylib_module *mod, *mods; 8374 struct merged_symbol **toc_order; 8375 struct merged_symbol_list *merged_symbol_list; 8376 struct merged_symbol *merged_symbol; 8377 struct dylib_table_of_contents *tocs, *toc; 8378 struct merged_section *ms; 8379 8380 /* 8381 * Output the reference table. 8382 */ 8383 flush_offset = output_dysymtab_info.dysymtab_command.extrefsymoff; 8384 refs = (struct dylib_reference *)(output_addr + flush_offset); 8385 ref = refs; 8386 if(multi_module_dylib == TRUE){ 8387 /* 8388 * For multi module dylibs there is a reference table for each 8389 * object loaded built from the reference_maps. 8390 */ 8391 for(q = &objects; *q; q = &(object_list->next)){ 8392 object_list = *q; 8393 for(i = 0; i < object_list->used; i++){ 8394 cur_obj = &(object_list->object_files[i]); 8395 if(cur_obj->dylib) 8396 continue; 8397 if(cur_obj->bundle_loader) 8398 continue; 8399 if(cur_obj->dylinker) 8400 continue; 8401 for(j = 0; j < cur_obj->nrefsym; j++){ 8402 ref->isym = merged_symbol_output_index( 8403 cur_obj->reference_maps[j].merged_symbol); 8404 ref->flags = cur_obj->reference_maps[j].flags; 8405 ref++; 8406 } 8407 } 8408 } 8409 } 8410 else{ 8411 /* 8412 * For single module dylibs there is one reference table and it is 8413 * built from the merged symbol table. 8414 */ 8415 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 8416 merged_symbol_root->list; 8417 merged_symbol_list != NULL; 8418 merged_symbol_list = merged_symbol_list->next){ 8419 for(i = 0; i < merged_symbol_list->used; i++){ 8420 merged_symbol = merged_symbol_list->symbols[i]; 8421 if(merged_symbol->referenced_in_non_dylib == FALSE) 8422 continue; 8423 if(dead_strip == TRUE && merged_symbol->live == FALSE) 8424 continue; 8425 if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) || 8426 merged_symbol->nlist.n_type == (N_EXT | N_PBUD) || 8427 (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && 8428 merged_symbol->defined_in_dylib == TRUE)){ 8429 ref->isym = merged_symbol_output_index(merged_symbol); 8430 ref->flags = merged_symbol->nlist.n_desc & 8431 REFERENCE_TYPE; 8432 ref++; 8433 } 8434 else if((merged_symbol->nlist.n_type & N_PEXT) == 0){ 8435 ref->isym = merged_symbol_output_index(merged_symbol); 8436 ref->flags = REFERENCE_FLAG_DEFINED; 8437 ref++; 8438 } 8439 } 8440 } 8441 } 8442 if(host_byte_sex != target_byte_sex){ 8443 swap_dylib_reference(refs, 8444 output_dysymtab_info.dysymtab_command.nextrefsyms, 8445 target_byte_sex); 8446 } 8447 output_flush(flush_offset, 8448 output_dysymtab_info.dysymtab_command.nextrefsyms * 8449 sizeof(struct dylib_reference)); 8450 8451 /* 8452 * Output the module table. 8453 */ 8454 flush_offset = output_dysymtab_info.dysymtab_command.modtaboff; 8455 mods = (struct dylib_module *)(output_addr + flush_offset); 8456 mod = mods; 8457 if(multi_module_dylib == TRUE){ 8458 /* 8459 * For multi module dylibs there is a module table for each 8460 * object loaded built from the info saved in the object struct. 8461 */ 8462 for(q = &objects; *q; q = &(object_list->next)){ 8463 object_list = *q; 8464 for(i = 0; i < object_list->used; i++){ 8465 cur_obj = &(object_list->object_files[i]); 8466 if(cur_obj->dylib == TRUE) 8467 continue; 8468 if(cur_obj->bundle_loader == TRUE) 8469 continue; 8470 mod->module_name = STRING_SIZE_OFFSET + 8471 merged_symbol_string_index(cur_obj->module_name); 8472 mod->iextdefsym = cur_obj->iextdefsym; 8473 mod->nextdefsym = cur_obj->nextdefsym; 8474 8475 mod->nrefsym = cur_obj->nrefsym; 8476 if(mod->nrefsym == 0) 8477 mod->irefsym = 0; 8478 else 8479 mod->irefsym = cur_obj->irefsym; 8480 8481 mod->nlocalsym = cur_obj->nlocalsym + cur_obj->nprivatesym; 8482 if(mod->nlocalsym == 0) 8483 mod->ilocalsym = 0; 8484 else 8485 mod->ilocalsym = cur_obj->ilocalsym; 8486 8487 mod->nextrel = cur_obj->nextrel; 8488 if(mod->nextrel == 0) 8489 mod->iextrel = 0; 8490 else 8491 mod->iextrel = cur_obj->iextrel; 8492 8493 mod->ninit_nterm = (cur_obj->nterm << 16) | cur_obj->ninit; 8494 if(cur_obj->ninit == 0) 8495 cur_obj->iinit = 0; 8496 if(cur_obj->nterm == 0) 8497 cur_obj->iterm = 0; 8498 mod->iinit_iterm = (cur_obj->iterm << 16) | cur_obj->iinit; 8499 if(cur_obj->objc_module_info != NULL){ 8500 mod->objc_module_info_addr = 8501 cur_obj->objc_module_info->output_section->s.addr + 8502 cur_obj->objc_module_info->offset; 8503 mod->objc_module_info_size = 8504 cur_obj->objc_module_info->s->size; 8505 } 8506 else{ 8507 mod->objc_module_info_addr = 0; 8508 mod->objc_module_info_size = 0; 8509 } 8510 mod++; 8511 } 8512 } 8513 } 8514 else{ 8515 /* 8516 * For single module dylibs there is one module table entry. 8517 */ 8518 mod->module_name = STRING_SIZE_OFFSET + 8519 merged_symbol_string_index(dylib_single_module_name); 8520 mod->iextdefsym = 8521 output_dysymtab_info.dysymtab_command.iextdefsym; 8522 mod->nextdefsym = 8523 output_dysymtab_info.dysymtab_command.nextdefsym; 8524 mod->irefsym = 0; 8525 mod->nrefsym = 8526 output_dysymtab_info.dysymtab_command.nextrefsyms; 8527 mod->ilocalsym = 8528 output_dysymtab_info.dysymtab_command.ilocalsym; 8529 mod->nlocalsym = 8530 output_dysymtab_info.dysymtab_command.nlocalsym; 8531 mod->iextrel = 0; 8532 mod->nextrel = 8533 output_dysymtab_info.dysymtab_command.nextrel; 8534 mod->iinit_iterm = 0; 8535 mod->ninit_nterm = (nterm << 16) | ninit; 8536 ms = lookup_merged_section(SEG_OBJC, SECT_OBJC_MODULES); 8537 if(ms != NULL){ 8538 mod->objc_module_info_addr = ms->s.addr; 8539 mod->objc_module_info_size = ms->s.size; 8540 } 8541 else{ 8542 mod->objc_module_info_addr = 0; 8543 mod->objc_module_info_size = 0; 8544 } 8545 } 8546 if(host_byte_sex != target_byte_sex){ 8547 swap_dylib_module(mods, 8548 output_dysymtab_info.dysymtab_command.nmodtab, 8549 target_byte_sex); 8550 } 8551 output_flush(flush_offset, 8552 output_dysymtab_info.dysymtab_command.nmodtab * 8553 sizeof(struct dylib_module)); 8554 8555 /* 8556 * Output the table of contents. 8557 */ 8558 toc_order = allocate(output_dysymtab_info.dysymtab_command.ntoc * 8559 sizeof(struct merged_symbol *)); 8560 ntoc = 0; 8561 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 8562 merged_symbol_root->list; 8563 merged_symbol_list != NULL; 8564 merged_symbol_list = merged_symbol_list->next){ 8565 for(i = 0; i < merged_symbol_list->used; i++){ 8566 merged_symbol = merged_symbol_list->symbols[i]; 8567 if(merged_symbol->referenced_in_non_dylib == FALSE) 8568 continue; 8569 if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF && 8570 (merged_symbol->nlist.n_type & N_TYPE) != N_PBUD && 8571 (merged_symbol->nlist.n_type & N_PEXT) == 0) 8572 toc_order[ntoc++] = merged_symbol; 8573 } 8574 } 8575 if(ntoc != output_dysymtab_info.dysymtab_command.ntoc) 8576 fatal("internal error: output_dylib_tables() inconsistent toc " 8577 "counts"); 8578 qsort(toc_order, ntoc, sizeof(struct merged_symbol *), 8579 (int (*)(const void *, const void *))qsort_by_name); 8580 flush_offset = output_dysymtab_info.dysymtab_command.tocoff; 8581 tocs = (struct dylib_table_of_contents *)(output_addr + 8582 flush_offset); 8583 toc = tocs; 8584 for(i = 0; i < ntoc; i++){ 8585 toc->symbol_index = merged_symbol_output_index(toc_order[i]); 8586 toc->module_index = object_index(toc_order[i]->definition_object); 8587 toc++; 8588 } 8589 if(host_byte_sex != target_byte_sex){ 8590 swap_dylib_table_of_contents(tocs, ntoc, target_byte_sex); 8591 } 8592 output_flush(flush_offset, ntoc * 8593 sizeof(struct dylib_table_of_contents)); 8594 free(toc_order); 8595} 8596 8597/* 8598 * When any merged_symbol has its flagged_read_only_reloc set then this static 8599 * is also set. This allows clear_read_only_reloc_flags() to avoid doing any 8600 * work. 8601 */ 8602static enum bool some_read_only_reloc_flags_set = FALSE; 8603 8604/* 8605 * clear_read_only_reloc_flags() clears the flagged_read_only_reloc flags on 8606 * all the merged symbols. 8607 */ 8608__private_extern__ 8609void 8610clear_read_only_reloc_flags( 8611void) 8612{ 8613 unsigned long i; 8614 struct merged_symbol_list *merged_symbol_list; 8615 struct merged_symbol *merged_symbol; 8616 8617 if(some_read_only_reloc_flags_set == FALSE) 8618 return; 8619 8620 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 8621 merged_symbol_root->list; 8622 merged_symbol_list != NULL; 8623 merged_symbol_list = merged_symbol_list->next){ 8624 for(i = 0; i < merged_symbol_list->used; i++){ 8625 merged_symbol = merged_symbol_list->symbols[i]; 8626 merged_symbol->flagged_read_only_reloc = FALSE; 8627 } 8628 } 8629 some_read_only_reloc_flags_set = FALSE; 8630} 8631 8632/* 8633 * flag_read_only_reloc() is called to flag an external relocation entry 8634 * refering to output_index in the specified section. If the symbol has not 8635 * already been flaged it's name is printed. Also if first_time point to 8636 * a TRUE value a leading print statement is done. 8637 */ 8638__private_extern__ 8639void 8640flag_read_only_reloc( 8641struct section *s, 8642unsigned long output_index, 8643enum bool *first_time) 8644{ 8645 unsigned long i; 8646 struct merged_symbol_list *merged_symbol_list; 8647 struct merged_symbol *merged_symbol; 8648 8649 if(*first_time == TRUE){ 8650 if(read_only_reloc_flag == READ_ONLY_RELOC_ERROR) 8651 error_with_cur_obj("has external relocation entries in " 8652 "non-writable section (%.16s,%.16s) for symbols:", 8653 s->segname, s->sectname); 8654 else 8655 warning_with_cur_obj("has external relocation entries in " 8656 "non-writable section (%.16s,%.16s) for symbols:", 8657 s->segname, s->sectname); 8658 *first_time = FALSE; 8659 } 8660 8661 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 8662 merged_symbol_root->list; 8663 merged_symbol_list != NULL; 8664 merged_symbol_list = merged_symbol_list->next){ 8665 for(i = 0; i < merged_symbol_list->used; i++){ 8666 merged_symbol = merged_symbol_list->symbols[i]; 8667 if(merged_symbol->output_index == output_index){ 8668 if(merged_symbol->flagged_read_only_reloc == FALSE){ 8669 print("%s\n", merged_symbol->nlist.n_un.n_name); 8670 merged_symbol->flagged_read_only_reloc = TRUE; 8671 some_read_only_reloc_flags_set = TRUE; 8672 } 8673 return; 8674 } 8675 } 8676 } 8677} 8678#endif /* !defined(RLD) */ 8679 8680#ifdef RLD 8681/* 8682 * free_multiple_defs() frees the multiple_defs array and resets the count to 8683 * zero if it exist. 8684 */ 8685__private_extern__ 8686void 8687free_multiple_defs(void) 8688{ 8689 if(nmultiple_defs != 0){ 8690 free(multiple_defs); 8691 multiple_defs = NULL; 8692 nmultiple_defs = 0; 8693 } 8694} 8695 8696/* 8697 * remove_merged_symbols() removes the merged symbols that are defined in the 8698 * current object file set and their strings. This take advantage of the fact 8699 * that symbols from the current set of symbols were all merged after the 8700 * previous set and appear last in symbol list and hash table. 8701 */ 8702__private_extern__ 8703void 8704remove_merged_symbols(void) 8705{ 8706 long i; 8707 unsigned long j; 8708 struct merged_symbol_list *m, *merged_symbol_list, *prev_merged_symbol_list, 8709 *next_merged_symbol_list; 8710 enum bool have_some_symbols; 8711 struct merged_symbol_chunk *p, *first_chunk, *prev_chunk, *next_chunk; 8712 struct string_block *string_block, *prev_string_block, *next_string_block; 8713 8714 /* 8715 * Clear all the merged symbol table entries for symbols that come 8716 * from the current set of object files. 8717 */ 8718 8719 /* 8720 * First clear all symbol pointers in the merged_symbol_list from this 8721 * set. Then if there are any symbol lists with no used symbols free 8722 * them. 8723 */ 8724 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 8725 merged_symbol_root->list; 8726 merged_symbol_list != NULL; 8727 merged_symbol_list = merged_symbol_list->next){ 8728 for(i = merged_symbol_list->used - 1; i >= 0; i--){ 8729 if(merged_symbol_list->symbols[i] != NULL && 8730 merged_symbol_list->symbols[i]->name_len != 0 && 8731 merged_symbol_list->symbols[i]->definition_object != NULL && 8732 merged_symbol_list->symbols[i]->definition_object->set_num == 8733 cur_set){ 8734 merged_symbol_list->symbols[i] = NULL; 8735 merged_symbol_list->used--; 8736 } 8737 } 8738 } 8739 /* 8740 * Find the first symbol list that now has 0 entries used if any. 8741 */ 8742 prev_merged_symbol_list = merged_symbol_root == NULL ? NULL : 8743 merged_symbol_root->list; 8744 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 8745 merged_symbol_root->list; 8746 merged_symbol_list != NULL; 8747 merged_symbol_list = merged_symbol_list->next){ 8748 if(merged_symbol_list->used == 0) 8749 break; 8750 prev_merged_symbol_list = merged_symbol_list; 8751 } 8752 /* 8753 * If there are any symbol lists with 0 entries used free it and the 8754 * chain of lists that follows. 8755 */ 8756 if(merged_symbol_list != NULL && merged_symbol_list->used == 0){ 8757 /* 8758 * First set the pointer to this list in the previous list to NULL. 8759 */ 8760 if(merged_symbol_list == merged_symbol_root->list) 8761 merged_symbol_root->list = NULL; 8762 else 8763 prev_merged_symbol_list->next = NULL; 8764 for(m = merged_symbol_list; m != NULL; m = next_merged_symbol_list){ 8765 next_merged_symbol_list = m->next; 8766 free(m); 8767 } 8768 } 8769 8770 /* 8771 * Second clear out the hash table entries and free any allocated chunks 8772 * that only have symbols from this set. 8773 */ 8774 have_some_symbols = FALSE; 8775 for(i = 0; i < SYMBOL_LIST_HASH_SIZE; i++){ 8776 if(merged_symbol_root == NULL) 8777 break; 8778 first_chunk = NULL; 8779 prev_chunk = NULL; 8780 for(p = &merged_symbol_root->chunks[i]; p != NULL; p = p->next){ 8781 for(j = 0; j < SYMBOL_CHUNK_SIZE; j++){ 8782 if(p->symbols[j].name_len != 0 && 8783 p->symbols[j].definition_object->set_num == cur_set){ 8784 memset(p->symbols + j, '\0', 8785 sizeof(struct merged_symbol)); 8786 /* 8787 * Save a pointer to the first chunk that is allocated 8788 * in the chain who first symbol (and all remaining) is 8789 * for this set. 8790 */ 8791 if(first_chunk == NULL && 8792 p != &merged_symbol_root->chunks[i] && 8793 j == 0) 8794 first_chunk = p; 8795 } 8796 else{ 8797 if(p->symbols[j].name_len != 0) 8798 have_some_symbols = TRUE; 8799 } 8800 } 8801 /* 8802 * If we have not yet found a first allocated chunk that has all 8803 * symbols from this set, save the pointer to this chunk as it 8804 * may end up being the previous chunk. 8805 */ 8806 if(first_chunk == NULL) 8807 prev_chunk = p; 8808 } 8809 /* 8810 * Free any allocated chunks after the first one in the hash table 8811 * that had symbols all from this set and clear the next pointer to 8812 * this chain. 8813 */ 8814 if(first_chunk != NULL){ 8815 for(p = first_chunk; p != NULL; p = next_chunk){ 8816 next_chunk = p->next; 8817 free(p); 8818 } 8819 prev_chunk->next = NULL; 8820 } 8821 } 8822 /* 8823 * If there are no symbol left in the hash table then free it too. 8824 */ 8825 if(have_some_symbols == FALSE){ 8826 free(merged_symbol_root); 8827 merged_symbol_root = NULL; 8828 } 8829 8830 /* 8831 * Third, find the first string block for the current set of object 8832 * files to clear them out. 8833 */ 8834 prev_string_block = NULL; 8835 for(string_block = merged_string_blocks; 8836 string_block != NULL; 8837 string_block = string_block->next){ 8838 if(string_block->set_num == cur_set) 8839 break; 8840 prev_string_block = string_block; 8841 } 8842 /* 8843 * If there are any string blocks for the current set of object files 8844 * free their strings and the blocks. 8845 */ 8846 if(string_block != NULL && string_block->set_num == cur_set){ 8847 /* 8848 * First set the pointer to this block in the previous block to 8849 * NULL. 8850 */ 8851 if(string_block == merged_string_blocks) 8852 merged_string_blocks = NULL; 8853 else 8854 prev_string_block->next = NULL; 8855 /* 8856 * Now free the stings for this block the block itself and do the 8857 * same for all remaining blocks. 8858 */ 8859 do { 8860 free(string_block->strings); 8861 next_string_block = string_block->next; 8862 free(string_block); 8863 string_block = next_string_block; 8864 }while(string_block != NULL); 8865 } 8866} 8867#endif /* RLD */ 8868 8869#ifdef DEBUG 8870/* 8871 * print_symbol_list() prints the merged symbol table. Used for debugging. 8872 */ 8873__private_extern__ 8874void 8875print_symbol_list( 8876char *string, 8877enum bool input_based) 8878{ 8879 struct merged_symbol_list *merged_symbol_list; 8880 struct merged_symbol_chunk *p; 8881 unsigned long i, j; 8882 struct nlist *nlist; 8883 struct section *s; 8884 struct section_map *maps; 8885 8886 print("Merged symbol list (%s)\n", string); 8887 for(merged_symbol_list = merged_symbol_root == NULL ? NULL : 8888 merged_symbol_root->list; 8889 merged_symbol_list != NULL; 8890 merged_symbol_list = merged_symbol_list->next){ 8891 print("merged_symbols\n"); 8892 for(i = 0; i < merged_symbol_list->used; i++){ 8893 print("%-4lu[0x%x]\n", i, 8894 (unsigned int)(merged_symbol_list->symbols + i)); 8895 nlist = &(merged_symbol_list->symbols[i]->nlist); 8896 print(" n_name %s\n", nlist->n_un.n_name); 8897 print(" n_type "); 8898 switch(nlist->n_type & N_TYPE){ 8899 case N_UNDF: 8900 if(nlist->n_value == 0) 8901 print("N_UNDF\n"); 8902 else 8903 print("common (size %u)\n", nlist->n_value); 8904 break; 8905 case N_PBUD: 8906 print("N_PBUD\n"); 8907 break; 8908 case N_ABS: 8909 print("N_ABS\n"); 8910 break; 8911 case N_SECT: 8912 print("N_SECT\n"); 8913 break; 8914 case N_INDR: 8915 print("N_INDR for %s\n", ((struct merged_symbol *) 8916 (nlist->n_value))->nlist.n_un.n_name); 8917 break; 8918 default: 8919 print("unknown 0x%x\n", (unsigned int)(nlist->n_type)); 8920 break; 8921 } 8922 print(" n_sect %d ", nlist->n_sect); 8923 maps = merged_symbol_list->symbols[i]-> 8924 definition_object->section_maps; 8925 if(nlist->n_sect == NO_SECT) 8926 print("NO_SECT\n"); 8927 else{ 8928 if(input_based == TRUE) 8929 print("(%.16s,%.16s)\n", 8930 maps[nlist->n_sect - 1].s->segname, 8931 maps[nlist->n_sect - 1].s->sectname); 8932 else{ 8933 s = get_output_section(nlist->n_sect); 8934 if(s != NULL) 8935 print("(%.16s,%.16s)\n",s->segname, s->sectname); 8936 else 8937 print("(bad section #%d)\n", nlist->n_sect); 8938 } 8939 } 8940 print(" n_desc 0x%04x\n", (unsigned int)(nlist->n_desc)); 8941 print(" n_value 0x%08x\n", (unsigned int)(nlist->n_value)); 8942#ifdef RLD 8943 print(" definition_object "); 8944 print_obj_name( 8945 merged_symbol_list->merged_symbols[i].definition_object); 8946 print("\n"); 8947 print(" set_num %d\n", merged_symbol_list->merged_symbols[i]. 8948 definition_object->set_num); 8949#endif 8950 } 8951 } 8952 8953 print("Hash table (merged_symbol_root 0x%x)\n", 8954 (unsigned int)(merged_symbol_root)); 8955 for(i = 0; i < SYMBOL_LIST_HASH_SIZE; i++){ 8956 for(p = &merged_symbol_root->chunks[i]; p != NULL; p = p->next){ 8957 for(j = 0; j < SYMBOL_CHUNK_SIZE; j++){ 8958 if(p->symbols[j].name_len != 0){ 8959 print(" %-5lu %-2lu [0x%x] %s\n", i, j, 8960 (unsigned int)(p->symbols + j), 8961 p->symbols[j].nlist.n_un.n_name); 8962 } 8963 } 8964 } 8965 } 8966} 8967 8968#endif /* DEBUG */ 8969/* 8970 * get_output_section() returns a pointer to the output section structure for 8971 * the section number passed to it. It returns NULL for section numbers that 8972 * are not in the output file. 8973 */ 8974__private_extern__ 8975struct section * 8976get_output_section( 8977unsigned long sect) 8978{ 8979 struct merged_segment **p, *msg; 8980 struct merged_section **content, **zerofill, *ms; 8981 8982 p = &merged_segments; 8983 while(*p){ 8984 msg = *p; 8985 content = &(msg->content_sections); 8986 while(*content){ 8987 ms = *content; 8988 if(ms->output_sectnum == sect) 8989 return(&(ms->s)); 8990 content = &(ms->next); 8991 } 8992 zerofill = &(msg->zerofill_sections); 8993 while(*zerofill){ 8994 ms = *zerofill; 8995 if(ms->output_sectnum == sect) 8996 return(&(ms->s)); 8997 zerofill = &(ms->next); 8998 } 8999 p = &(msg->next); 9000 } 9001 return(NULL); 9002} 9003 9004#ifdef DEBUG 9005 9006#ifndef RLD 9007/* 9008 * print_undefined_list() prints the undefined symbol list. Used for debugging. 9009 */ 9010__private_extern__ 9011void 9012print_undefined_list(void) 9013{ 9014 struct undefined_list *undefined; 9015 9016 print("Undefined list\n"); 9017 for(undefined = undefined_list.next; 9018 undefined != &undefined_list; 9019 undefined = undefined->next){ 9020 print(" %s", undefined->merged_symbol->nlist.n_un.n_name); 9021 if(undefined->merged_symbol->nlist.n_type == (N_UNDF | N_EXT) || 9022 undefined->merged_symbol->nlist.n_value != 0) 9023 print("\n"); 9024 else 9025 print(" (no longer undefined)\n"); 9026 } 9027} 9028#endif /* !defined(RLD) */ 9029#endif /* DEBUG */ 9030