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 that deal with indirect sections (both 28 * lazy and non-lazy symbol pointer sections as well as symbol stub sections). 29 */ 30#include <stdlib.h> 31#if !(defined(KLD) && defined(__STATIC__)) 32#include <stdio.h> 33#include <mach/mach.h> 34#else /* defined(KLD) && defined(__STATIC__) */ 35#include <mach/kern_return.h> 36#endif /* !(defined(KLD) && defined(__STATIC__)) */ 37#include <stdarg.h> 38#include <string.h> 39#include "stuff/openstep_mach.h" 40#include <mach-o/loader.h> 41#include <mach-o/nlist.h> 42#include <mach-o/stab.h> 43#include <mach-o/reloc.h> 44#include <mach-o/ppc/reloc.h> 45#include <mach-o/hppa/reloc.h> 46#include "stuff/arch.h" 47#include "stuff/reloc.h" 48 49#include "ld.h" 50#include "live_refs.h" 51#include "objects.h" 52#include "sections.h" 53#include "pass2.h" 54#include "generic_reloc.h" 55#include "pass1.h" 56#include "symbols.h" 57#include "layout.h" 58#include "coalesced_sections.h" 59#include "dylibs.h" 60 61/* 62 * coalesced_section_merge() merges items from a coalesced section from the 63 * specified section in the current object file (cur_obj). When redo_live is 64 * FALSE it allocates a fine relocation map and sets the fine_relocs field in 65 * the section_map to it (as well as the count). 66 * 67 * When redo_live is FALSE after all the items for this section in this object 68 * file have been merged two more things are done. First the number of 69 * relocation entries that will be in the output file is adjusted (incremented) 70 * based on which items are used from this object's section. Second the number 71 * of local symbol table entries and the size of the string table is adjusted 72 * (decremented) based on the which symbols are in the items from this object's 73 * section that will be in the resulting object file. 74 * 75 * When redo_live is TRUE it re-merges only the live items from a coalesced 76 * section from the specified section in the current object file (cur_obj). 77 */ 78__private_extern__ 79void 80coalesced_section_merge( 81void *data, 82struct merged_section *ms, 83struct section *s, 84struct section_map *section_map, 85enum bool redo_live) 86{ 87 unsigned long i, j, nsect, count; 88 struct nlist *object_symbols; 89 char *object_strings; 90 enum bool start_section; 91 struct load_order *load_orders; 92 struct fine_reloc *fine_relocs; 93 struct merged_symbol *merged_symbol; 94 struct relocation_info *relocs, reloc; 95 struct scattered_relocation_info *sreloc, *spair_reloc; 96 unsigned long r_address, r_pcrel, r_length, r_type, pair_r_type, r_extern, 97 r_symbolnum, r_scattered, pair, r_value; 98 struct undefined_map *undefined_map; 99#ifndef RLD 100 enum bool pic; 101#endif 102 enum bool defined, force_extern_reloc; 103 104 pair_r_type = 0; 105 /* 106 * If the size of the section is zero there is nothing to merge. 107 */ 108 if(s->size == 0) 109 return; 110 111 merged_symbol = NULL; 112 113 /* 114 * Figure out the nsect in the object file we are about to merge. 115 * This is so we can count the symbols that match this nsect which 116 * are defined in this section. 117 */ 118 nsect = 0; 119 for(i = 0; i < cur_obj->nsection_maps; i++){ 120 if(&(cur_obj->section_maps[i]) == section_map){ 121 nsect = i + 1; 122 break; 123 } 124 } 125 if(nsect == 0){ 126 fatal("internal error: coalesced_section_merge() called " 127 "with bad section_map for section (%.16s,%.16s)", 128 s->segname, s->sectname); 129 } 130 131 /* 132 * Count the number of symbols in this section in this object file. 133 * Check to see if there is a symbol at the beginning of the section. 134 * and that all symbols defined in this section are global. 135 */ 136 count = 0; 137 start_section = FALSE; 138 if(cur_obj->symtab != NULL){ 139 object_symbols = (struct nlist *)(cur_obj->obj_addr + 140 cur_obj->symtab->symoff); 141 object_strings = (char *)(cur_obj->obj_addr + 142 cur_obj->symtab->stroff); 143 } 144 else{ 145 object_symbols = NULL; 146 object_strings = NULL; 147 } 148 if(redo_live == TRUE) 149 goto set_load_orders; 150 151 if(cur_obj->symtab != NULL){ 152 for(i = 0; i < cur_obj->symtab->nsyms; i++){ 153 if((object_symbols[i].n_type & N_TYPE) == N_SECT && 154 object_symbols[i].n_sect == nsect && 155 (object_symbols[i].n_type & N_STAB) == 0){ 156 count++; 157/* 158 * Allow private extern and local symbols. 159 */ 160#ifdef notdef 161 if((object_symbols[i].n_type & (N_EXT|N_PEXT)) == 162 (N_EXT|N_PEXT)){ 163 error_with_cur_obj("malformed object (symbol: %s in " 164 "S_COALESCE section (%.16s,%.16s) can't be a " 165 "private extern symbol)", 166 object_strings + object_symbols[i].n_un.n_strx, 167 s->segname, s->sectname); 168 return; 169 } 170 if((object_symbols[i].n_type & N_EXT) != N_EXT){ 171 error_with_cur_obj("malformed object (symbol: %s in " 172 "S_COALESCE section (%.16s,%.16s) not an external " 173 "symbol)", 174 object_strings + object_symbols[i].n_un.n_strx, 175 s->segname, s->sectname); 176 return; 177 } 178#endif 179 if(object_symbols[i].n_value == s->addr) 180 start_section = TRUE; 181 } 182 } 183 } 184 if(start_section == FALSE){ 185 error_with_cur_obj("malformed object (section (%.16s,%.16s) no " 186 "symbol at start of coalesced section)",s->segname,s->sectname); 187 return; 188 } 189 190set_load_orders: 191 /* 192 * Allocate a load order map for the symbols in this section. 193 * We are not ordering the section but simpily needing to figure out 194 * the sizes and offsets of each symbol and a load order map is now 195 * this is normally done. 196 */ 197 if(redo_live == FALSE){ 198 load_orders = allocate(sizeof(struct load_order) * count); 199 memset(load_orders, '\0', sizeof(struct load_order) * count); 200 section_map->load_orders = load_orders; 201 section_map->nload_orders = count; 202 } 203 else{ 204 load_orders = section_map->load_orders; 205 count = section_map->nload_orders; 206 goto deal_with_contents; 207 } 208 209 /* 210 * Fill in symbol names and values the load order map for this section 211 * in this object file. 212 */ 213 j = 0; 214 for(i = 0; i < cur_obj->symtab->nsyms; i++){ 215 if((object_symbols[i].n_type & N_TYPE) == N_SECT && 216 object_symbols[i].n_sect == nsect && 217 (object_symbols[i].n_type & N_STAB) == 0){ 218 load_orders[j].name = object_strings + 219 object_symbols[i].n_un.n_strx; 220 load_orders[j].value = 221 object_symbols[i].n_value; 222 /* 223 * We fill in the 'global_coalesced_symbol' field with a 224 * boolean test of if the symbol is external or not. See 225 * below where this is used. 226 */ 227 load_orders[j].global_coalesced_symbol = 228 (object_symbols[i].n_type & N_EXT) == N_EXT; 229 j++; 230 } 231 } 232 233#ifdef DEBUG 234 if(debug & (1 << 14)) 235 print_load_order(load_orders, count, ms, 236 cur_obj, "names and values"); 237#endif /* DEBUG */ 238 239 /* 240 * Sort the load order map by symbol value so the 241 * size and input offset fields can be set. 242 */ 243 qsort(load_orders, 244 count, 245 sizeof(struct load_order), 246 (int (*)(const void *, const void *))qsort_load_order_values); 247 /* 248 * Set the input offset and size fields. 249 */ 250 for(i = 0; i < count - 1; i++){ 251 load_orders[i].input_offset = 252 load_orders[i].value - 253 s->addr; 254 load_orders[i].input_size = 255 load_orders[i + 1].value - 256 load_orders[i].value; 257 } 258 load_orders[i].input_offset = 259 load_orders[i].value - 260 s->addr; 261 load_orders[i].input_size = 262 s->addr + s->size - 263 load_orders[i].value; 264#ifdef DEBUG 265 if(debug & (1 << 15)) 266 print_load_order(load_orders, count, ms, 267 cur_obj, "sizes and offsets"); 268#endif /* DEBUG */ 269 270deal_with_contents: 271 /* 272 * First deal with the contents of section for each symbol and determine 273 * based on the symbol if the contents will be used from this object or 274 * used from a previously merged object. This information is encoded 275 * into the fine_reloc structures for each item. 276 */ 277 if(redo_live == FALSE){ 278 fine_relocs = allocate(count * sizeof(struct fine_reloc)); 279 memset(fine_relocs, '\0', count * sizeof(struct fine_reloc)); 280 section_map->fine_relocs = fine_relocs; 281 section_map->nfine_relocs = count; 282 } 283 else{ 284 fine_relocs = section_map->fine_relocs; 285 count = section_map->nfine_relocs; 286 } 287 for(i = 0; i < count; i++){ 288 if(redo_live == FALSE) 289 fine_relocs[i].input_offset = load_orders[i].input_offset; 290 /* 291 * We previously filled in the 'global_coalesced_symbol' field with 292 * a boolean test of if the symbol is external or not. See above 293 * where this is done. 294 */ 295 if(load_orders[i].global_coalesced_symbol == TRUE){ 296 merged_symbol = lookup_symbol(load_orders[i].name); 297 if(merged_symbol->name_len == 0) 298 fatal("internal error, coalesced_section_merge() failed in " 299 "looking up external symbol: %s",load_orders[i].name); 300 /* 301 * If the merged symbol comes from this object then this 302 * object's contents will be used. If not it won't. 303 */ 304 if(merged_symbol->definition_object == cur_obj){ 305 if(redo_live == FALSE){ 306 fine_relocs[i].use_contents = TRUE; 307 fine_relocs[i].indirect_defined = FALSE; 308 } 309 if(redo_live == FALSE || fine_relocs[i].live == TRUE){ 310 /* align size before using it to assign output offset */ 311 ms->s.size = align_to_input_mod(ms->s.size, 312 fine_relocs[i].input_offset, 313 ms->s.align); 314 fine_relocs[i].output_offset = ms->s.size; 315 ms->s.size += load_orders[i].input_size; 316 } 317 } 318 else{ 319 if(redo_live == FALSE){ 320 fine_relocs[i].use_contents = FALSE; 321 fine_relocs[i].indirect_defined = FALSE; 322 fine_relocs[i].merged_symbol = merged_symbol; 323 } 324 } 325 /* 326 * We want to set local_symbol to TRUE if this symbol is a 327 * private extern symbol so that section difference relocation 328 * entries to it are not flagged as illegal references. 329 */ 330 if((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT){ 331 if(redo_live == FALSE) 332 fine_relocs[i].local_symbol = TRUE; 333 } 334 else{ 335 if(redo_live == FALSE) 336 fine_relocs[i].local_symbol = FALSE; 337 } 338 } 339 else{ 340 /* 341 * This is a local or private_extern symbol so keep its 342 * contents. 343 */ 344 if(redo_live == FALSE){ 345 fine_relocs[i].use_contents = TRUE; 346 fine_relocs[i].local_symbol = TRUE; 347 fine_relocs[i].indirect_defined = FALSE; 348 } 349 if(redo_live == FALSE || fine_relocs[i].live == TRUE){ 350 /* align size before using it to assign output offset */ 351 ms->s.size = align_to_input_mod(ms->s.size, 352 fine_relocs[i].input_offset, 353 ms->s.align); 354 fine_relocs[i].output_offset = ms->s.size; 355 ms->s.size += load_orders[i].input_size; 356 } 357 } 358 } 359 360#ifdef COALESCE_DEBUG 361 /* 362 * For debugging print out the fine relocs we created for this section. 363 */ 364 printf("Fine relocs created for coalesced section (%.16s,%.16s) in ", 365 s->segname, s->sectname); 366 print_obj_name(cur_obj); 367 printf("\n"); 368 for(i = 0; i < count; i++){ 369 printf("fine_relocs[%lu] load_orders[%lu].name = %s\n", 370 i, i, load_orders[i].name); 371 printf("\tuse_contents = %s\n", fine_relocs[i].use_contents == TRUE 372 ? "TRUE" : "FALSE"); 373 printf("\tlocal_symbol = %s\n", fine_relocs[i].local_symbol == TRUE 374 ? "TRUE" : "FALSE"); 375 printf("\tinput_offset = %d\n", fine_relocs[i].input_offset); 376 if(fine_relocs[i].use_contents == TRUE) 377 printf("\toutput_offset = %ld\n", fine_relocs[i].output_offset); 378 else{ 379 merged_symbol = fine_relocs[i].merged_symbol; 380 printf("\t%s from ", merged_symbol->nlist.n_un.n_name); 381 print_obj_name(merged_symbol->definition_object); 382 printf("\n"); 383 } 384 } 385#endif 386 387 /* 388 * Second deal with the relocation entries for the section in this 389 * object file. Now that it has been determined for which items the 390 * contents will be used from this object file. 391 */ 392 393 /* 394 * This loop loops through the relocation entries and using the 395 * use_contents field (via a call to fine_reloc_offset_in_output()) * of the fine_relocs just created determines how many relocation 396 * entries will be in the output for this section of this object file. 397 */ 398 relocs = (struct relocation_info *)(cur_obj->obj_addr + s->reloff); 399 for(i = 0; i < s->nreloc; i++){ 400 reloc = relocs[i]; 401 if(cur_obj->swapped && 402 section_map->input_relocs_already_swapped == FALSE) 403 swap_relocation_info(&reloc, 1, host_byte_sex); 404 /* 405 * Break out the fields of the relocation entry we need here. 406 */ 407 if((reloc.r_address & R_SCATTERED) != 0){ 408 sreloc = (struct scattered_relocation_info *)(&reloc); 409 r_scattered = 1; 410 r_address = sreloc->r_address; 411 r_pcrel = sreloc->r_pcrel; 412 r_length = sreloc->r_length; 413 r_type = sreloc->r_type; 414 r_extern = 0; 415 r_value = sreloc->r_value; 416 /* calculate the r_symbolnum (n_sect) from the r_value */ 417 r_symbolnum = 0; 418 for(j = 0; j < cur_obj->nsection_maps; j++){ 419 if(r_value >= cur_obj->section_maps[j].s->addr && 420 r_value < cur_obj->section_maps[j].s->addr + 421 cur_obj->section_maps[j].s->size){ 422 r_symbolnum = j + 1; 423 break; 424 } 425 } 426 if(r_symbolnum == 0){ 427 /* 428 * The edge case where the last address past then end of 429 * of the last section is referenced. 430 */ 431 for(j = 0; j < cur_obj->nsection_maps; j++){ 432 if(r_value == cur_obj->section_maps[j].s->addr + 433 cur_obj->section_maps[j].s->size){ 434 r_symbolnum = j + 1; 435 break; 436 } 437 } 438 if(r_symbolnum == 0){ 439 error_with_cur_obj("r_value (0x%x) field of relocation " 440 "entry %lu in section (%.16s,%.16s) out of range", 441 (unsigned int)r_value, i, section_map->s->segname, 442 section_map->s->sectname); 443 return; 444 } 445 } 446 } 447 else{ 448 r_scattered = 0; 449 r_address = reloc.r_address; 450 r_pcrel = reloc.r_pcrel; 451 r_length = reloc.r_length; 452 r_type = reloc.r_type; 453 r_extern = reloc.r_extern; 454 r_symbolnum = reloc.r_symbolnum; 455 } 456 /* 457 * Make sure that this is not a stray PAIR relocation entry. 458 */ 459 if(r_type == reloc_pair_r_type(arch_flag.cputype)){ 460 error_with_cur_obj("malformed object (stray relocation PAIR " 461 "entry (%lu) in section (%.16s,%.16s))", i, s->segname, 462 s->sectname); 463 continue; 464 } 465 /* 466 * The r_address field is really an offset into the contents of the 467 * section and must reference something inside the section. 468 */ 469 if(r_address >= s->size){ 470 error_with_cur_obj("malformed object (r_address (0x%x) field " 471 "of relocation entry %ld in section (%.16s,%.16s) out of " 472 "range)",(unsigned int)r_address, i,s->segname,s->sectname); 473 continue; 474 } 475 /* 476 * If this relocation entry is suppose to have a PAIR make sure it 477 * does. 478 */ 479 if(reloc_has_pair(arch_flag.cputype, r_type)){ 480 if(i + 1 < s->nreloc){ 481 reloc = relocs[i + 1]; 482 if(cur_obj->swapped && 483 section_map->input_relocs_already_swapped == FALSE) 484 swap_relocation_info(&reloc, 1, host_byte_sex); 485 if((reloc.r_address & R_SCATTERED) != 0){ 486 spair_reloc = (struct scattered_relocation_info *) 487 &reloc; 488 pair_r_type = spair_reloc->r_type; 489 } 490 else{ 491 pair_r_type = reloc.r_type; 492 } 493 } 494 if(i + 1 >= s->nreloc || 495 pair_r_type != reloc_pair_r_type(arch_flag.cputype)){ 496 error_with_cur_obj("malformed object (relocation entry " 497 "(%lu) in section (%.16s,%.16s) missing following " 498 "associated PAIR entry)", i, s->segname, s->sectname); 499 continue; 500 } 501 } 502 503 /* 504 * Assumed the symbol for this relocation entry is defined (always 505 * true for local relocation entries). Then reset the variable 506 * "defined" correctly if this is an external relocation entry based 507 * on if the symbol is defined, where it is defined and the output 508 * file type. 509 */ 510 defined = TRUE; 511 force_extern_reloc = FALSE; 512 if(output_for_dyld && r_extern){ 513 /* 514 * This is an external relocation entry. So the value to be 515 * added to the item to be relocated is the value of the symbol. 516 * r_symbolnum is an index into the input file's symbol table 517 * of the symbol being refered to. The symbol must be an 518 * undefined symbol to be used in an external relocation entry 519 * or a global coalesced symbol. 520 */ 521 if(r_symbolnum >= cur_obj->symtab->nsyms){ 522 error_with_cur_obj("r_symbolnum (%lu) field of external " 523 "relocation entry %lu in section (%.16s,%.16s) out of " 524 "range", r_symbolnum, i, s->segname, s->sectname); 525 continue; 526 } 527 undefined_map = bsearch(&r_symbolnum, cur_obj->undefined_maps, 528 cur_obj->nundefineds, sizeof(struct undefined_map), 529 (int (*)(const void *, const void *))undef_bsearch); 530 if(undefined_map != NULL){ 531 merged_symbol = undefined_map->merged_symbol; 532 /* 533 * We must allow and create references to defined global 534 * coalesced symbols with external relocation entries so 535 * that the dynamic linker can relocate all references to 536 * the same symbol. 537 */ 538 if((merged_symbol->nlist.n_type & N_TYPE) == N_SECT && 539 (merged_symbol->definition_object->section_maps[ 540 merged_symbol->nlist.n_sect - 1].s->flags & 541 SECTION_TYPE) == S_COALESCED){ 542 if(((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT && 543 keep_private_externs == FALSE) || 544 dynamic == FALSE || 545 (output_for_dyld && has_dynamic_linker_command)) 546 force_extern_reloc = FALSE; 547 else 548 force_extern_reloc = TRUE; 549 } 550 } 551 else{ 552 if((object_symbols[r_symbolnum].n_type & N_EXT) != N_EXT){ 553 error_with_cur_obj("r_symbolnum (%lu) field of external" 554 " relocation entry %lu in section (%.16s,%.16s) " 555 "refers to a non-external symbol", r_symbolnum, i, 556 section_map->s->segname, section_map->s->sectname); 557 return; 558 } 559 /* 560 * We must allow and create references to defined global 561 * coalesced symbols with external relocation entries so 562 * that the dynamic linker can relocate all references to 563 * the same symbol. 564 */ 565 if((object_symbols[r_symbolnum].n_type & N_TYPE) == 566 N_SECT && 567 (cur_obj->section_maps[object_symbols[r_symbolnum]. 568 n_sect-1].s->flags & SECTION_TYPE) == S_COALESCED){ 569 merged_symbol = lookup_symbol(object_strings + 570 object_symbols[r_symbolnum].n_un.n_strx); 571 if(merged_symbol->name_len == 0){ 572 fatal("internal error, in coalesced_section_merge()" 573 " failed to lookup coalesced symbol %s", 574 object_strings + 575 object_symbols[r_symbolnum].n_un.n_strx); 576 } 577 /* 578 * While the .o file's symbol is a coalesced symbol, it 579 * may have been weak and the merged symbol now being 580 * used is not a coalesced symbol. In that case we don't 581 * force an external relocation entry. 582 */ 583 if(((merged_symbol->nlist.n_type & N_TYPE) == N_SECT && 584 (merged_symbol->definition_object->section_maps[ 585 merged_symbol->nlist.n_sect-1]. 586 s->flags & SECTION_TYPE) != S_COALESCED) || 587 ((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT && 588 keep_private_externs == FALSE) || 589 dynamic == FALSE || 590 (output_for_dyld && has_dynamic_linker_command)) 591 force_extern_reloc = FALSE; 592 else 593 force_extern_reloc = TRUE; 594 } 595 else{ 596 if(object_symbols[r_symbolnum].n_type != 597 (N_EXT | N_UNDF)){ 598 error_with_cur_obj("r_symbolnum (%lu) field of " 599 "external relocation entry %lu in section " 600 "(%.16s,%.16s) refers to a non-undefined " 601 "symbol", r_symbolnum, i, 602 section_map->s->segname, 603 section_map->s->sectname); 604 return; 605 } 606 print_obj_name(cur_obj); 607 fatal("internal error, in coalesced_section_merge() " 608 "symbol index %lu in above file not in undefined " 609 "map", r_symbolnum); 610 } 611 } 612 /* 613 * If this is an indirect symbol resolve indirection (all chains 614 * of indirect symbols have been resolved so that they point at 615 * a symbol that is not an indirect symbol). 616 */ 617 if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR) 618 merged_symbol = (struct merged_symbol *) 619 merged_symbol->nlist.n_value; 620 /* 621 * Is the merged symbol for this external relocation entry 622 * defined in the output file. 623 */ 624 if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) || 625 merged_symbol->nlist.n_type == (N_EXT | N_PBUD) || 626 (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && 627 merged_symbol->defined_in_dylib == TRUE)) 628 defined = FALSE; 629 else 630 defined = TRUE; 631 } 632 if(reloc_has_pair(arch_flag.cputype, r_type)) 633 pair = 1; 634 else 635 pair = 0; 636 637 /* 638 * For output_for_dyld PPC_RELOC_JBSR and HPPA_RELOC_JBSR's are 639 * never put out. 640 */ 641 if(output_for_dyld && 642 ((arch_flag.cputype == CPU_TYPE_POWERPC && 643 r_type == PPC_RELOC_JBSR) || 644 (arch_flag.cputype == CPU_TYPE_HPPA && 645 r_type == HPPA_RELOC_JBSR)) ){ 646 i += pair; 647 continue; 648 } 649#ifndef RLD 650 /* 651 * If saving relocation entries see if this relocation entry is for 652 * an item that is going to be in the output file and if so count it 653 * as one of the output relocation entries. 654 */ 655 if(output_for_dyld && 656 fine_reloc_offset_in_output(section_map, r_address)){ 657 /* 658 * Mark this section as being relocated (staticly). 659 */ 660 if(dead_strip == FALSE || redo_live == TRUE) 661 ms->relocated = TRUE; 662 if(r_extern == 0) 663 pic = (enum bool) 664 (reloc_is_sectdiff(arch_flag.cputype, r_type) || 665 (r_pcrel == 1 && r_symbolnum != NO_SECT)); 666 else 667 pic = (enum bool) 668 (r_pcrel == 1 && 669 (merged_symbol->nlist.n_type & N_TYPE) == N_SECT); 670 /* 671 * The number of relocation entries in the output file is based 672 * on one of three different cases: 673 * The output file is a multi module dynamic shared library 674 * The output file has a dynamic linker load command 675 * The output does not have a dynamic linker load command 676 */ 677 if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ 678 /* 679 * For a multi module dynamic shared library the modules are 680 * kept separate so external relocation entries on input 681 * will be external relocation entries on output. For local 682 * relocation entries only non-position-independent local 683 * relocation entries are kept. Modules of dylibs are not 684 * linked together and can only be slid keeping all sections 685 * relative to each other the same. 686 */ 687 if(r_extern && (merged_symbol->nlist.n_type & N_PEXT) == 0) 688 section_map->nextrel += 1 + pair; 689 else if(pic == FALSE) 690 section_map->nlocrel += 1 + pair; 691 } 692 else if(has_dynamic_linker_command){ 693 /* 694 * For an file with a dynamic linker load command only 695 * external relocation entries for undefined symbols are 696 * kept. This output file is a fixed address and can't be 697 * moved. 698 */ 699 if(r_extern && defined == FALSE) 700 section_map->nextrel += 1 + pair; 701 } 702 else{ 703 /* 704 * For an file without a dynamic linker load command 705 * external relocation entries for undefined symbols are 706 * kept and locals that are non-position-independent are 707 * kept. This file can only be slid keeping all sections 708 * relative to each other the same. 709 */ 710 if(r_extern && (merged_symbol->nlist.n_type & N_PEXT) == 0){ 711 if(defined == FALSE || force_extern_reloc == TRUE) 712 section_map->nextrel += 1 + pair; 713 else if(pic == FALSE) 714 section_map->nlocrel += 1 + pair; 715 } 716 else if(pic == FALSE) 717 section_map->nlocrel += 1 + pair; 718 } 719 } 720 else if(save_reloc && 721 fine_reloc_offset_in_output(section_map, r_address)){ 722 ms->s.nreloc += 1 + pair; 723 nreloc += 1 + pair; 724 } 725#endif /* !defined(RLD) */ 726 i += pair; 727 } 728 /* 729 * If the the number of relocation entries is not zero mark this section 730 * as being relocated (staticly). 731 */ 732 if(ms->s.nreloc != 0){ 733 if(dead_strip == FALSE || redo_live == TRUE) 734 ms->relocated = TRUE; 735 } 736 737 /* 738 * Third deal with the symbol table entries for local symbols and N_STAB 739 * symbols in this section in this object file. Now that it has been 740 * determined for which items the contents will be used from this 741 * object file. 742 * 743 * When -dead_strip this can't be called when redo_live is FALSE as the 744 * live marking has not been done yet. And when TRUE will get called for 745 * all sections including coalesced sections as part of 746 * count_live_symbols() calling removed_dead_local_symbols_in_section(). 747 */ 748 if(dead_strip == FALSE) 749 discard_local_symbols_for_section(nsect, object_symbols, 750 object_strings, s, section_map); 751 752 /* 753 * The load_orders are free()'ed if -dead_strip is not specified. Or 754 * if this the second time we are called, when redo_live == TRUE, we 755 * are done with the load_orders so they can be free()'ed at this point. 756 */ 757 if(dead_strip == FALSE || redo_live == TRUE){ 758 free(load_orders); 759 section_map->load_orders = NULL; 760 section_map->nload_orders = 0; 761 } 762} 763 764__private_extern__ 765void 766coalesced_section_order( 767void *data, 768struct merged_section *ms) 769{ 770#ifndef RLD 771 kern_return_t r; 772#ifdef __MWERKS__ 773 struct coalesced_section_data *dummy1; 774 struct merged_section *dummy2; 775 dummy1 = data; 776 dummy2 = ms; 777#endif 778 779 warning("section ordering for coalesced sections not supported (" 780 "-sectorder %s %s %s ignored)", ms->s.segname, ms->s.sectname, 781 ms->order_filename); 782 /* 783 * Deallocate the memory for the load order file now that it is 784 * nolonger needed. 785 */ 786 if((r = vm_deallocate(mach_task_self(), (vm_address_t) 787 ms->order_addr, ms->order_size)) != KERN_SUCCESS) 788 mach_fatal(r, "can't vm_deallocate() memory for -sectorder " 789 "file: %s for section (%.16s,%.16s)", 790 ms->order_filename, ms->s.segname, 791 ms->s.sectname); 792 ms->order_addr = NULL; 793#else /* RLD */ 794#ifdef __MWERKS__ 795 struct coalesced_section_data *dummy1; 796 struct merged_section *dummy2; 797 dummy1 = data; 798 dummy2 = ms; 799#endif 800#endif /* RLD */ 801} 802 803/* 804 * coalesced_section_reset_live() is called when -dead_strip is specified after 805 * the coalesced sections the input objects are merged. It resets the merged 806 * section size and the count of relocation entries back to zero so the live 807 * coalesced items can be re-merged (by later calling coalesced_section_merge() 808 * with redo_live == TRUE. 809 */ 810__private_extern__ 811void 812coalesced_section_reset_live( 813void *data, 814struct merged_section *ms) 815{ 816 /* reset the merge section size back to zero */ 817 ms->s.size = 0; 818 819 /* reset the count of relocation entries for this merged section */ 820 if(output_for_dyld){ 821 ms->nlocrel = 0; 822 ms->nextrel = 0; 823 } 824 else if(save_reloc){ 825 nreloc -= ms->s.nreloc; 826 ms->s.nreloc = 0; 827 } 828} 829