1/* 2 * Copyright (c) 1999-2003 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 sections that 28 * appear in the headers of the input files. It builds a merged section table 29 * (which is a linked list of merged_segments with merged_sections linked to 30 * them). The merged section list becomes the output files's section list. 31 */ 32#include <stdlib.h> 33#if !(defined(KLD) && defined(__STATIC__)) 34#include <stdio.h> 35#include <mach/mach.h> 36#else /* defined(KLD) && defined(__STATIC__) */ 37#include <mach/kern_return.h> 38#endif /* !(defined(KLD) && defined(__STATIC__)) */ 39#include <stdarg.h> 40#include <string.h> 41#include <sys/time.h> 42#include "stuff/openstep_mach.h" 43#include <mach-o/loader.h> 44#include <mach-o/nlist.h> 45#include <mach-o/reloc.h> 46#include <mach-o/ppc/reloc.h> 47#include <mach-o/hppa/reloc.h> 48#include <ar.h> 49#include "stuff/arch.h" 50#include "stuff/reloc.h" 51 52#include "ld.h" 53#include "specs.h" 54#include "live_refs.h" 55#include "objects.h" 56#include "pass1.h" 57#include "symbols.h" 58#include "sections.h" 59#include "cstring_literals.h" 60#include "4byte_literals.h" 61#include "8byte_literals.h" 62#include "literal_pointers.h" 63#include "indirect_sections.h" 64#include "mod_sections.h" 65#include "coalesced_sections.h" 66#include "pass2.h" 67#include "generic_reloc.h" 68#include "i860_reloc.h" 69#include "ppc_reloc.h" 70#include "m88k_reloc.h" 71#include "hppa_reloc.h" 72#include "sparc_reloc.h" 73#include "arm_reloc.h" 74#include "sets.h" 75#include "hash_string.h" 76#include "layout.h" 77#include "dylibs.h" 78 79/* the pointer to the head of the output file's section list */ 80__private_extern__ struct merged_segment *merged_segments = NULL; 81#ifdef RLD 82/* 83 * The pointer to the head of the output file's section list before they are 84 * all placed in one segment for the MH_OBJECT format in layout(). This is 85 * used in reset_merged_sections() to put the list back with it's original 86 * segments. 87 */ 88__private_extern__ struct merged_segment *original_merged_segments = NULL; 89#endif /* RLD */ 90 91/* 92 * Any debug sections will be merged in the first pass and placed in their 93 * merged segments to allow for error checking. Their contents are not put in 94 * the output file so before the segments are layed out they are removed from 95 * the list by remove_debug_segments() and placed on this list. 96 */ 97__private_extern__ struct merged_segment *debug_merged_segments = NULL; 98 99/* 100 * The total number relocation entries, used only in layout() to help 101 * calculate the size of the link edit segment. 102 */ 103__private_extern__ unsigned long nreloc = 0; 104 105/* 106 * This is set to TRUE if any of the input objects do not have the 107 * MH_SUBSECTIONS_VIA_SYMBOLS bit set in the mach_header flags field. 108 */ 109__private_extern__ enum bool some_non_subsection_via_symbols_objects = FALSE; 110 111/* table for S_* flags (section types) for error messages */ 112static const char * 113#ifndef __DYNAMIC__ 114const 115#endif 116section_flags[] = { 117 "S_REGULAR", 118 "S_ZEROFILL", 119 "S_CSTRING_LITERALS", 120 "S_4BYTE_LITERALS", 121 "S_8BYTE_LITERALS", 122 "S_LITERAL_POINTERS", 123 "S_NON_LAZY_SYMBOL_POINTERS", 124 "S_LAZY_SYMBOL_POINTERS", 125 "S_SYMBOL_STUBS", 126 "S_MOD_INIT_FUNC_POINTERS", 127 "S_MOD_TERM_FUNC_POINTERS", 128 "S_COALESCED" 129}; 130 131#ifndef RLD 132/* 133 * These are the arrays used for finding archive,object,symbol name 134 * triples and object,symbol name pairs when processing -sectorder options. 135 * The array of symbol names is the load_order structure pointed to by 136 * the cur_load_orders field of the object_file structure. 137 */ 138struct archive_name { 139 char *archive_name; /* name of the archive file */ 140 struct object_name 141 *object_names; /* names of the archive members */ 142 unsigned long 143 nobject_names; /* number of archive members */ 144}; 145static struct archive_name *archive_names = NULL; 146static unsigned long narchive_names = 0; 147 148struct object_name { 149 char *object_name; /* name of object file */ 150 unsigned long 151 index_length; /* if this is not in an archive its an index into the */ 152 /* object_name to the base name of the object file */ 153 /* name else it is the length of the object name */ 154 /* which is an archive member name that may have */ 155 /* been truncated. */ 156 struct object_file /* pointer to the object file */ 157 *object_file; 158}; 159static struct object_name *object_names = NULL; 160static unsigned long nobject_names = 0; 161 162struct load_symbol { 163 char *symbol_name; /* the symbol name this is hashed on */ 164 char *object_name; /* the loaded object that contains this symbol */ 165 char *archive_name; /* the loaded archive that contains this object */ 166 /* or NULL if not in an archive */ 167 unsigned long 168 index_length; /* if archive_name is NULL the this is index into the */ 169 /* object_name to the base name of the object file */ 170 /* name else it is the length of the object name */ 171 /* which is an archive member name that may have */ 172 /* been truncated. */ 173 struct load_order 174 *load_order; /* the load order for the above triple names */ 175 struct load_symbol 176 *other_names; /* other load symbols for the same symbol_name */ 177 struct load_symbol 178 *next; /* next hash table pointer */ 179}; 180#define LOAD_SYMBOL_HASHTABLE_SIZE 10000 181static struct load_symbol **load_symbol_hashtable = NULL; 182static struct load_symbol *load_symbols = NULL; 183static unsigned long load_symbols_size = 0; 184static unsigned long load_symbols_used = 0; 185static unsigned long ambiguous_specifications = 0; 186 187static void layout_ordered_section( 188 struct merged_section *ms); 189static void create_name_arrays( 190 void); 191static struct archive_name *create_archive_name( 192 char *archive_name); 193static void create_object_name( 194 struct object_name **object_names, 195 unsigned long *nobject_names, 196 char *object_name, 197 unsigned long index_length, 198 char *archive_name); 199static void free_name_arrays( 200 void); 201static void create_load_symbol_hash_table( 202 unsigned long nsection_symbols, 203 struct merged_section *ms); 204static void free_load_symbol_hash_table( 205 void); 206static void create_load_symbol_hash_table_for_object( 207 char *archive_name, 208 char *object_name, 209 unsigned long index_length, 210 struct load_order *load_orders, 211 unsigned long nload_orders, 212 struct merged_section *ms); 213static struct load_order *lookup_load_order( 214 char *archive_name, 215 char *object_name, 216 char *symbol_name, 217 struct merged_section *ms, 218 unsigned long line_number); 219static char * trim( 220 char *name); 221static struct section_map *lookup_section_map( 222 char *archive_name, 223 char *object_name); 224static int qsort_load_order_names( 225 const struct load_order *load_order1, 226 const struct load_order *load_order2); 227static int bsearch_load_order_names( 228 char *symbol_name, 229 const struct load_order *load_order); 230static int qsort_load_order_input_offset( 231 const struct load_order *load_order1, 232 const struct load_order *load_order2); 233static int qsort_archive_names( 234 const struct archive_name *archive_name1, 235 const struct archive_name *archive_name2); 236static int bsearch_archive_names( 237 const char *name, 238 const struct archive_name *archive_name); 239static int qsort_object_names( 240 const struct object_name *object_name1, 241 const struct object_name *object_name2); 242static int bsearch_object_names( 243 const char *name, 244 const struct object_name *object_name); 245static int qsort_fine_reloc_input_offset( 246 const struct fine_reloc *fine_reloc1, 247 const struct fine_reloc *fine_reloc2); 248static int qsort_order_load_map_orders( 249 const struct order_load_map *order_load_map1, 250 const struct order_load_map *order_load_map2); 251static void create_order_load_maps( 252 struct merged_section *ms, 253 unsigned long norder_load_maps); 254#ifdef DEBUG 255static void print_symbol_name_from_order_load_maps( 256 struct section_map *map, 257 unsigned long value); 258#endif /* DEBUG */ 259static void resize_live_section( 260 struct merged_section *ms); 261static void count_relocs( 262 struct section_map *map, 263 struct relocation_info *relocs, 264 unsigned long *nlocrel, 265 unsigned long *nextrel); 266#endif /* !defined(RLD) */ 267static void scatter_copy( 268 struct section_map *map, 269 char *contents); 270#ifndef RLD 271static void reloc_output_for_dyld( 272 struct section_map *map, 273 struct relocation_info *relocs, 274 struct relocation_info *output_locrel, 275 struct relocation_info *output_extrel, 276 unsigned long *nlocrel, 277 unsigned long *nextrel); 278static enum bool is_merged_section_read_only( 279 struct merged_section *key); 280static unsigned long scatter_copy_relocs( 281 struct section_map *map, 282 struct relocation_info *relocs, 283 struct relocation_info *output_relocs); 284static double calculate_time_used( 285 struct timeval *start, 286 struct timeval *end); 287static void build_references( 288 void); 289static void print_references( 290 void); 291static void setup_references_in_section( 292 struct merged_section *ms); 293static void setup_references( 294 struct section_map *map, 295 struct object_file *obj); 296static void setup_reference( 297 struct live_ref *ref, 298 struct object_file *obj, 299 struct fine_reloc *self_fine_reloc); 300static void mark_all_fine_relocs_live_in_section( 301 struct merged_section *ms); 302/* 303 * The routines that walk the references these are the operations: 304 * mark live references 305 * search down for any live references (and if so mark it live) 306 * check for references that touch a live block (and if so mark it live) 307 */ 308enum walk_references_operation { 309 MARK_LIVE, 310 SEARCH_FOR_LIVE, 311 CHECK_FOR_LIVE_TOUCH 312}; 313#ifdef DEBUG 314char * walk_references_operation_names[] = { 315 "MARK_LIVE", 316 "SEARCH_FOR_LIVE", 317 "CHECK_FOR_LIVE_TOUCH" 318}; 319#endif /* DEBUG */ 320static void walk_references_in_section( 321 enum walk_references_operation operation, 322 struct merged_section *ms); 323static enum bool walk_references( 324 enum walk_references_operation operation, 325 struct fine_reloc *fine_reloc, 326 struct section_map *map, 327 struct object_file *obj); 328static enum bool ref_operation( 329 enum walk_references_operation operation, 330 struct ref *ref, 331 struct object_file *obj); 332 333#endif /* !defined(RLD) */ 334#ifdef DEBUG 335static void print_load_symbol_hash_table( 336 void); 337#endif /* DEBUG */ 338 339/* 340 * merge_sections() merges the sections of the current object file (cur_obj) 341 * into the merged section list that will be in the output file. For each 342 * section in the current object file it records the offset that section will 343 * start in the output file. It also accumulates the size of each merged 344 * section, the number of relocation entries in it and the maximum alignment. 345 */ 346__private_extern__ 347void 348merge_sections(void) 349{ 350 unsigned long i; 351 struct section *s; 352 struct merged_section *ms; 353 struct mach_header *mh; 354 355 /* 356 * We need to preserve the marking of objects that can have their 357 * sections safely divided up by the symbols for dead code stripping. 358 * Only if all input objects are marked with this will the output also 359 * be marked with this. 360 */ 361 if(cur_obj != base_obj){ 362 mh = (struct mach_header *)(cur_obj->obj_addr); 363 if((mh->flags & MH_SUBSECTIONS_VIA_SYMBOLS) != 364 MH_SUBSECTIONS_VIA_SYMBOLS){ 365 some_non_subsection_via_symbols_objects = TRUE; 366 } 367 } 368 369 for(i = 0; i < cur_obj->nsection_maps; i++){ 370 s = cur_obj->section_maps[i].s; 371 ms = create_merged_section(s); 372 if(errors) 373 return; 374 cur_obj->section_maps[i].output_section = ms; 375 /* 376 * If this is a debug section it will not be in the output file. 377 * Set the debug attribute in the merged section (if dynamic is 378 * TRUE it would not have been set). Then just return not 379 * accounting for it size, alignment and number of relocation * entries as none of that info will be in the output file. 380 * Also set output_uuid_info.emit to TRUE since we have seen an 381 * input file with a debug section. 382 */ 383 if((s->flags & S_ATTR_DEBUG) == S_ATTR_DEBUG){ 384 ms->s.flags |= S_ATTR_DEBUG; 385 output_uuid_info.emit = TRUE; 386 continue; 387 } 388 switch(ms->s.flags & SECTION_TYPE){ 389 case S_REGULAR: 390 case S_ZEROFILL: 391 /* 392 * For the base file of an incremental link all that is needed 393 * is the section (and it's alignment) so the symbols can refer 394 * to them. Their contents do not appear in the output file. 395 * If the section size is zero then do NOT adjust the merged 396 * section size to the alignment because if the merged size 397 * was not aligned then that area created does not get flushed 398 * because its associated with a section of size 0. 399 */ 400 if(cur_obj != base_obj && s->size != 0){ 401 cur_obj->section_maps[i].flush_offset = ms->s.size; 402 ms->s.size = rnd(ms->s.size, 1 << s->align); 403 cur_obj->section_maps[i].offset = ms->s.size; 404 ms->s.size += s->size; 405 ms->s.nreloc += s->nreloc; 406 nreloc += s->nreloc; 407 } 408#ifdef KLD 409 /* 410 * For KLD the section's alignment from the base file is NOT 411 * picked up. 412 */ 413 if(cur_obj != base_obj) 414#endif /* KLD */ 415 if(s->align > ms->s.align) 416 ms->s.align = s->align; 417 if(dynamic == TRUE) 418 ms->s.flags |= (s->flags & SECTION_ATTRIBUTES); 419 break; 420 421 case S_CSTRING_LITERALS: 422 case S_4BYTE_LITERALS: 423 case S_8BYTE_LITERALS: 424 case S_LITERAL_POINTERS: 425 case S_SYMBOL_STUBS: 426 case S_NON_LAZY_SYMBOL_POINTERS: 427 case S_LAZY_SYMBOL_POINTERS: 428 case S_MOD_INIT_FUNC_POINTERS: 429 case S_MOD_TERM_FUNC_POINTERS: 430 case S_COALESCED: 431 if(arch_flag.cputype == CPU_TYPE_I860) 432 error_with_cur_obj("literal section (%.16s,%.16s) " 433 "not allowed in I860 cputype objects", 434 ms->s.segname, ms->s.sectname); 435#ifdef KLD 436 /* 437 * For KLD the section's alignment from the base file is NOT 438 * picked up. 439 */ 440 if(cur_obj != base_obj) 441#endif /* KLD */ 442 if(s->align > ms->s.align) 443 ms->s.align = s->align; 444 if(dynamic == TRUE) 445 ms->s.flags |= (s->flags & SECTION_ATTRIBUTES); 446 break; 447 448 default: 449 fatal("internal error: merge_section() called " 450 "with unknown section type (0x%x) for section (%.16s," 451 "%.16s)", (unsigned int)(ms->s.flags & SECTION_TYPE), 452 ms->s.segname, ms->s.sectname); 453 break; 454 } 455#ifndef RLD 456 /* 457 * For dynamic shared libraries record the section map of the 458 * (__OBJC,__module_info) section so it can be used to fill in 459 * objc_module_info_{addr,size} of the module table entries. 460 * Also check to see that it is a regular section. 461 */ 462 if(filetype == MH_DYLIB && 463 strcmp(s->segname, SEG_OBJC) == 0 && 464 strcmp(s->sectname, SECT_OBJC_MODULES) == 0){ 465 if((ms->s.flags & SECTION_TYPE) != S_REGULAR) 466 error_with_cur_obj("for MH_DYLIB output files section " 467 "(%.16s,%.16s) must have a section type of S_REGULAR", 468 s->segname, s->sectname); 469 cur_obj->objc_module_info = cur_obj->section_maps + i; 470 } 471#endif 472 } 473} 474 475/* 476 * create_merged_section() looks for the section passed to it in the merged 477 * section list. If the section is found then it is check to see the flags 478 * of the section matches and if so returns a pointer to the merged section 479 * structure for it. If the flags don't match it is an error. If no merged 480 * section structure is found then one is created and added to the end of the 481 * list and a pointer to it is returned. 482 */ 483__private_extern__ 484struct merged_section * 485create_merged_section( 486struct section *s) 487{ 488 struct merged_segment **p, *msg; 489 struct merged_section **q, **r, *ms; 490 491 p = &merged_segments; 492 while(*p){ 493 msg = *p; 494 /* see if this is section is in this segment */ 495 if(strncmp(msg->sg.segname, s->segname, sizeof(s->segname)) == 0){ 496 /* 497 * If this segment contains debug sections then this section too 498 * must be a debug section. And if it exists and does not 499 * contain debug sections then this section must not be a debug 500 * section. 501 */ 502 if(msg->debug_only == TRUE && 503 (s->flags & S_ATTR_DEBUG) != S_ATTR_DEBUG){ 504 error_with_cur_obj("section's (%.16s,%.16s) does not have " 505 "have debug attribute (S_ATTR_DEBUG) which does not " 506 "match previously loaded object's sections for this " 507 "segment", s->segname, s->sectname); 508 return(NULL); 509 } 510 if(msg->debug_only == FALSE && 511 (s->flags & S_ATTR_DEBUG) == S_ATTR_DEBUG){ 512 error_with_cur_obj("section's (%.16s,%.16s) has debug " 513 "attribute (S_ATTR_DEBUG) which does not match " 514 "previously loaded object's sections for this segment", 515 s->segname, s->sectname); 516 return(NULL); 517 } 518 /* 519 * Depending on the flags of the section depends on which list 520 * it might be found in. In either case it must not be found in 521 * the other list. 522 */ 523 if((s->flags & SECTION_TYPE) == S_ZEROFILL){ 524 q = &(msg->zerofill_sections); 525 r = &(msg->content_sections); 526 } 527 else{ 528 q = &(msg->content_sections); 529 r = &(msg->zerofill_sections); 530 } 531 /* check to see if it is in the list it might be found in */ 532 while(*q){ 533 ms = *q; 534 if(strncmp(ms->s.sectname, s->sectname, 535 sizeof(s->sectname)) == 0){ 536 if((ms->s.flags & SECTION_TYPE) != 537 (s->flags & SECTION_TYPE)){ 538 error_with_cur_obj("section's (%.16s,%.16s) type " 539 "%s does not match previous objects type %s", 540 s->segname, s->sectname, 541 section_flags[s->flags & SECTION_TYPE], 542 section_flags[ms->s.flags & SECTION_TYPE]); 543 return(NULL); 544 } 545 if((ms->s.flags & SECTION_TYPE) == S_SYMBOL_STUBS && 546 ms->s.reserved2 != s->reserved2){ 547 error_with_cur_obj("section's (%.16s,%.16s) sizeof " 548 "stub %u does not match previous objects " 549 "sizeof stub %u", s->segname, s->sectname, 550 s->reserved2, ms->s.reserved2); 551 return(NULL); 552 } 553 return(ms); 554 } 555 q = &(ms->next); 556 } 557 /* 558 * It was not found in the list it might be in so check to make 559 * sure it is not in the other list where it shouldn't be. 560 */ 561 while(*r){ 562 ms = *r; 563 if(strncmp(ms->s.sectname, s->sectname, 564 sizeof(s->sectname)) == 0){ 565 error_with_cur_obj("section's (%.16s,%.16s) type %s " 566 "does not match previous objects type %s", 567 s->segname, s->sectname, 568 section_flags[s->flags & SECTION_TYPE], 569 section_flags[ms->s.flags & SECTION_TYPE]); 570 return(NULL); 571 } 572 r = &(ms->next); 573 } 574 /* add it to the list it should be in */ 575 msg->sg.nsects++; 576 *q = allocate(sizeof(struct merged_section)); 577 ms = *q; 578 memset(ms, '\0', sizeof(struct merged_section)); 579 strncpy(ms->s.sectname, s->sectname, sizeof(s->sectname)); 580 strncpy(ms->s.segname, s->segname, sizeof(s->segname)); 581 /* 582 * This needs to be something other than zero (NO_SECT) so the 583 * call to the *_reloc() routines in count_reloc() can determine 584 * if a relocation to a symbol stub is now referencing an 585 * absolute symbol with a pcrel relocation entry. 586 */ 587 ms->output_sectnum = 1; 588 if(dynamic != TRUE) 589 ms->s.flags = (s->flags & ~SECTION_ATTRIBUTES); 590 else 591 ms->s.flags = s->flags; 592 if((ms->s.flags & SECTION_TYPE) == S_CSTRING_LITERALS){ 593 ms->literal_data = allocate(sizeof(struct cstring_data)); 594 memset(ms->literal_data, '\0', sizeof(struct cstring_data)); 595 ms->literal_merge = cstring_merge; 596 ms->literal_order = cstring_order; 597 ms->literal_reset_live = cstring_reset_live; 598 ms->literal_output = cstring_output; 599 ms->literal_free = cstring_free; 600 } 601 else if((ms->s.flags & SECTION_TYPE) == S_4BYTE_LITERALS){ 602 ms->literal_data = allocate(sizeof(struct literal4_data)); 603 memset(ms->literal_data, '\0',sizeof(struct literal4_data)); 604 ms->literal_merge = literal4_merge; 605 ms->literal_order = literal4_order; 606 ms->literal_reset_live = literal4_reset_live; 607 ms->literal_output = literal4_output; 608 ms->literal_free = literal4_free; 609 } 610 else if((ms->s.flags & SECTION_TYPE) == S_8BYTE_LITERALS){ 611 ms->literal_data = allocate(sizeof(struct literal8_data)); 612 memset(ms->literal_data, '\0',sizeof(struct literal8_data)); 613 ms->literal_merge = literal8_merge; 614 ms->literal_order = literal8_order; 615 ms->literal_reset_live = literal8_reset_live; 616 ms->literal_output = literal8_output; 617 ms->literal_free = literal8_free; 618 } 619 else if((ms->s.flags & SECTION_TYPE) == S_LITERAL_POINTERS){ 620 ms->literal_data = 621 allocate(sizeof(struct literal_pointer_data)); 622 memset(ms->literal_data, '\0', 623 sizeof(struct literal_pointer_data)); 624 ms->literal_merge = literal_pointer_merge; 625 ms->literal_order = literal_pointer_order; 626 ms->literal_reset_live = literal_pointer_reset_live; 627 ms->literal_output = literal_pointer_output; 628 ms->literal_free = literal_pointer_free; 629 } 630#ifndef SA_RLD 631 else if((ms->s.flags & SECTION_TYPE) == S_SYMBOL_STUBS || 632 (ms->s.flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS || 633 (ms->s.flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS){ 634 ms->literal_data = 635 allocate(sizeof(struct indirect_section_data)); 636 memset(ms->literal_data, '\0', 637 sizeof(struct indirect_section_data)); 638 ms->literal_merge = indirect_section_merge; 639 ms->literal_order = indirect_section_order; 640 ms->literal_reset_live = indirect_section_reset_live; 641 ms->literal_output = NULL; 642 ms->literal_free = indirect_section_free; 643 if((ms->s.flags & SECTION_TYPE) == S_SYMBOL_STUBS) 644 ms->s.reserved2 = s->reserved2; 645 } 646#endif /* !defined(SA_RLD) */ 647 else if((ms->s.flags & SECTION_TYPE) == 648 S_MOD_INIT_FUNC_POINTERS || 649 (ms->s.flags & SECTION_TYPE) == 650 S_MOD_TERM_FUNC_POINTERS){ 651 ms->literal_data = allocate(sizeof(struct mod_term_data)); 652 memset(ms->literal_data, '\0', 653 sizeof(struct mod_term_data)); 654 ms->literal_merge = mod_section_merge; 655 ms->literal_order = mod_section_order; 656 ms->literal_reset_live = mod_section_reset_live; 657 ms->literal_output = NULL; 658 ms->literal_free = mod_section_free; 659 } 660 else if((ms->s.flags & SECTION_TYPE) == S_COALESCED){ 661 ms->literal_data = NULL; 662 ms->literal_merge = coalesced_section_merge; 663 ms->literal_order = coalesced_section_order; 664 ms->literal_reset_live = coalesced_section_reset_live; 665 ms->literal_output = NULL; 666 ms->literal_free = NULL; 667 } 668#ifdef RLD 669 ms->set_num = cur_set; 670#endif /* RLD */ 671 return(ms); 672 } 673 p = &(msg->next); 674 } 675 /* 676 * The segment this section is in wasn't found so add a merged segment 677 * for it and add a merged section to that segment for this section. 678 */ 679 *p = allocate(sizeof(struct merged_segment)); 680 msg = *p; 681 memset(msg, '\0', sizeof(struct merged_segment)); 682 strncpy(msg->sg.segname, s->segname, sizeof(s->segname)); 683 msg->sg.nsects = 1; 684 msg->filename = outputfile; 685#ifdef RLD 686 msg->set_num = cur_set; 687#endif /* RLD */ 688 if((s->flags & SECTION_TYPE) == S_ZEROFILL) 689 q = &(msg->zerofill_sections); 690 else 691 q = &(msg->content_sections); 692 *q = allocate(sizeof(struct merged_section)); 693 ms = *q; 694 memset(ms, '\0', sizeof(struct merged_section)); 695 strncpy(ms->s.sectname, s->sectname, sizeof(s->sectname)); 696 strncpy(ms->s.segname, s->segname, sizeof(s->segname)); 697 /* 698 * This needs to be something other than zero (NO_SECT) so the 699 * call to the *_reloc() routines in count_reloc() can determine 700 * if a relocation to a symbol stub is now referencing an 701 * absolute symbol with a pcrel relocation entry. 702 */ 703 ms->output_sectnum = 1; 704 if(dynamic != TRUE) 705 ms->s.flags = (s->flags & ~SECTION_ATTRIBUTES); 706 else 707 ms->s.flags = s->flags; 708 if((ms->s.flags & SECTION_TYPE) == S_CSTRING_LITERALS){ 709 ms->literal_data = allocate(sizeof(struct cstring_data)); 710 memset(ms->literal_data, '\0', sizeof(struct cstring_data)); 711 ms->literal_merge = cstring_merge; 712 ms->literal_order = cstring_order; 713 ms->literal_reset_live = cstring_reset_live; 714 ms->literal_output = cstring_output; 715 ms->literal_free = cstring_free; 716 } 717 else if((ms->s.flags & SECTION_TYPE) == S_4BYTE_LITERALS){ 718 ms->literal_data = allocate(sizeof(struct literal4_data)); 719 memset(ms->literal_data, '\0', sizeof(struct literal4_data)); 720 ms->literal_merge = literal4_merge; 721 ms->literal_order = literal4_order; 722 ms->literal_reset_live = literal4_reset_live; 723 ms->literal_output = literal4_output; 724 ms->literal_free = literal4_free; 725 } 726 else if((ms->s.flags & SECTION_TYPE) == S_8BYTE_LITERALS){ 727 ms->literal_data = allocate(sizeof(struct literal8_data)); 728 memset(ms->literal_data, '\0', sizeof(struct literal8_data)); 729 ms->literal_merge = literal8_merge; 730 ms->literal_order = literal8_order; 731 ms->literal_reset_live = literal8_reset_live; 732 ms->literal_output = literal8_output; 733 ms->literal_free = literal8_free; 734 } 735 else if((ms->s.flags & SECTION_TYPE) == S_LITERAL_POINTERS) { 736 ms->literal_data = allocate(sizeof(struct literal_pointer_data)); 737 memset(ms->literal_data, '\0', sizeof(struct literal_pointer_data)); 738 ms->literal_merge = literal_pointer_merge; 739 ms->literal_order = literal_pointer_order; 740 ms->literal_reset_live = literal_pointer_reset_live; 741 ms->literal_output = literal_pointer_output; 742 ms->literal_free = literal_pointer_free; 743 } 744#ifndef SA_RLD 745 else if((ms->s.flags & SECTION_TYPE) == S_SYMBOL_STUBS || 746 (ms->s.flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS || 747 (ms->s.flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS){ 748 ms->literal_data = allocate(sizeof(struct indirect_section_data)); 749 memset(ms->literal_data, '\0',sizeof(struct indirect_section_data)); 750 ms->literal_merge = indirect_section_merge; 751 ms->literal_order = indirect_section_order; 752 ms->literal_reset_live = indirect_section_reset_live; 753 ms->literal_output = NULL; 754 ms->literal_free = indirect_section_free; 755 if((ms->s.flags & SECTION_TYPE) == S_SYMBOL_STUBS) 756 ms->s.reserved2 = s->reserved2; 757 } 758#endif /* !defined(SA_RLD) */ 759 else if((ms->s.flags & SECTION_TYPE) == S_MOD_INIT_FUNC_POINTERS || 760 (ms->s.flags & SECTION_TYPE) == S_MOD_TERM_FUNC_POINTERS){ 761 ms->literal_data = NULL; 762 ms->literal_merge = mod_section_merge; 763 ms->literal_order = mod_section_order; 764 ms->literal_reset_live = mod_section_reset_live; 765 ms->literal_output = NULL; 766 ms->literal_free = NULL; 767 } 768 else if((ms->s.flags & SECTION_TYPE) == S_COALESCED){ 769 ms->literal_data = NULL; 770 ms->literal_merge = coalesced_section_merge; 771 ms->literal_order = coalesced_section_order; 772 ms->literal_reset_live = coalesced_section_reset_live; 773 ms->literal_output = NULL; 774 ms->literal_free = NULL; 775 } 776#ifdef RLD 777 ms->set_num = cur_set; 778#endif /* RLD */ 779 msg->debug_only = (s->flags & S_ATTR_DEBUG) == S_ATTR_DEBUG; 780 return(ms); 781} 782 783/* 784 * lookup_merged_segment() looks up the specified segment name 785 * in the merged segment list and returns a pointer to the 786 * merged segment if it exist. It returns NULL if it doesn't exist. 787 */ 788__private_extern__ 789struct merged_segment * 790lookup_merged_segment( 791char *segname) 792{ 793 struct merged_segment **p, *msg; 794 795 p = &merged_segments; 796 while(*p){ 797 msg = *p; 798 if(strncmp(msg->sg.segname, segname, sizeof(msg->sg.segname)) == 0) 799 return(msg); 800 p = &(msg->next); 801 } 802 return(NULL); 803} 804 805/* 806 * lookup_merged_section() looks up the specified section name 807 * (segname,sectname) in the merged section list and returns a pointer to the 808 * merged section if it exist. It returns NULL if it doesn't exist. 809 */ 810__private_extern__ 811struct merged_section * 812lookup_merged_section( 813char *segname, 814char *sectname) 815{ 816 struct merged_segment **p, *msg; 817 struct merged_section **q, *ms; 818 819 p = &merged_segments; 820 while(*p){ 821 msg = *p; 822 if(strncmp(msg->sg.segname, segname, sizeof(msg->sg.segname)) == 0){ 823 q = &(msg->content_sections); 824 while(*q){ 825 ms = *q; 826 if(strncmp(ms->s.sectname, sectname, 827 sizeof(ms->s.sectname)) == 0){ 828 return(ms); 829 } 830 q = &(ms->next); 831 } 832 q = &(msg->zerofill_sections); 833 while(*q){ 834 ms = *q; 835 if(strncmp(ms->s.sectname, sectname, 836 sizeof(ms->s.sectname)) == 0){ 837 return(ms); 838 } 839 q = &(ms->next); 840 } 841 return(NULL); 842 } 843 p = &(msg->next); 844 } 845 return(NULL); 846} 847 848/* 849 * remove_debug_segments() removed the debug segments from the list of merged 850 * segments. These segments and the sections in them are on the merged list in 851 * pass1 to allow checking that all sections in the segment are debug section. 852 * This gets called in layout_segments() so that these segments are not in the 853 * output. The output_sectnum for these sections is set to MAX_SECT+1 so that 854 * it can't match any legal section number in the output, so when searching an 855 * object's section map for a matching output section number it is never 856 * matched. 857 */ 858__private_extern__ 859void 860remove_debug_segments( 861void) 862{ 863 struct merged_segment **p, **q, *msg; 864 struct merged_section **c, *ms; 865 866 p = &merged_segments; 867 q = &debug_merged_segments; 868 while(*p){ 869 msg = *p; 870 /* 871 * If this is a segment with only debug sections take it off the 872 * list of merged_segments and put it on the list of 873 * debug_merged_segments. 874 */ 875 if(msg->debug_only == TRUE){ 876 *q = msg; 877 q = &(msg->next); 878 *p = msg->next; 879 /* 880 * Set the output_sectnum to an value that is not legal so it 881 * won't be matched when searching for output symbols section 882 * incorrectly to this section. 883 */ 884 c = &(msg->content_sections); 885 while(*c){ 886 ms = *c; 887 ms->output_sectnum = MAX_SECT + 1; 888 c = &(ms->next); 889 } 890 /* 891 * We leave this merged segment to point to the next segment 892 * in the list so we can walk the rest of the list of merged 893 * segments. Even though this is a debug segment. We will 894 * terminate the list of debug segments after the end of the 895 * loop. 896 */ 897 } 898 p = &(msg->next); 899 } 900 /* 901 * If we put any debug segments on the list of debug_merged_segments 902 * then set the last one's next pointer to NULL to terminate the list. 903 */ 904 if(*q != NULL){ 905 *q = NULL; 906 } 907} 908 909/* 910 * merge_literal_sections() goes through all the object files to be loaded and 911 * merges the literal sections from them. This is called from layout(), with 912 * redo_live == FALSE, and has to be done after all the alignment from all the 913 * sections headers have been merged and the command line section alignment has 914 * been folded in. This way the individual literal items from all the objects 915 * can be aligned to the output alignment. 916 * 917 * If -dead_strip is specified this is called a second time from layout() with 918 * redo_live == TRUE. In this case it is used to drive re-merging of only live 919 * literals. 920 */ 921__private_extern__ 922void 923merge_literal_sections( 924enum bool redo_live) 925{ 926 unsigned long i, j; 927 struct object_list *object_list, **p; 928 struct merged_section *ms; 929#ifndef RLD 930 struct merged_segment **q, *msg; 931 struct merged_section **content; 932 933 /* 934 * If any literal (except literal pointer) section has an order file 935 * then process it for that section if redo_live == FALSE. If redo_live 936 * is TRUE then we are being called a second time so instead call the 937 * literal_reset_live function that resets the literal section before 938 * only the live literals are re-merged. 939 */ 940 q = &merged_segments; 941 while(*q){ 942 msg = *q; 943 content = &(msg->content_sections); 944 while(*content){ 945 ms = *content; 946 if((ms->s.flags & SECTION_TYPE) == S_CSTRING_LITERALS || 947 (ms->s.flags & SECTION_TYPE) == S_4BYTE_LITERALS || 948 (ms->s.flags & SECTION_TYPE) == S_8BYTE_LITERALS || 949 (ms->s.flags & SECTION_TYPE) == S_SYMBOL_STUBS || 950 (ms->s.flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS|| 951 (ms->s.flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 952 (ms->s.flags & SECTION_TYPE) == S_MOD_INIT_FUNC_POINTERS || 953 (ms->s.flags & SECTION_TYPE) == S_MOD_TERM_FUNC_POINTERS || 954 (ms->s.flags & SECTION_TYPE) == S_COALESCED){ 955 if(redo_live == FALSE){ 956 if(ms->order_filename != NULL) 957 (*ms->literal_order)(ms->literal_data, ms); 958 } 959 else 960 (*ms->literal_reset_live)(ms->literal_data, ms); 961 } 962 content = &(ms->next); 963 } 964 q = &(msg->next); 965 } 966#endif /* !defined(RLD) */ 967 968 /* 969 * Merged the literals for each object for each section that is a 970 * literal (but not a literal pointer section). 971 */ 972 for(p = &objects; *p; p = &(object_list->next)){ 973 object_list = *p; 974 for(i = 0; i < object_list->used; i++){ 975 cur_obj = &(object_list->object_files[i]); 976 if(cur_obj == base_obj) 977 continue; 978 if(cur_obj->dylib) 979 continue; 980 if(cur_obj->bundle_loader) 981 continue; 982 if(cur_obj->dylinker) 983 continue; 984#ifdef RLD 985 if(cur_obj->set_num != cur_set) 986 continue; 987#endif /* RLD */ 988 for(j = 0; j < cur_obj->nsection_maps; j++){ 989 ms = cur_obj->section_maps[j].output_section; 990 if((ms->s.flags & SECTION_TYPE) == S_CSTRING_LITERALS || 991 (ms->s.flags & SECTION_TYPE) == S_4BYTE_LITERALS || 992 (ms->s.flags & SECTION_TYPE) == S_8BYTE_LITERALS || 993 (ms->s.flags & SECTION_TYPE) == S_SYMBOL_STUBS || 994 (ms->s.flags & SECTION_TYPE) == 995 S_NON_LAZY_SYMBOL_POINTERS || 996 (ms->s.flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 997 (ms->s.flags & SECTION_TYPE) == 998 S_MOD_INIT_FUNC_POINTERS || 999 (ms->s.flags & SECTION_TYPE) == 1000 S_MOD_TERM_FUNC_POINTERS || 1001 (ms->s.flags & SECTION_TYPE) == S_COALESCED) 1002 (*ms->literal_merge)(ms->literal_data, ms, 1003 cur_obj->section_maps[j].s, 1004 &(cur_obj->section_maps[j]), 1005 redo_live); 1006 } 1007 } 1008 } 1009 1010#ifndef RLD 1011 /* 1012 * Now that the the literals are all merged if any literal pointer 1013 * section has an order file then process it for that section if 1014 * redo_live == FALSE. If redo_live is TRUE then we are being called a 1015 * second time so instead call the literal_reset_live function that 1016 * resets the literal section before only the live literals are 1017 * re-merged. 1018 */ 1019 q = &merged_segments; 1020 while(*q){ 1021 msg = *q; 1022 content = &(msg->content_sections); 1023 while(*content){ 1024 ms = *content; 1025 if((ms->s.flags & SECTION_TYPE) == S_LITERAL_POINTERS){ 1026 if(redo_live == FALSE){ 1027 if(ms->order_filename != NULL) 1028 (*ms->literal_order)(ms->literal_data, ms); 1029 } 1030 else{ 1031 (*ms->literal_reset_live)(ms->literal_data, ms); 1032 } 1033 } 1034 content = &(ms->next); 1035 } 1036 q = &(msg->next); 1037 } 1038#endif /* !defined(RLD) */ 1039 /* 1040 * Now that the the literals are all merged merge the literal pointers 1041 * for each object for each section that is a a literal pointer section. 1042 */ 1043 for(p = &objects; *p; p = &(object_list->next)){ 1044 object_list = *p; 1045 for(i = 0; i < object_list->used; i++){ 1046 cur_obj = &(object_list->object_files[i]); 1047 if(cur_obj == base_obj) 1048 continue; 1049 if(cur_obj->dylib) 1050 continue; 1051 if(cur_obj->bundle_loader) 1052 continue; 1053 if(cur_obj->dylinker) 1054 continue; 1055#ifdef RLD 1056 if(cur_obj->set_num != cur_set) 1057 continue; 1058#endif /* RLD */ 1059 for(j = 0; j < cur_obj->nsection_maps; j++){ 1060 ms = cur_obj->section_maps[j].output_section; 1061 if((ms->s.flags & SECTION_TYPE) == S_LITERAL_POINTERS) 1062 (*ms->literal_merge)(ms->literal_data, ms, 1063 cur_obj->section_maps[j].s, 1064 &(cur_obj->section_maps[j]), 1065 redo_live); 1066 } 1067 } 1068 } 1069} 1070 1071#ifndef RLD 1072/* 1073 * layout_ordered_sections() calls layout_ordered_section() for each section 1074 * that has an order file specified with -sectorder, or if -dead_strip is 1075 * specified. 1076 */ 1077__private_extern__ 1078void 1079layout_ordered_sections(void) 1080{ 1081 enum bool ordered_sections; 1082 struct merged_segment **p, *msg; 1083 struct merged_section **content, **zerofill, *ms; 1084 struct object_file *last_object; 1085 1086 /* 1087 * Determine if their are any sections that have an order file or 1088 * -dead_strip is specified and if not just return. This saves 1089 * creating the name arrays when there is no need to. 1090 */ 1091 ordered_sections = FALSE; 1092 p = &merged_segments; 1093 while(*p){ 1094 msg = *p; 1095 content = &(msg->content_sections); 1096 while(*content){ 1097 ms = *content; 1098 if(ms->order_filename != NULL){ 1099 ordered_sections = TRUE; 1100 break; 1101 } 1102 content = &(ms->next); 1103 } 1104 zerofill = &(msg->zerofill_sections); 1105 while(*zerofill){ 1106 ms = *zerofill; 1107 if(ms->order_filename != NULL){ 1108 ordered_sections = TRUE; 1109 break; 1110 } 1111 zerofill = &(ms->next); 1112 } 1113 if(ordered_sections == TRUE) 1114 break; 1115 p = &(msg->next); 1116 } 1117 if(ordered_sections == FALSE && dead_strip == FALSE) 1118 return; 1119 1120 /* 1121 * Add the object file the common symbols that the link editor allocated 1122 * into the object file list. 1123 */ 1124 last_object = add_last_object_file(&link_edit_common_object); 1125 1126 /* 1127 * Build the arrays of archive names and object names which along 1128 * with the load order maps will be use to search for archive,object, 1129 * symbol name triples from the load order files specified by the user. 1130 */ 1131 create_name_arrays(); 1132#ifdef DEBUG 1133 if(debug & (1 << 13)) 1134 print_name_arrays(); 1135#endif /* DEBUG */ 1136 1137 /* 1138 * For each merged section that has a load order file, or all merged 1139 * sections if -dead_strip is specified, layout all objects that have 1140 * this section in it. 1141 */ 1142 p = &merged_segments; 1143 while(*p){ 1144 msg = *p; 1145 content = &(msg->content_sections); 1146 while(*content){ 1147 ms = *content; 1148 /* no load order for this section, or no -dead_strip continue */ 1149 if((ms->order_filename == NULL && dead_strip == FALSE) || 1150 ms->contents_filename != NULL){ 1151 content = &(ms->next); 1152 continue; 1153 } 1154 /* 1155 * If a regular section (not a literal section) then layout 1156 * the sections using symbol names. Literal sections are 1157 * handled by their specific literal merge functions. 1158 */ 1159 if((ms->s.flags & SECTION_TYPE) == S_REGULAR) 1160 layout_ordered_section(ms); 1161 if(errors != 0) 1162 return; 1163 content = &(ms->next); 1164 } 1165 zerofill = &(msg->zerofill_sections); 1166 while(*zerofill){ 1167 ms = *zerofill; 1168 /* no load order for this section, or no -dead_strip continue */ 1169 if(ms->order_filename == NULL && dead_strip == FALSE){ 1170 zerofill = &(ms->next); 1171 continue; 1172 } 1173 layout_ordered_section(ms); 1174 if(errors != 0) 1175 return; 1176 zerofill = &(ms->next); 1177 } 1178 p = &(msg->next); 1179 } 1180 1181 /* 1182 * Free the space for the symbol table. 1183 */ 1184 free_load_symbol_hash_table(); 1185 1186 /* 1187 * Free the space for the name arrays if there has been no load order 1188 * map specified (this is because the map has pointers to the object 1189 * names that were allocated in the name arrarys). 1190 */ 1191 if(load_map == FALSE) 1192 free_name_arrays(); 1193 1194 /* 1195 * Remove the object file the common symbols that the link editor 1196 * allocated from the object file list. 1197 */ 1198 remove_last_object_file(last_object); 1199} 1200 1201/* 1202 * layout_ordered_section() creates the fine reloc maps for the section in 1203 * each object from the load order file specified with -sectorder. 1204 */ 1205static 1206void 1207layout_ordered_section( 1208struct merged_section *ms) 1209{ 1210 unsigned long i, j, k, l; 1211 struct object_list *object_list, **q; 1212 1213 unsigned long nsect, nload_orders, nsection_symbols; 1214 struct load_order *load_orders; 1215 enum bool start_section, any_order; 1216 1217 struct nlist *object_symbols; 1218 char *object_strings; 1219 1220 unsigned long n, order, output_offset, line_number, line_length; 1221 unsigned long unused_specifications, no_specifications; 1222 char *line, *archive_name, *object_name, *symbol_name; 1223 struct load_order *load_order; 1224 struct section_map *section_map; 1225 kern_return_t r; 1226 1227 struct fine_reloc *fine_relocs; 1228 struct merged_symbol *merged_symbol; 1229 1230 /* 1231 * Reset the count of the number of symbol for this 1232 * section (used as the number of load_symbol structs 1233 * to allocate). 1234 */ 1235 nsection_symbols = 0; 1236 1237 /* 1238 * For each object file that has this section process it. 1239 */ 1240 for(q = &objects; *q; q = &(object_list->next)){ 1241 object_list = *q; 1242 for(i = 0; i < object_list->used; i++){ 1243 cur_obj = &(object_list->object_files[i]); 1244 if(cur_obj == base_obj) 1245 continue; 1246 if(cur_obj->dylib) 1247 continue; 1248 if(cur_obj->bundle_loader) 1249 continue; 1250 if(cur_obj->dylinker) 1251 continue; 1252 /* 1253 * Reset the current section map which points to the 1254 * load order map and count in this object that 1255 * is being processed for this merged section. This 1256 * will be used in later loops to avoid going through 1257 * the section maps again. 1258 */ 1259 cur_obj->cur_section_map = NULL; 1260 1261 for(j = 0; j < cur_obj->nsection_maps; j++){ 1262 if(cur_obj->section_maps[j].output_section != ms) 1263 continue; 1264 if(cur_obj->section_maps[j].s->size == 0) 1265 continue; 1266 /* 1267 * We can only handle only be one of these sections in 1268 * the section maps for a given object file but their might 1269 * be more than one. So this test will check to see if 1270 * more than one section with the same name exists in the 1271 * same object. 1272 */ 1273 if(cur_obj->cur_section_map != NULL){ 1274 error_with_cur_obj("can't use -sectorder or -dead_strip" 1275 " with objects that contain more than one section " 1276 "with the same name (section %d and %ld are both " 1277 "named (%.16s,%.16s))", cur_obj->cur_section_map - 1278 cur_obj->section_maps + 1, j + 1, ms->s.segname, 1279 ms->s.sectname); 1280 return; 1281 } 1282 1283 cur_obj->cur_section_map = &(cur_obj->section_maps[j]); 1284 1285 /* 1286 * Count the number of symbols in this section in 1287 * this object file. For this object nsect is the 1288 * section number for the merged section. Also 1289 * acount for one extra symbol if there is no symbol 1290 * at the beginning of the section. 1291 */ 1292 object_symbols = (struct nlist *)(cur_obj->obj_addr 1293 + cur_obj->symtab->symoff); 1294 object_strings = (char *)(cur_obj->obj_addr + 1295 cur_obj->symtab->stroff); 1296 nsect = j + 1; 1297 nload_orders = 0; 1298 start_section = FALSE; 1299 for(k = 0; k < cur_obj->symtab->nsyms; k++){ 1300 if(object_symbols[k].n_sect == nsect && 1301 (object_symbols[k].n_type & N_STAB) == 0){ 1302 nload_orders++; 1303 if(object_symbols[k].n_value == 1304 cur_obj->section_maps[j].s->addr) 1305 start_section = TRUE; 1306 } 1307 } 1308 if(start_section == FALSE) 1309 nload_orders++; 1310 1311 /* 1312 * Allocate the load order map for this section in 1313 * this object file and set the current section map 1314 * in this object that will point to the load order 1315 * map and count. 1316 */ 1317 load_orders = allocate(sizeof(struct load_order) * 1318 nload_orders); 1319 memset(load_orders, '\0', 1320 sizeof(struct load_order) * nload_orders); 1321 cur_obj->section_maps[j].nload_orders= nload_orders; 1322 cur_obj->section_maps[j].load_orders = load_orders; 1323 cur_obj->cur_section_map = 1324 &(cur_obj->section_maps[j]); 1325 cur_obj->cur_section_map->start_section = start_section; 1326 1327 /* 1328 * Fill in symbol names and values the load order 1329 * map for this section in this object file. 1330 */ 1331 l = 0; 1332 if(start_section == FALSE){ 1333 load_orders[l].name = ".section_start"; 1334 load_orders[l].value = 1335 cur_obj->section_maps[j].s->addr; 1336 l++; 1337 } 1338 for(k = 0; k < cur_obj->symtab->nsyms; k++){ 1339 if(object_symbols[k].n_sect == nsect && 1340 (object_symbols[k].n_type & N_STAB) == 0){ 1341 load_orders[l].name = object_strings + 1342 object_symbols[k].n_un.n_strx; 1343 load_orders[l].value = 1344 object_symbols[k].n_value; 1345 load_orders[l].index = k; 1346 l++; 1347 } 1348 } 1349#ifdef DEBUG 1350 if(debug & (1 << 14)) 1351 print_load_order(load_orders, nload_orders, ms, 1352 cur_obj, "names and values"); 1353#endif /* DEBUG */ 1354 1355 /* 1356 * Sort the load order map by symbol value so the 1357 * size and input offset fields can be set. 1358 */ 1359 qsort(load_orders, 1360 nload_orders, 1361 sizeof(struct load_order), 1362 (int (*)(const void *, const void *)) 1363 qsort_load_order_values); 1364 for(l = 0; l < nload_orders - 1; l++){ 1365 load_orders[l].input_offset = 1366 load_orders[l].value - 1367 cur_obj->section_maps[j].s->addr; 1368 load_orders[l].input_size = 1369 load_orders[l + 1].value - 1370 load_orders[l].value; 1371 } 1372 load_orders[l].input_offset = load_orders[l].value - 1373 cur_obj->section_maps[j].s->addr; 1374 load_orders[l].input_size = 1375 cur_obj->section_maps[j].s->addr + 1376 cur_obj->section_maps[j].s->size - 1377 load_orders[l].value; 1378#ifdef DEBUG 1379 if(debug & (1 << 15)) 1380 print_load_order(load_orders, nload_orders, ms, 1381 cur_obj, "sizes and offsets"); 1382#endif /* DEBUG */ 1383 1384 /* 1385 * Now sort the load order map by symbol name so 1386 * that it can be used for lookup. 1387 */ 1388 qsort(load_orders, 1389 nload_orders, 1390 sizeof(struct load_order), 1391 (int (*)(const void *, const void *)) 1392 qsort_load_order_names); 1393#ifdef DEBUG 1394 if(debug & (1 << 16)) 1395 print_load_order(load_orders, nload_orders, ms, 1396 cur_obj, "sorted by name"); 1397#endif /* DEBUG */ 1398 /* 1399 * Increment the number of load_symbol needed for 1400 * this section by the number of symbols in this 1401 * object. 1402 */ 1403 nsection_symbols += nload_orders; 1404 1405 /* 1406 * We can only handle one of these sections in the section 1407 * maps for a given object file but their might be more than 1408 * one. So let the loop continue and the test at the top 1409 * of the loop will check to see if more than one section 1410 * with the same name exists in the same object. 1411 */ 1412 } 1413 } 1414 } 1415 /* 1416 * Create the load_symbol hash table. Used for looking up 1417 * symbol names and trying to match load order file lines to 1418 * them if the line is not a perfect match. 1419 */ 1420 create_load_symbol_hash_table(nsection_symbols, ms); 1421 1422 /* 1423 * Clear the counter of ambiguous secifications before the next 1424 * section is processed. 1425 */ 1426 ambiguous_specifications = 0; 1427#ifdef DEBUG 1428 if(debug & (1 << 13)) 1429 print_load_symbol_hash_table(); 1430#endif /* DEBUG */ 1431 1432 /* 1433 * Parse the load order file by changing '\n' to '\0'. 1434 */ 1435 for(i = 0; i < ms->order_size; i++){ 1436 if(ms->order_addr[i] == '\n') 1437 ms->order_addr[i] = '\0'; 1438 } 1439 1440 /* 1441 * For lines in the order file set the orders and output_offset 1442 * in the load maps for this section in all the object files 1443 * that have this section. 1444 */ 1445 order = 1; 1446 output_offset = 0; 1447 line_number = 1; 1448 unused_specifications = 0; 1449 for(i = 0; i < ms->order_size; ){ 1450 line = ms->order_addr + i; 1451 line_length = strlen(line); 1452 1453 /* 1454 * Igore lines that start with a '#'. 1455 */ 1456 if(*line == '#'){ 1457 i += line_length + 1; 1458 line_number++; 1459 continue; 1460 } 1461 1462 parse_order_line(line, &archive_name, &object_name, &symbol_name, 1463 ms, line_number); 1464 1465 load_order = lookup_load_order(archive_name, object_name, 1466 symbol_name, ms, line_number); 1467 if(load_order != NULL){ 1468 if(load_order->order != 0){ 1469 if(archive_name == NULL){ 1470 if(*object_name == '\0'){ 1471 warning("multiple specification of symbol: %s in " 1472 "-sectorder file: %s line %lu for " 1473 "section (%.16s,%.16s)", 1474 symbol_name, ms->order_filename, 1475 line_number, ms->s.segname, 1476 ms->s.sectname); 1477 } 1478 else{ 1479 warning("multiple specification of %s:%s in " 1480 "-sectorder file: %s line %lu for " 1481 "section (%.16s,%.16s)", object_name, 1482 symbol_name, ms->order_filename, 1483 line_number, ms->s.segname, 1484 ms->s.sectname); 1485 } 1486 } 1487 else 1488 warning("multiple specification of %s:%s:%s in " 1489 "-sectorder file: %s line %lu for " 1490 "section (%.16s,%.16s)", archive_name, 1491 object_name, symbol_name, 1492 ms->order_filename, line_number, 1493 ms->s.segname, ms->s.sectname); 1494 } 1495 else{ 1496 load_order->order = order++; 1497 load_order->line_number = line_number; 1498 output_offset = align_to_input_mod(output_offset, 1499 load_order->input_offset, 1500 ms->s.align); 1501 load_order->output_offset = output_offset; 1502 output_offset += load_order->input_size; 1503 } 1504 } 1505 else{ 1506 if(strncmp(symbol_name, ".section_offset", 1507 sizeof(".section_offset") - 1) == 0){ 1508 char *p, *endp; 1509 unsigned long offset; 1510 1511 p = symbol_name + sizeof(".section_offset"); 1512 offset = strtoul(p, &endp, 0); 1513 if(*endp != '\0') 1514 error("bad specification of .section_offset in " 1515 "-sectorder file: %s line %lu for section " 1516 "(%.16s,%.16s) (junk after offset value)", 1517 ms->order_filename, line_number, ms->s.segname, 1518 ms->s.sectname); 1519 else if(offset < output_offset) 1520 error("bad offset value (0x%x) of .section_offset in " 1521 "-sectorder file: %s line %lu for section " 1522 "(%.16s,%.16s) (value less than current " 1523 "offset 0x%x)", (unsigned int)offset, 1524 ms->order_filename, line_number, ms->s.segname, 1525 ms->s.sectname, (unsigned int)output_offset); 1526 else 1527 output_offset = offset; 1528 } 1529 if(strncmp(symbol_name, ".section_align", 1530 sizeof(".section_align") - 1) == 0){ 1531 char *p, *endp; 1532 unsigned long align; 1533 1534 p = symbol_name + sizeof(".section_align"); 1535 align = strtoul(p, &endp, 0); 1536 if(*endp != '\0') 1537 error("bad specification of .section_align in " 1538 "-sectorder file: %s line %lu for section " 1539 "(%.16s,%.16s) (junk after align value)", 1540 ms->order_filename, line_number, ms->s.segname, 1541 ms->s.sectname); 1542 else if(align > MAXSECTALIGN) 1543 error("bad align value (%lu) of .section_align in " 1544 "-sectorder file: %s line %lu for section " 1545 "(%.16s,%.16s) (value must be equal to or less " 1546 "than %d)", align, ms->order_filename, 1547 line_number, ms->s.segname, ms->s.sectname, 1548 MAXSECTALIGN); 1549 else 1550 output_offset = rnd(output_offset, 1 << align); 1551 } 1552 else if(strcmp(symbol_name, ".section_all") == 0){ 1553 section_map = lookup_section_map(archive_name, 1554 object_name); 1555 if(section_map != NULL){ 1556 section_map->no_load_order = TRUE; 1557 section_map->order = order++; 1558 output_offset = rnd(output_offset, 1559 (1 << section_map->s->align)); 1560 section_map->offset = output_offset; 1561 output_offset += section_map->s->size; 1562 } 1563 else if(sectorder_detail == TRUE){ 1564 if(archive_name == NULL){ 1565 warning("specification of %s:%s in " 1566 "-sectorder file: %s line %lu for " 1567 "section (%.16s,%.16s) not used " 1568 "(object with that section not in " 1569 "loaded objects)", object_name, 1570 symbol_name, ms->order_filename, 1571 line_number, ms->s.segname, 1572 ms->s.sectname); 1573 } 1574 else{ 1575 warning("specification of %s:%s:%s in " 1576 "-sectorder file: %s line %lu for " 1577 "section (%.16s,%.16s) not used " 1578 "(object with that section not in " 1579 "loaded objects)", archive_name, 1580 object_name, symbol_name, 1581 ms->order_filename, line_number, 1582 ms->s.segname, ms->s.sectname); 1583 } 1584 } 1585 else{ 1586 unused_specifications++; 1587 } 1588 } 1589 else if(sectorder_detail == TRUE){ 1590 if(archive_name == NULL){ 1591 warning("specification of %s:%s in -sectorder " 1592 "file: %s line %lu for section (%.16s," 1593 "%.16s) not found in loaded objects", 1594 object_name, symbol_name, 1595 ms->order_filename, line_number, 1596 ms->s.segname, ms->s.sectname); 1597 } 1598 else{ 1599 warning("specification of %s:%s:%s in " 1600 "-sectorder file: %s line %lu for " 1601 "section (%.16s,%.16s) not found in " 1602 "loaded objects", archive_name, 1603 object_name, symbol_name, 1604 ms->order_filename, line_number, 1605 ms->s.segname, ms->s.sectname); 1606 } 1607 } 1608 else{ 1609 unused_specifications++; 1610 } 1611 } 1612 i += line_length + 1; 1613 line_number++; 1614 } 1615 1616 /* 1617 * Deallocate the memory for the load order file now that it is 1618 * nolonger needed (since the memory has been written on it is 1619 * always deallocated so it won't get written to the swap file 1620 * unnecessarily). 1621 */ 1622 if((r = vm_deallocate(mach_task_self(), (vm_address_t) 1623 ms->order_addr, ms->order_size)) != KERN_SUCCESS) 1624 mach_fatal(r, "can't vm_deallocate() memory for -sectorder " 1625 "file: %s for section (%.16s,%.16s)", 1626 ms->order_filename, ms->s.segname, 1627 ms->s.sectname); 1628 ms->order_addr = NULL; 1629 1630 /* 1631 * For all entries in the load maps that do not have an order 1632 * because they were not specified in the load order file 1633 * assign them an order. 1634 */ 1635 no_specifications = 0; 1636 for(q = &objects; *q; q = &(object_list->next)){ 1637 object_list = *q; 1638 for(i = 0; i < object_list->used; i++){ 1639 cur_obj = &(object_list->object_files[i]); 1640 if(cur_obj == base_obj) 1641 continue; 1642 if(cur_obj->dylib) 1643 continue; 1644 if(cur_obj->bundle_loader) 1645 continue; 1646 if(cur_obj->dylinker) 1647 continue; 1648 if(cur_obj->cur_section_map == NULL) 1649 continue; 1650#ifdef DEBUG 1651 if(debug & (1 << 17)) 1652 print_load_order( 1653 cur_obj->cur_section_map->load_orders, 1654 cur_obj->cur_section_map->nload_orders, 1655 ms, cur_obj, "file orders assigned"); 1656#endif /* DEBUG */ 1657 load_order = cur_obj->cur_section_map->load_orders; 1658 n = cur_obj->cur_section_map->nload_orders; 1659 1660 /* 1661 * When there is no load order or in the case of dead stripping, 1662 * we re-sort the load orders by input_offset to keep them in 1663 * the "natural" link order. For dead code stripping this can 1664 * still lead to problems with assembly code where blocks can 1665 * get removed or padding can be added between blocks for 1666 * alignment. For sections with order files that are incomplete 1667 * the "natural" link order is said to be better for symbols not 1668 * listed. 1669 */ 1670 qsort(load_order, n, sizeof(struct load_order), 1671 (int (*)(const void *, const void *)) 1672 qsort_load_order_input_offset); 1673 1674 /* 1675 * If there is no orders in this object then cause it to be 1676 * treated as if it had a .section_all by default unless 1677 * -dead_strip is specified. This is done to help the default 1678 * case work in more cases and not scatter the object when no 1679 * symbols were ordered from it. 1680 */ 1681 any_order = FALSE; 1682 for(j = 0; j < n; j++){ 1683 if(load_order[j].order != 0){ 1684 any_order = TRUE; 1685 break; 1686 } 1687 } 1688 if(any_order == FALSE && 1689 cur_obj->cur_section_map->no_load_order == FALSE){ 1690 /* 1691 * If -dead_strip is specified, even if this there were 1692 * no orders listed in the order file we need to break up 1693 * the section into blocks so it can effectively dead 1694 * stripped by falling through to the code below. However 1695 * if this section has the no dead strip attribute we will 1696 * be keeping all the blocks. And in this case it is better 1697 * to make one block in order to make more cases work. Or 1698 * If this section comes from an object file that is not 1699 * marked with MH_SUBSECTIONS_VIA_SYMBOLS we make one block 1700 * for the section. 1701 */ 1702 if(dead_strip == FALSE || 1703 (cur_obj->cur_section_map->s->flags & 1704 S_ATTR_NO_DEAD_STRIP) == S_ATTR_NO_DEAD_STRIP || 1705 (cur_obj->obj_addr != NULL && 1706 (((struct mach_header *)(cur_obj->obj_addr))->flags & 1707 MH_SUBSECTIONS_VIA_SYMBOLS) != 1708 MH_SUBSECTIONS_VIA_SYMBOLS)){ 1709 1710 cur_obj->cur_section_map->no_load_order = TRUE; 1711 if(cur_obj->cur_section_map->order == 0) 1712 cur_obj->cur_section_map->order = order++; 1713 output_offset = rnd(output_offset, 1714 (1 << cur_obj->cur_section_map->s->align)); 1715 cur_obj->cur_section_map->offset = output_offset; 1716 output_offset += cur_obj->cur_section_map->s->size; 1717 1718 if(sectorder_detail == TRUE && 1719 ms->order_filename != NULL){ 1720 if(no_specifications == 0) 1721 warning("no specification for the following " 1722 "symbols in -sectorder file: %s for " 1723 "section (%.16s,%.16s):", 1724 ms->order_filename, 1725 ms->s.segname, ms->s.sectname); 1726 for(j = 0; j < n; j++){ 1727 if(cur_obj->ar_hdr == NULL){ 1728 if(nowarnings == FALSE) 1729 print("%s:%s\n", cur_obj->file_name, 1730 load_order[j].name); 1731 } 1732 else{ 1733 if(nowarnings == FALSE) 1734 print("%s:%.*s:%s\n", 1735 cur_obj->file_name, 1736 (int)cur_obj->ar_name_size, 1737 cur_obj->ar_name, 1738 load_order[j].name); 1739 } 1740 } 1741 } 1742 no_specifications += n; 1743 } 1744 } 1745 1746 for(j = 0; j < n; j++){ 1747 if(load_order[j].order == 0){ 1748 if(cur_obj->cur_section_map->no_load_order == TRUE) 1749 continue; 1750 load_order[j].order = order++; 1751 output_offset = align_to_input_mod( 1752 output_offset, 1753 load_order[j].input_offset, 1754 ms->s.align); 1755 load_order[j].output_offset = output_offset; 1756 output_offset += load_order[j].input_size; 1757 if(sectorder_detail == TRUE && 1758 ms->order_filename != NULL){ 1759 if(no_specifications == 0) 1760 warning("no specification for the following " 1761 "symbols in -sectorder file: %s for " 1762 "section (%.16s,%.16s):", 1763 ms->order_filename, 1764 ms->s.segname, ms->s.sectname); 1765 if(cur_obj->ar_hdr == NULL){ 1766 if(nowarnings == FALSE) 1767 print("%s:%s\n", cur_obj->file_name, 1768 load_order[j].name); 1769 } 1770 else{ 1771 if(nowarnings == FALSE) 1772 print("%s:%.*s:%s\n", cur_obj->file_name, 1773 (int)cur_obj->ar_name_size, 1774 cur_obj->ar_name, load_order[j].name); 1775 } 1776 } 1777 no_specifications++; 1778 } 1779 else{ 1780 if(cur_obj->cur_section_map->no_load_order == TRUE && 1781 any_order == TRUE){ 1782 if(cur_obj->ar_hdr == NULL){ 1783 error("specification for both %s:%s " 1784 "and %s:%s in -sectorder file: " 1785 "%s for section (%.16s,%.16s) " 1786 "(not allowed)", 1787 cur_obj->file_name, 1788 ".section_all", 1789 cur_obj->file_name, 1790 load_order[j].name, 1791 ms->order_filename, 1792 ms->s.segname, ms->s.sectname); 1793 } 1794 else{ 1795 error("specification for both " 1796 "%s:%.*s:%s and %s:%.*s:%s " 1797 "in -sectorder file: %s for " 1798 "section (%.16s,%.16s) " 1799 "(not allowed)", 1800 cur_obj->file_name, 1801 (int)cur_obj->ar_name_size, 1802 cur_obj->ar_name, 1803 ".section_all", 1804 cur_obj->file_name, 1805 (int)cur_obj->ar_name_size, 1806 cur_obj->ar_name, 1807 load_order[j].name, 1808 ms->order_filename, 1809 ms->s.segname, ms->s.sectname); 1810 } 1811 } 1812 } 1813 } 1814 1815 /* 1816 * If .section_all has been seen for this object (or we forced 1817 * that effect) and we are creating a load map or -dead_strip 1818 * was specified toss the old load_orders and create one load 1819 * order that represents the entire section. 1820 */ 1821 if(cur_obj->cur_section_map->no_load_order == TRUE && 1822 (load_map == TRUE || dead_strip == TRUE)){ 1823 free(cur_obj->cur_section_map->load_orders); 1824 load_order = allocate(sizeof(struct load_order)); 1825 n = 1; 1826 cur_obj->cur_section_map->load_orders = load_order; 1827 cur_obj->cur_section_map->nload_orders = n; 1828 load_order->order = cur_obj->cur_section_map->order; 1829 if(dead_strip == TRUE) 1830 load_order->name = ".section_all"; 1831 else 1832 load_order->name = NULL; 1833 load_order->value = cur_obj->section_maps->s->addr; 1834 load_order->input_offset = 0; 1835 load_order->output_offset = output_offset; 1836 load_order->input_size = cur_obj->cur_section_map->s->size; 1837 } 1838 1839#ifdef DEBUG 1840 if(debug & (1 << 18)) 1841 print_load_order( 1842 cur_obj->cur_section_map->load_orders, 1843 cur_obj->cur_section_map->nload_orders, 1844 ms, cur_obj, "all orders assigned"); 1845#endif /* DEBUG */ 1846 } 1847 } 1848 if(sectorder_detail == FALSE && ms->order_filename != NULL){ 1849 if(unused_specifications != 0) 1850 warning("%lu symbols specified in -sectorder file: %s " 1851 "for section (%.16s,%.16s) not found in " 1852 "loaded objects", unused_specifications, 1853 ms->order_filename, ms->s.segname, 1854 ms->s.sectname); 1855 if(no_specifications != 0) 1856 warning("%lu symbols have no specifications in " 1857 "-sectorder file: %s for section (%.16s," 1858 "%.16s)",no_specifications, ms->order_filename, 1859 ms->s.segname, ms->s.sectname); 1860 if(ambiguous_specifications != 0) 1861 warning("%lu symbols have ambiguous specifications in " 1862 "-sectorder file: %s for section (%.16s," 1863 "%.16s)", ambiguous_specifications, 1864 ms->order_filename, ms->s.segname, 1865 ms->s.sectname); 1866 } 1867 1868 /* 1869 * There can be seen a ".section_all" and symbol names for the 1870 * same object file and these are reported as an error not a 1871 * warning. 1872 */ 1873 if(errors) 1874 return; 1875 1876 /* 1877 * Now the final size of the merged section can be set with all 1878 * the contents of the section laid out. 1879 */ 1880 ms->s.size = output_offset; 1881 1882 /* 1883 * Finally the fine relocation maps can be allocated and filled 1884 * in from the load order maps. 1885 */ 1886 object_symbols = NULL; 1887 object_strings = NULL; 1888 for(q = &objects; *q; q = &(object_list->next)){ 1889 object_list = *q; 1890 for(i = 0; i < object_list->used; i++){ 1891 cur_obj = &(object_list->object_files[i]); 1892 if(cur_obj == base_obj) 1893 continue; 1894 if(cur_obj->dylib) 1895 continue; 1896 if(cur_obj->bundle_loader) 1897 continue; 1898 if(cur_obj->dylinker) 1899 continue; 1900 if(cur_obj->cur_section_map == NULL) 1901 continue; 1902 /* 1903 * If this object file has no load orders (a .section_all for it 1904 * was specified) or -dead_strip was spefified and this section 1905 * has the no dead strip attribute then just create a single 1906 * fine relocation entry for it that take care of the whole 1907 * section. 1908 */ 1909 if(cur_obj->cur_section_map->no_load_order == TRUE || 1910 (dead_strip == TRUE && 1911 (cur_obj->cur_section_map->s->flags & 1912 S_ATTR_NO_DEAD_STRIP) == S_ATTR_NO_DEAD_STRIP && 1913 ms->order_filename == NULL) ){ 1914 fine_relocs = allocate(sizeof(struct fine_reloc)); 1915 memset(fine_relocs, '\0', sizeof(struct fine_reloc)); 1916 cur_obj->cur_section_map->fine_relocs = fine_relocs; 1917 cur_obj->cur_section_map->nfine_relocs = 1; 1918 fine_relocs[0].input_offset = 0; 1919 fine_relocs[0].output_offset = 1920 cur_obj->cur_section_map->offset; 1921 if(dead_strip == TRUE){ 1922 load_orders = cur_obj->cur_section_map->load_orders; 1923 load_orders[0].fine_reloc = fine_relocs + 0; 1924 load_orders[0].order = cur_obj->cur_section_map->order; 1925 } 1926 continue; 1927 } 1928 n = cur_obj->cur_section_map->nload_orders; 1929 load_orders = cur_obj->cur_section_map->load_orders; 1930 start_section = cur_obj->cur_section_map->start_section; 1931 fine_relocs = allocate(sizeof(struct fine_reloc) * n); 1932 memset(fine_relocs, '\0', sizeof(struct fine_reloc) * n); 1933 cur_obj->cur_section_map->fine_relocs = fine_relocs; 1934 cur_obj->cur_section_map->nfine_relocs = n; 1935 if(dead_strip == TRUE){ 1936 object_symbols = (struct nlist *)(cur_obj->obj_addr 1937 + cur_obj->symtab->symoff); 1938 object_strings = (char *)(cur_obj->obj_addr + 1939 cur_obj->symtab->stroff); 1940 } 1941 for(j = 0; j < n ; j++){ 1942 fine_relocs[j].input_offset = 1943 load_orders[j].input_offset; 1944 fine_relocs[j].output_offset = 1945 load_orders[j].output_offset; 1946 if(dead_strip == TRUE){ 1947 if((start_section == TRUE || j != 0) && 1948 object_symbols[load_orders[j].index].n_type & N_EXT){ 1949 merged_symbol = lookup_symbol(object_strings + 1950 object_symbols[load_orders[j].index]. 1951 n_un.n_strx); 1952 if(merged_symbol->name_len != 0 && 1953 merged_symbol->definition_object == cur_obj){ 1954 fine_relocs[j].merged_symbol = merged_symbol; 1955 merged_symbol->fine_reloc = fine_relocs + j; 1956 } 1957 } 1958 } 1959 } 1960 /* 1961 * Leave the fine relocation map in sorted order by 1962 * their input offset so that the pass2 routines can 1963 * use them. 1964 */ 1965 qsort(fine_relocs, 1966 n, 1967 sizeof(struct fine_reloc), 1968 (int (*)(const void *, const void *)) 1969 qsort_fine_reloc_input_offset); 1970 1971 /* 1972 * When -dead_strip is specified resize_live_section() walks the 1973 * order_load_map that will be created in 1974 * create_order_load_maps() when reassigning the output_offset 1975 * to live items. To know what is live the load_order structs 1976 * need to point at the fine_reloc so it can use the live field 1977 * in there. We must set the pointer to the fine_reloc after 1978 * the above last sort of the fine_relocs. To do that we also 1979 * sort the load_orders by the input_offset so we can then 1980 * assign the correct fine_reloc pointer to the corresponding 1981 * load_order. 1982 */ 1983 if(dead_strip == TRUE){ 1984 qsort(load_orders, n, sizeof(struct load_order), 1985 (int (*)(const void *, const void *)) 1986 qsort_load_order_input_offset); 1987 for(j = 0; j < n ; j++) 1988 load_orders[j].fine_reloc = fine_relocs + j; 1989 } 1990 1991 /* 1992 * The load order maps are now no longer needed unless 1993 * the load map (-M) has been specified or we are doing dead 1994 * stripping (-dead_strip). 1995 */ 1996 if(load_map == FALSE && dead_strip == FALSE){ 1997 free(cur_obj->cur_section_map->load_orders); 1998 cur_obj->cur_section_map->load_orders = NULL; 1999 cur_obj->cur_section_map->nload_orders = 0; 2000 } 2001 } 2002 } 2003 2004 /* 2005 * If the load map option (-M) or dead stripping (-dead_strip) is 2006 * specified build the structures to print the map. 2007 */ 2008 if(load_map == TRUE || dead_strip == TRUE) 2009 create_order_load_maps(ms, order - 1); 2010} 2011#endif /* !RLD */ 2012 2013/* 2014 * align_to_input_mod() is passed the current output_offset, and returns the 2015 * next output_offset aligned to the passed input offset modulus the passed 2016 * power of 2 alignment. 2017 */ 2018__private_extern__ 2019unsigned long 2020align_to_input_mod( 2021unsigned long output_offset, 2022unsigned long input_offset, 2023unsigned long align) 2024{ 2025 unsigned long output_mod, input_mod; 2026 2027 output_mod = output_offset % (1 << align); 2028 input_mod = input_offset % (1 << align); 2029 if(output_mod <= input_mod) 2030 return(output_offset + (input_mod - output_mod)); 2031 else 2032 return(rnd(output_offset, (1 << align)) + input_mod); 2033} 2034 2035#ifndef RLD 2036/* 2037 * is_literal_output_offset_live() is passed a pointer to a merged literal 2038 * section and an output_offset in there and returns if the literal for that 2039 * is live. This is only used literal sections that have order files and when 2040 * -dead_strip is specified. It is very brute force and not fast. 2041 */ 2042__private_extern__ 2043enum bool 2044is_literal_output_offset_live( 2045struct merged_section *ms, 2046unsigned long output_offset) 2047{ 2048 unsigned long i, j, k, n; 2049 struct object_list *object_list, **q; 2050 struct fine_reloc *fine_relocs; 2051 2052 /* 2053 * For each object file that has this section process it. 2054 */ 2055 for(q = &objects; *q; q = &(object_list->next)){ 2056 object_list = *q; 2057 for(i = 0; i < object_list->used; i++){ 2058 cur_obj = &(object_list->object_files[i]); 2059 if(cur_obj == base_obj) 2060 continue; 2061 if(cur_obj->dylib) 2062 continue; 2063 if(cur_obj->bundle_loader) 2064 continue; 2065 if(cur_obj->dylinker) 2066 continue; 2067 for(j = 0; j < cur_obj->nsection_maps; j++){ 2068 if(cur_obj->section_maps[j].output_section != ms) 2069 continue; 2070 fine_relocs = cur_obj->section_maps[j].fine_relocs; 2071 n = cur_obj->section_maps[j].nfine_relocs; 2072 for(k = 0; k < n ; k++){ 2073 if(fine_relocs[k].output_offset == output_offset && 2074 fine_relocs[k].live == TRUE) 2075 return(TRUE); 2076 } 2077 /* 2078 * Since there can only be one of these sections in 2079 * the section map and it was found just break out 2080 * of the loop looking for it. 2081 */ 2082 break; 2083 } 2084 } 2085 } 2086 return(FALSE); 2087} 2088 2089/* 2090 * parse_order_line() parses a load order line into it's archive name, object 2091 * name and symbol name. The format for the lines is the following: 2092 * 2093 * [<archive name>:]<object name>:<symbol name> 2094 * 2095 * If the archive name is not present NULL is returned, if the object name is 2096 * not present it is set to point at "" and if the symbol name is not present it 2097 * is set to "". 2098 */ 2099__private_extern__ 2100void 2101parse_order_line( 2102char *line, 2103char **archive_name, 2104char **object_name, 2105char **symbol_name, 2106struct merged_section *ms, 2107unsigned long line_number) 2108{ 2109 unsigned long line_length; 2110 char *left_bracket; 2111 2112 /* 2113 * The trim has to be done before the checking for objective-C names 2114 * syntax because it could have spaces at the end of the line. 2115 */ 2116 line = trim(line); 2117 2118 line_length = strlen(line); 2119 if(line_length == 0){ 2120 *archive_name = NULL; 2121 (*object_name) = ""; 2122 (*symbol_name) = ""; 2123 return; 2124 } 2125 2126 /* 2127 * To allow the objective-C symbol syntax of: 2128 * +-[ClassName(CategoryName) Method:Name] 2129 * since the method name can have ':'s the brackets 2130 * have to be recognized. This is the only place where 2131 * the link editor knows about this. 2132 */ 2133 if(line[line_length - 1] == ']'){ 2134 left_bracket = strrchr(line, '['); 2135 if(left_bracket == NULL) 2136 fatal("format error in -sectorder file: %s line %lu " 2137 "for section (%.16s,%.16s) (no matching " 2138 "'[' for ending ']' found in symbol name)", 2139 ms->order_filename, line_number, 2140 ms->s.segname, ms->s.sectname); 2141 *left_bracket = '\0'; 2142 *symbol_name = strrchr(line, ':'); 2143 *left_bracket = '['; 2144 } 2145 /* 2146 * A hack for the 3.2 C++ compiler where the symbol name does not end 2147 * with a ']' but with the encoded arguments. 2148 */ 2149 else if((left_bracket = strrchr(line, '[')) != NULL){ 2150 *left_bracket = '\0'; 2151 *symbol_name = strrchr(line, ':'); 2152 *left_bracket = '['; 2153 } 2154 else 2155 *symbol_name = strrchr(line, ':'); 2156 2157 if(*symbol_name == NULL){ 2158 *symbol_name = line; 2159 line = ""; 2160 } 2161 else{ 2162 **symbol_name = '\0'; 2163 (*symbol_name)++; 2164 } 2165 2166 *object_name = strrchr(line, ':'); 2167 if(*object_name == NULL){ 2168 *object_name = line; 2169 *archive_name = NULL; 2170 } 2171 else{ 2172 **object_name = '\0'; 2173 (*object_name)++; 2174 *archive_name = line; 2175 } 2176} 2177 2178/* 2179 * create_name_arrays() build the sorted arrays of archive names and object 2180 * names which along with the load order maps will be use to search for archive, 2181 * object,symbol name triples from the load order files specified by the user. 2182 */ 2183static 2184void 2185create_name_arrays(void) 2186{ 2187 unsigned long i; 2188 long j; 2189 struct object_list *object_list, **p; 2190 struct archive_name *ar; 2191 char *ar_name, *last_slash; 2192 2193 for(p = &objects; *p; p = &(object_list->next)){ 2194 object_list = *p; 2195 for(i = 0; i < object_list->used; i++){ 2196 cur_obj = &(object_list->object_files[i]); 2197 if(cur_obj == base_obj) 2198 continue; 2199 if(cur_obj->dylib) 2200 continue; 2201 if(cur_obj->bundle_loader) 2202 continue; 2203 if(cur_obj->dylinker) 2204 continue; 2205 if(cur_obj->command_line) 2206 continue; 2207 if(cur_obj->ar_hdr != NULL){ 2208 ar = create_archive_name(cur_obj->file_name); 2209 ar_name = allocate(cur_obj->ar_name_size + 1); 2210 strncpy(ar_name, cur_obj->ar_name, cur_obj->ar_name_size); 2211 ar_name[cur_obj->ar_name_size] = '\0'; 2212 create_object_name(&(ar->object_names),&(ar->nobject_names), 2213 ar_name, strlen(ar_name), 2214 cur_obj->file_name); 2215 } 2216 else{ 2217 last_slash = strrchr(cur_obj->file_name, '/'); 2218 if(last_slash == NULL) 2219 j = 0; 2220 else 2221 j = last_slash - cur_obj->file_name + 1; 2222 create_object_name(&object_names, &nobject_names, 2223 cur_obj->file_name, j, NULL); 2224 } 2225 } 2226 } 2227 2228 /* 2229 * Sort the arrays of names. 2230 */ 2231 if(narchive_names != 0){ 2232 archive_names = reallocate(archive_names, 2233 sizeof(struct archive_name) * 2234 narchive_names); 2235 qsort(archive_names, 2236 narchive_names, 2237 sizeof(struct archive_name), 2238 (int (*)(const void *, const void *))qsort_archive_names); 2239 for(i = 0; i < narchive_names; i++){ 2240 archive_names[i].object_names = reallocate( 2241 archive_names[i].object_names, 2242 sizeof(struct object_name) * 2243 archive_names[i].nobject_names); 2244 qsort(archive_names[i].object_names, 2245 archive_names[i].nobject_names, 2246 sizeof(struct object_name), 2247 (int (*)(const void *, const void *))qsort_object_names); 2248 } 2249 } 2250 if(nobject_names != nobjects) 2251 object_names = reallocate(object_names, 2252 sizeof(struct object_name) * nobject_names); 2253 qsort(object_names, 2254 nobject_names, 2255 sizeof(struct object_name), 2256 (int (*)(const void *, const void *))qsort_object_names); 2257} 2258 2259/* 2260 * create_archive_name() creates a slot in the archive names array for the name 2261 * passed to it. The name may be seen more than once. The archive name must 2262 * not have a ':' in it since that is used to delimit names in the -sectorder 2263 * files. 2264 */ 2265static 2266struct archive_name * 2267create_archive_name( 2268char *archive_name) 2269{ 2270 unsigned long i; 2271 struct archive_name *ar; 2272 2273 if(strchr(archive_name, ':') != NULL) 2274 fatal("archive name: %s has a ':' (it can't when -sectorder " 2275 "options are used)", archive_name); 2276 ar = archive_names; 2277 for(i = 0; i < narchive_names; i++){ 2278 if(strcmp(ar->archive_name, archive_name) == 0) 2279 return(ar); 2280 ar++; 2281 } 2282 if(archive_names == NULL) 2283 archive_names = allocate(sizeof(struct archive_name) * nobjects); 2284 ar = archive_names + narchive_names; 2285 narchive_names++; 2286 ar->archive_name = archive_name; 2287 ar->object_names = NULL; 2288 ar->nobject_names = 0; 2289 return(ar); 2290} 2291 2292/* 2293 * create_object_name() creates a slot in the object names array passed to it 2294 * for the name passed to it and the current object (cur_obj). The size of the 2295 * array is in nobject_names. Both the object names array and it's size are 2296 * passed indirectly since it may be allocated to add the name. The name should 2297 * not be duplicated in the array. If this objects array is for an archive 2298 * the archive_name is passed for error messages and is NULL in not in an 2299 * archive. The object name must not have a ':' in it since that is used to 2300 * delimit names in the -sectorder files. 2301 */ 2302static 2303void 2304create_object_name( 2305struct object_name **object_names, 2306unsigned long *nobject_names, 2307char *object_name, 2308unsigned long index_length, 2309char *archive_name) 2310{ 2311 unsigned long n, i; 2312 struct object_name *o; 2313 2314 if(strchr(object_name, ':') != NULL){ 2315 if(archive_name != NULL) 2316 fatal("archive member name: %s(%s) has a ':' in it (it can't " 2317 "when -sectorder options are used)", archive_name, 2318 object_name); 2319 else 2320 fatal("object file name: %s has a ':' in it (it can't when " 2321 "-sectorder options are used)", object_name); 2322 } 2323 2324 o = *object_names; 2325 n = *nobject_names; 2326 for(i = 0; i < n; i++){ 2327 if(strcmp(o->object_name, object_name) == 0){ 2328 if(archive_name != NULL){ 2329#ifdef notdef 2330/* 2331 * Since the 4.4bsd extened format #1 could be used for long member names this 2332 * warning is now always printed again. 2333 */ 2334 struct ar_hdr ar_hdr; 2335 /* 2336 * The warning is not printed when the name is likely to 2337 * have been truncated. Some tools use the whole ar_name 2338 * but ar(1) uses one less so it can put a '\0' in when 2339 * in memory. 2340 */ 2341 if(strlen(object_name) != sizeof(ar_hdr.ar_name) && 2342 strlen(object_name) != sizeof(ar_hdr.ar_name) - 1) 2343#endif 2344 warning("duplicate archive member name: %s(%s) loaded (" 2345 "could be ambiguous when -sectorder options " 2346 "are used)", archive_name, object_name); 2347 } 2348 else 2349 warning("duplicate object file name: %s loaded (could be " 2350 "ambiguous when -sectorder options are used)", 2351 object_name); 2352 } 2353 o++; 2354 } 2355 if(*object_names == NULL) 2356 *object_names = allocate(sizeof(struct object_name) * nobjects); 2357 o = *object_names + *nobject_names; 2358 (*nobject_names)++; 2359 o->object_name = object_name; 2360 o->object_file = cur_obj; 2361 o->index_length = index_length; 2362} 2363 2364/* 2365 * free_name_arrays() frees up the space created for the sorted name arrays. 2366 */ 2367static 2368void 2369free_name_arrays(void) 2370{ 2371 unsigned long i, j; 2372 2373 if(archive_names != NULL){ 2374 for(i = 0; i < narchive_names; i++){ 2375 for(j = 0; j < archive_names[i].nobject_names; j++){ 2376 free(archive_names[i].object_names[j].object_name); 2377 } 2378 } 2379 free(archive_names); 2380 archive_names = NULL; 2381 narchive_names = 0; 2382 } 2383 if(object_names != NULL){ 2384 free(object_names); 2385 object_names = NULL; 2386 nobject_names = 0; 2387 } 2388} 2389 2390/* 2391 * create_load_symbol_hash_table() creates a hash table of all the symbol names 2392 * in the section for the current section map. This table is use by 2393 * lookup_load_order when an exact match for the specification can't be found. 2394 */ 2395static 2396void 2397create_load_symbol_hash_table( 2398unsigned long nsection_symbols, 2399struct merged_section *ms) 2400{ 2401 unsigned long i, j; 2402 2403 /* set up the hash table */ 2404 if(load_symbol_hashtable == NULL) 2405 load_symbol_hashtable = allocate(sizeof(struct load_symbol *) * 2406 LOAD_SYMBOL_HASHTABLE_SIZE); 2407 memset(load_symbol_hashtable, '\0', sizeof(struct load_symbol *) * 2408 LOAD_SYMBOL_HASHTABLE_SIZE); 2409 2410 /* set up the load_symbols */ 2411 if(nsection_symbols > load_symbols_size){ 2412 load_symbols_size = nsection_symbols; 2413 load_symbols = reallocate(load_symbols, sizeof(struct load_symbol) * 2414 load_symbols_size); 2415 } 2416 memset(load_symbols, '\0', sizeof(struct load_symbol) * 2417 load_symbols_size); 2418 load_symbols_used = 0; 2419 2420 for(i = 0; i < narchive_names; i++){ 2421 for(j = 0; j < archive_names[i].nobject_names; j++){ 2422 if(archive_names[i].object_names[j].object_file-> 2423 cur_section_map != NULL) 2424 create_load_symbol_hash_table_for_object( 2425 archive_names[i].archive_name, 2426 archive_names[i].object_names[j].object_name, 2427 archive_names[i].object_names[j].index_length, 2428 archive_names[i].object_names[j].object_file-> 2429 cur_section_map->load_orders, 2430 archive_names[i].object_names[j].object_file-> 2431 cur_section_map->nload_orders, 2432 ms); 2433 } 2434 } 2435 2436 for(j = 0; j < nobject_names; j++){ 2437 if(object_names[j].object_file->cur_section_map != NULL) 2438 create_load_symbol_hash_table_for_object( 2439 NULL, 2440 object_names[j].object_name, 2441 object_names[j].index_length, 2442 object_names[j].object_file->cur_section_map->load_orders, 2443 object_names[j].object_file->cur_section_map->nload_orders, 2444 ms); 2445 } 2446} 2447 2448/* 2449 * free_load_symbol_hash_table() frees up the space used by the symbol hash 2450 * table. 2451 */ 2452static 2453void 2454free_load_symbol_hash_table( 2455void) 2456{ 2457 /* free the hash table */ 2458 if(load_symbol_hashtable != NULL) 2459 free(load_symbol_hashtable); 2460 load_symbol_hashtable = NULL; 2461 2462 /* free the load_symbols */ 2463 if(load_symbols != NULL) 2464 free(load_symbols); 2465 load_symbols_size = 0; 2466 load_symbols_used = 0; 2467} 2468 2469/* 2470 * create_load_symbol_hash_table_for_object() is used by 2471 * create_load_symbol_hash_table() to create the hash table of all the symbol 2472 * names in the section that is being scatter loaded. This routine enters all 2473 * the symbol names in the load_orders in to the hash table for the specified 2474 * archive_name object_name pair. 2475 */ 2476static 2477void 2478create_load_symbol_hash_table_for_object( 2479char *archive_name, 2480char *object_name, 2481unsigned long index_length, 2482struct load_order *load_orders, 2483unsigned long nload_orders, 2484struct merged_section *ms) 2485{ 2486 unsigned long i, hash_index; 2487 struct load_symbol *load_symbol, *hash_load_symbol, *other_name; 2488 2489 for(i = 0; i < nload_orders; i++){ 2490 /* 2491 * Get a new load symbol and set the fields for it this load order 2492 * entry. 2493 */ 2494 load_symbol = load_symbols + load_symbols_used; 2495 load_symbols_used++; 2496 load_symbol->symbol_name = load_orders[i].name; 2497 load_symbol->object_name = object_name; 2498 load_symbol->archive_name = archive_name; 2499 load_symbol->index_length = index_length; 2500 load_symbol->load_order = &(load_orders[i]); 2501 2502 /* find this symbol's place in the hash table */ 2503 hash_index = hash_string(load_orders[i].name, NULL) % 2504 LOAD_SYMBOL_HASHTABLE_SIZE; 2505 for(hash_load_symbol = load_symbol_hashtable[hash_index]; 2506 hash_load_symbol != NULL; 2507 hash_load_symbol = hash_load_symbol->next){ 2508 if(strcmp(load_orders[i].name, 2509 hash_load_symbol->symbol_name) == 0) 2510 break; 2511 } 2512 /* if the symbol was not found in the hash table enter it */ 2513 if(hash_load_symbol == NULL){ 2514 load_symbol->other_names = NULL; 2515 load_symbol->next = load_symbol_hashtable[hash_index]; 2516 load_symbol_hashtable[hash_index] = load_symbol; 2517 } 2518 else{ 2519 /* 2520 * If the symbol was found in the hash table go through the 2521 * other load symbols for the same name checking if their is 2522 * another with exactly the same archive and object name and 2523 * generate a warning if so. Then add this load symbol to the 2524 * list of other names. 2525 */ 2526 for(other_name = hash_load_symbol; 2527 other_name != NULL && ms->order_filename != NULL; 2528 other_name = other_name->other_names){ 2529 2530 if(archive_name != NULL){ 2531 if(strcmp(other_name->object_name, object_name) == 0 && 2532 other_name->archive_name != NULL && 2533 strcmp(other_name->archive_name, archive_name) == 0){ 2534 warning("symbol appears more than once in the same " 2535 "file (%s:%s:%s) which is ambiguous when " 2536 "using a -sectorder option", 2537 other_name->archive_name, 2538 other_name->object_name, 2539 other_name->symbol_name); 2540 break; 2541 } 2542 } 2543 else{ 2544 if(strcmp(other_name->object_name, object_name) == 0 && 2545 other_name->archive_name == NULL){ 2546 warning("symbol appears more than once in the same " 2547 "file (%s:%s) which is ambiguous when " 2548 "using a -sectorder option", 2549 other_name->object_name, 2550 other_name->symbol_name); 2551 break; 2552 } 2553 } 2554 } 2555 load_symbol->other_names = hash_load_symbol->other_names; 2556 hash_load_symbol->other_names = load_symbol; 2557 load_symbol->next = NULL; 2558 } 2559 } 2560} 2561 2562/* 2563 * lookup_load_order() is passed an archive, object, symbol name triple and that 2564 * is looked up in the name arrays and the load order map and returns a pointer 2565 * to the load order map that matches it. Only archive_name may be NULL on 2566 * input. It returns NULL if not found. 2567 */ 2568static 2569struct load_order * 2570lookup_load_order( 2571char *archive_name, 2572char *object_name, 2573char *symbol_name, 2574struct merged_section *ms, 2575unsigned long line_number) 2576{ 2577 struct archive_name *a; 2578 struct object_name *o; 2579 struct load_order *l; 2580 unsigned long n; 2581 2582 unsigned long hash_index, number_of_matches; 2583 struct load_symbol *hash_load_symbol, *other_name, *first_match; 2584 char *last_slash, *base_name, *archive_base_name; 2585 2586 if(archive_name != NULL){ 2587 a = bsearch(archive_name, archive_names, narchive_names, 2588 sizeof(struct archive_name), 2589 (int (*)(const void *, const void *)) 2590 bsearch_archive_names); 2591 if(a == NULL) 2592 goto no_exact_match; 2593 o = a->object_names; 2594 n = a->nobject_names; 2595 } 2596 else{ 2597 o = object_names; 2598 n = nobject_names; 2599 } 2600 2601 o = bsearch(object_name, o, n, sizeof(struct object_name), 2602 (int (*)(const void *, const void *))bsearch_object_names); 2603 if(o == NULL) 2604 goto no_exact_match; 2605 if(o->object_file->cur_section_map == NULL) 2606 goto no_exact_match; 2607 2608 l = o->object_file->cur_section_map->load_orders; 2609 n = o->object_file->cur_section_map->nload_orders; 2610 l = bsearch(symbol_name, l, n, sizeof(struct load_order), 2611 (int (*)(const void *, const void *)) 2612 bsearch_load_order_names); 2613 if(l == NULL) 2614 goto no_exact_match; 2615 return(l); 2616 2617no_exact_match: 2618 /* 2619 * To get here an exact match of the archive_name, object_name, and 2620 * symbol_name was not found so try to find some load_order for the 2621 * symbol_name using the hash table of symbol names. First thing here 2622 * is to strip leading and trailing blanks from the names. 2623 */ 2624 archive_name = trim(archive_name); 2625 object_name = trim(object_name); 2626 symbol_name = trim(symbol_name); 2627 2628 /* find this symbol's place in the hash table */ 2629 hash_index = hash_string(symbol_name, NULL) % 2630 LOAD_SYMBOL_HASHTABLE_SIZE; 2631 for(hash_load_symbol = load_symbol_hashtable[hash_index]; 2632 hash_load_symbol != NULL; 2633 hash_load_symbol = hash_load_symbol->next){ 2634 if(strcmp(symbol_name, hash_load_symbol->symbol_name) == 0) 2635 break; 2636 } 2637 /* if the symbol was not found then give up */ 2638 if(hash_load_symbol == NULL) 2639 return(NULL); 2640 2641 /* if this symbol is in only one object file then use that */ 2642 if(hash_load_symbol->other_names == NULL) 2643 return(hash_load_symbol->load_order); 2644 2645 /* 2646 * Now try to see if their is just one name that has not had an order 2647 * specified for it and use that if that is the case. This ignores both 2648 * the archive_name and the object_name. 2649 */ 2650 number_of_matches = 0; 2651 first_match = NULL; 2652 for(other_name = hash_load_symbol; 2653 other_name != NULL; 2654 other_name = other_name->other_names){ 2655 if(other_name->load_order->order == 0){ 2656 if(first_match == NULL) 2657 first_match = other_name; 2658 number_of_matches++; 2659 } 2660 } 2661 if(number_of_matches == 1) 2662 return(first_match->load_order); 2663 if(number_of_matches == 0) 2664 return(NULL); 2665 2666 /* 2667 * Now try to see if their is just one name that the object file name 2668 * specified for it matches and use that if that is the case. Only the 2669 * object basename is used and matched against the base name of the 2670 * objects or the archive member name that may have been truncated. 2671 * This ignores the archive name. 2672 */ 2673 last_slash = strrchr(object_name, '/'); 2674 if(last_slash == NULL) 2675 base_name = object_name; 2676 else 2677 base_name = last_slash + 1; 2678 number_of_matches = 0; 2679 first_match = NULL; 2680 for(other_name = hash_load_symbol; 2681 other_name != NULL; 2682 other_name = other_name->other_names){ 2683 if(other_name->load_order->order == 0){ 2684 if(other_name->archive_name != NULL){ 2685 if(strncmp(base_name, other_name->object_name, 2686 other_name->index_length) == 0){ 2687 if(first_match == NULL) 2688 first_match = other_name; 2689 number_of_matches++; 2690 } 2691 } 2692 else{ 2693 if(strcmp(base_name, other_name->object_name + 2694 other_name->index_length) == 0){ 2695 if(first_match == NULL) 2696 first_match = other_name; 2697 number_of_matches++; 2698 } 2699 } 2700 } 2701 } 2702 if(number_of_matches == 1) 2703 return(first_match->load_order); 2704 2705 /* 2706 * Now try to see if their is just one name that the base name of the 2707 * archive file name specified for it matches and use that if that is 2708 * the case. This ignores the object name. 2709 */ 2710 if(archive_name != NULL){ 2711 last_slash = strrchr(archive_name, '/'); 2712 if(last_slash == NULL) 2713 base_name = archive_name; 2714 else 2715 base_name = last_slash + 1; 2716 number_of_matches = 0; 2717 first_match = NULL; 2718 for(other_name = hash_load_symbol; 2719 other_name != NULL; 2720 other_name = other_name->other_names){ 2721 if(other_name->load_order->order == 0){ 2722 if(other_name->archive_name != NULL){ 2723 last_slash = strrchr(other_name->archive_name, '/'); 2724 if(last_slash == NULL) 2725 archive_base_name = other_name->archive_name; 2726 else 2727 archive_base_name = last_slash + 1; 2728 2729 if(strcmp(base_name, archive_base_name) == 0){ 2730 if(first_match == NULL) 2731 first_match = other_name; 2732 number_of_matches++; 2733 } 2734 } 2735 } 2736 } 2737 if(number_of_matches == 1) 2738 return(first_match->load_order); 2739 } 2740 2741 /* 2742 * Now we know their is more than one possible match for this symbol 2743 * name. So the first one that does not have an order is picked and 2744 * either the ambiguous_specifications count is incremented or warnings 2745 * are generated. 2746 */ 2747 first_match = NULL; 2748 for(other_name = hash_load_symbol; 2749 other_name != NULL; 2750 other_name = other_name->other_names){ 2751 if(other_name->load_order->order == 0){ 2752 first_match = other_name; 2753 if(sectorder_detail){ 2754 if(archive_name != NULL){ 2755 if(other_name->archive_name != NULL) 2756 warning("ambiguous specification of %s:%s:%s in " 2757 "-sectorder file: %s line %lu for " 2758 "section (%.16s,%.16s) using %s:%s:%s", 2759 archive_name, object_name, symbol_name, 2760 ms->order_filename, line_number, 2761 ms->s.segname, ms->s.sectname, 2762 other_name->archive_name, 2763 other_name->object_name, 2764 other_name->symbol_name); 2765 else 2766 warning("ambiguous specification of %s:%s:%s in " 2767 "-sectorder file: %s line %lu for " 2768 "section (%.16s,%.16s) using %s:%s", 2769 archive_name, object_name, symbol_name, 2770 ms->order_filename, line_number, 2771 ms->s.segname, ms->s.sectname, 2772 other_name->object_name, 2773 other_name->symbol_name); 2774 } 2775 else{ 2776 if(other_name->archive_name != NULL) 2777 warning("ambiguous specification of %s:%s in " 2778 "-sectorder file: %s line %lu for " 2779 "section (%.16s,%.16s) using %s:%s:%s", 2780 object_name, symbol_name, 2781 ms->order_filename, line_number, 2782 ms->s.segname, ms->s.sectname, 2783 other_name->archive_name, 2784 other_name->object_name, 2785 other_name->symbol_name); 2786 else 2787 warning("ambiguous specification of %s:%s in " 2788 "-sectorder file: %s line %lu for " 2789 "section (%.16s,%.16s) using %s:%s", 2790 object_name, symbol_name, 2791 ms->order_filename, line_number, 2792 ms->s.segname, ms->s.sectname, 2793 other_name->object_name, 2794 other_name->symbol_name); 2795 } 2796 } 2797 break; 2798 } 2799 } 2800 if(sectorder_detail == TRUE){ 2801 for(other_name = hash_load_symbol; 2802 other_name != NULL; 2803 other_name = other_name->other_names){ 2804 if(other_name->load_order->order == 0 && 2805 first_match != other_name){ 2806 if(archive_name != NULL){ 2807 if(other_name->archive_name != NULL) 2808 warning("specification %s:%s:%s ambiguous with " 2809 "%s:%s:%s", archive_name, object_name, 2810 symbol_name, other_name->archive_name, 2811 other_name->object_name, 2812 other_name->symbol_name); 2813 else 2814 warning("specification %s:%s:%s ambiguous with " 2815 "%s:%s", archive_name, object_name, 2816 symbol_name, other_name->object_name, 2817 other_name->symbol_name); 2818 } 2819 else{ 2820 if(other_name->archive_name != NULL) 2821 warning("specification %s:%s ambiguous with " 2822 "%s:%s:%s", object_name, symbol_name, 2823 other_name->archive_name, 2824 other_name->object_name, 2825 other_name->symbol_name); 2826 else 2827 warning("specification %s:%s ambiguous with " 2828 "%s:%s", object_name, symbol_name, 2829 other_name->object_name, 2830 other_name->symbol_name); 2831 } 2832 } 2833 } 2834 } 2835 else{ 2836 ambiguous_specifications++; 2837 } 2838 return(first_match->load_order); 2839} 2840 2841/* 2842 * trim() is passed a name and trims the spaces off the begining and endding of 2843 * the name. It writes '\0' in the spaces at the end of the name. It returns 2844 * a pointer into the trimed name. 2845 */ 2846static 2847char * 2848trim( 2849char *name) 2850{ 2851 char *p; 2852 2853 if(name == NULL) 2854 return(name); 2855 2856 while(*name != '\0' && *name == ' ') 2857 name++; 2858 if(*name == '\0') 2859 return(name); 2860 2861 p = name; 2862 while(*p != '\0') 2863 p++; 2864 p--; 2865 while(p != name && *p == ' ') 2866 *p-- = '\0'; 2867 return(name); 2868} 2869 2870/* 2871 * lookup_section_map() is passed an archive, object pair and that is looked up 2872 * in the name arrays and returns a pointer to the section map that matches it. 2873 * It returns NULL if not found. 2874 */ 2875static 2876struct section_map * 2877lookup_section_map( 2878char *archive_name, 2879char *object_name) 2880{ 2881 struct archive_name *a; 2882 struct object_name *o; 2883 unsigned long n; 2884 2885 if(archive_name != NULL){ 2886 a = bsearch(archive_name, archive_names, narchive_names, 2887 sizeof(struct archive_name), 2888 (int (*)(const void *, const void *)) 2889 bsearch_archive_names); 2890 if(a == NULL) 2891 return(NULL); 2892 o = a->object_names; 2893 n = a->nobject_names; 2894 } 2895 else{ 2896 o = object_names; 2897 n = nobject_names; 2898 } 2899 2900 o = bsearch(object_name, o, n, sizeof(struct object_name), 2901 (int (*)(const void *, const void *))bsearch_object_names); 2902 if(o == NULL) 2903 return(NULL); 2904 return(o->object_file->cur_section_map); 2905} 2906#endif /* RLD */ 2907 2908/* 2909 * Function for qsort to sort load_order structs by their value 2910 */ 2911__private_extern__ 2912int 2913qsort_load_order_values( 2914const struct load_order *load_order1, 2915const struct load_order *load_order2) 2916{ 2917 /* 2918 * This test is needed to fix an obscure bug where two symbols have 2919 * the same value. This fix makes the load_orders and the fine_relocs 2920 * sorted by value end up in the same order even though the load_order 2921 * was sorted by name between their sorts by value. Without this the 2922 * blocks for the symbols at the same address get placed in the file 2923 * in the wrong place because the subtraction of their input offsets 2924 * does not yeild the size of the block in this case. This is kinda 2925 * a funky fix to avoid adding a size field to the fine reloc struct 2926 * which would be very expensive in space. 2927 */ 2928 if(load_order1->value == load_order2->value) 2929 return(strcmp(load_order1->name, load_order2->name)); 2930 else 2931 return(load_order1->value - load_order2->value); 2932} 2933 2934#ifndef RLD 2935/* 2936 * Function for qsort to sort load_order structs by their name. 2937 */ 2938static 2939int 2940qsort_load_order_names( 2941const struct load_order *load_order1, 2942const struct load_order *load_order2) 2943{ 2944 return(strcmp(load_order1->name, load_order2->name)); 2945} 2946 2947/* 2948 * Function for bsearch to search load_order structs for their name. 2949 */ 2950static 2951int 2952bsearch_load_order_names( 2953char *symbol_name, 2954const struct load_order *load_order) 2955{ 2956 return(strcmp(symbol_name, load_order->name)); 2957} 2958 2959/* 2960 * Function for qsort to sort load_order structs by their input_offset. 2961 */ 2962static 2963int 2964qsort_load_order_input_offset( 2965const struct load_order *load_order1, 2966const struct load_order *load_order2) 2967{ 2968 /* 2969 * This test is needed to fix an obscure bug where two symbols have 2970 * the same value. This fix makes the load_orders and the fine_relocs 2971 * sorted by value end up in the same order even though the load_order 2972 * was sorted by name between their sorts by value then by name. 2973 */ 2974 if(load_order1->input_offset == load_order2->input_offset) 2975 return(strcmp(load_order1->name, load_order2->name)); 2976 else 2977 return(load_order1->input_offset - load_order2->input_offset); 2978} 2979 2980/* 2981 * Function for qsort for comparing archive names. 2982 */ 2983static 2984int 2985qsort_archive_names( 2986const struct archive_name *archive_name1, 2987const struct archive_name *archive_name2) 2988{ 2989 return(strcmp(archive_name1->archive_name, 2990 archive_name2->archive_name)); 2991} 2992 2993/* 2994 * Function for bsearch for finding archive names. 2995 */ 2996static 2997int 2998bsearch_archive_names( 2999const char *name, 3000const struct archive_name *archive_name) 3001{ 3002 return(strcmp(name, archive_name->archive_name)); 3003} 3004 3005/* 3006 * Function for qsort for comparing object names. 3007 */ 3008static 3009int 3010qsort_object_names( 3011const struct object_name *object_name1, 3012const struct object_name *object_name2) 3013{ 3014 return(strcmp(object_name1->object_name, 3015 object_name2->object_name)); 3016} 3017 3018/* 3019 * Function for bsearch for finding object names. 3020 */ 3021static 3022int 3023bsearch_object_names( 3024const char *name, 3025const struct object_name *object_name) 3026{ 3027 return(strcmp(name, object_name->object_name)); 3028} 3029 3030/* 3031 * Function for qsort to sort fine_reloc structs by their input_offset 3032 */ 3033static 3034int 3035qsort_fine_reloc_input_offset( 3036const struct fine_reloc *fine_reloc1, 3037const struct fine_reloc *fine_reloc2) 3038{ 3039 return(fine_reloc1->input_offset - fine_reloc2->input_offset); 3040} 3041 3042/* 3043 * Function for qsort to sort order_load_map structs by their order. 3044 */ 3045static 3046int 3047qsort_order_load_map_orders( 3048const struct order_load_map *order_load_map1, 3049const struct order_load_map *order_load_map2) 3050{ 3051 return(order_load_map1->order - order_load_map2->order); 3052} 3053 3054/* 3055 * create_order_load_map() creates the structures to be use for printing the 3056 * load map and for -dead_strip. 3057 */ 3058static 3059void 3060create_order_load_maps( 3061struct merged_section *ms, 3062unsigned long norder_load_maps) 3063{ 3064 unsigned long i, j, k, l, m, n; 3065 struct order_load_map *order_load_maps; 3066 struct load_order *load_orders; 3067 3068 order_load_maps = allocate(sizeof(struct order_load_map) * 3069 norder_load_maps); 3070 ms->order_load_maps = order_load_maps; 3071 ms->norder_load_maps = norder_load_maps; 3072 l = 0; 3073 for(i = 0; i < narchive_names; i++){ 3074 for(j = 0; j < archive_names[i].nobject_names; j++){ 3075 cur_obj = archive_names[i].object_names[j].object_file; 3076 for(m = 0; m < cur_obj->nsection_maps; m++){ 3077 if(cur_obj->section_maps[m].output_section != ms) 3078 continue; 3079/* 3080 if(cur_obj->section_maps[m].no_load_order == TRUE){ 3081 continue; 3082 } 3083*/ 3084 n = cur_obj->section_maps[m].nload_orders; 3085 load_orders = cur_obj->section_maps[m].load_orders; 3086 for(k = 0; k < n ; k++){ 3087 order_load_maps[l].archive_name = 3088 archive_names[i].archive_name; 3089 order_load_maps[l].object_name = 3090 archive_names[i].object_names[j].object_name; 3091 order_load_maps[l].symbol_name = load_orders[k].name; 3092 order_load_maps[l].value = load_orders[k].value; 3093 order_load_maps[l].section_map = 3094 &(cur_obj->section_maps[m]); 3095 order_load_maps[l].size = load_orders[k].input_size; 3096 order_load_maps[l].order = load_orders[k].order; 3097 order_load_maps[l].load_order = load_orders + k; 3098 l++; 3099 } 3100 break; 3101 } 3102 } 3103 } 3104 for(j = 0; j < nobject_names; j++){ 3105 cur_obj = object_names[j].object_file; 3106 for(m = 0; m < cur_obj->nsection_maps; m++){ 3107 if(cur_obj->section_maps[m].output_section != ms) 3108 continue; 3109/* 3110 if(cur_obj->section_maps[m].no_load_order == TRUE) 3111 continue; 3112*/ 3113 n = cur_obj->section_maps[m].nload_orders; 3114 load_orders = cur_obj->section_maps[m].load_orders; 3115 for(k = 0; k < n ; k++){ 3116 order_load_maps[l].archive_name = NULL; 3117 order_load_maps[l].object_name = 3118 object_names[j].object_name; 3119 order_load_maps[l].symbol_name = load_orders[k].name; 3120 order_load_maps[l].value = load_orders[k].value; 3121 order_load_maps[l].section_map = 3122 &(cur_obj->section_maps[m]); 3123 order_load_maps[l].size = load_orders[k].input_size; 3124 order_load_maps[l].order = load_orders[k].order; 3125 order_load_maps[l].load_order = load_orders + k; 3126 l++; 3127 } 3128 } 3129 } 3130 3131#ifdef DEBUG 3132 if(debug & (1 << 19)){ 3133 for(i = 0; i < norder_load_maps; i++){ 3134 if(order_load_maps[i].archive_name != NULL) 3135 print("%s:", order_load_maps[i].archive_name); 3136 if(order_load_maps[i].symbol_name != NULL) 3137 print("%s:%s\n", order_load_maps[i].object_name, 3138 order_load_maps[i].symbol_name); 3139 else 3140 print("%s\n", order_load_maps[i].object_name); 3141 } 3142 } 3143#endif /* DEBUG */ 3144 3145 qsort(order_load_maps, 3146 norder_load_maps, 3147 sizeof(struct order_load_map), 3148 (int (*)(const void *, const void *))qsort_order_load_map_orders); 3149} 3150 3151#ifdef DEBUG 3152/* 3153 * print_symbol_name_from_order_load_maps() is used in printing a symbol name 3154 * for a block in the -dead_code stripping debug printing. 3155 */ 3156static 3157void 3158print_symbol_name_from_order_load_maps( 3159struct section_map *map, 3160unsigned long value) 3161{ 3162 unsigned int i, n; 3163 struct order_load_map *order_load_maps; 3164 3165 order_load_maps = map->output_section->order_load_maps; 3166 n = map->output_section->norder_load_maps; 3167 for(i = 0; i < n; i++){ 3168 if(order_load_maps[i].value == value){ 3169 print(":%s", order_load_maps[i].symbol_name); 3170 return; 3171 } 3172 } 3173} 3174#endif /* DEBUG */ 3175 3176/* 3177 * resize_live_sections() resizes the regular and zerofill sections using the 3178 * live file_reloc sizes. 3179 */ 3180__private_extern__ 3181void 3182resize_live_sections( 3183void) 3184{ 3185 struct merged_segment **p, *msg; 3186 struct merged_section **content, **zerofill, *ms; 3187 3188 /* 3189 * For each merged S_REGULAR and zerofill section cause the section to 3190 * be resized to include only the live fine_relocs. 3191 */ 3192 p = &merged_segments; 3193 while(*p){ 3194 msg = *p; 3195 content = &(msg->content_sections); 3196 while(*content){ 3197 ms = *content; 3198 /* 3199 * If a regular section (not a literal section) then call 3200 * resize_live_section() on it. 3201 */ 3202 if((ms->s.flags & SECTION_TYPE) == S_REGULAR && 3203 ms->contents_filename == NULL) 3204 resize_live_section(ms); 3205 content = &(ms->next); 3206 } 3207 zerofill = &(msg->zerofill_sections); 3208 while(*zerofill){ 3209 ms = *zerofill; 3210 resize_live_section(ms); 3211 zerofill = &(ms->next); 3212 } 3213 p = &(msg->next); 3214 } 3215} 3216 3217/* 3218 * resize_live_section() resizes the merged section based on the live 3219 * fine_relocs. 3220 */ 3221static 3222void 3223resize_live_section( 3224struct merged_section *ms) 3225{ 3226 unsigned long n, i, output_offset; 3227 struct order_load_map *order_load_maps; 3228 struct load_order *load_order; 3229 struct fine_reloc *fine_reloc; 3230 3231 /* 3232 * Using the order_load_map of the merged section reassign the 3233 * output_offset of each live fine_reloc. 3234 */ 3235 output_offset = 0; 3236 n = ms->norder_load_maps; 3237 order_load_maps = ms->order_load_maps; 3238 for(i = 0; i < n; i++){ 3239 if(order_load_maps[i].load_order->fine_reloc->live == FALSE){ 3240 if(ms->order_filename != NULL && 3241 sectorder_detail == TRUE && 3242 order_load_maps[i].load_order->line_number != 0) 3243 warning("specification of symbol: %s in -sectorder file: " 3244 "%s line %lu for section (%.16s,%.16s) not used " 3245 "(dead stripped)", 3246 order_load_maps[i].load_order->name, 3247 ms->order_filename, 3248 order_load_maps[i].load_order->line_number, 3249 ms->s.segname, ms->s.sectname); 3250 continue; 3251 } 3252 3253 load_order = order_load_maps[i].load_order; 3254 fine_reloc = load_order->fine_reloc; 3255 3256 output_offset = align_to_input_mod(output_offset, 3257 load_order->input_offset, 3258 ms->s.align); 3259 load_order->output_offset = output_offset; 3260 fine_reloc->output_offset = output_offset; 3261 output_offset += load_order->input_size; 3262 } 3263 3264 /* 3265 * Now the size of the resized merged section can be set with just 3266 * the sizes of the live file_relocs included in the section. 3267 */ 3268 ms->s.size = output_offset; 3269} 3270 3271/* 3272 * relayout_relocs() resets the counts and indexes for the relocation 3273 * entries that will be in the output file when output_for_dyld is TRUE or 3274 * -dead_strip is specified. 3275 */ 3276__private_extern__ 3277void 3278relayout_relocs( 3279void) 3280{ 3281 unsigned long i, j, section_type, nlocrel, nextrel; 3282 struct object_list *object_list, **p; 3283 struct section_map *map; 3284 struct relocation_info *relocs; 3285 3286 struct merged_segment **q, *msg; 3287 struct merged_section **content, *ms; 3288 3289 /* 3290 * For regular and module initialization function pointer sections count 3291 * the number of relocation entries that will be in the output file 3292 * being created (which in the case of output_for_dyld depends on the 3293 * type of output file). 3294 */ 3295 nlocrel = 0; 3296 nextrel = 0; 3297 for(p = &objects; *p; p = &(object_list->next)){ 3298 object_list = *p; 3299 for(i = 0; i < object_list->used; i++){ 3300 cur_obj = &(object_list->object_files[i]); 3301 if(cur_obj == base_obj) 3302 continue; 3303 if(cur_obj->dylib) 3304 continue; 3305 if(cur_obj->bundle_loader) 3306 continue; 3307 if(cur_obj->dylinker) 3308 continue; 3309 cur_obj->ilocrel = nlocrel; 3310 cur_obj->iextrel = nextrel; 3311 for(j = 0; j < cur_obj->nsection_maps; j++){ 3312 if(cur_obj->section_maps[j].s->flags & S_ATTR_DEBUG) 3313 continue; 3314 section_type = cur_obj->section_maps[j].s->flags & 3315 SECTION_TYPE; 3316 if(section_type == S_REGULAR || 3317 section_type == S_MOD_INIT_FUNC_POINTERS || 3318 section_type == S_MOD_TERM_FUNC_POINTERS){ 3319 map = cur_obj->section_maps + j; 3320 relocs = (struct relocation_info *) 3321 (cur_obj->obj_addr + map->s->reloff); 3322 count_relocs(map, relocs, &nlocrel, &nextrel); 3323 } 3324 } 3325 /* 3326 * For merged sections that have external relocation entries 3327 * they need to be kept with the object's other external 3328 * relocation entries so that in a dynamic library they get 3329 * relocated. 3330 */ 3331 for(j = 0; j < cur_obj->nsection_maps; j++){ 3332 section_type = cur_obj->section_maps[j].s->flags & 3333 SECTION_TYPE; 3334 if(section_type == S_COALESCED){ 3335 map = cur_obj->section_maps + j; 3336 if(map->nextrel != 0){ 3337 map->iextrel = nextrel; 3338 nextrel += map->nextrel; 3339 cur_obj->nextrel += map->nextrel; 3340 } 3341 if(map->nlocrel != 0){ 3342 map->ilocrel = nlocrel; 3343 nlocrel += map->nlocrel; 3344 cur_obj->nlocrel += map->nlocrel; 3345 } 3346 } 3347 } 3348 } 3349 } 3350 3351 /* 3352 * For merged sections that could have relocation entries the number 3353 * that will be in the type of output file being created was counted 3354 * up as the section was merged. So here just set the indexes into 3355 * the local and external relocation entries and add their counts to 3356 * the total. 3357 */ 3358 q = &merged_segments; 3359 while(*q){ 3360 msg = *q; 3361 content = &(msg->content_sections); 3362 while(*content){ 3363 ms = *content; 3364 section_type = ms->s.flags & SECTION_TYPE; 3365 if(section_type == S_LITERAL_POINTERS || 3366 section_type == S_SYMBOL_STUBS || 3367 section_type == S_LAZY_SYMBOL_POINTERS){ 3368 if(ms->nlocrel != 0){ 3369 ms->ilocrel = nlocrel; 3370 nlocrel += ms->nlocrel; 3371 ms->s.flags |= S_ATTR_LOC_RELOC; 3372 } 3373 /* 3374 * It is an error if one of these types of merged sections 3375 * has an external relocation entry and the output is a 3376 * multi module dynamic library. As in a multi module dylib 3377 * no library module will "own" it and it will never get 3378 * used by the dynamic linker and the item relocated. 3379 */ 3380 if(ms->nextrel != 0){ 3381 if(filetype == MH_DYLIB && multi_module_dylib == TRUE) 3382 fatal("internal error: relayout_relocs() " 3383 "called with external relocation entries for " 3384 "merged section (%.16s,%.16s) for multi module " 3385 "MH_DYLIB output", ms->s.segname, ms->s.sectname); 3386/* TODO: can this ever get here? even if not MH_DYLIB? */ 3387 ms->iextrel = nextrel; 3388 nextrel += ms->nextrel; 3389 ms->s.flags |= S_ATTR_EXT_RELOC; 3390 } 3391 } 3392 content = &(ms->next); 3393 } 3394 q = &(msg->next); 3395 } 3396 3397 output_dysymtab_info.dysymtab_command.nlocrel = nlocrel; 3398 output_dysymtab_info.dysymtab_command.nextrel = nextrel; 3399} 3400 3401/* 3402 * count_relocs() increments the counts of the nlocrel and nextrel for the 3403 * current object for the specified section based on which relocation entries 3404 * will be in the output file. 3405 */ 3406static 3407void 3408count_relocs( 3409struct section_map *map, 3410struct relocation_info *relocs, 3411unsigned long *nlocrel, 3412unsigned long *nextrel) 3413{ 3414 unsigned long i, j, pair, prev_nlocrel, prev_nextrel; 3415 struct relocation_info reloc, pair_reloc; 3416 struct scattered_relocation_info *sreloc; 3417 unsigned long r_address, r_type, r_extern, r_symbolnum, r_pcrel, r_value, 3418 r_length; 3419 struct undefined_map *undefined_map; 3420 struct merged_symbol *merged_symbol; 3421 struct nlist *nlists; 3422 char *strings; 3423 enum bool defined, pic; 3424 struct section_map *local_map; 3425 struct section_map fake_map; 3426 struct section fake_s; 3427 char fake_contents[4]; 3428 struct relocation_info fake_relocs[2]; 3429 3430 /* to shut up compiler warning messages "may be used uninitialized" */ 3431 merged_symbol = NULL; 3432 defined = FALSE; 3433 3434 prev_nlocrel = cur_obj->nlocrel; 3435 prev_nextrel = cur_obj->nextrel; 3436 for(i = 0; i < map->s->nreloc; i++){ 3437 /* 3438 * Note all errors are not flagged here but left for the *_reloc() 3439 * routines to flag them. 3440 */ 3441 reloc = relocs[i]; 3442 if(cur_obj->swapped && map->input_relocs_already_swapped == FALSE) 3443 swap_relocation_info(&reloc, 1, host_byte_sex); 3444 /* 3445 * Break out the fields of the relocation entry we need here. 3446 */ 3447 if((reloc.r_address & R_SCATTERED) != 0){ 3448 sreloc = (struct scattered_relocation_info *)(&reloc); 3449 r_address = sreloc->r_address; 3450 r_pcrel = sreloc->r_pcrel; 3451 r_type = sreloc->r_type; 3452 r_length = sreloc->r_length; 3453 r_extern = 0; 3454 r_value = sreloc->r_value; 3455 /* calculate the r_symbolnum (n_sect) from the r_value */ 3456 r_symbolnum = 0; 3457 for(j = 0; j < cur_obj->nsection_maps; j++){ 3458 if(r_value >= cur_obj->section_maps[j].s->addr && 3459 r_value < cur_obj->section_maps[j].s->addr + 3460 cur_obj->section_maps[j].s->size){ 3461 r_symbolnum = j + 1; 3462 break; 3463 } 3464 } 3465 if(r_symbolnum == 0){ 3466 /* 3467 * The edge case where the last address past then end of 3468 * of the last section is referenced. 3469 */ 3470 for(j = 0; j < cur_obj->nsection_maps; j++){ 3471 if(r_value == cur_obj->section_maps[j].s->addr + 3472 cur_obj->section_maps[j].s->size){ 3473 r_symbolnum = j + 1; 3474 break; 3475 } 3476 } 3477 if(r_symbolnum == 0){ 3478 return; 3479 } 3480 } 3481 } 3482 else{ 3483 r_address = reloc.r_address; 3484 r_pcrel = reloc.r_pcrel; 3485 r_type = reloc.r_type; 3486 r_length = reloc.r_length; 3487 r_extern = reloc.r_extern; 3488 r_symbolnum = reloc.r_symbolnum; 3489 } 3490 if(r_extern){ 3491 if(r_symbolnum >= cur_obj->symtab->nsyms) 3492 return; 3493 undefined_map = bsearch(&r_symbolnum, cur_obj->undefined_maps, 3494 cur_obj->nundefineds, sizeof(struct undefined_map), 3495 (int (*)(const void *, const void *))undef_bsearch); 3496 if(undefined_map != NULL) 3497 merged_symbol = undefined_map->merged_symbol; 3498 else{ 3499 nlists = (struct nlist *)(cur_obj->obj_addr + 3500 cur_obj->symtab->symoff); 3501 strings = (char *)(cur_obj->obj_addr + 3502 cur_obj->symtab->stroff); 3503 if((nlists[r_symbolnum].n_type & N_EXT) != N_EXT) 3504 return; 3505 /* 3506 * We must allow and create references to defined global 3507 * coalesced symbols with external relocation entries so 3508 * that the dynamic linker can relocate all references to 3509 * the same symbol. 3510 */ 3511 if((nlists[r_symbolnum].n_type & N_TYPE) == N_SECT && 3512 (cur_obj->section_maps[nlists[r_symbolnum].n_sect-1]. 3513 s->flags & SECTION_TYPE) == S_COALESCED){ 3514 merged_symbol = lookup_symbol(strings + 3515 nlists[r_symbolnum].n_un.n_strx); 3516 if(merged_symbol->name_len == 0){ 3517 fatal("internal error, in count_relocs() failed to " 3518 "lookup coalesced symbol %s", strings + 3519 nlists[r_symbolnum].n_un.n_strx); 3520 } 3521 } 3522 else 3523 return; 3524 } 3525 if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR && 3526 merged_symbol->defined_in_dylib == FALSE) 3527 merged_symbol = (struct merged_symbol *) 3528 merged_symbol->nlist.n_value; 3529 if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) || 3530 merged_symbol->nlist.n_type == (N_EXT | N_PBUD) || 3531 (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && 3532 merged_symbol->defined_in_dylib == TRUE)){ 3533 defined = FALSE; 3534 } 3535 else{ 3536 /* 3537 * The symbol is defined but may be a coalesced symbol. 3538 * If so and the output is not an executable (does not 3539 * have a dynamic linker command) this relocation entry 3540 * will remain as an external relocation entry so set 3541 * the variable 'defined' to FALSE. 3542 */ 3543 if((merged_symbol->nlist.n_type & N_TYPE) == N_SECT && 3544 (merged_symbol->definition_object->section_maps[ 3545 merged_symbol->nlist.n_sect-1]. 3546 s->flags & SECTION_TYPE) == S_COALESCED && 3547 has_dynamic_linker_command == FALSE){ 3548 defined = FALSE; 3549 } 3550 else{ 3551 defined = TRUE; 3552 } 3553 } 3554 } 3555 if(reloc_has_pair(arch_flag.cputype, r_type)) 3556 pair = 1; 3557 else 3558 pair = 0; 3559 if(r_extern == 0){ 3560 /* 3561 * If the r_symbolnum refers to a symbol stub section where 3562 * the indirect symbol for what is being reference is now 3563 * defined as an N_ABS symbol it will turn r_symbolnum 3564 * into NO_SECT. So what was a pcrel relocation entry refering 3565 * to another section now refers to absolute symbol and the 3566 * relocation entry is no longer pic and must be kept. 3567 */ 3568 if(r_symbolnum > cur_obj->nsection_maps) 3569 return; 3570 local_map = &(cur_obj->section_maps[r_symbolnum - 1]); 3571 if(r_symbolnum != NO_SECT && 3572 (local_map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS && 3573 local_map->absolute_indirect_defineds == TRUE && 3574 r_pcrel == 1){ 3575 /* 3576 * So we need to know if r_symbolnum will turn into NO_SECT. 3577 * We do this by faking doing the relocation and pick up 3578 * the resulting r_symbolnum after relocation. 3579 */ 3580 if(r_address >= map->s->size) 3581 return; 3582 if(pair && i == map->s->nreloc - 1) 3583 return; 3584 /* fake up a section contents using just this item */ 3585 memcpy(fake_contents, 3586 cur_obj->obj_addr + map->s->offset + r_address, 3587 1 << r_length); 3588 /* fake up relocation entries using just the ones for item*/ 3589 fake_relocs[0] = reloc; 3590 if((reloc.r_address & R_SCATTERED) != 0){ 3591 sreloc = (struct scattered_relocation_info *) 3592 (&fake_relocs[0]); 3593 sreloc->r_address = 0; 3594 } 3595 else 3596 fake_relocs[0].r_address = 0; 3597 if(pair){ 3598 pair_reloc = relocs[i+1]; 3599 if(cur_obj->swapped && 3600 map->input_relocs_already_swapped == FALSE) 3601 swap_relocation_info(&pair_reloc, 1, host_byte_sex); 3602 fake_relocs[1] = pair_reloc; 3603 } 3604 /* 3605 * fake up a section map that will cause the correct 3606 * r_symbolnum (the relocation may be wrong but we don't 3607 * need that). 3608 */ 3609 fake_s = *(map->s); 3610 fake_s.nreloc = 1 + pair; 3611 fake_s.size = 1 << r_length; 3612 fake_s.addr += r_address; 3613 fake_map = *map; 3614 fake_map.s = &fake_s; 3615 fake_map.nfine_relocs = 0; 3616 fake_map.fine_relocs = NULL; 3617 3618 /* do the fake relocation */ 3619 if(arch_flag.cputype == CPU_TYPE_MC680x0) 3620 generic_reloc(fake_contents, fake_relocs, &fake_map, 3621 FALSE, NULL, 0); 3622 else if(arch_flag.cputype == CPU_TYPE_I386) 3623 generic_reloc(fake_contents, fake_relocs, &fake_map, 3624 TRUE, NULL, 0); 3625 else if(arch_flag.cputype == CPU_TYPE_POWERPC || 3626 arch_flag.cputype == CPU_TYPE_VEO) 3627 ppc_reloc(fake_contents, fake_relocs, &fake_map, 3628 NULL, 0); 3629 else if(arch_flag.cputype == CPU_TYPE_MC88000) 3630 m88k_reloc(fake_contents, fake_relocs, &fake_map); 3631 else if(arch_flag.cputype == CPU_TYPE_HPPA) 3632 hppa_reloc(fake_contents, fake_relocs, &fake_map); 3633 else if(arch_flag.cputype == CPU_TYPE_SPARC) 3634 sparc_reloc(fake_contents, fake_relocs, &fake_map); 3635#ifndef RLD 3636 else if(arch_flag.cputype == CPU_TYPE_I860) 3637 i860_reloc(fake_contents, fake_relocs, map); 3638#endif /* RLD */ 3639 else if(arch_flag.cputype == CPU_TYPE_ARM) 3640 arm_reloc(fake_contents, fake_relocs, &fake_map, 3641 NULL, 0); 3642 3643 /* now pick up the correct resulting r_symbolnum */ 3644 r_symbolnum = fake_relocs[0].r_symbolnum; 3645 } 3646 /* 3647 * If this local relocation entry is refering to a coalesced 3648 * section and the r_value is that of a global coalesced 3649 * symbol then this relocation entry will into a external 3650 * relocation entry and the item to be relocated will be 3651 * "unrelocated" removing the value of the global coalesced 3652 * symbol. 3653 */ 3654 else if(r_symbolnum != NO_SECT && 3655 (local_map->s->flags & SECTION_TYPE) == S_COALESCED){ 3656 /* 3657 * The address of the item being referenced for a scattered 3658 * relocation entry is r_address. But for local relocation 3659 * entries the address is in the contents of the item being 3660 * relocated (which is architecure/relocation type dependent 3661 * to get). 3662 * 3663 * Once you have that address you have to go through the 3664 * cur_obj's symbol table trying to matching that address. 3665 * If you find a match then to need to determine if that 3666 * symbols is global in the output file (not a private 3667 * extern turned in to a static). 3668 * 3669 * If all this is true then this relocation entry will 3670 * be turned back into an external relocation entry. 3671 */ 3672 ; 3673 } 3674 pic = (enum bool) 3675 (reloc_is_sectdiff(arch_flag.cputype, r_type) || 3676 (r_pcrel == 1 && r_symbolnum != NO_SECT)); 3677 } 3678 else 3679 pic = (enum bool) 3680 (r_pcrel == 1 && 3681 (merged_symbol->nlist.n_type & N_TYPE) == N_SECT); 3682 /* 3683 * For output_for_dyld PPC_RELOC_JBSR and HPPA_RELOC_JBSR's are 3684 * never put out. 3685 */ 3686 if((arch_flag.cputype == CPU_TYPE_POWERPC && 3687 r_type == PPC_RELOC_JBSR) || 3688 (arch_flag.cputype == CPU_TYPE_HPPA && 3689 r_type == HPPA_RELOC_JBSR)){ 3690 i += pair; 3691 continue; 3692 } 3693 3694 /* 3695 * If -dead_strip is specified then this relocation entry may be 3696 * part of a dead block and thus will not be put out. 3697 */ 3698 if(dead_strip == TRUE){ 3699 if(fine_reloc_offset_in_output(map, r_address) == FALSE){ 3700 i += pair; 3701 continue; 3702 } 3703 } 3704 3705 /* 3706 * When output_for_dyld is FALSE all of relocation entries not in 3707 * dead blocks will be in the output if save_reloc == TRUE. And 3708 * will be extern if from an extern reloc and the symbol is not 3709 * defined else it will be local. 3710 */ 3711 if(output_for_dyld == FALSE){ 3712 if(save_reloc == TRUE){ 3713 if(r_extern == TRUE && defined == FALSE){ 3714 (*nextrel) += 1 + pair; 3715 cur_obj->nextrel += 1 + pair; 3716 } 3717 else{ 3718 (*nlocrel) += 1 + pair; 3719 cur_obj->nlocrel += 1 + pair; 3720 } 3721 } 3722 i += pair; 3723 continue; 3724 } 3725 3726 /* 3727 * When output_for_dyld is TRUE the number of relocation entries in 3728 * the output file is based on one of three different cases: 3729 * The output file is a multi module dynamic shared library 3730 * The output file has a dynamic linker load command 3731 * The output does not have a dynamic linker load command 3732 */ 3733 if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ 3734 /* 3735 * For multi module dynamic shared library files all external 3736 * relocations are kept as external relocation entries except 3737 * for references to private externs (which are kept as locals) 3738 * and all non-position-independent local relocation entries 3739 * are kept. Modules of multi module dylibs are not linked 3740 * together and can only be slid keeping all sections relative 3741 * to each other the same. 3742 */ 3743 if(r_extern && (merged_symbol->nlist.n_type & N_PEXT) == 0){ 3744 (*nextrel) += 1 + pair; 3745 cur_obj->nextrel += 1 + pair; 3746 } 3747 else if(pic == FALSE){ 3748 (*nlocrel) += 1 + pair; 3749 cur_obj->nlocrel += 1 + pair; 3750 } 3751 } 3752 else if(has_dynamic_linker_command){ 3753 /* 3754 * For an file with a dynamic linker load command only external 3755 * relocation entries for undefined symbols are kept. This 3756 * output file is a fixed address and can't be moved. 3757 */ 3758 if(r_extern){ 3759 if(defined == FALSE){ 3760 (*nextrel) += 1 + pair; 3761 cur_obj->nextrel += 1 + pair; 3762 } 3763 } 3764 } 3765 else{ 3766 /* 3767 * For an file without a dynamic linker load command external 3768 * relocation entries for undefined symbols are kept and locals 3769 * that are non-position-independent are kept. This file can 3770 * only be slid keeping all sections relative to each other the 3771 * same. 3772 */ 3773 if(r_extern && (merged_symbol->nlist.n_type & N_PEXT) == 0){ 3774 if(defined == FALSE){ 3775 (*nextrel) += 1 + pair; 3776 cur_obj->nextrel += 1 + pair; 3777 } 3778 else if(pic == FALSE){ 3779 (*nlocrel) += 1 + pair; 3780 cur_obj->nlocrel += 1 + pair; 3781 } 3782 } 3783 else if(pic == FALSE){ 3784 (*nlocrel) += 1 + pair; 3785 cur_obj->nlocrel += 1 + pair; 3786 } 3787 } 3788 i += pair; 3789 } 3790 map->nextrel = cur_obj->nextrel - prev_nextrel; 3791 map->nlocrel = cur_obj->nlocrel - prev_nlocrel; 3792 if(prev_nextrel != cur_obj->nextrel) 3793 map->output_section->s.flags |= S_ATTR_EXT_RELOC; 3794 if(prev_nlocrel != cur_obj->nlocrel) 3795 map->output_section->s.flags |= S_ATTR_LOC_RELOC; 3796} 3797#endif /* !defined(RLD) */ 3798 3799/* 3800 * output_literal_sections() causes each merged literal section to be copied 3801 * to the output file. It is called from pass2(). 3802 */ 3803__private_extern__ 3804void 3805output_literal_sections(void) 3806{ 3807 struct merged_segment **p, *msg; 3808 struct merged_section **content, *ms; 3809 3810 p = &merged_segments; 3811 while(*p){ 3812 msg = *p; 3813 content = &(msg->content_sections); 3814 while(*content){ 3815 ms = *content; 3816 if((ms->s.flags & SECTION_TYPE) == S_CSTRING_LITERALS || 3817 (ms->s.flags & SECTION_TYPE) == S_4BYTE_LITERALS || 3818 (ms->s.flags & SECTION_TYPE) == S_8BYTE_LITERALS || 3819 (ms->s.flags & SECTION_TYPE) == S_LITERAL_POINTERS) 3820 (*ms->literal_output)(ms->literal_data, ms); 3821 content = &(ms->next); 3822 } 3823 p = &(msg->next); 3824 } 3825} 3826 3827#ifndef RLD 3828/* 3829 * output_sections_from_files() causes each section created from a file to be 3830 * copied to the output file. It is called from pass2(). 3831 */ 3832__private_extern__ 3833void 3834output_sections_from_files(void) 3835{ 3836 struct merged_segment **p, *msg; 3837 struct merged_section **content, *ms; 3838#ifdef DEBUG 3839 kern_return_t r; 3840#endif /* DEBUG */ 3841 3842 p = &merged_segments; 3843 while(*p){ 3844 msg = *p; 3845 content = &(msg->content_sections); 3846 while(*content){ 3847 ms = *content; 3848 if(ms->contents_filename != NULL){ 3849 memcpy(output_addr + ms->s.offset, 3850 ms->file_addr, ms->file_size); 3851 /* 3852 * The entire section size is flushed (ms->s.size) not just 3853 * the size of the file used to create it (ms->filesize) so 3854 * to flush the padding due to alignment. 3855 */ 3856 output_flush(ms->s.offset, ms->s.size); 3857#ifdef DEBUG 3858 if((r = vm_deallocate(mach_task_self(), (vm_address_t) 3859 ms->file_addr, ms->file_size)) != KERN_SUCCESS) 3860 mach_fatal(r, "can't vm_deallocate() memory for file: " 3861 "%s used to create section (%.16s,%.16s)", 3862 ms->contents_filename, ms->s.segname, 3863 ms->s.sectname); 3864 ms->file_addr = NULL; 3865#endif /* DEBUG */ 3866 } 3867 content = &(ms->next); 3868 } 3869 p = &(msg->next); 3870 } 3871} 3872#endif /* !defined(RLD) */ 3873 3874/* 3875 * output_section() copies the contents of a section and it's relocation entries 3876 * (if saving relocation entries) into the output file's memory buffer. Then it 3877 * calls the appropriate routine specific to the target machine to relocate the 3878 * section and update the relocation entries (if saving relocation entries). 3879 */ 3880__private_extern__ 3881void 3882output_section( 3883struct section_map *map) 3884{ 3885 char *contents; 3886 struct relocation_info *relocs; 3887#ifndef RLD 3888 struct relocation_info *output_relocs, *output_locrel, *output_extrel; 3889 unsigned long nlocrel, nextrel; 3890 unsigned long nreloc; 3891#endif 3892 3893#ifdef DEBUG 3894 /* The compiler "warning: `output_relocs' may be used uninitialized */ 3895 /* in this function" can safely be ignored */ 3896 output_relocs = NULL; 3897#endif 3898 3899 /* 3900 * If this section has no contents and no relocation entries just 3901 * return. This can happen a lot with object files that have empty 3902 * sections. 3903 */ 3904 if(map->s->size == 0 && map->s->nreloc == 0) 3905 return; 3906 3907 /* 3908 * Copy the contents of the section from the input file into the memory 3909 * buffer for the output file. 3910 */ 3911 if(map->nfine_relocs != 0) 3912 contents = allocate(map->s->size); 3913 else{ 3914 /* 3915 * This is a hack to pad an i386 pure instructions sections with 3916 * nop's (opcode 0x90) to make disassembly cleaner between object's 3917 * sections. 3918 */ 3919 if(arch_flag.cputype == CPU_TYPE_I386 && 3920 (map->s->flags & S_ATTR_PURE_INSTRUCTIONS) != 0){ 3921 contents = output_addr + map->output_section->s.offset + 3922 map->flush_offset; 3923 memset(contents, 0x90, map->offset - map->flush_offset); 3924 } 3925 contents = output_addr + map->output_section->s.offset +map->offset; 3926 } 3927 memcpy(contents, cur_obj->obj_addr + map->s->offset, map->s->size); 3928 3929 /* 3930 * If the section has no relocation entries then no relocation is to be 3931 * done so just flush the contents and return. 3932 */ 3933 if(map->s->nreloc == 0){ 3934#ifndef RLD 3935 if(map->nfine_relocs != 0){ 3936 scatter_copy(map, contents); 3937 free(contents); 3938 } 3939 else 3940 output_flush(map->output_section->s.offset + map->flush_offset, 3941 map->s->size + (map->offset - map->flush_offset)); 3942#endif /* !defined(RLD) */ 3943 return; 3944 } 3945 else 3946 map->output_section->relocated = TRUE; 3947 3948 /* 3949 * Set up the pointer to the relocation entries to be used by the 3950 * relocation routine. If the relocation entries appear in the file 3951 * the relocation routine will update them. If only some but not all 3952 * of the relocation entries will appear in the output file then copy 3953 * them from the input file into the memory buffer. If all of the 3954 * relocation entries will appear in the output file then copy them into 3955 * the buffer for the output file. Lastly if no relocation entries will 3956 * appear in the output file just used the input files relocation 3957 * entries for the relocation routines. 3958 */ 3959 if(output_for_dyld){ 3960 relocs = allocate(map->s->nreloc * sizeof(struct relocation_info)); 3961 memcpy(relocs, 3962 cur_obj->obj_addr + map->s->reloff, 3963 map->s->nreloc * sizeof(struct relocation_info)); 3964 } 3965 else if(save_reloc){ 3966 /* 3967 * For indirect and coalesced sections only those relocation entries 3968 * for items in the section used from this object will be saved. So 3969 * allocate a buffer to put them in to use to do the relocation and 3970 * later scatter_copy_relocs() will pick out the the relocation 3971 * entries to be put in the output file. 3972 */ 3973 if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS || 3974 (map->s->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS || 3975 (map->s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 3976 (map->s->flags & SECTION_TYPE) == S_COALESCED){ 3977 relocs = allocate(map->s->nreloc * 3978 sizeof(struct relocation_info)); 3979 memcpy(relocs, 3980 cur_obj->obj_addr + map->s->reloff, 3981 map->s->nreloc * sizeof(struct relocation_info)); 3982 } 3983 else{ 3984 relocs = (struct relocation_info *)(output_addr + 3985 map->output_section->s.reloff + 3986 map->output_section->output_nrelocs * 3987 sizeof(struct relocation_info)); 3988 memcpy(relocs, 3989 cur_obj->obj_addr + map->s->reloff, 3990 map->s->nreloc * sizeof(struct relocation_info)); 3991 } 3992 } 3993 else{ 3994 relocs = (struct relocation_info *)(cur_obj->obj_addr + 3995 map->s->reloff); 3996 } 3997 if(cur_obj->swapped && map->input_relocs_already_swapped == FALSE){ 3998 swap_relocation_info(relocs, map->s->nreloc, host_byte_sex); 3999 map->input_relocs_already_swapped = TRUE; 4000 } 4001 4002 /* 4003 * Relocate the contents of the section (based on the target machine) 4004 */ 4005 if(arch_flag.cputype == CPU_TYPE_MC680x0) 4006 generic_reloc(contents, relocs, map, FALSE, NULL, 0); 4007 else if(arch_flag.cputype == CPU_TYPE_I386) 4008 generic_reloc(contents, relocs, map, TRUE, NULL, 0); 4009 else if(arch_flag.cputype == CPU_TYPE_POWERPC || 4010 arch_flag.cputype == CPU_TYPE_VEO) 4011 ppc_reloc(contents, relocs, map, NULL, 0); 4012 else if(arch_flag.cputype == CPU_TYPE_MC88000) 4013 m88k_reloc(contents, relocs, map); 4014 else if(arch_flag.cputype == CPU_TYPE_HPPA) 4015 hppa_reloc(contents, relocs, map); 4016 else if(arch_flag.cputype == CPU_TYPE_SPARC) 4017 sparc_reloc(contents, relocs, map); 4018#ifndef RLD 4019 else if(arch_flag.cputype == CPU_TYPE_I860) 4020 i860_reloc(contents, relocs, map); 4021#endif /* RLD */ 4022 else if(arch_flag.cputype == CPU_TYPE_ARM) 4023 arm_reloc(contents, relocs, map, NULL, 0); 4024 else 4025 fatal("internal error: output_section() called with unknown " 4026 "cputype (%d) set", arch_flag.cputype); 4027 4028 /* 4029 * If the reloc routines caused errors then return as so to not cause 4030 * later internal error below. 4031 */ 4032 if(errors) 4033 return; 4034 4035 /* 4036 * Copy and/or flush the relocated section contents to the output file. 4037 */ 4038 if(map->nfine_relocs != 0){ 4039 scatter_copy(map, contents); 4040 free(contents); 4041 } 4042#ifndef RLD 4043 else 4044 output_flush(map->output_section->s.offset + map->flush_offset, 4045 map->s->size + (map->offset - map->flush_offset)); 4046 4047 /* 4048 * If relocation entries will be in the output file copy and/or flush 4049 * them to the output file. 4050 */ 4051 if(output_for_dyld){ 4052 /* 4053 * Setup pointers in the output file buffer for local and external 4054 * relocation entries. 4055 */ 4056 if((map->s->flags & SECTION_TYPE) == S_REGULAR || 4057 (map->s->flags & SECTION_TYPE) == S_MOD_INIT_FUNC_POINTERS || 4058 (map->s->flags & SECTION_TYPE) == S_MOD_TERM_FUNC_POINTERS){ 4059 output_locrel = (struct relocation_info *)(output_addr + 4060 output_dysymtab_info.dysymtab_command.locreloff + 4061 cur_obj->ilocrel * sizeof(struct relocation_info)); 4062 output_extrel = (struct relocation_info *)(output_addr + 4063 output_dysymtab_info.dysymtab_command.extreloff + 4064 cur_obj->iextrel * sizeof(struct relocation_info)); 4065 } 4066 else if((map->s->flags & SECTION_TYPE) == S_COALESCED){ 4067 output_locrel = (struct relocation_info *)(output_addr + 4068 output_dysymtab_info.dysymtab_command.locreloff + 4069 map->ilocrel * sizeof(struct relocation_info)); 4070 output_extrel = (struct relocation_info *)(output_addr + 4071 output_dysymtab_info.dysymtab_command.extreloff + 4072 map->iextrel * sizeof(struct relocation_info)); 4073 } 4074 else{ 4075 output_locrel = (struct relocation_info *)(output_addr + 4076 output_dysymtab_info.dysymtab_command.locreloff + 4077 map->output_section->ilocrel * 4078 sizeof(struct relocation_info)); 4079 output_extrel = (struct relocation_info *)(output_addr + 4080 output_dysymtab_info.dysymtab_command.extreloff + 4081 map->output_section->iextrel * 4082 sizeof(struct relocation_info)); 4083 } 4084 /* 4085 * Copy out the local and external relocation entries to be kept 4086 * for the output file type and adjust the r_address values to be 4087 * based on the offset from starting address of the first segment 4088 * rather than the offset of the section. 4089 */ 4090 reloc_output_for_dyld(map, relocs, output_locrel, output_extrel, 4091 &nlocrel, &nextrel); 4092 /* 4093 * count_reloc() and coalesced_section_merge() counted and recorded 4094 * the number of relocation entries the section was to have in the 4095 * output. This should match what reloc_output_for_dyld() copied 4096 * out. 4097 */ 4098 if((map->s->flags & SECTION_TYPE) == S_REGULAR || 4099 (map->s->flags & SECTION_TYPE) == S_MOD_INIT_FUNC_POINTERS || 4100 (map->s->flags & SECTION_TYPE) == S_MOD_TERM_FUNC_POINTERS || 4101 (map->s->flags & SECTION_TYPE) == S_COALESCED){ 4102 if(nextrel != map->nextrel) 4103 fatal("internal error: output_section() count of external " 4104 "relocation entries does not match\n"); 4105 if(nlocrel != map->nlocrel) 4106 fatal("internal error: output_section() count of local " 4107 "relocation entries does not match\n"); 4108 } 4109 4110 if(host_byte_sex != target_byte_sex){ 4111 swap_relocation_info(output_locrel, nlocrel, target_byte_sex); 4112 swap_relocation_info(output_extrel, nextrel, target_byte_sex); 4113 } 4114 /* 4115 * Flush output file buffer's local and external relocation entries 4116 * and increment the counts. 4117 */ 4118 if((map->s->flags & SECTION_TYPE) == S_REGULAR || 4119 (map->s->flags & SECTION_TYPE) == S_MOD_INIT_FUNC_POINTERS || 4120 (map->s->flags & SECTION_TYPE) == S_MOD_TERM_FUNC_POINTERS){ 4121 output_flush(output_dysymtab_info.dysymtab_command.locreloff + 4122 cur_obj->ilocrel * sizeof(struct relocation_info), 4123 nlocrel * sizeof(struct relocation_info)); 4124 cur_obj->ilocrel += nlocrel; 4125 output_flush(output_dysymtab_info.dysymtab_command.extreloff + 4126 cur_obj->iextrel * sizeof(struct relocation_info), 4127 nextrel * sizeof(struct relocation_info)); 4128 cur_obj->iextrel += nextrel; 4129 } 4130 else if((map->s->flags & SECTION_TYPE) == S_COALESCED){ 4131 output_flush(output_dysymtab_info.dysymtab_command.locreloff + 4132 map->ilocrel * sizeof(struct relocation_info), 4133 nlocrel * sizeof(struct relocation_info)); 4134 /* no increment of map->nlocrel */ 4135 output_flush(output_dysymtab_info.dysymtab_command.extreloff + 4136 map->iextrel * sizeof(struct relocation_info), 4137 nextrel * sizeof(struct relocation_info)); 4138 /* no increment of map->nextrel */ 4139 } 4140 else{ 4141 output_flush(output_dysymtab_info.dysymtab_command.locreloff + 4142 map->output_section->ilocrel * 4143 sizeof(struct relocation_info), 4144 nlocrel * sizeof(struct relocation_info)); 4145 map->output_section->ilocrel += nlocrel; 4146 output_flush(output_dysymtab_info.dysymtab_command.extreloff + 4147 map->output_section->iextrel * 4148 sizeof(struct relocation_info), 4149 nextrel * sizeof(struct relocation_info)); 4150 map->output_section->iextrel += nextrel; 4151 } 4152 free(relocs); 4153 } 4154 else if(save_reloc){ 4155 if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS || 4156 (map->s->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS || 4157 (map->s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 4158 (map->s->flags & SECTION_TYPE) == S_COALESCED){ 4159 4160 output_relocs = (struct relocation_info *)(output_addr + 4161 map->output_section->s.reloff + 4162 map->output_section->output_nrelocs * 4163 sizeof(struct relocation_info)); 4164 nreloc = scatter_copy_relocs(map, relocs, output_relocs); 4165 free(relocs); 4166 } 4167 else{ 4168 nreloc = map->s->nreloc; 4169 output_relocs = relocs; 4170 } 4171 if(host_byte_sex != target_byte_sex) 4172 swap_relocation_info(output_relocs, nreloc, target_byte_sex); 4173 output_flush(map->output_section->s.reloff + 4174 map->output_section->output_nrelocs * 4175 sizeof(struct relocation_info), 4176 nreloc * sizeof(struct relocation_info)); 4177 map->output_section->output_nrelocs += nreloc; 4178 } 4179#endif /* !defined(RLD) */ 4180} 4181 4182#ifndef RLD 4183 4184/* 4185 * is_pass2_merged_symbol_coalesced() is passed a merged symbol as it appears 4186 * in the second pass (that is with its n_sect) set to the output's section 4187 * number) and returns TRUE if the symbol is in a coalesced section and FALSE 4188 * otherwise. This is used by scatter_copy() below to set the value of 4189 * non-lazy pointers. This absolutely need to be done by the static linker for 4190 * private extern coalesced symbols (when -keep_private_extern is not in effect) 4191 * as their indirect symbol table will be INDIRECT_SYMBOL_LOCAL on output and 4192 * then the dynamic linker can't fix them up. 4193 */ 4194static 4195enum bool 4196is_pass2_merged_symbol_coalesced( 4197struct merged_symbol *merged_symbol) 4198{ 4199 unsigned long i; 4200 4201 if(merged_symbol == NULL) 4202 return(FALSE); 4203 if((merged_symbol->nlist.n_type & N_TYPE) != N_SECT) 4204 return(FALSE); 4205 for(i = 0; i < merged_symbol->definition_object->nsection_maps; i++){ 4206 if(merged_symbol->nlist.n_sect == merged_symbol->definition_object-> 4207 section_maps[i].output_section->output_sectnum) 4208 if((merged_symbol->definition_object->section_maps[ 4209 i].output_section->s.flags & SECTION_TYPE) == S_COALESCED) 4210 return(TRUE); 4211 } 4212 return(FALSE); 4213} 4214#endif /* !defined(RLD) */ 4215 4216/* 4217 * pass2_nsect_merged_symbol_section_type() is passed an n_sect merged symbol as 4218 * it appears in the second pass (that is with its n_sect) set to the output's 4219 * section number) and returns the section type of that symbol in the output. 4220 * otherwise. This is used by legal_reference() in the case of weak coalesced 4221 * symbols being discarded for some other symbol to figure out what section is 4222 * being referenced in the output. 4223 */ 4224__private_extern__ 4225unsigned long 4226pass2_nsect_merged_symbol_section_type( 4227struct merged_symbol *merged_symbol) 4228{ 4229 unsigned long i; 4230 4231 if(merged_symbol == NULL || 4232 (merged_symbol->nlist.n_type & N_TYPE) != N_SECT) 4233 fatal("internal error, s_pass2_merged_symbol_coalesced() passed " 4234 "a non-N_SECT symbol"); 4235 for(i = 0; i < merged_symbol->definition_object->nsection_maps; i++){ 4236 if(merged_symbol->nlist.n_sect == merged_symbol->definition_object-> 4237 section_maps[i].output_section->output_sectnum) 4238 return(merged_symbol->definition_object->section_maps[i]. 4239 output_section->s.flags & SECTION_TYPE); 4240 } 4241 fatal("internal error, s_pass2_merged_symbol_coalesced() failed\n"); 4242 return(0); 4243} 4244 4245/* 4246 * scatter_copy() copies the relocated contents of a section into the output 4247 * file's memory buffer based on the section's fine relocation maps. 4248 */ 4249static 4250void 4251scatter_copy( 4252struct section_map *map, 4253char *contents) 4254{ 4255 unsigned long i; 4256#ifndef RLD 4257 unsigned long j; 4258 struct nlist *nlists; 4259 unsigned long *indirect_symtab, index, value; 4260 struct undefined_map *undefined_map; 4261 struct merged_symbol *merged_symbol; 4262 char *strings; 4263 struct section_map *section_map; 4264 long delta; 4265 char *jmpEntry; 4266 4267 /* 4268 * For non-lazy pointer type indirect sections only copy those parts of 4269 * the section who's contents are used in the output file and if the 4270 * symbol for the non-lazy pointer is defined then use that as instead 4271 * of the contents. This bit of code assumes that all the checks done 4272 * when merging the indirect section are valid and so none of them are 4273 * done here. It also assumes that the fine relocation entries each 4274 * cover the 4 byte non-lazy pointer. 4275 * 4276 * If prebinding and this is a lazy pointer section do the same as for 4277 * non-lazy pointers. That is use the value of the indirect symbol. 4278 */ 4279 if((map->s->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS || 4280 (prebinding == TRUE && 4281 (map->s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS)){ 4282 /* setup pointers to the symbol table and indirect symbol table */ 4283 nlists = (struct nlist *)(cur_obj->obj_addr + 4284 cur_obj->symtab->symoff); 4285 indirect_symtab = (unsigned long *)(cur_obj->obj_addr + 4286 cur_obj->dysymtab->indirectsymoff); 4287 strings = cur_obj->obj_addr + cur_obj->symtab->stroff; 4288 for(i = 0; i < map->nfine_relocs - 1; i++){ 4289 if(map->fine_relocs[i].use_contents == TRUE && 4290 (dead_strip == FALSE || map->fine_relocs[i].live == TRUE)){ 4291 index = indirect_symtab[map->s->reserved1 + 4292 (map->fine_relocs[i].input_offset / 4)]; 4293 if(map->fine_relocs[i].indirect_defined == TRUE || 4294 is_pass2_merged_symbol_coalesced( 4295 map->fine_relocs[i].merged_symbol) == TRUE || 4296 (prebinding == TRUE && 4297 (index != INDIRECT_SYMBOL_LOCAL && 4298 index != INDIRECT_SYMBOL_ABS))){ 4299 if(is_pass2_merged_symbol_coalesced( 4300 map->fine_relocs[i].merged_symbol) == TRUE){ 4301 value = map->fine_relocs[i].merged_symbol-> 4302 nlist.n_value; 4303 if((map->fine_relocs[i].merged_symbol-> 4304 nlist.n_desc & N_ARM_THUMB_DEF)) 4305 value |= 1; 4306 } 4307 else if(map->fine_relocs[i].local_symbol == FALSE){ 4308 undefined_map = bsearch(&index, 4309 cur_obj->undefined_maps, cur_obj->nundefineds, 4310 sizeof(struct undefined_map), 4311 (int (*)(const void *, const void *)) 4312 undef_bsearch); 4313 if(undefined_map == NULL){ 4314 merged_symbol = lookup_symbol(strings + 4315 nlists[index].n_un.n_strx); 4316 if(merged_symbol->name_len == 0) 4317 fatal("interal error, scatter_copy() failed" 4318 " in looking up external symbol"); 4319 } 4320 else 4321 merged_symbol = undefined_map->merged_symbol; 4322 if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR) 4323 merged_symbol = (struct merged_symbol *) 4324 merged_symbol->nlist.n_value; 4325 value = merged_symbol->nlist.n_value; 4326 if((merged_symbol->nlist.n_desc & N_ARM_THUMB_DEF)) 4327 value |= 1; 4328 } 4329 else{ 4330 if(nlists[index].n_sect == NO_SECT) 4331 value = nlists[index].n_value; 4332 else{ 4333 section_map = &(cur_obj->section_maps[ 4334 nlists[index].n_sect -1]); 4335 if(section_map->nfine_relocs == 0) 4336 value = nlists[index].n_value - 4337 section_map->s->addr + 4338 section_map->output_section->s.addr + 4339 section_map->offset; 4340 else 4341 value = 4342 section_map->output_section->s.addr + 4343 fine_reloc_output_offset(section_map, 4344 nlists[index].n_value - 4345 section_map->s->addr); 4346 } 4347 if((nlists[index].n_desc & N_ARM_THUMB_DEF)) 4348 value |= 1; 4349 } 4350 if(host_byte_sex != target_byte_sex) 4351 value = SWAP_LONG(value); 4352 memcpy(output_addr + map->output_section->s.offset + 4353 map->fine_relocs[i].output_offset, 4354 &value, sizeof(unsigned long)); 4355 } 4356 else{ 4357 /* 4358 * If the indirect symbol table entry is 4359 * INDIRECT_SYMBOL_LOCAL the value of the symbol pointer 4360 * neededs to be adjusted to where it is in the output. 4361 */ 4362 if(index == INDIRECT_SYMBOL_LOCAL){ 4363 memcpy(&value, contents + 4364 map->fine_relocs[i].input_offset, 4); 4365 if(cur_obj->swapped) 4366 value = SWAP_LONG(value); 4367 for(j = 0; j < cur_obj->nsection_maps; j++){ 4368 if(value >= cur_obj->section_maps[j].s->addr && 4369 value < cur_obj->section_maps[j].s->addr + 4370 cur_obj->section_maps[j].s->size){ 4371 break; 4372 } 4373 } 4374 if(j >= cur_obj->nsection_maps){ 4375 error_with_cur_obj("value of symbol pointer " 4376 "(0x%x) in section (%.16s,%.16s) at index " 4377 "%ld out of range for an indirect symbol " 4378 "table value of INDIRECT_SYMBOL_LOCAL", 4379 (unsigned int)value, 4380 map->output_section->s.segname, 4381 map->output_section->s.sectname, i); 4382 return; 4383 } 4384 section_map = &(cur_obj->section_maps[j]); 4385 if(section_map->nfine_relocs == 0) 4386 value = value - 4387 section_map->s->addr + 4388 section_map->output_section->s.addr + 4389 section_map->offset; 4390 else 4391 value = 4392 section_map->output_section->s.addr + 4393 fine_reloc_output_offset(section_map, 4394 value - section_map->s->addr); 4395 if(host_byte_sex != target_byte_sex) 4396 value = SWAP_LONG(value); 4397 memcpy(output_addr + map->output_section->s.offset + 4398 map->fine_relocs[i].output_offset, 4399 &value, sizeof(unsigned long)); 4400 } 4401 else{ 4402 memcpy(output_addr + map->output_section->s.offset + 4403 map->fine_relocs[i].output_offset, 4404 contents + map->fine_relocs[i].input_offset, 4405 map->fine_relocs[i+1].input_offset - 4406 map->fine_relocs[i].input_offset); 4407 } 4408 } 4409 } 4410 } 4411 if(map->fine_relocs[i].use_contents == TRUE && 4412 (dead_strip == FALSE || map->fine_relocs[i].live == TRUE)){ 4413 index = indirect_symtab[map->s->reserved1 + 4414 (map->fine_relocs[i].input_offset / 4)]; 4415 if(map->fine_relocs[i].indirect_defined == TRUE || 4416 is_pass2_merged_symbol_coalesced( 4417 map->fine_relocs[i].merged_symbol) == TRUE || 4418 (prebinding == TRUE && 4419 (index != INDIRECT_SYMBOL_LOCAL && 4420 index != INDIRECT_SYMBOL_ABS))){ 4421 if(is_pass2_merged_symbol_coalesced( 4422 map->fine_relocs[i].merged_symbol) == TRUE){ 4423 value = map->fine_relocs[i].merged_symbol-> 4424 nlist.n_value; 4425 if((map->fine_relocs[i].merged_symbol-> 4426 nlist.n_desc & N_ARM_THUMB_DEF)) 4427 value |= 1; 4428 } 4429 else if(map->fine_relocs[i].local_symbol == FALSE){ 4430 undefined_map = bsearch(&index, 4431 cur_obj->undefined_maps, cur_obj->nundefineds, 4432 sizeof(struct undefined_map), 4433 (int (*)(const void *, const void *)) 4434 undef_bsearch); 4435 if(undefined_map == NULL){ 4436 merged_symbol = lookup_symbol(strings + 4437 nlists[index].n_un.n_strx); 4438 if(merged_symbol->name_len == 0) 4439 fatal("interal error, scatter_copy() failed" 4440 " in looking up external symbol"); 4441 } 4442 else 4443 merged_symbol = undefined_map->merged_symbol; 4444 if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR) 4445 merged_symbol = (struct merged_symbol *) 4446 merged_symbol->nlist.n_value; 4447 value = merged_symbol->nlist.n_value; 4448 if((merged_symbol->nlist.n_desc & N_ARM_THUMB_DEF)) 4449 value |= 1; 4450 } 4451 else{ 4452 if(nlists[index].n_sect == NO_SECT) 4453 value = nlists[index].n_value; 4454 else{ 4455 section_map = &(cur_obj->section_maps[ 4456 nlists[index].n_sect -1]); 4457 if(section_map->nfine_relocs == 0) 4458 value = nlists[index].n_value - 4459 section_map->s->addr + 4460 section_map->output_section->s.addr + 4461 section_map->offset; 4462 else 4463 value = 4464 section_map->output_section->s.addr + 4465 fine_reloc_output_offset(section_map, 4466 nlists[index].n_value - 4467 section_map->s->addr); 4468 } 4469 if((nlists[index].n_desc & N_ARM_THUMB_DEF)) 4470 value |= 1; 4471 } 4472 if(host_byte_sex != target_byte_sex) 4473 value = SWAP_LONG(value); 4474 memcpy(output_addr + map->output_section->s.offset + 4475 map->fine_relocs[i].output_offset, 4476 &value, sizeof(unsigned long)); 4477 } 4478 else{ 4479 /* 4480 * If the indirect symbol table entry is 4481 * INDIRECT_SYMBOL_LOCAL the value of the symbol pointer 4482 * neededs to be adjusted to where it is in the output. 4483 */ 4484 if(index == INDIRECT_SYMBOL_LOCAL){ 4485 memcpy(&value, contents + 4486 map->fine_relocs[i].input_offset, 4); 4487 if(cur_obj->swapped) 4488 value = SWAP_LONG(value); 4489 for(j = 0; j < cur_obj->nsection_maps; j++){ 4490 if(value >= cur_obj->section_maps[j].s->addr && 4491 value < cur_obj->section_maps[j].s->addr + 4492 cur_obj->section_maps[j].s->size){ 4493 break; 4494 } 4495 } 4496 if(j >= cur_obj->nsection_maps){ 4497 error_with_cur_obj("value of symbol pointer (0x%x) " 4498 "in section (%.16s,%.16s) at index %ld out of " 4499 "range for an indirect symbol table value of " 4500 "INDIRECT_SYMBOL_LOCAL", (unsigned int)value, 4501 map->output_section->s.segname, 4502 map->output_section->s.sectname, i); 4503 return; 4504 } 4505 section_map = &(cur_obj->section_maps[j]); 4506 if(section_map->nfine_relocs == 0) 4507 value = value - 4508 section_map->s->addr + 4509 section_map->output_section->s.addr + 4510 section_map->offset; 4511 else 4512 value = 4513 section_map->output_section->s.addr + 4514 fine_reloc_output_offset(section_map, 4515 value - section_map->s->addr); 4516 if(host_byte_sex != target_byte_sex) 4517 value = SWAP_LONG(value); 4518 memcpy(output_addr + map->output_section->s.offset + 4519 map->fine_relocs[i].output_offset, 4520 &value, sizeof(unsigned long)); 4521 } 4522 else{ 4523 memcpy(output_addr + map->output_section->s.offset + 4524 map->fine_relocs[i].output_offset, 4525 contents + map->fine_relocs[i].input_offset, 4526 map->s->size - map->fine_relocs[i].input_offset); 4527 } 4528 } 4529 } 4530 } 4531 /* 4532 * The i386 has a special 5 byte stub that is modify by dyld to become 4533 * a JMP instruction. When building prebound, we set the stub to be 4534 * the JMP instruction. 4535 */ 4536 else if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS && 4537 prebinding == TRUE && 4538 arch_flag.cputype == CPU_TYPE_I386 && 4539 (map->s->flags & S_ATTR_SELF_MODIFYING_CODE) == 4540 S_ATTR_SELF_MODIFYING_CODE && 4541 map->s->reserved2 == 5){ 4542 nlists = (struct nlist *)(cur_obj->obj_addr + 4543 cur_obj->symtab->symoff); 4544 indirect_symtab = (unsigned long *)(cur_obj->obj_addr + 4545 cur_obj->dysymtab->indirectsymoff); 4546 strings = cur_obj->obj_addr + cur_obj->symtab->stroff; 4547 for(i = 0; i < map->nfine_relocs; i++){ 4548 if(map->fine_relocs[i].use_contents == TRUE && 4549 (dead_strip == FALSE || map->fine_relocs[i].live == TRUE)){ 4550 index = indirect_symtab[map->s->reserved1 + 4551 (map->fine_relocs[i].input_offset / 5)]; 4552 undefined_map = bsearch(&index, 4553 cur_obj->undefined_maps, cur_obj->nundefineds, 4554 sizeof(struct undefined_map), 4555 (int (*)(const void *, const void *)) 4556 undef_bsearch); 4557 if(undefined_map == NULL){ 4558 merged_symbol = lookup_symbol(strings + 4559 nlists[index].n_un.n_strx); 4560 if(merged_symbol->name_len == 0) 4561 fatal("interal error, scatter_copy() failed" 4562 " in looking up external symbol"); 4563 } 4564 else 4565 merged_symbol = undefined_map->merged_symbol; 4566 value = merged_symbol->nlist.n_value; 4567 delta = value - (map->output_section->s.addr + 4568 map->fine_relocs[i].output_offset + 5); 4569 jmpEntry = output_addr + map->output_section->s.offset + 4570 map->fine_relocs[i].output_offset; 4571 if(host_byte_sex != target_byte_sex) 4572 delta = SWAP_LONG(delta); 4573 *jmpEntry = 0xE9; /* JMP rel32 */ 4574 memcpy(jmpEntry + 1, &delta, sizeof(unsigned long)); 4575 } 4576 } 4577 } 4578 else 4579#endif /* !defined(RLD) */ 4580 /* 4581 * For other indirect sections and coalesced sections only copy those 4582 * parts of the section who's contents are used in the output file. 4583 */ 4584 if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS || 4585 (map->s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 4586 (map->s->flags & SECTION_TYPE) == S_COALESCED){ 4587 for(i = 0; i < map->nfine_relocs - 1; i++){ 4588 if(map->fine_relocs[i].use_contents == TRUE && 4589 (dead_strip == FALSE || map->fine_relocs[i].live == TRUE)){ 4590 memcpy(output_addr + map->output_section->s.offset + 4591 map->fine_relocs[i].output_offset, 4592 contents + map->fine_relocs[i].input_offset, 4593 map->fine_relocs[i+1].input_offset - 4594 map->fine_relocs[i].input_offset); 4595 } 4596 } 4597 if(map->fine_relocs[i].use_contents == TRUE && 4598 (dead_strip == FALSE || map->fine_relocs[i].live == TRUE)){ 4599 memcpy(output_addr + map->output_section->s.offset + 4600 map->fine_relocs[i].output_offset, 4601 contents + map->fine_relocs[i].input_offset, 4602 map->s->size - map->fine_relocs[i].input_offset); 4603 } 4604 } 4605 else{ 4606 for(i = 0; i < map->nfine_relocs - 1; i++){ 4607 if(dead_strip == FALSE || map->fine_relocs[i].live == TRUE){ 4608 memcpy(output_addr + map->output_section->s.offset + 4609 map->fine_relocs[i].output_offset, 4610 contents + map->fine_relocs[i].input_offset, 4611 map->fine_relocs[i+1].input_offset - 4612 map->fine_relocs[i].input_offset); 4613 } 4614 } 4615 if(dead_strip == FALSE || map->fine_relocs[i].live == TRUE){ 4616 memcpy(output_addr + map->output_section->s.offset + 4617 map->fine_relocs[i].output_offset, 4618 contents + map->fine_relocs[i].input_offset, 4619 map->s->size - map->fine_relocs[i].input_offset); 4620 } 4621 } 4622} 4623 4624#ifndef RLD 4625/* 4626 * reloc_output_for_dyld() takes the relocation entries after being processed by 4627 * a relocation routine and copys the ones to be in the output file for a file 4628 * the is output for dyld. It also changes the r_address field of the of the 4629 * relocation entries to be relative to the first segment's address rather than 4630 * the section's address. 4631 */ 4632static 4633void 4634reloc_output_for_dyld( 4635struct section_map *map, 4636struct relocation_info *relocs, 4637struct relocation_info *output_locrel, 4638struct relocation_info *output_extrel, 4639unsigned long *nlocrel, 4640unsigned long *nextrel) 4641{ 4642 unsigned long i, addr_adjust, temp, pair; 4643 struct relocation_info *reloc; 4644 struct scattered_relocation_info *sreloc; 4645 unsigned long r_address, r_extern, r_type, r_scattered, r_pcrel, 4646 r_symbolnum, r_value; 4647 enum bool partial_section, sectdiff, pic, has_sect_diff_relocs; 4648 enum bool flag_relocs, first_time; 4649 4650 /* to shut up compiler warning messages "may be used uninitialized" */ 4651 sreloc = NULL; 4652 4653 /* 4654 * If we are flagging relocation entries in read only sections set up 4655 * to do that. 4656 */ 4657 first_time = TRUE; 4658 if(read_only_reloc_flag != READ_ONLY_RELOC_SUPPRESS) 4659 flag_relocs = is_merged_section_read_only(map->output_section); 4660 else 4661 flag_relocs = FALSE; 4662 if(flag_relocs == TRUE) 4663 clear_read_only_reloc_flags(); 4664 has_sect_diff_relocs = FALSE; 4665 4666 *nlocrel = 0; 4667 *nextrel = 0; 4668 partial_section = (enum bool) 4669 (dead_strip == TRUE || 4670 (map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS || 4671 (map->s->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS || 4672 (map->s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 4673 (map->s->flags & SECTION_TYPE) == S_COALESCED); 4674 /* 4675 * For MH_SPLIT_SEGS images the r_address is relative to the first 4676 * read-write segment and there are no relocation entries allowed in 4677 * the read-only segments. This is needed because the r_address field 4678 * is 24 bits which means that the normal split of 265meg wouldn't allow 4679 * the use of 24 bits from the address of the first segment which is 4680 * what is normally used for outputs for dyld. 4681 */ 4682 if(segs_read_only_addr_specified == TRUE) 4683 addr_adjust = map->output_section->s.addr - 4684 segs_read_write_addr; 4685 else 4686 addr_adjust = map->output_section->s.addr - 4687 merged_segments->sg.vmaddr; 4688 /* 4689 * These relocation entries have been processed by a relocation routine 4690 * turning external relocation entries into local relocation entries and 4691 * updating the r_address field to be relative to the output section's 4692 * address. 4693 */ 4694 for(i = 0; i < map->s->nreloc; i++){ 4695 reloc = relocs + i; 4696 /* 4697 * Break out the fields of the relocation entry we need here. 4698 */ 4699 if((relocs[i].r_address & R_SCATTERED) != 0){ 4700 sreloc = (struct scattered_relocation_info *)(relocs + i); 4701 r_scattered = 1; 4702 r_address = sreloc->r_address; 4703 r_pcrel = sreloc->r_pcrel; 4704 r_type = sreloc->r_type; 4705 r_extern = 0; 4706 r_value = sreloc->r_value; 4707 /* 4708 * For a scattered relocation entry the r_symbolnum is never 4709 * NO_SECT and that is all we need to know in this routine for 4710 * a scattered relocation entry. Calculating the r_symbolnum 4711 * (n_sect) from the r_value now that it has been processed by 4712 * a relocation routine is not easy as the value could be 4713 * in a section with fine relocation entries. It is doable but 4714 * not needed here. So we fake r_symbolnum to be anything but 4715 * NO_SECT (the first section ordinal is used). 4716 */ 4717 r_symbolnum = 1; 4718 } 4719 else{ 4720 r_scattered = 0; 4721 r_address = reloc->r_address; 4722 r_pcrel = reloc->r_pcrel; 4723 r_type = reloc->r_type; 4724 r_extern = reloc->r_extern; 4725 r_symbolnum = reloc->r_symbolnum; 4726 } 4727 if(reloc_has_pair(arch_flag.cputype, r_type)) 4728 pair = 1; 4729 else 4730 pair = 0; 4731 if(partial_section){ 4732 if(fine_reloc_offset_in_output_for_output_offset(map, 4733 r_address) == FALSE){ 4734 i += pair; 4735 continue; 4736 } 4737 } 4738 if(r_extern == 0){ 4739 sectdiff = reloc_is_sectdiff(arch_flag.cputype, r_type); 4740 has_sect_diff_relocs |= sectdiff; 4741 pic = (enum bool) 4742 (sectdiff == TRUE || 4743 (r_pcrel == 1 && r_symbolnum != NO_SECT)); 4744 } 4745 else 4746 pic = FALSE; 4747 /* 4748 * For output_for_dyld PPC_RELOC_JBSR and HPPA_RELOC_JBSR's are 4749 * never put out. 4750 */ 4751 if((arch_flag.cputype == CPU_TYPE_POWERPC && 4752 r_type == PPC_RELOC_JBSR) || 4753 (arch_flag.cputype == CPU_TYPE_HPPA && 4754 r_type == HPPA_RELOC_JBSR)){ 4755 i += pair; 4756 continue; 4757 } 4758 4759 /* 4760 * The relocation entries in the output file is based on one of 4761 * three different cases: 4762 * The output file is a multi module dynamic shared library 4763 * The output file has a dynamic linker load command 4764 * The output does not have a dynamic linker load command 4765 */ 4766 if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ 4767 /* 4768 * For multi module dynamic shared library files all external 4769 * relocations are kept as external relocation entries except 4770 * for references to private externs (which are have been turned 4771 * into locals and kept as locals) and all non-position- 4772 * independent local relocation entrie are kept. Modules of 4773 * multi module dylibs are not linked together and can only be 4774 * slid keeping all sections relative to each other the same. 4775 */ 4776 if(r_extern){ 4777 reloc->r_address += addr_adjust; 4778 memcpy(output_extrel + *nextrel, reloc, 4779 sizeof(struct relocation_info) * (1 + pair)); 4780 (*nextrel) += 1 + pair; 4781 if(flag_relocs == TRUE) 4782 flag_read_only_reloc(map->s, r_symbolnum, &first_time); 4783 } 4784 else if(pic == FALSE){ 4785 if(r_scattered) 4786 sreloc->r_address += addr_adjust; 4787 else 4788 reloc->r_address += addr_adjust; 4789 memcpy(output_locrel + *nlocrel, reloc, 4790 sizeof(struct relocation_info) * (1 + pair)); 4791 (*nlocrel) += 1 + pair; 4792 } 4793 } 4794 else if(has_dynamic_linker_command){ 4795 /* 4796 * For an file with a dynamic linker load command only external 4797 * relocation entries for undefined symbols (those that have 4798 * not been turned into locals) are kept. This output file is 4799 * at a fixed address and can't be moved. 4800 */ 4801 if(r_extern){ 4802 reloc->r_address += addr_adjust; 4803 memcpy(output_extrel + *nextrel, reloc, 4804 sizeof(struct relocation_info) * (1 + pair)); 4805 (*nextrel) += 1 + pair; 4806 if(flag_relocs == TRUE) 4807 flag_read_only_reloc(map->s, r_symbolnum, &first_time); 4808 } 4809 /* 4810 * Even though the file can't be moved we may be trying to 4811 * prebind. If we are prebinging we need the local 4812 * relocation entries for lazy symbol pointers to be saved 4813 * so dyld will have the info to undo this if it fails. 4814 */ 4815 else if(save_lazy_symbol_pointer_relocs == TRUE && 4816 (map->s->flags & SECTION_TYPE) == 4817 S_LAZY_SYMBOL_POINTERS){ 4818 if(r_scattered){ 4819 temp = sreloc->r_address + addr_adjust; 4820 sreloc->r_address += addr_adjust; 4821 if(sreloc->r_address != temp) 4822 error_with_cur_obj("can't create relocation entry " 4823 "for prebinding (address of section (%.16s," 4824 "%.16s) more than 24-bits away from first " 4825 "segment, use -noprebind)", 4826 map->s->segname, map->s->sectname); 4827 } 4828 else 4829 reloc->r_address += addr_adjust; 4830 memcpy(output_locrel + *nlocrel, reloc, 4831 sizeof(struct relocation_info) * (1 + pair)); 4832 (*nlocrel) += 1 + pair; 4833 } 4834 } 4835 else{ 4836 /* 4837 * For an file without a dynamic linker load command external 4838 * relocation entries for undefined symbols (those that have 4839 * not been turned into locals) are kept and locals that are 4840 * non-position-independent are kept. This file can only be 4841 * slid keeping all sections relative to each other the same. 4842 */ 4843 if(r_extern){ 4844 reloc->r_address += addr_adjust; 4845 memcpy(output_extrel + *nextrel, reloc, 4846 sizeof(struct relocation_info) * (1 + pair)); 4847 (*nextrel) += 1 + pair; 4848 if(flag_relocs == TRUE) 4849 flag_read_only_reloc(map->s, r_symbolnum, &first_time); 4850 } 4851 else if(pic == FALSE){ 4852 if(r_scattered) 4853 sreloc->r_address += addr_adjust; 4854 else 4855 reloc->r_address += addr_adjust; 4856 memcpy(output_locrel + *nlocrel, reloc, 4857 sizeof(struct relocation_info) * (1 + pair)); 4858 (*nlocrel) += 1 + pair; 4859 } 4860 } 4861 i += pair; 4862 } 4863 if(flag_relocs == TRUE && *nlocrel != 0){ 4864 if(read_only_reloc_flag == READ_ONLY_RELOC_ERROR) 4865 error_with_cur_obj("has local relocation entries in " 4866 "non-writable section (%.16s,%.16s)", 4867 map->s->segname, map->s->sectname); 4868 else 4869 warning_with_cur_obj("has local relocation entries in " 4870 "non-writable section (%.16s,%.16s)", 4871 map->s->segname, map->s->sectname); 4872 } 4873 if(sect_diff_reloc_flag != SECT_DIFF_RELOC_SUPPRESS && 4874 has_sect_diff_relocs == TRUE){ 4875 if(sect_diff_reloc_flag == SECT_DIFF_RELOC_ERROR) 4876 error_with_cur_obj("has section difference relocation entries " 4877 "in section (%.16s,%.16s)", map->s->segname, 4878 map->s->sectname); 4879 else 4880 warning_with_cur_obj("has section difference relocation entries" 4881 " in section (%.16s,%.16s)", map->s->segname, 4882 map->s->sectname); 4883 } 4884} 4885 4886/* 4887 * is_merged_section_read_only() returns TRUE if the merged section is in a 4888 * segment that does not have write permision. Otherwise it returns FALSE. 4889 */ 4890static 4891enum bool 4892is_merged_section_read_only( 4893struct merged_section *key) 4894{ 4895 struct merged_segment **p, *msg; 4896 struct merged_section **q, *ms; 4897 4898 p = &merged_segments; 4899 while(*p){ 4900 msg = *p; 4901 q = &(msg->content_sections); 4902 while(*q){ 4903 ms = *q; 4904 if(ms == key){ 4905 if((msg->sg.initprot & VM_PROT_WRITE) == 0) 4906 return(TRUE); 4907 else 4908 return(FALSE); 4909 } 4910 q = &(ms->next); 4911 } 4912 q = &(msg->zerofill_sections); 4913 while(*q){ 4914 ms = *q; 4915 if(ms == key){ 4916 if((msg->sg.initprot & VM_PROT_WRITE) == 0) 4917 return(TRUE); 4918 else 4919 return(FALSE); 4920 } 4921 q = &(ms->next); 4922 } 4923 p = &(msg->next); 4924 } 4925 fatal("internal error: is_merged_section_read_only() called with " 4926 "bad merged section"); 4927 return(FALSE); 4928} 4929 4930/* 4931 * is_merged_symbol_coalesced() is needed by the relocation routines to check 4932 * for illegal references to coalesced symbols via external relocation routines. 4933 * The section number in a merged symbol when relocation is done is the section 4934 * number in the output file so we have to look through the merged sections to 4935 * find which section this is. This routine returns TRUE if the symbol is in 4936 * a coalesced section. 4937 */ 4938__private_extern__ 4939enum bool 4940is_merged_symbol_coalesced( 4941struct merged_symbol *merged_symbol) 4942{ 4943 struct merged_segment **p, *msg; 4944 struct merged_section **q, *ms; 4945 4946 if((merged_symbol->nlist.n_type & N_TYPE) != N_SECT) 4947 return(FALSE); 4948 4949 p = &merged_segments; 4950 while(*p){ 4951 msg = *p; 4952 q = &(msg->content_sections); 4953 while(*q){ 4954 ms = *q; 4955 if(ms->output_sectnum == merged_symbol->nlist.n_sect){ 4956 if((ms->s.flags & SECTION_TYPE) == S_COALESCED) 4957 return(TRUE); 4958 else 4959 return(FALSE); 4960 } 4961 q = &(ms->next); 4962 } 4963 p = &(msg->next); 4964 } 4965 fatal("internal error: is_merged_symbol_coalesced() called with " 4966 "bad merged symbol"); 4967 return(FALSE); 4968} 4969 4970/* 4971 * scatter_copy_relocs() copies the relocation entries for an indirect section 4972 * or coalesced section (or any regular section if -dead_strip is specified) 4973 * into the output file based on which items in the section are in the output 4974 * file. It returns the number of relocation entries that were put in the 4975 * output file. 4976 */ 4977static 4978unsigned long 4979scatter_copy_relocs( 4980struct section_map *map, 4981struct relocation_info *relocs, 4982struct relocation_info *output_relocs) 4983{ 4984 unsigned long i, nreloc; 4985 struct relocation_info *reloc; 4986 struct scattered_relocation_info *sreloc; 4987 unsigned long r_address, r_type; 4988 4989 /* 4990 * No checks done here as they were previously done and if there were 4991 * errors this will not even get called. 4992 */ 4993 nreloc = 0; 4994 for(i = 0; i < map->s->nreloc; i++){ 4995 reloc = relocs + i; 4996 /* 4997 * Break out the fields of the relocation entry we need here. 4998 */ 4999 if((relocs[i].r_address & R_SCATTERED) != 0){ 5000 sreloc = (struct scattered_relocation_info *)(relocs + i); 5001 r_address = sreloc->r_address; 5002 r_type = sreloc->r_type; 5003 } 5004 else{ 5005 r_address = reloc->r_address; 5006 r_type = reloc->r_type; 5007 } 5008 if(fine_reloc_offset_in_output_for_output_offset(map, r_address)){ 5009 /* copy reloc into output file */ 5010 memcpy(output_relocs + nreloc, reloc, 5011 sizeof(struct relocation_info)); 5012 nreloc++; 5013 if(reloc_has_pair(arch_flag.cputype, r_type)){ 5014 /* copy the reloc's pair into output file */ 5015 memcpy(output_relocs + nreloc, reloc + 1, 5016 sizeof(struct relocation_info)); 5017 nreloc++; 5018 i++; 5019 } 5020 } 5021 else if(reloc_has_pair(arch_flag.cputype, r_type)) 5022 i++; 5023 } 5024 return(nreloc); 5025} 5026 5027/* 5028 * nop_pure_instruction_scattered_sections() is a hack to pad an i386 pure 5029 * instructions sections with nop's (opcode 0x90) to make disassembly cleaner 5030 * between scatter loaded symbols. 5031 */ 5032__private_extern__ 5033void 5034nop_pure_instruction_scattered_sections(void) 5035{ 5036 struct merged_segment **p, *msg; 5037 struct merged_section **content, *ms; 5038 char *contents; 5039 5040 p = &merged_segments; 5041 while(*p){ 5042 msg = *p; 5043 content = &(msg->content_sections); 5044 while(*content){ 5045 ms = *content; 5046 if((ms->order_filename != NULL && 5047 (ms->s.flags & SECTION_TYPE) == S_REGULAR) || 5048 ((ms->s.flags & SECTION_TYPE) == S_SYMBOL_STUBS || 5049 (ms->s.flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS|| 5050 (ms->s.flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 5051 (ms->s.flags & SECTION_TYPE) == S_COALESCED)){ 5052 if(arch_flag.cputype == CPU_TYPE_I386 && 5053 (ms->s.flags & S_ATTR_PURE_INSTRUCTIONS) != 0){ 5054 contents = output_addr + ms->s.offset; 5055 memset(contents, 0x90, ms->s.size); 5056 } 5057 } 5058 content = &(ms->next); 5059 } 5060 p = &(msg->next); 5061 } 5062} 5063 5064/* 5065 * flush_scatter_copied_sections() flushes the entire merged section's output 5066 * for each merged regular (non-literal) content section that has a load order 5067 * (and indirect sections). 5068 */ 5069__private_extern__ 5070void 5071flush_scatter_copied_sections(void) 5072{ 5073 struct merged_segment **p, *msg; 5074 struct merged_section **content, *ms; 5075 5076 p = &merged_segments; 5077 while(*p){ 5078 msg = *p; 5079 content = &(msg->content_sections); 5080 while(*content){ 5081 ms = *content; 5082 if((ms->contents_filename == NULL && 5083 (ms->order_filename != NULL || dead_strip == TRUE) && 5084 (ms->s.flags & SECTION_TYPE) == S_REGULAR) || 5085 ((ms->s.flags & SECTION_TYPE) == S_SYMBOL_STUBS || 5086 (ms->s.flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS|| 5087 (ms->s.flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 5088 (ms->s.flags & SECTION_TYPE) == S_COALESCED)){ 5089 output_flush(ms->s.offset, ms->s.size); 5090 } 5091 else if((dead_strip == TRUE) && 5092 ((ms->s.flags & SECTION_TYPE) == S_MOD_INIT_FUNC_POINTERS || 5093 (ms->s.flags & SECTION_TYPE) == S_MOD_TERM_FUNC_POINTERS)){ 5094 output_flush(ms->s.offset, ms->s.size); 5095 } 5096 content = &(ms->next); 5097 } 5098 p = &(msg->next); 5099 } 5100} 5101 5102/* 5103 * live_marking() is called when -dead_strip is specified and marks the 5104 * fine_relocs of the sections and symbols live if they can be reached by the 5105 * exported symbols or other live blocks. 5106 */ 5107__private_extern__ 5108void 5109live_marking(void) 5110{ 5111 struct merged_symbol *merged_symbol; 5112 enum bool found; 5113 unsigned long i, input_offset, section_type; 5114 struct fine_reloc *fine_reloc; 5115 struct merged_segment *msg, **p; 5116 struct merged_section *ms, **content, **zerofill; 5117 struct timeval t0, t1, t2, t3, t4, t5; 5118 double time_used; 5119 5120 if(dead_strip_times == TRUE) 5121 gettimeofday(&t0, NULL); 5122 5123 /* 5124 * First set up all the refs arrays in each fine_reloc and the pointer 5125 * to the fine_reloc in each merged_symbol. 5126 */ 5127 build_references(); 5128 /* 5129 * If build_references() encountered a relocation error just return now. 5130 */ 5131 if(errors) 5132 return; 5133 5134 if(dead_strip_times == TRUE) 5135 gettimeofday(&t1, NULL); 5136 5137 /* 5138 * If the output filetype has an entry point mark it live. If the 5139 * entry point symbol was specified mark it live and if it is in a 5140 * section mark the fine_reloc for it live. Else if no entry point 5141 * symbol symbol specified mark the first non-zero sized fine_reloc in 5142 * the first content section if there is one. 5143 */ 5144 if(filetype != MH_FVMLIB && 5145 filetype != MH_DYLIB && 5146 filetype != MH_BUNDLE){ 5147 if(entry_point_name != NULL){ 5148 merged_symbol = lookup_symbol(entry_point_name); 5149 /* 5150 * If the symbol is not found the entry point it can't be 5151 * marked live. Note: the error of specifying a bad entry point 5152 * name is handled in layout_segments() in layout.c . 5153 */ 5154 if(merged_symbol->name_len != 0){ 5155#ifdef DEBUG 5156 if(((debug & (1 << 25)) || (debug & (1 << 26)))){ 5157 print("** In live_marking() -e symbol "); 5158 print_obj_name(merged_symbol->definition_object); 5159 print("%s\n", merged_symbol->nlist.n_un.n_name); 5160 } 5161#endif /* DEBUG */ 5162 merged_symbol->live = TRUE; 5163 fine_reloc = merged_symbol->fine_reloc; 5164 if(fine_reloc != NULL) 5165 fine_reloc->live = TRUE; 5166 } 5167 } 5168 else{ 5169 /* 5170 * To find the first non-zero sized fine_reloc in the the first 5171 * content section we require that we have the info for the 5172 * load maps. 5173 */ 5174 found = FALSE; 5175 for(msg = merged_segments; 5176 msg != NULL && found == FALSE; 5177 msg = msg->next){ 5178 for(ms = msg->content_sections; 5179 ms != NULL && found == FALSE; 5180 ms = ms->next){ 5181 for(i = 0; 5182 i < ms->norder_load_maps && found == FALSE; 5183 i++){ 5184 if(ms->order_load_maps[i].size != 0){ 5185 input_offset = ms->order_load_maps[i].value - 5186 ms->order_load_maps[i].section_map->s->addr; 5187 fine_reloc = fine_reloc_for_input_offset( 5188 ms->order_load_maps[i].section_map, 5189 input_offset); 5190 fine_reloc->live = TRUE; 5191 if(fine_reloc->merged_symbol != NULL) 5192 fine_reloc->merged_symbol->live = TRUE; 5193 found = TRUE; 5194#ifdef DEBUG 5195 if(((debug & (1 << 25)) || 5196 (debug & (1 << 26)))){ 5197 print("** In live_marking() entry point "); 5198 if(ms->order_load_maps[i].archive_name != 5199 NULL) 5200 print("%s(%s):", 5201 ms->order_load_maps[i].archive_name, 5202 ms->order_load_maps[i].object_name); 5203 else 5204 print("%s:", 5205 ms->order_load_maps[i].object_name); 5206 print("(%.16s,%.16s):0x%x:", 5207 ms->s.segname, ms->s.sectname, 5208 (unsigned int) 5209 (fine_reloc->input_offset)); 5210 print("%s\n", 5211 ms->order_load_maps[i].symbol_name); 5212 } 5213#endif /* DEBUG */ 5214 } 5215 } 5216 } 5217 } 5218 } 5219 } 5220 5221 /* 5222 * If this is a shared library and a -init symbol was specified mark it 5223 * live. 5224 */ 5225 if(filetype == MH_DYLIB && init_name != NULL){ 5226 merged_symbol = lookup_symbol(init_name); 5227 /* 5228 * If the symbol is not found the init routine it can't be marked 5229 * live. Note: the error of specifying a bad init routine name is 5230 * handled in layout_segments() in layout.c . 5231 */ 5232 if(merged_symbol->name_len != 0){ 5233#ifdef DEBUG 5234 if(((debug & (1 << 25)) || (debug & (1 << 26)))){ 5235 print("** In live_marking() -init symbol "); 5236 print_obj_name(merged_symbol->definition_object); 5237 print("%s\n", merged_symbol->nlist.n_un.n_name); 5238 } 5239#endif /* DEBUG */ 5240 merged_symbol->live = TRUE; 5241 if(merged_symbol->fine_reloc != NULL) 5242 merged_symbol->fine_reloc->live = TRUE; 5243 } 5244 } 5245 5246 /* 5247 * Now mark the "exported" merged symbols and their fine_relocs live. 5248 */ 5249 mark_globals_live(); 5250 5251 /* 5252 * Now mark the fine_relocs for local symbols with the N_NO_DEAD_STRIP 5253 * bit set live. 5254 */ 5255 mark_N_NO_DEAD_STRIP_local_symbols_live(); 5256 5257 /* 5258 * Now mark all the fine_relocs in sections with the 5259 * S_ATTR_NO_DEAD_STRIP attribute live. 5260 */ 5261 p = &merged_segments; 5262 while(*p){ 5263 msg = *p; 5264 content = &(msg->content_sections); 5265 while(*content){ 5266 ms = *content; 5267 if(ms->s.flags & S_ATTR_NO_DEAD_STRIP) 5268 mark_all_fine_relocs_live_in_section(ms); 5269 content = &(ms->next); 5270 } 5271 zerofill = &(msg->zerofill_sections); 5272 while(*zerofill){ 5273 ms = *zerofill; 5274 if(ms->s.flags & S_ATTR_NO_DEAD_STRIP) 5275 mark_all_fine_relocs_live_in_section(ms); 5276 zerofill = &(ms->next); 5277 } 5278 p = &(msg->next); 5279 } 5280 5281 /* 5282 * If -no_dead_strip_inits_and_terms is specified for all things in 5283 * mod init and term sections to be live. 5284 */ 5285 if(no_dead_strip_inits_and_terms == TRUE){ 5286 p = &merged_segments; 5287 while(*p){ 5288 msg = *p; 5289 content = &(msg->content_sections); 5290 while(*content){ 5291 ms = *content; 5292 section_type = ms->s.flags & SECTION_TYPE; 5293 if(section_type == S_MOD_INIT_FUNC_POINTERS || 5294 section_type == S_MOD_TERM_FUNC_POINTERS) 5295 mark_all_fine_relocs_live_in_section(ms); 5296 content = &(ms->next); 5297 } 5298 p = &(msg->next); 5299 } 5300 } 5301 5302 if(dead_strip_times == TRUE) 5303 gettimeofday(&t2, NULL); 5304 5305 /* 5306 * Now with the above code marking the initial fine_relocs live cause 5307 * the references from the live fine relocs to be marked live. 5308 */ 5309 p = &merged_segments; 5310 while(*p){ 5311 msg = *p; 5312 content = &(msg->content_sections); 5313 while(*content){ 5314 ms = *content; 5315#ifdef DEBUG 5316 if(debug & (1 << 25)) 5317 print("In live_marking() for section (%.16s,%.16s)\n", 5318 ms->s.segname, ms->s.sectname); 5319#endif /* DEBUG */ 5320 walk_references_in_section(MARK_LIVE, ms); 5321 content = &(ms->next); 5322 } 5323 p = &(msg->next); 5324 } 5325 5326 if(dead_strip_times == TRUE) 5327 gettimeofday(&t3, NULL); 5328 5329 /* 5330 * If -no_dead_strip_inits_and_terms was not specified, now with all 5331 * other things marked live determine if the mod init and term 5332 * routines are touching something live and if so mark them and their 5333 * references live. 5334 */ 5335 if(no_dead_strip_inits_and_terms == FALSE){ 5336 p = &merged_segments; 5337 while(*p){ 5338 msg = *p; 5339 content = &(msg->content_sections); 5340 while(*content){ 5341 ms = *content; 5342 section_type = ms->s.flags & SECTION_TYPE; 5343 if(section_type == S_MOD_INIT_FUNC_POINTERS || 5344 section_type == S_MOD_TERM_FUNC_POINTERS) 5345 walk_references_in_section(SEARCH_FOR_LIVE, ms); 5346 content = &(ms->next); 5347 } 5348 p = &(msg->next); 5349 } 5350 } 5351 5352 if(dead_strip_times == TRUE) 5353 gettimeofday(&t4, NULL); 5354 5355 /* 5356 * Now with all other things marked live, for the sections marked with 5357 * the S_ATTR_LIVE_SUPPORT attribute check to see if any of the 5358 * references for each the fine_reloc touches some thing live. If so 5359 * cause it and its references to be live. 5360 */ 5361 p = &merged_segments; 5362 while(*p){ 5363 msg = *p; 5364 content = &(msg->content_sections); 5365 while(*content){ 5366 ms = *content; 5367 if(ms->s.flags & S_ATTR_LIVE_SUPPORT) 5368 walk_references_in_section(CHECK_FOR_LIVE_TOUCH, ms); 5369 content = &(ms->next); 5370 } 5371 p = &(msg->next); 5372 } 5373 5374 if(dead_strip_times == TRUE){ 5375 gettimeofday(&t5, NULL); 5376 time_used = calculate_time_used(&t0, &t1); 5377 print("building of references: %f\n", time_used); 5378 time_used = calculate_time_used(&t1, &t2); 5379 print("mark initial live blocks: %f\n", time_used); 5380 time_used = calculate_time_used(&t2, &t3); 5381 print("mark live blocks referenced: %f\n", time_used); 5382 time_used = calculate_time_used(&t3, &t4); 5383 print("mark live constructors: %f\n", time_used); 5384 time_used = calculate_time_used(&t4, &t5); 5385 print("mark live exception frames: %f\n", time_used); 5386 } 5387} 5388 5389/* 5390 * calculate_time_used() takes a start timeval and and an end time value and 5391 * calculates the difference as a double value and returns that. 5392 */ 5393static 5394double 5395calculate_time_used( 5396struct timeval *start, 5397struct timeval *end) 5398{ 5399 double time_used; 5400 5401 time_used = end->tv_sec - start->tv_sec; 5402 if(end->tv_usec >= start->tv_usec) 5403 time_used += ((double)(end->tv_usec - start->tv_usec)) / 1000000.0; 5404 else 5405 time_used += -1.0 + 5406 ((double)(1000000 + end->tv_usec - start->tv_usec) / 1000000.0); 5407 return(time_used); 5408} 5409 5410/* 5411 * build_references() is called by live_marking() to set up the references 5412 * arrays off each fine reloc structure in each section. 5413 */ 5414static 5415void 5416build_references( 5417void) 5418{ 5419 struct merged_segment *msg, **p; 5420 struct merged_section *ms, **content; 5421 5422 /* 5423 * For objects that there sections loaded as one block we need to get 5424 * all the merged symbols in those blocks to have their fine_reloc 5425 * pointer set correctly. 5426 */ 5427 set_fine_relocs_for_merged_symbols(); 5428 5429 /* 5430 * Set up the references for each section. 5431 */ 5432 p = &merged_segments; 5433 while(*p){ 5434 msg = *p; 5435 content = &(msg->content_sections); 5436 while(*content){ 5437 ms = *content; 5438#ifdef DEBUG 5439 if(debug & (1 << 27)) 5440 print("In build_references() for section (%.16s,%.16s)\n", 5441 ms->s.segname, ms->s.sectname); 5442#endif /* DEBUG */ 5443 setup_references_in_section(ms); 5444 /* 5445 * If setup_references_in_section() encountered a relocation 5446 * error just return now. 5447 */ 5448 if(errors) 5449 return; 5450 content = &(ms->next); 5451 } 5452 p = &(msg->next); 5453 } 5454 5455#ifdef DEBUG 5456 if(debug & (1 << 28)) 5457 print_references(); 5458#endif /* DEBUG */ 5459} 5460 5461#ifdef DEBUG 5462/* 5463 * print_references() is a debugging routine to print the references off each 5464 * fine_reloc after build_references() has been called. 5465 */ 5466static 5467void 5468print_references( 5469void) 5470{ 5471 unsigned long i, j, k; 5472 struct object_list *object_list, **q; 5473 struct object_file *obj; 5474 struct fine_reloc *fine_relocs, *fine_reloc; 5475 struct section_map *map; 5476 struct ref *ref; 5477 5478 for(q = &objects; *q; q = &(object_list->next)){ 5479 object_list = *q; 5480 for(i = 0; i < object_list->used; i++){ 5481 obj = &(object_list->object_files[i]); 5482 if(obj == base_obj) 5483 continue; 5484 if(obj->dylib) 5485 continue; 5486 if(obj->bundle_loader) 5487 continue; 5488 if(obj->dylinker) 5489 continue; 5490 for(j = 0; j < obj->nsection_maps; j++){ 5491 if(obj->section_maps[j].s->size == 0) 5492 continue; 5493 map = &(obj->section_maps[j]); 5494 if(map->nfine_relocs == 0) 5495 continue; 5496 print("references for "); 5497 print_obj_name(obj); 5498 print("in section (%.16s,%.16s)\n", 5499 map->s->segname, map->s->sectname); 5500 fine_relocs = map->fine_relocs; 5501 for(k = 0; k < map->nfine_relocs; k++){ 5502 fine_reloc = map->fine_relocs + k; 5503 if(fine_reloc->refs != NULL){ 5504 print(" offset:0x%x", 5505 (unsigned int)(fine_reloc->input_offset)); 5506 if(fine_reloc->merged_symbol != NULL) 5507 print(":%s", fine_reloc-> 5508 merged_symbol->nlist.n_un.n_name); 5509 else 5510 print_symbol_name_from_order_load_maps(map, 5511 map->s->addr + fine_reloc->input_offset); 5512 print("\n"); 5513 } 5514 for(ref = fine_reloc->refs; 5515 ref != NULL; 5516 ref = ref->next){ 5517 if(ref->merged_symbol != NULL) 5518 print(" %s\n", 5519 ref->merged_symbol->nlist.n_un.n_name); 5520 else{ 5521 print(" (%.16s,%.16s):0x%x", 5522 ref->map->s->segname, 5523 ref->map->s->sectname, 5524 (unsigned int) 5525 (ref->fine_reloc->input_offset)); 5526 print_symbol_name_from_order_load_maps( 5527 ref->map, 5528 ref->map->s->addr + 5529 ref->fine_reloc->input_offset); 5530 printf("\n"); 5531 } 5532 } 5533 } 5534 } 5535 } 5536 } 5537} 5538#endif /* DEBUG */ 5539 5540/* 5541 * setup_references_in_section() is called with a merged section and sets up all 5542 * the references of the fine_relocs in that section. 5543 */ 5544static 5545void 5546setup_references_in_section( 5547struct merged_section *ms) 5548{ 5549 unsigned long i, j; 5550 struct object_list *object_list, **q; 5551 struct object_file *obj; 5552 struct section_map *map; 5553 5554 /* 5555 * For each object file that has this section process it. 5556 */ 5557 for(q = &objects; *q; q = &(object_list->next)){ 5558 object_list = *q; 5559 for(i = 0; i < object_list->used; i++){ 5560 obj = &(object_list->object_files[i]); 5561 if(obj == base_obj) 5562 continue; 5563 if(obj->dylib) 5564 continue; 5565 if(obj->bundle_loader) 5566 continue; 5567 if(obj->dylinker) 5568 continue; 5569 map = NULL; 5570 for(j = 0; j < obj->nsection_maps; j++){ 5571 if(obj->section_maps[j].output_section != ms) 5572 continue; 5573 if(obj->section_maps[j].s->size == 0) 5574 continue; 5575 map = &(obj->section_maps[j]); 5576 break; 5577 } 5578 if(map == NULL) 5579 continue; 5580#ifdef DEBUG 5581 if(debug & (1 << 27)){ 5582 print(" In setup_references_in_section() with object "); 5583 print_obj_name(obj); 5584 print("\n"); 5585 } 5586#endif /* DEBUG */ 5587 setup_references(map, obj); 5588 } 5589 } 5590} 5591 5592/* 5593 * setup_references() is passed a section map and the object file it is in. It 5594 * digs through the relocation entries of the section creating a references for 5595 * each. 5596 */ 5597static 5598void 5599setup_references( 5600struct section_map *map, 5601struct object_file *obj) 5602{ 5603 unsigned long i, pair; 5604 struct relocation_info *relocs, reloc; 5605 struct scattered_relocation_info *sreloc; 5606 unsigned long r_address, r_type; 5607 char *contents; 5608 struct live_refs refs; 5609 struct fine_reloc *fine_reloc; 5610 5611#ifdef DEBUG 5612 if(debug & (1 << 27)){ 5613 print(" In setup_references() "); 5614 print_obj_name(obj); 5615 print("(%.16s,%.16s)\n", map->s->segname, map->s->sectname); 5616 } 5617#endif /* DEBUG */ 5618 5619 /* 5620 * Walk all the relocation entries of this section creating the 5621 * references between blocks. 5622 */ 5623 relocs = (struct relocation_info *)(obj->obj_addr + map->s->reloff); 5624 if(obj->swapped && map->input_relocs_already_swapped == FALSE){ 5625 swap_relocation_info(relocs, map->s->nreloc, host_byte_sex); 5626 map->input_relocs_already_swapped = TRUE; 5627 } 5628 for(i = 0; i < map->s->nreloc; i++){ 5629 /* 5630 * Note all errors are not flagged here but left for the *_reloc() 5631 * routines to flag them. So for errors we just return from here. 5632 */ 5633 reloc = relocs[i]; 5634 /* 5635 * Break out just the fields of the relocation entry we need to 5636 * determine if this entry (and its possible pair) are for this 5637 * fine_reloc. 5638 */ 5639 if((reloc.r_address & R_SCATTERED) != 0){ 5640 sreloc = (struct scattered_relocation_info *)(&reloc); 5641 r_address = sreloc->r_address; 5642 r_type = sreloc->r_type; 5643 } 5644 else{ 5645 r_address = reloc.r_address; 5646 r_type = reloc.r_type; 5647 } 5648 if(reloc_has_pair(arch_flag.cputype, r_type)){ 5649 if(i + 1 >= map->s->nreloc) 5650 return; 5651 pair = 1; 5652 } 5653 else 5654 pair = 0; 5655#ifdef DEBUG 5656 if(debug & (1 << 27)){ 5657 print(" reloc entry %lu", i); 5658 if(pair) 5659 print(",%lu", i+1); 5660 print("\n"); 5661 } 5662#endif /* DEBUG */ 5663 5664 /* 5665 * Get the references for this relocation entry(s). 5666 */ 5667 cur_obj = obj; 5668 contents = obj->obj_addr + map->s->offset; 5669 if(arch_flag.cputype == CPU_TYPE_POWERPC || 5670 arch_flag.cputype == CPU_TYPE_VEO) 5671 ppc_reloc(contents, relocs, map, &refs, i); 5672 else if(arch_flag.cputype == CPU_TYPE_MC680x0) 5673 generic_reloc(contents, relocs, map, FALSE, &refs, i); 5674 else if(arch_flag.cputype == CPU_TYPE_I386) 5675 generic_reloc(contents, relocs, map, TRUE, &refs, i); 5676 else if(arch_flag.cputype == CPU_TYPE_ARM) 5677 arm_reloc(contents, relocs, map, &refs, i); 5678 else if(arch_flag.cputype == CPU_TYPE_MC88000 || 5679 arch_flag.cputype == CPU_TYPE_HPPA || 5680 arch_flag.cputype == CPU_TYPE_SPARC || 5681 arch_flag.cputype == CPU_TYPE_I860) 5682 fatal("-dead_strip not supported with cputype (%d)", 5683 arch_flag.cputype); 5684 else 5685 fatal("internal error: setup_references() " 5686 "called with unknown cputype (%d) set", 5687 arch_flag.cputype); 5688 /* if there was a problem with the relocation just return now */ 5689 if(errors) 5690 return; 5691 5692 /* 5693 * If this reloc has references then add them to the tmp_refs[] 5694 * array if they are new. 5695 */ 5696 if(refs.ref1.ref_type != LIVE_REF_NONE){ 5697 fine_reloc = fine_reloc_for_input_offset(map, r_address); 5698 setup_reference(&refs.ref1, obj, fine_reloc); 5699 } 5700 if(refs.ref2.ref_type != LIVE_REF_NONE){ 5701 fine_reloc = fine_reloc_for_input_offset(map, r_address); 5702 setup_reference(&refs.ref2, obj, fine_reloc); 5703 } 5704 i += pair; 5705 } 5706} 5707 5708/* 5709 * setup_reference() is passed a pointer to a live_ref struct in the specified 5710 * object and the fine_reloc that reference comes from. It creates a struct 5711 * ref for the live_ref struct. Then if that reference is not to itself and 5712 * already on the list for the fine_reloc it is added to the list. 5713 */ 5714static 5715void 5716setup_reference( 5717struct live_ref *ref, 5718struct object_file *obj, 5719struct fine_reloc *self_fine_reloc) 5720{ 5721 unsigned long r_symbolnum; 5722 struct section_map *local_map; 5723 struct fine_reloc *ref_fine_reloc; 5724 struct ref r, *refs, *new_ref; 5725 5726 r.next = NULL; 5727 r.fine_reloc = NULL; 5728 r.map = NULL; 5729 r.obj = NULL; 5730 r.merged_symbol = NULL; 5731 if(ref->ref_type == LIVE_REF_VALUE){ 5732 r_symbolnum = r_symbolnum_from_r_value(ref->value, obj); 5733 local_map = &(obj->section_maps[r_symbolnum - 1]); 5734 ref_fine_reloc = fine_reloc_for_input_offset(local_map, 5735 ref->value - local_map->s->addr); 5736#ifdef DEBUG 5737 if(debug & (1 << 27)){ 5738 print(" ref "); 5739 print("(%.16s,%.16s):0x%x", local_map->s->segname, 5740 local_map->s->sectname, 5741 (unsigned int)(ref_fine_reloc->input_offset)); 5742 print_symbol_name_from_order_load_maps(local_map, 5743 local_map->s->addr + ref_fine_reloc->input_offset); 5744 printf("\n"); 5745 } 5746#endif /* DEBUG */ 5747 if(self_fine_reloc == ref_fine_reloc) 5748 return; 5749 r.fine_reloc = ref_fine_reloc; 5750 r.map = local_map; 5751 r.obj = obj; 5752 r.merged_symbol = NULL; 5753 } 5754 else if(ref->ref_type == LIVE_REF_SYMBOL){ 5755 r.merged_symbol = ref->merged_symbol; 5756 r.fine_reloc = NULL; 5757 r.map = NULL; 5758 r.obj = NULL; 5759#ifdef DEBUG 5760 if(debug & (1 << 27)){ 5761 print(" ref "); 5762 print("%s", ref->merged_symbol->nlist.n_un.n_name); 5763 printf("\n"); 5764 } 5765#endif /* DEBUG */ 5766 } 5767 /* 5768 * See if this reference is already in the list of references. 5769 */ 5770 for(refs = self_fine_reloc->refs ; refs != NULL ; refs = refs->next){ 5771 if(r.fine_reloc == refs->fine_reloc && 5772 r.map == refs->map && 5773 r.obj == refs->obj && 5774 r.merged_symbol == refs->merged_symbol) 5775 return; 5776 } 5777 /* it is not in the list so add it */ 5778 new_ref = allocate(sizeof(struct ref)); 5779 *new_ref = r; 5780 new_ref->next = self_fine_reloc->refs; 5781 self_fine_reloc->refs = new_ref; 5782} 5783 5784/* 5785 * get_fine_reloc_for_merged_symbol() finds the fine_reloc for the 5786 * specified merged_symbol (if any) and returns it or NULL. It also returns 5787 * the section map for the symbol if local_map is not NULL. 5788 */ 5789__private_extern__ 5790struct fine_reloc * 5791get_fine_reloc_for_merged_symbol( 5792struct merged_symbol *merged_symbol, 5793struct section_map **local_map) 5794{ 5795 unsigned long n_sect, input_offset, i; 5796 struct section_map *map; 5797 struct fine_reloc *fine_reloc; 5798 5799 /* N_INDR symbols have had their indirection resolved at this point. */ 5800 if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR) 5801 merged_symbol = (struct merged_symbol *) 5802 merged_symbol->nlist.n_value; 5803 5804 /* 5805 * Find the fine_reloc for this symbol if any. That will be in the 5806 * section map for the object that defines this symbol. 5807 */ 5808 if(merged_symbol->defined_in_dylib == FALSE && 5809 (merged_symbol->nlist.n_type & N_TYPE) == N_SECT){ 5810 n_sect = merged_symbol->nlist.n_sect; 5811 map = &(merged_symbol->definition_object->section_maps[n_sect - 1]); 5812 if(map->nfine_relocs != 0){ 5813 /* 5814 * The value of the merged symbol is the value in the input 5815 * file at this point. 5816 */ 5817 input_offset = merged_symbol->nlist.n_value - map->s->addr; 5818 fine_reloc = fine_reloc_for_input_offset(map, input_offset); 5819 /* 5820 * It is possible that there may be more than one merged symbol 5821 * at the same input_offset. If this fine_reloc is not for this 5822 * merged symbol search the fine_relocs for one that has this 5823 * merged_symbol. 5824 */ 5825 if(fine_reloc->merged_symbol != merged_symbol){ 5826 for(i = 0; i < map->nfine_relocs; i++){ 5827 if(map->fine_relocs[i].merged_symbol == merged_symbol){ 5828 fine_reloc = map->fine_relocs + i; 5829 break; 5830 } 5831 } 5832 } 5833 if(local_map != NULL) 5834 *local_map = map; 5835 return(fine_reloc); 5836 } 5837 } 5838 return(NULL); 5839} 5840 5841/* 5842 * mark_all_fine_relocs_live_in_section() is called for sections that have the 5843 * S_ATTR_NO_DEAD_STRIP section attribute and marks all the fine_relocs in 5844 * objects with that section live. 5845 */ 5846static 5847void 5848mark_all_fine_relocs_live_in_section( 5849struct merged_section *ms) 5850{ 5851 unsigned long i, j; 5852 struct object_list *object_list, **q; 5853 struct fine_reloc *fine_relocs; 5854 struct object_file *obj; 5855 struct section_map *map; 5856 5857 /* 5858 * For each object file that has this section process it. 5859 */ 5860 for(q = &objects; *q; q = &(object_list->next)){ 5861 object_list = *q; 5862 for(i = 0; i < object_list->used; i++){ 5863 obj = &(object_list->object_files[i]); 5864 if(obj == base_obj) 5865 continue; 5866 if(obj->dylib) 5867 continue; 5868 if(obj->bundle_loader) 5869 continue; 5870 if(obj->dylinker) 5871 continue; 5872 map = NULL; 5873 for(j = 0; j < obj->nsection_maps; j++){ 5874 if(obj->section_maps[j].output_section != ms) 5875 continue; 5876 if(obj->section_maps[j].s->size == 0) 5877 continue; 5878 map = &(obj->section_maps[j]); 5879 break; 5880 } 5881 if(map == NULL) 5882 continue; 5883 5884#ifdef DEBUG 5885 if(debug & (1 << 25)){ 5886 print(" mark_all_fine_relocs_live_in_section() with " 5887 "object"); 5888 print_obj_name(obj); 5889 print("\n"); 5890 } 5891#endif /* DEBUG */ 5892 5893 fine_relocs = map->fine_relocs; 5894 for(j = 0; j < map->nfine_relocs; j++){ 5895 fine_relocs[j].live = TRUE; 5896 } 5897 } 5898 } 5899} 5900 5901/* 5902 * walk_references_in_section() is called with an operation and a merged section 5903 * and walks the references of the fine_relocs in that section. 5904 * 5905 * If the operation is MARK_LIVE it looks for live fine_relocs in the specified 5906 * section and causes its references to be marked live. 5907 * 5908 * If the operation is SEARCH_FOR_LIVE it is being called with a mod init or 5909 * term section and for each fine_reloc in the section it determines if it's 5910 * references reach something that is live. If it does it marks the fine_reloc 5911 * live and causes all of its references to be marked live. 5912 * 5913 * If the operation is CHECK_FOR_LIVE_TOUCH it is being called for a section 5914 * with the live support attribute and for each fine_reloc in the section it 5915 * determines if it directly references something that is live. If it does it 5916 * marks the fine_reloc live and causes all of its references to be marked live. 5917 */ 5918static 5919void 5920walk_references_in_section( 5921enum walk_references_operation operation, 5922struct merged_section *ms) 5923{ 5924 unsigned long i, j; 5925 struct object_list *object_list, **q; 5926 struct fine_reloc *fine_relocs; 5927 struct object_file *obj; 5928 struct section_map *map; 5929 enum bool found_live; 5930 5931 /* 5932 * For each object file that has this section process it. 5933 */ 5934 for(q = &objects; *q; q = &(object_list->next)){ 5935 object_list = *q; 5936 for(i = 0; i < object_list->used; i++){ 5937 obj = &(object_list->object_files[i]); 5938 if(obj == base_obj) 5939 continue; 5940 if(obj->dylib) 5941 continue; 5942 if(obj->bundle_loader) 5943 continue; 5944 if(obj->dylinker) 5945 continue; 5946 map = NULL; 5947 for(j = 0; j < obj->nsection_maps; j++){ 5948 if(obj->section_maps[j].output_section != ms) 5949 continue; 5950 if(obj->section_maps[j].s->size == 0) 5951 continue; 5952 map = &(obj->section_maps[j]); 5953 break; 5954 } 5955 if(map == NULL) 5956 continue; 5957 5958#ifdef DEBUG 5959 if(debug & (1 << 25)){ 5960 print(" In walk_references_in_section() with object "); 5961 print_obj_name(obj); 5962 print("\n"); 5963 } 5964#endif /* DEBUG */ 5965 5966 fine_relocs = map->fine_relocs; 5967 for(j = 0; j < map->nfine_relocs; j++){ 5968 if(operation == MARK_LIVE){ 5969 if(fine_relocs[j].live == TRUE && 5970 fine_relocs[j].refs_marked_live == FALSE){ 5971 walk_references( 5972 MARK_LIVE, 5973 fine_relocs + j, 5974 map, 5975 obj); 5976 } 5977 } 5978 else if(operation == SEARCH_FOR_LIVE || 5979 operation == CHECK_FOR_LIVE_TOUCH){ 5980 found_live = FALSE; 5981 if(fine_relocs[j].searched_for_live_refs == FALSE || 5982 operation == CHECK_FOR_LIVE_TOUCH){ 5983 found_live = walk_references( 5984 operation, 5985 fine_relocs + j, 5986 map, 5987 obj); 5988 /* 5989 * If something reached or touched from this 5990 * fine_reloc was found to be live then mark it 5991 * live and cause its references to be marked live. 5992 */ 5993 if(found_live == TRUE){ 5994#ifdef DEBUG 5995 if(debug & (1 << 25)){ 5996 print(" In walk_references_in_section(" 5997 "%s) with object ", 5998 walk_references_operation_names[ 5999 operation]); 6000 print_obj_name(obj); 6001 print("fine_relocs[%lu].input_offset = " 6002 "0x%x found_live == TRUE\n", j, 6003 (unsigned int) 6004 (fine_relocs[j].input_offset) ); 6005 } 6006#endif /* DEBUG */ 6007 fine_relocs[j].live = TRUE; 6008 if(fine_relocs[j].refs_marked_live == FALSE){ 6009 walk_references( 6010 MARK_LIVE, 6011 fine_relocs + j, 6012 map, 6013 obj); 6014 } 6015 } 6016 } 6017 } 6018 else{ 6019 fatal("internal error: walk_references_in_section() " 6020 "called with unknown operation (%d)", operation); 6021 } 6022 } 6023 } 6024 } 6025} 6026 6027/* 6028 * walk_references() walks the references of the specified fine_reloc in the 6029 * specified map, in the the specified object. 6030 * 6031 * For the MARK_LIVE operation it is called with a fine_reloc that is live, 6032 * this routine marks all the fine_reloc references live. The return value is 6033 * meaningless for the MARK_LIVE operation. 6034 * 6035 * For the SEARCH_FOR_LIVE operation it searches for any referenced fine_reloc 6036 * that is marked live. If it finds a referenced fine_reloc that is marked 6037 * live it returns TRUE and stops searching. If it completes it search without 6038 * finding a fine_reloc that is marked live it returns FALSE. 6039 * 6040 * For the CHECK_FOR_LIVE_TOUCH operation it checks only the directly referenced 6041 * fine_reloc's to see if one of them is live. If it finds a referenced 6042 * fine_reloc that is marked live it returns TRUE. If it does not it returns 6043 * FALSE. 6044 */ 6045static 6046enum bool 6047walk_references( 6048enum walk_references_operation operation, 6049struct fine_reloc *fine_reloc, 6050struct section_map *map, 6051struct object_file *obj) 6052{ 6053 enum bool found_live; 6054 struct ref r, *ref; 6055 6056#ifdef DEBUG 6057 if(debug & (1 << 25)){ 6058 print(" In walk_references(%s) ", 6059 walk_references_operation_names[operation]); 6060 print_obj_name(obj); 6061 print("(%.16s,%.16s):0x%x", map->s->segname, map->s->sectname, 6062 (unsigned int)(fine_reloc->input_offset)); 6063 if(fine_reloc->merged_symbol != NULL) 6064 print(":%s", fine_reloc->merged_symbol->nlist.n_un.n_name); 6065 print("\n"); 6066 } 6067#endif /* DEBUG */ 6068 6069 if(operation == MARK_LIVE){ 6070 fine_reloc->refs_marked_live = TRUE; 6071 /* 6072 * Since this fine_reloc is live if this is in a symbol stub or 6073 * or symbol pointer section we need to mark the indirect symbol 6074 * for it live. 6075 */ 6076 if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS || 6077 (map->s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 6078 (map->s->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS){ 6079 if(indirect_live_ref(fine_reloc, map, obj, &r) == TRUE) 6080 ref_operation(MARK_LIVE, &r, obj); 6081 } 6082 } 6083 else{ /* operation == SEARCH_FOR_LIVE */ 6084 fine_reloc->searched_for_live_refs = TRUE; 6085 if(fine_reloc->live == TRUE) 6086 return(TRUE); 6087 } 6088 6089 /* 6090 * Walk the references of this fine_reloc. 6091 */ 6092 for(ref = fine_reloc->refs; ref != NULL; ref = ref->next){ 6093 if(operation == MARK_LIVE){ 6094 ref_operation(MARK_LIVE, ref, obj); 6095 } 6096 else if(operation == SEARCH_FOR_LIVE || 6097 operation == CHECK_FOR_LIVE_TOUCH){ 6098 found_live = ref_operation(operation, ref, obj); 6099 if(found_live == TRUE) 6100 return(TRUE); 6101 } 6102 else{ 6103 fatal("internal error: walk_references() called with " 6104 "unknown operation (%d)", operation); 6105 } 6106 } 6107 return(FALSE); 6108} 6109 6110/* 6111 * ref_operation() gets the fine_reloc being referenced from the specified 6112 * ref in the specified object then preforms the specified operation. 6113 * 6114 * For the MARK_LIVE operation if the fine_reloc is not marked live, it is 6115 * marked live and then walk_references() is called with the MARK_LIVE operation 6116 * to mark its references live. If the specified ref is a symbol defined 6117 * in a dylib then 6118mark_dylib_references_live() is called to mark that dylib's module's 6119 * references live. For the MARK_LIVE operation the return value is meaningless. 6120 * 6121 * For the SEARCH_FOR_LIVE operation if the fine_reloc is marked live then TRUE 6122 * is returned. Else walk_references() is called with the SEARCH_FOR_LIVE 6123 * operation and if it returns TRUE then TRUE is returned. Else FALSE is 6124 * returned. If the specified ref is a symbol defined in a dylib then 6125something will called to walk the references of the dylib searching for a live 6126 * symbol. 6127 * 6128 * For the CHECK_FOR_LIVE_TOUCH operation if the fine_reloc is marked live the 6129 * TRUE is returned else FALSE is returned. 6130 */ 6131static 6132enum bool 6133ref_operation( 6134enum walk_references_operation operation, 6135struct ref *ref, 6136struct object_file *obj) 6137{ 6138 unsigned long n_sect; 6139 struct section_map *local_map; 6140 struct merged_symbol *indr_merged_symbol; 6141 enum bool found_live; 6142 struct fine_reloc *ref_fine_reloc; 6143 6144 if(ref->merged_symbol == NULL){ 6145#ifdef DEBUG 6146 if((((debug & (1 << 25)) || (debug & (1 << 26))) && 6147 ref->fine_reloc->live != TRUE)){ 6148 print("** In ref_operation(%s) ", 6149 walk_references_operation_names[operation]); 6150 print_obj_name(obj); 6151 print("(%.16s,%.16s):0x%x", ref->map->s->segname, 6152 ref->map->s->sectname, 6153 (unsigned int)(ref->fine_reloc->input_offset)); 6154 if(ref->fine_reloc->merged_symbol != NULL){ 6155 print(":%s", 6156 ref->fine_reloc->merged_symbol->nlist.n_un.n_name); 6157 } 6158 else{ 6159 print_symbol_name_from_order_load_maps(ref->map, 6160 ref->map->s->addr + ref->fine_reloc->input_offset); 6161 } 6162 print("\n"); 6163 } 6164#endif /* DEBUG */ 6165 6166 if(operation == MARK_LIVE){ 6167 ref->fine_reloc->live = TRUE; 6168 if(ref->fine_reloc->merged_symbol != NULL) 6169 ref->fine_reloc->merged_symbol->live = TRUE; 6170 if(ref->fine_reloc->refs_marked_live == FALSE){ 6171 walk_references( 6172 MARK_LIVE, 6173 ref->fine_reloc, 6174 ref->map, 6175 ref->obj); 6176 } 6177 } 6178 else if(operation == SEARCH_FOR_LIVE){ 6179 if(ref->fine_reloc->live == TRUE) 6180 return(TRUE); 6181 else{ 6182 if(ref->fine_reloc->searched_for_live_refs == FALSE){ 6183 found_live = walk_references( 6184 SEARCH_FOR_LIVE, 6185 ref->fine_reloc, 6186 ref->map, 6187 ref->obj); 6188 if(found_live == TRUE) 6189 return(TRUE); 6190 } 6191 } 6192 } 6193 else if(operation == CHECK_FOR_LIVE_TOUCH){ 6194 if(ref->fine_reloc->live == TRUE && 6195 (ref->map->s->flags & S_ATTR_LIVE_SUPPORT) == 0) 6196 return(TRUE); 6197 else 6198 return(FALSE); 6199 } 6200 else{ 6201 fatal("internal error: ref_operation() called with " 6202 "unknown operation (%d)", operation); 6203 } 6204 } 6205 else /* ref->merged_symbol != NULL */ { 6206 if(operation == MARK_LIVE){ 6207 ref->merged_symbol->live = TRUE; 6208 if((ref->merged_symbol->nlist.n_type & N_TYPE) == N_INDR){ 6209 indr_merged_symbol = (struct merged_symbol *) 6210 ref->merged_symbol->nlist.n_value; 6211 indr_merged_symbol->live = TRUE; 6212 } 6213 } 6214 else if(operation == SEARCH_FOR_LIVE){ 6215 if(ref->merged_symbol->live == TRUE) 6216 return(TRUE); 6217 } 6218 else if(operation == CHECK_FOR_LIVE_TOUCH){ 6219 if(ref->merged_symbol->live == TRUE) 6220 return(TRUE); 6221 else 6222 return(FALSE); 6223 } 6224 else{ 6225 fatal("internal error: ref_operation() called with " 6226 "unknown operation (%d)", operation); 6227 } 6228 6229 if(ref->merged_symbol->defined_in_dylib == TRUE){ 6230 if(operation == MARK_LIVE){ 6231 /* 6232 * If this is defined in a dylib then we need to mark 6233 * that module's referernces live in case the references 6234 * loop back and reference something in the objects 6235 * being loaded. 6236 mark_dylib_references_live(ref->merged_symbol); 6237 */ 6238 ; 6239 } 6240 else{ /* operation == SEARCH_FOR_LIVE */ 6241/* need to add code to search through a dylib's references for live symbols */ 6242 ; 6243 } 6244 } 6245 else /* merged_symbol->defined_in_dylib == FALSE */ { 6246 ref_fine_reloc = ref->merged_symbol->fine_reloc; 6247 if((ref->merged_symbol->nlist.n_type & N_TYPE) == N_SECT){ 6248 n_sect = ref->merged_symbol->nlist.n_sect; 6249 local_map = &(ref->merged_symbol->definition_object-> 6250 section_maps[n_sect - 1]); 6251 } 6252 else 6253 local_map = NULL; 6254 if(ref_fine_reloc != NULL){ 6255#ifdef DEBUG 6256 if((((debug & (1 << 25)) || (debug & (1 << 26))) && 6257 ref_fine_reloc->live != TRUE)){ 6258 print("** In ref_operation(%s) ", 6259 walk_references_operation_names[operation]); 6260 print_obj_name(ref->merged_symbol->definition_object); 6261 if(local_map != NULL) 6262 print("(%.16s,%.16s)", local_map->s->segname, 6263 local_map->s->sectname); 6264 print(":%s\n", ref->merged_symbol->nlist.n_un.n_name); 6265 } 6266#endif /* DEBUG */ 6267 if(operation == MARK_LIVE){ 6268 ref_fine_reloc->live = TRUE; 6269 if(ref_fine_reloc->refs_marked_live == FALSE){ 6270 walk_references( 6271 MARK_LIVE, 6272 ref_fine_reloc, 6273 local_map, 6274 ref->merged_symbol->definition_object); 6275 } 6276 } 6277 else{ /* operation == SEARCH_FOR_LIVE */ 6278 if(ref_fine_reloc->live == TRUE) 6279 return(TRUE); 6280 if(ref_fine_reloc->searched_for_live_refs == FALSE){ 6281 found_live = walk_references( 6282 SEARCH_FOR_LIVE, 6283 ref_fine_reloc, 6284 local_map, 6285 ref->merged_symbol->definition_object); 6286 if(found_live == TRUE) 6287 return(TRUE); 6288 } 6289 } 6290 } 6291 } 6292 } 6293 return(FALSE); 6294} 6295 6296/* 6297 * r_symbolnum_from_r_value calculates the r_symbolnum (n_sect) from the 6298 * specified r_value in the specified object_file. If the r_value is not in 6299 * any section then 0 (NO_SECT) is returned. 6300 */ 6301__private_extern__ 6302unsigned long 6303r_symbolnum_from_r_value( 6304unsigned long r_value, 6305struct object_file *obj) 6306{ 6307 unsigned i, r_symbolnum; 6308 6309 r_symbolnum = 0; 6310 for(i = 0; i < obj->nsection_maps; i++){ 6311 if(r_value >= obj->section_maps[i].s->addr && 6312 r_value < obj->section_maps[i].s->addr + 6313 obj->section_maps[i].s->size){ 6314 r_symbolnum = i + 1; 6315 break; 6316 } 6317 } 6318 if(r_symbolnum == 0){ 6319 /* 6320 * The edge case where the last address past the end of 6321 * of the last section is referenced. 6322 */ 6323 for(i = 0; i < obj->nsection_maps; i++){ 6324 if(r_value == obj->section_maps[i].s->addr + 6325 obj->section_maps[i].s->size){ 6326 r_symbolnum = i + 1; 6327 break; 6328 } 6329 } 6330 } 6331 return(r_symbolnum); 6332} 6333 6334#endif /* !defined(RLD) */ 6335 6336#ifdef RLD 6337/* 6338 * reset_merged_sections() is called from rld_load() to place the merged 6339 * sections back on their merged segment (layout() placed all of them on the 6340 * object_segment for the MH_OBJECT filetype) and it zeros the size of each the 6341 * merged section so it can be accumulated for the next rld_load(). 6342 */ 6343__private_extern__ 6344void 6345reset_merged_sections(void) 6346{ 6347 struct merged_segment *msg; 6348 struct merged_section *ms, *prev_ms; 6349 6350 /* 6351 * First add the debug segments back on the end of the list of the 6352 * original merged segments. 6353 */ 6354 for(msg = original_merged_segments; 6355 msg != NULL; 6356 /* no increment expression */){ 6357 if(msg->next == NULL) 6358 break; 6359 msg = msg->next; 6360 } 6361 if(msg != NULL) 6362 msg->next = debug_merged_segments; 6363 6364 msg = original_merged_segments; 6365 if(msg != NULL && merged_segments->content_sections != NULL){ 6366 ms = merged_segments->content_sections; 6367 while(ms != NULL){ 6368 if(strncmp(ms->s.segname, msg->sg.segname, 6369 sizeof(msg->sg.segname)) == 0){ 6370 msg->content_sections = ms; 6371 ms->s.size = 0; 6372 prev_ms = ms; 6373 ms = ms->next; 6374 while(ms != NULL && strncmp(ms->s.segname, msg->sg.segname, 6375 sizeof(msg->sg.segname)) == 0){ 6376 ms->s.size = 0; 6377 prev_ms = ms; 6378 ms = ms->next; 6379 } 6380 prev_ms->next = NULL; 6381 } 6382 else{ 6383 msg = msg->next; 6384 } 6385 } 6386 } 6387 6388 msg = original_merged_segments; 6389 if(msg != NULL && merged_segments->zerofill_sections != NULL){ 6390 ms = merged_segments->zerofill_sections; 6391 while(ms != NULL){ 6392 if(strncmp(ms->s.segname, msg->sg.segname, 6393 sizeof(msg->sg.segname)) == 0){ 6394 msg->zerofill_sections = ms; 6395 ms->s.size = 0; 6396 prev_ms = ms; 6397 ms = ms->next; 6398 while(ms != NULL && strncmp(ms->s.segname, msg->sg.segname, 6399 sizeof(msg->sg.segname)) == 0){ 6400 ms->s.size = 0; 6401 prev_ms = ms; 6402 ms = ms->next; 6403 } 6404 prev_ms->next = NULL; 6405 } 6406 else{ 6407 msg = msg->next; 6408 } 6409 } 6410 } 6411 merged_segments = original_merged_segments; 6412 original_merged_segments = NULL; 6413} 6414 6415/* 6416 * zero_merged_sections_sizes() is called from rld_load() to zero the size field 6417 * in the merged sections so the sizes can be accumulated and free the literal 6418 * data for any literal sections. Also the alignment of the existing sections 6419 * is reset to zero. 6420 */ 6421__private_extern__ 6422void 6423zero_merged_sections_sizes(void) 6424{ 6425 struct merged_segment **p, *msg; 6426 struct merged_section **q, *ms; 6427 6428 p = &merged_segments; 6429 while(*p){ 6430 msg = *p; 6431 q = &(msg->content_sections); 6432 while(*q){ 6433 ms = *q; 6434 ms->s.size = 0; 6435 ms->s.align = 0; 6436 if(ms->literal_data != NULL){ 6437 if(ms->literal_free != NULL){ 6438 (*ms->literal_free)(ms->literal_data, ms); 6439 } 6440 } 6441 q = &(ms->next); 6442 } 6443 q = &(msg->zerofill_sections); 6444 while(*q){ 6445 ms = *q; 6446 ms->s.size = 0; 6447 ms->s.align = 0; 6448 q = &(ms->next); 6449 } 6450 p = &(msg->next); 6451 } 6452} 6453 6454/* 6455 * remove_sections() removes the sections and segments that first came from the 6456 * current set from the merged section list. The order that sections are 6457 * merged on to the lists is taken advantaged of here. 6458 */ 6459__private_extern__ 6460void 6461remove_merged_sections(void) 6462{ 6463 struct merged_segment *msg, *prev_msg, *next_msg; 6464 struct merged_section *ms, *prev_ms, *next_ms; 6465 6466 /* The compiler "warning: `prev_msg' and `prev_ms' may be used */ 6467 /* uninitialized in this function" can safely be ignored */ 6468 prev_msg = NULL; 6469 prev_ms = NULL; 6470 6471 if(original_merged_segments != NULL) 6472 reset_merged_sections(); 6473 6474 for(msg = merged_segments; msg != NULL; msg = msg->next){ 6475 /* 6476 * If this segment first comes from the current set then all 6477 * remaining segments also come from this set and all of their 6478 * sections. So they are all removed from the list. 6479 */ 6480 if(msg->set_num == cur_set){ 6481 if(msg == merged_segments) 6482 merged_segments = NULL; 6483 else 6484 prev_msg->next = NULL; 6485 while(msg != NULL){ 6486 ms = msg->content_sections; 6487 while(ms != NULL){ 6488 if(ms->literal_data != NULL){ 6489 if(ms->literal_free != NULL){ 6490 (*ms->literal_free)(ms->literal_data, ms); 6491 free(ms->literal_data); 6492 ms->literal_data = NULL; 6493 } 6494 } 6495 next_ms = ms->next; 6496 free(ms); 6497 ms = next_ms; 6498 } 6499 ms = msg->zerofill_sections; 6500 while(ms != NULL){ 6501 next_ms = ms->next; 6502 free(ms); 6503 ms = next_ms; 6504 } 6505 next_msg = msg->next; 6506 free(msg); 6507 msg = next_msg; 6508 } 6509 break; 6510 } 6511 else{ 6512 /* 6513 * This segment first comes from other than the current set 6514 * so check to see in any of it's sections from from the 6515 * current set and if so remove them. Again advantage of the 6516 * order is taken so that if a section if found to come from 6517 * the current set all remaining sections in that list also come 6518 * from that set. 6519 */ 6520 for(ms = msg->content_sections; ms != NULL; ms = ms->next){ 6521 if(ms->set_num == cur_set){ 6522 if(ms == msg->content_sections) 6523 msg->content_sections = NULL; 6524 else 6525 prev_ms->next = NULL; 6526 while(ms != NULL){ 6527 msg->sg.nsects--; 6528 if(ms->literal_data != NULL) 6529 free(ms->literal_data); 6530 next_ms = ms->next; 6531 free(ms); 6532 ms = next_ms; 6533 } 6534 break; 6535 } 6536 prev_ms = ms; 6537 } 6538 for(ms = msg->zerofill_sections; ms != NULL; ms = ms->next){ 6539 if(ms->set_num == cur_set){ 6540 if(ms == msg->zerofill_sections) 6541 msg->zerofill_sections = NULL; 6542 else 6543 prev_ms->next = NULL; 6544 while(ms != NULL){ 6545 msg->sg.nsects--; 6546 next_ms = ms->next; 6547 free(ms); 6548 ms = next_ms; 6549 } 6550 break; 6551 } 6552 prev_ms = ms; 6553 } 6554 } 6555 prev_msg = msg; 6556 } 6557} 6558#endif /* RLD */ 6559 6560#ifdef DEBUG 6561/* 6562 * print_merged_sections() prints the merged section table. For debugging. 6563 */ 6564__private_extern__ 6565void 6566print_merged_sections( 6567char *string) 6568{ 6569 struct merged_segment *msg; 6570 struct merged_section *ms; 6571 6572 print("Merged section list (%s)\n", string); 6573 for(msg = merged_segments; msg ; msg = msg->next){ 6574 print(" Segment %.16s\n", msg->sg.segname); 6575 print("\tcmd %u\n", msg->sg.cmd); 6576 print("\tcmdsize %u\n", msg->sg.cmdsize); 6577 print("\tvmaddr 0x%x ", (unsigned int)msg->sg.vmaddr); 6578 print("(addr_set %s)\n", msg->addr_set ? "TRUE" : "FALSE"); 6579 print("\tvmsize 0x%x\n", (unsigned int)msg->sg.vmsize); 6580 print("\tfileoff %u\n", msg->sg.fileoff); 6581 print("\tfilesize %u\n", msg->sg.filesize); 6582 print("\tmaxprot "); 6583 print_prot(msg->sg.maxprot); 6584 print(" (prot_set %s)\n", msg->prot_set ? "TRUE" : "FALSE"); 6585 print("\tinitprot "); 6586 print_prot(msg->sg.initprot); 6587 print("\n"); 6588 print("\tnsects %u\n", msg->sg.nsects); 6589 print("\tflags %u\n", msg->sg.flags); 6590#ifdef RLD 6591 print("\tset_num %lu\n", msg->set_num); 6592#endif /* RLD */ 6593 print("\tfilename %s\n", msg->filename); 6594 print("\tcontent_sections\n"); 6595 for(ms = msg->content_sections; ms ; ms = ms->next){ 6596 print("\t Section (%.16s,%.16s)\n", 6597 ms->s.segname, ms->s.sectname); 6598 print("\t\taddr 0x%x\n", (unsigned int)ms->s.addr); 6599 print("\t\tsize %u\n", ms->s.size); 6600 print("\t\toffset %u\n", ms->s.offset); 6601 print("\t\talign %u\n", ms->s.align); 6602 print("\t\tnreloc %u\n", ms->s.nreloc); 6603 print("\t\treloff %u\n", ms->s.reloff); 6604 print("\t\tflags %s\n", 6605 section_flags[ms->s.flags & SECTION_TYPE]); 6606#ifdef RLD 6607 print("\t\tset_num %d\n", ms->set_num); 6608#endif /* RLD */ 6609 if(ms->relocated == TRUE) 6610 print("\t relocated TRUE\n"); 6611 else 6612 print("\t relocated FALSE\n"); 6613 if(ms->referenced == TRUE) 6614 print("\t referenced TRUE\n"); 6615 else 6616 print("\t referenced FALSE\n"); 6617 if(ms->contents_filename){ 6618 print("\t contents_filename %s\n", 6619 ms->contents_filename); 6620 print("\t file_addr 0x%x\n", 6621 (unsigned int)ms->file_addr); 6622 print("\t file_size %lu\n", ms->file_size); 6623 } 6624 if(ms->order_filename){ 6625 print("\t order_filename %s\n", 6626 ms->order_filename); 6627 print("\t order_addr 0x%x\n", 6628 (unsigned int)ms->order_addr); 6629 print("\t order_size %lu\n", ms->order_size); 6630 } 6631 if((ms->s.flags & SECTION_TYPE) == S_CSTRING_LITERALS) 6632 print_cstring_data(ms->literal_data, "\t "); 6633 if((ms->s.flags & SECTION_TYPE) == S_4BYTE_LITERALS) 6634 print_literal4_data(ms->literal_data, "\t "); 6635 if((ms->s.flags & SECTION_TYPE) == S_8BYTE_LITERALS) 6636 print_literal8_data(ms->literal_data, "\t "); 6637 if((ms->s.flags & SECTION_TYPE) == S_LITERAL_POINTERS) 6638 print_literal_pointer_data(ms->literal_data, "\t "); 6639 } 6640 print("\tzerofill_sections\n"); 6641 for(ms = msg->zerofill_sections; ms ; ms = ms->next){ 6642 print("\t Section (%.16s,%.16s)\n", 6643 ms->s.segname, ms->s.sectname); 6644 print("\t\taddr 0x%x\n", (unsigned int)ms->s.addr); 6645 print("\t\tsize %u\n", ms->s.size); 6646 print("\t\toffset %u\n", ms->s.offset); 6647 print("\t\talign %u\n", ms->s.align); 6648 print("\t\tnreloc %u\n", ms->s.nreloc); 6649 print("\t\treloff %u\n", ms->s.reloff); 6650 print("\t\tflags %s\n", 6651 section_flags[ms->s.flags & SECTION_TYPE]); 6652#ifdef RLD 6653 print("\t\tset_num %lu\n", ms->set_num); 6654#endif /* RLD */ 6655 } 6656 } 6657} 6658 6659/* 6660 * print_merged_section_stats() prints the stats for the merged sections. 6661 * For tuning.. 6662 */ 6663__private_extern__ 6664void 6665print_merged_section_stats(void) 6666{ 6667 struct merged_segment *msg; 6668 struct merged_section *ms; 6669 6670 for(msg = merged_segments; msg ; msg = msg->next){ 6671 for(ms = msg->content_sections; ms ; ms = ms->next){ 6672 if((ms->s.flags & SECTION_TYPE) == S_LITERAL_POINTERS) 6673 literal_pointer_data_stats(ms->literal_data, ms); 6674 else if((ms->s.flags & SECTION_TYPE) == S_CSTRING_LITERALS) 6675 cstring_data_stats(ms->literal_data, ms); 6676 else if((ms->s.flags & SECTION_TYPE) == S_4BYTE_LITERALS) 6677 literal4_data_stats(ms->literal_data, ms); 6678 else if((ms->s.flags & SECTION_TYPE) == S_8BYTE_LITERALS) 6679 literal8_data_stats(ms->literal_data, ms); 6680 } 6681 } 6682} 6683 6684/* 6685 * print_load_order() prints the load_order array passed to it. 6686 * For debugging. 6687 */ 6688__private_extern__ 6689void 6690print_load_order( 6691struct load_order *load_order, 6692unsigned long nload_order, 6693struct merged_section *ms, 6694struct object_file *object_file, 6695char *string) 6696{ 6697 unsigned long i; 6698 6699 print("Load order 0x%x %lu entries for (%.16s,%.16s) of ", 6700 (unsigned int)load_order, nload_order, 6701 ms->s.segname, ms->s.sectname); 6702 print_obj_name(object_file); 6703 print("(%s)\n", string); 6704 for(i = 0; i < nload_order; i++){ 6705 print("entry[%lu]\n", i); 6706 print(" name %s\n", load_order[i].name == NULL ? "null" : 6707 load_order[i].name); 6708 print(" value 0x%08x\n",(unsigned int)load_order[i].value); 6709 print(" order %lu\n", load_order[i].order); 6710 print(" input_offset %lu\n", load_order[i].input_offset); 6711 print(" input_size %lu\n", load_order[i].input_size); 6712 print(" output_offset %lu\n", load_order[i].output_offset); 6713 } 6714} 6715 6716/* 6717 * print_name_arrays() prints the sorted arrays of archive and object names. 6718 * For debugging. 6719 */ 6720__private_extern__ 6721void 6722print_name_arrays(void) 6723{ 6724 unsigned long i, j; 6725 6726 print("Sorted archive names:\n"); 6727 for(i = 0; i < narchive_names; i++){ 6728 print(" archive name %s\n", archive_names[i].archive_name); 6729 print(" number of objects %lu\n",archive_names[i].nobject_names); 6730 print(" Sorted object names:\n"); 6731 for(j = 0; j < archive_names[i].nobject_names; j++){ 6732 print("\tobject name %s\n", 6733 archive_names[i].object_names[j].object_name); 6734 print("\tlength %lu\n", 6735 archive_names[i].object_names[j].index_length); 6736 print("\tobject file 0x%x ", (unsigned int) 6737 (archive_names[i].object_names[j].object_file)); 6738 print_obj_name(archive_names[i].object_names[j].object_file); 6739 print("\n"); 6740 } 6741 } 6742 print("Sorted object names:\n"); 6743 for(j = 0; j < nobject_names; j++){ 6744 print("\tobject name %s\n", object_names[j].object_name); 6745 print("\tindex %lu\n", object_names[j].index_length); 6746 print("\tobject file 0x%x ", 6747 (unsigned int)(object_names[j].object_file)); 6748 print_obj_name(object_names[j].object_file); 6749 print("\n"); 6750 } 6751} 6752 6753static 6754void 6755print_load_symbol_hash_table(void) 6756{ 6757 unsigned long i; 6758 struct load_symbol *load_symbol, *other_name; 6759 6760 print("load_symbol_hash_table:\n"); 6761 if(load_symbol_hashtable == NULL) 6762 return; 6763 for(i = 0; i < LOAD_SYMBOL_HASHTABLE_SIZE; i++){ 6764 if(load_symbol_hashtable[i] != NULL) 6765 print("[%lu]\n", i); 6766 for(load_symbol = load_symbol_hashtable[i]; 6767 load_symbol != NULL; 6768 load_symbol = load_symbol->next){ 6769 print("load symbol: %lu\n", i); 6770 if(load_symbol->archive_name != NULL){ 6771 print(" (%s:%s:%s) length %lu\n", 6772 load_symbol->archive_name, 6773 load_symbol->object_name, 6774 load_symbol->symbol_name, 6775 load_symbol->index_length); 6776 } 6777 else{ 6778 print(" (%s:%s) index %lu\n", 6779 load_symbol->object_name, 6780 load_symbol->symbol_name, 6781 load_symbol->index_length); 6782 } 6783 print(" load_order 0x%x\n", 6784 (unsigned int)(load_symbol->load_order)); 6785 print(" other_names 0x%x\n", 6786 (unsigned int)(load_symbol->other_names)); 6787 print(" next 0x%x\n", 6788 (unsigned int)(load_symbol->next)); 6789 for(other_name = load_symbol->other_names; 6790 other_name != NULL; 6791 other_name = other_name->other_names){ 6792 print("other name\n"); 6793 if(other_name->archive_name != NULL){ 6794 print(" (%s:%s:%s) length %lu\n", 6795 other_name->archive_name, 6796 other_name->object_name, 6797 other_name->symbol_name, 6798 other_name->index_length); 6799 } 6800 else{ 6801 print(" (%s:%s) index %lu\n", 6802 other_name->object_name, 6803 other_name->symbol_name, 6804 other_name->index_length); 6805 } 6806 print(" load_order 0x%x\n", 6807 (unsigned int)(other_name->load_order)); 6808 print(" other_names 0x%x\n", 6809 (unsigned int)(other_name->other_names)); 6810 print(" next 0x%x\n", 6811 (unsigned int)(load_symbol->next)); 6812 } 6813 } 6814 } 6815} 6816#endif /* DEBUG */ 6817