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/reloc.h> 43#include "stuff/arch.h" 44#include "stuff/reloc.h" 45 46#include "ld.h" 47#include "live_refs.h" 48#include "objects.h" 49#include "sections.h" 50#include "pass2.h" 51#include "generic_reloc.h" 52#include "pass1.h" 53#include "symbols.h" 54#include "layout.h" 55#include "indirect_sections.h" 56#include "dylibs.h" 57 58/* 59 * The number of indirect symbol table entries in the output file. 60 */ 61__private_extern__ unsigned long nindirectsyms = 0; 62 63/* 64 * If we are still attempting to prebind when indirect_section_merge() is 65 * called save_lazy_symbol_pointer_relocs will get set in layout.c. 66 * Between the time indirect_section_merge() gets called and the time 67 * reloc_output_for_dyld() gets called prebinding may be disabled because of 68 * various problems. But the count of relocs can't change after layout so 69 * we'll put them out anyway. 70 */ 71__private_extern__ enum bool save_lazy_symbol_pointer_relocs = FALSE; 72 73#ifndef SA_RLD 74 75static unsigned long lookup_indirect_item( 76 struct merged_symbol *merged_symbol, 77 struct object_file *obj, 78 unsigned long index, 79 struct indirect_section_data *data, 80 unsigned long stride, 81 enum bool *new); 82 83/* 84 * indirect_section_merge() merges items from symbol pointers and symbol stub 85 * sections from the specified section in the current object file (cur_obj). 86 * When redo_live is FALSE it allocates a fine relocation map and sets the 87 * fine_relocs field in the section_map to it (as well as the count). 88 * 89 * When redo_live is FALSE after all the items for this section in this object 90 * file have been merged two more things are done. First the number of 91 * relocation entries that will be in the output file is adjusted (incremented) 92 * based on which items are used from this object's section. Second the number 93 * of local symbol table entries and the size of the string table is adjusted 94 * (decremented) based on the which symbols are in the items from this object's 95 * section that will be in the resulting object file. 96 * 97 * When redo_live is TRUE it re-merges only the live items from symbol pointers 98 * and symbol stub sections from the specified section in the current object 99 * file (cur_obj). 100 */ 101__private_extern__ 102void 103indirect_section_merge( 104struct indirect_section_data *data, 105struct merged_section *ms, 106struct section *s, 107struct section_map *section_map, 108enum bool redo_live) 109{ 110 unsigned long i, j, stride, section_type, nitems, index; 111 struct fine_reloc *fine_relocs; 112 struct nlist *nlists; 113 unsigned long *indirect_symtab; 114 struct undefined_map *undefined_map; 115 struct merged_symbol *merged_symbol, *indr_symbol; 116 enum bool new; 117 118 struct relocation_info *relocs, reloc; 119 struct scattered_relocation_info *sreloc, *spair_reloc; 120 unsigned long r_address, r_pcrel, r_length, r_type, pair_r_type, r_extern, 121 r_symbolnum, r_scattered, r_value, pair; 122#ifndef RLD 123 enum bool pic; 124#endif 125 enum bool defined, force_extern_reloc; 126 unsigned long nsect; 127 char *strings; 128 129 /* to shut up compiler warning messages "may be used uninitialized" */ 130 merged_symbol = NULL; 131 132 if(s->size == 0) 133 return; 134 135 stride = 0; 136 pair_r_type = 0; 137 section_type = s->flags & SECTION_TYPE; 138 if(section_type == S_LAZY_SYMBOL_POINTERS || 139 section_type == S_NON_LAZY_SYMBOL_POINTERS){ 140 stride = 4; 141 } 142 else if(section_type == S_SYMBOL_STUBS) 143 stride = s->reserved2; 144 else 145 fatal("internal error, in indirect_section_merge() section type " 146 "(%lu) is not correct for an indirect section", section_type); 147 nitems = s->size / stride; 148 149 if(s->size % stride != 0){ 150 error_with_cur_obj("malformed object (section (%.16s,%.16s) size " 151 "is not a multiple of %lu bytes)", s->segname, s->sectname, 152 stride); 153 return; 154 } 155 if(cur_obj->dysymtab == NULL){ 156 error_with_cur_obj("malformed object (file has indirect section " 157 "(%.16s,%.16s) but no dysymtab_command)", s->segname, 158 s->sectname); 159 return; 160 } 161 if(s->reserved1 > cur_obj->dysymtab->nindirectsyms){ 162 error_with_cur_obj("malformed object (index into indirect symbol " 163 "table (reserved1 field) for indirect section (%.16s,%.16s) " 164 "past the end of the table)", s->segname, s->sectname); 165 return; 166 } 167 if(s->reserved1 + nitems > cur_obj->dysymtab->nindirectsyms){ 168 error_with_cur_obj("malformed object (indirect symbol table entries" 169 "for section (%.16s,%.16s) extends past the end of the table)", 170 s->segname, s->sectname); 171 return; 172 } 173 if(s->size == 0){ 174 if(redo_live == FALSE){ 175 section_map->fine_relocs = NULL; 176 section_map->nfine_relocs = 0; 177 } 178 return; 179 } 180#ifdef DEBUG 181 if(redo_live == FALSE){ 182 data->nfiles++; 183 data->nitems += nitems; 184 } 185#endif /* DEBUG */ 186 187 /* 188 * First deal with the contents of the indirect section and determine 189 * based on the indirect symbol for each item in the section if the 190 * contents 1) will in the output and used from this object, 2) used 191 * from a previous merged object or 3) the value of the indirect symbol 192 * will be used instead of the contents of this item. This information 193 * is encoded into the fine_reloc structures for each item. 194 */ 195 /* setup pointers to the symbol, indirect symbol and string tables */ 196 nlists = (struct nlist *)(cur_obj->obj_addr + 197 cur_obj->symtab->symoff); 198 indirect_symtab = (unsigned long *)(cur_obj->obj_addr + 199 cur_obj->dysymtab->indirectsymoff); 200 strings = cur_obj->obj_addr + cur_obj->symtab->stroff; 201 if(redo_live == FALSE){ 202 fine_relocs = allocate(nitems * sizeof(struct fine_reloc)); 203 memset(fine_relocs, '\0', nitems * sizeof(struct fine_reloc)); 204 } 205 else{ 206 fine_relocs = section_map->fine_relocs; 207 nitems = section_map->nfine_relocs; 208 } 209 for(i = 0; i < nitems; i++){ 210 /* get the indirect symbol table entry for this item */ 211 index = indirect_symtab[s->reserved1 + i]; 212 /* 213 * With strip(1), nmedit(l) or and "ld(1) -r with private externs 214 * index could be INDIRECT_SYMBOL_LOCAL or INDIRECT_SYMBOL_ABS. 215 */ 216 if(index == INDIRECT_SYMBOL_LOCAL || 217 index == INDIRECT_SYMBOL_ABS){ 218 if(redo_live == FALSE){ 219 fine_relocs[i].local_symbol = TRUE; 220 fine_relocs[i].indirect_defined = FALSE; 221 fine_relocs[i].use_contents = TRUE; 222 fine_relocs[i].input_offset = i * stride; 223 fine_relocs[i].merged_symbol = NULL; 224 if(index == INDIRECT_SYMBOL_LOCAL) 225 fine_relocs[i].indirect_symbol_local = TRUE; 226 } 227 if(redo_live == FALSE || fine_relocs[i].live == TRUE){ 228 fine_relocs[i].output_offset = lookup_indirect_item( 229 NULL, cur_obj, index, data, stride, &new); 230 } 231 else if(redo_live == TRUE && fine_relocs[i].live == FALSE){ 232 fine_relocs[i].use_contents = FALSE; 233 } 234 goto account_for_size; 235 } 236 237 /* 238 * Since the indirect symbol table entry should be for an undefined 239 * symbol use the current object's undefined symbol map to get the 240 * merged symbol. 241 */ 242 undefined_map = bsearch(&index, cur_obj->undefined_maps, 243 cur_obj->nundefineds, sizeof(struct undefined_map), 244 (int (*)(const void *, const void *))undef_bsearch); 245 if(undefined_map != NULL){ 246 merged_symbol = undefined_map->merged_symbol; 247 /* 248 * If the indirect symbol table entry is for a private extern 249 * it is an error. 250 */ 251 if((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT && 252 (merged_symbol->nlist.n_type & N_EXT) != N_EXT && 253 section_type == S_NON_LAZY_SYMBOL_POINTERS && 254 output_for_dyld == FALSE) 255 fatal("indirect symbol:%s can not be a private extern", 256 strings + nlists[index].n_un.n_strx); 257 } 258 else if((nlists[index].n_type & N_EXT) == N_EXT){ 259 /* 260 * The indirect symbol table entry was not for an undefined but 261 * it is an external symbol so get the merged_symbol for this 262 * external symbol by looking it up by name. 263 */ 264 merged_symbol = lookup_symbol(strings + 265 nlists[index].n_un.n_strx); 266 if(merged_symbol->name_len == 0) 267 fatal("interal error, indirect_section_merge() failed in " 268 "looking up external symbol"); 269 /* 270 * If this is an indirect symbol resolve indirection (all chains 271 * of indirect symbols have been resolved so that they point at 272 * a symbol that is not an indirect symbol). 273 */ 274 if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR) 275 merged_symbol = (struct merged_symbol *) 276 merged_symbol->nlist.n_value; 277 /* 278 * If the indirect symbol table entry is for a private extern 279 * it is an error. 280 */ 281 if((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT && 282 (merged_symbol->nlist.n_type & N_EXT) != N_EXT && 283 section_type == S_NON_LAZY_SYMBOL_POINTERS && 284 output_for_dyld == FALSE) 285 fatal("indirect symbol:%s can not be a private extern", 286 strings + nlists[index].n_un.n_strx); 287 } 288 else if((nlists[index].n_type & N_PEXT) == N_PEXT && 289 (nlists[index].n_type & N_EXT) != N_EXT && 290 section_type == S_NON_LAZY_SYMBOL_POINTERS && 291 output_for_dyld == FALSE) 292 /* 293 * If the indirect symbol table entry is for a private extern 294 * it is an error. 295 */ 296 fatal("indirect symbol:%s can not be a private extern", 297 strings + nlists[index].n_un.n_strx); 298 else if((nlists[index].n_type & N_STAB) == 0){ 299 /* 300 * The indirect symbol table entry was not even an external 301 * symbol but it is a local defined symbol. So the symbol table 302 * index will be use in place of the merged_symbol. This is 303 * allowed on input only for stub sections and won't be created 304 * on output. 305 */ 306 merged_symbol = NULL; 307 } 308 else{ 309 /* 310 * The indirect symbol table entry was a stab, this is an error. 311 */ 312 error_with_cur_obj("malformed object (bad indirect symbol " 313 "table entry (%ld) (symbol at index %lu is a stab)", 314 s->reserved1 + i, index); 315 return; 316 } 317 /* 318 * Now set the values in the fine relocation entry for this item 319 * based on the type of section and the merged symbol for this 320 * item's indirect symbol and if the output file is a dynamic 321 * shared library file. 322 */ 323 if(redo_live == FALSE) 324 fine_relocs[i].input_offset = i * stride; 325 if(merged_symbol == NULL){ 326 /* 327 * Indirect table entries which refer to local defined symbols 328 * are allowed only in symbol stub and lazy pointer sections so 329 * they can always be removed and never created on output. 330 */ 331 if(section_type == S_NON_LAZY_SYMBOL_POINTERS){ 332 if((nlists[index].n_type & N_PEXT) == 0){ 333 error_with_cur_obj("malformed object (bad indirect " 334 "symbol table entry (%ld) (symbol at index %lu is " 335 "not external)", s->reserved1 + i, index); 336 return; 337 } 338 /* 339 * A non-lazy symbol pointer for a private extern that no 340 * longer is external. 341 */ 342 if(redo_live == FALSE){ 343 fine_relocs[i].local_symbol = TRUE; 344 fine_relocs[i].indirect_defined = TRUE; 345 fine_relocs[i].use_contents = TRUE; 346 fine_relocs[i].merged_symbol = NULL; 347 } 348 if(redo_live == FALSE || fine_relocs[i].live == TRUE){ 349 fine_relocs[i].output_offset = lookup_indirect_item( 350 NULL, cur_obj, index, data, stride, &new); 351 } 352 else if(redo_live == TRUE && fine_relocs[i].live == FALSE){ 353 fine_relocs[i].use_contents = FALSE; 354 } 355 } 356 else{ 357 if(redo_live == FALSE){ 358 fine_relocs[i].local_symbol = TRUE; 359 fine_relocs[i].indirect_defined = TRUE; 360 fine_relocs[i].use_contents = FALSE; 361 fine_relocs[i].output_offset = index; 362 fine_relocs[i].merged_symbol = NULL; 363 } 364 } 365 } 366 else{ 367 /* 368 * If this is an indirect symbol resolve indirection (all chains 369 * of indirect symbols have been resolved so that they point at 370 * a symbol that is not an indirect symbol). 371 */ 372 if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR && 373 merged_symbol->defined_in_dylib == FALSE){ 374 /* 375 * If this N_INDR symbol was in a chain has symbols both 376 * from dylib and not from dylibs get then there was a 377 * recorded a pair for the merged symbol and the first in 378 * the chain defined in a dylib for the indr_symbol to be 379 * used. If not then merged_symbol->nlist.n_value can be 380 * used. 381 */ 382 indr_symbol = NULL; 383 for(j = 0; j < nindr_symbol_pairs; j++){ 384 if(indr_symbol_pairs[j].merged_symbol == merged_symbol) 385 indr_symbol = indr_symbol_pairs[j].indr_symbol; 386 } 387 if(indr_symbol == NULL) 388 indr_symbol = (struct merged_symbol *) 389 (merged_symbol->nlist.n_value); 390 merged_symbol = indr_symbol; 391 } 392 393 if(redo_live == FALSE) 394 fine_relocs[i].local_symbol = FALSE; 395 396 if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) || 397 merged_symbol->nlist.n_type == (N_EXT | N_PBUD) || 398 (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && 399 merged_symbol->defined_in_dylib == TRUE)){ 400 if(redo_live == FALSE){ 401 fine_relocs[i].indirect_defined = FALSE; 402 } 403 } 404 else if((merged_symbol->nlist.n_type & N_TYPE) == N_SECT && 405 (merged_symbol->definition_object->section_maps[ 406 merged_symbol->nlist.n_sect - 1]. 407 s->flags & SECTION_TYPE) == S_COALESCED && 408 filetype != MH_DYLINKER){ 409 if((output_for_dyld && 410 (has_dynamic_linker_command || filetype == MH_BUNDLE) && 411 (((merged_symbol->nlist.n_desc & N_WEAK_DEF) != 412 N_WEAK_DEF) || 413 ((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT && 414 keep_private_externs == FALSE) ) ) || 415 (filetype == MH_DYLIB && multi_module_dylib == FALSE && 416 (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT) ){ 417 if(redo_live == FALSE) 418 fine_relocs[i].indirect_defined = TRUE; 419 } 420 else{ 421 if(redo_live == FALSE) 422 fine_relocs[i].indirect_defined = FALSE; 423 } 424 } 425 else{ 426 if(redo_live == FALSE) 427 fine_relocs[i].indirect_defined = TRUE; 428 } 429 430 if((merged_symbol->nlist.n_type & N_TYPE) == N_ABS) 431 section_map->absolute_indirect_defineds = TRUE; 432 433 if((filetype == MH_DYLIB && multi_module_dylib == TRUE) || 434 section_type == S_NON_LAZY_SYMBOL_POINTERS || 435 fine_relocs[i].indirect_defined == FALSE){ 436 if(redo_live == FALSE || fine_relocs[i].live == TRUE){ 437 fine_relocs[i].output_offset = lookup_indirect_item( 438 merged_symbol, NULL, 0, data, stride, &new); 439 } 440 else if(redo_live == TRUE && fine_relocs[i].live == FALSE){ 441 new = FALSE; 442 } 443 fine_relocs[i].use_contents = new; 444 if(redo_live == FALSE) 445 fine_relocs[i].merged_symbol = merged_symbol; 446 } 447 else{ 448 if(redo_live == FALSE){ 449 fine_relocs[i].use_contents = FALSE; 450 fine_relocs[i].merged_symbol = merged_symbol; 451 } 452 } 453 } 454 455account_for_size: 456 /* 457 * If this item's contents will be used in the output file account 458 * for it's size in the merged section and it's entry in the 459 * indirect symbol table. 460 */ 461 if(fine_relocs[i].use_contents){ 462 /* 463 * When -dead_strip is specified this will be called a second 464 * time and redo_live will be TRUE. If so only account for this 465 * item if it is live. 466 */ 467 if(redo_live == FALSE || fine_relocs[i].live == TRUE){ 468 ms->s.size += stride; 469 nindirectsyms++; 470 } 471 } 472 } 473 if(redo_live == FALSE){ 474 section_map->fine_relocs = fine_relocs; 475 section_map->nfine_relocs = nitems; 476 } 477 478 /* 479 * Second deal with the relocation entries for the section in this 480 * object file. Now that it has been determined for which items the 481 * contents will be used from this object file. 482 */ 483 /* 484 * A lazy symbol pointer section must have one relocation entry for each 485 * pointer. A non-lazy symbol pointer section can't have any relocation 486 * entries (this was checked in check_cur_obj() before getting here). 487 * And a symbol stub section may have many relocation entries. 488 */ 489 if(section_type == S_LAZY_SYMBOL_POINTERS && s->nreloc != nitems){ 490 error_with_cur_obj("malformed object (lazy symbol pointer section " 491 "(%.16s,%.16s) does not have is exactly one relocation entry " 492 "for each pointer)", s->segname, s->sectname); 493 return; 494 } 495 /* 496 * This loop loops through the relocation entries and using the 497 * use_contents field (via a call to fine_reloc_offset_in_output()) 498 * of the fine_relocs just created determines how many relocation 499 * entries will be in the output for this section of this object file. 500 */ 501 relocs = (struct relocation_info *)(cur_obj->obj_addr + s->reloff); 502 for(i = 0; i < s->nreloc; i++){ 503 reloc = relocs[i]; 504 if(cur_obj->swapped && 505 section_map->input_relocs_already_swapped == FALSE) 506 swap_relocation_info(&reloc, 1, host_byte_sex); 507 /* 508 * Break out the fields of the relocation entry we need here. 509 */ 510 if((reloc.r_address & R_SCATTERED) != 0){ 511 sreloc = (struct scattered_relocation_info *)(&reloc); 512 r_scattered = 1; 513 r_address = sreloc->r_address; 514 r_pcrel = sreloc->r_pcrel; 515 r_length = sreloc->r_length; 516 r_value = sreloc->r_value; 517 r_type = sreloc->r_type; 518 r_extern = 0; 519 520 /* calculate the r_symbolnum (n_sect) from the r_value */ 521 r_symbolnum = 0; 522 for(j = 0; j < cur_obj->nsection_maps; j++){ 523 if(r_value >= cur_obj->section_maps[j].s->addr && 524 r_value < cur_obj->section_maps[j].s->addr + 525 cur_obj->section_maps[j].s->size){ 526 r_symbolnum = j + 1; 527 break; 528 } 529 } 530 if(r_symbolnum == 0){ 531 /* 532 * The edge case where the last address past then end of 533 * of the last section is referenced. 534 */ 535 for(j = 0; j < cur_obj->nsection_maps; j++){ 536 if(r_value == cur_obj->section_maps[j].s->addr + 537 cur_obj->section_maps[j].s->size){ 538 r_symbolnum = j + 1; 539 break; 540 } 541 } 542 if(r_symbolnum == 0){ 543 error_with_cur_obj("r_value (0x%x) field of relocation " 544 "entry %lu in section (%.16s,%.16s) out of range", 545 (unsigned int)r_value, i, section_map->s->segname, 546 section_map->s->sectname); 547 return; 548 } 549 } 550 } 551 else{ 552 r_scattered = 0; 553 r_address = reloc.r_address; 554 r_pcrel = reloc.r_pcrel; 555 r_length = reloc.r_length; 556 r_type = reloc.r_type; 557 r_extern = reloc.r_extern; 558 r_symbolnum = reloc.r_symbolnum; 559 } 560 /* 561 * Make sure that this is not a stray PAIR relocation entry. 562 */ 563 if(r_type == reloc_pair_r_type(arch_flag.cputype)){ 564 error_with_cur_obj("malformed object (stray relocation PAIR " 565 "entry (%lu) in section (%.16s,%.16s))", i, s->segname, 566 s->sectname); 567 continue; 568 } 569 /* 570 * The r_address field is really an offset into the contents of the 571 * section and must reference something inside the section. 572 */ 573 if(r_address >= s->size){ 574 error_with_cur_obj("malformed object (r_address (0x%x) field " 575 "of relocation entry %ld in section (%.16s,%.16s) out of " 576 "range)",(unsigned int)r_address, i,s->segname,s->sectname); 577 continue; 578 } 579 /* 580 * If this relocation entry is suppose to have a PAIR make sure it 581 * does. 582 */ 583 if(reloc_has_pair(arch_flag.cputype, r_type)){ 584 if(i + 1 < s->nreloc){ 585 reloc = relocs[i + 1]; 586 if(cur_obj->swapped && 587 section_map->input_relocs_already_swapped == FALSE) 588 swap_relocation_info(&reloc, 1, host_byte_sex); 589 if((reloc.r_address & R_SCATTERED) != 0){ 590 spair_reloc = (struct scattered_relocation_info *) 591 &reloc; 592 pair_r_type = spair_reloc->r_type; 593 } 594 else{ 595 pair_r_type = reloc.r_type; 596 } 597 } 598 if(i + 1 >= s->nreloc || 599 pair_r_type != reloc_pair_r_type(arch_flag.cputype)){ 600 error_with_cur_obj("malformed object (relocation entry " 601 "(%lu) in section (%.16s,%.16s) missing following " 602 "associated PAIR entry)", i, s->segname, s->sectname); 603 continue; 604 } 605 } 606 /* 607 * For a lazy symbol pointer section all relocation entries must be 608 * for one of the pointers or an external relocation entry and 609 * therefore the offset must be a multiple of 4 (the size of a 610 * pointer), have an r_length field of 2 (long) and a r_pcrel field 611 * of 0 (FALSE). 612 */ 613 if(section_type == S_LAZY_SYMBOL_POINTERS){ 614 if(r_address % 4 != 0){ 615 error_with_cur_obj("malformed object, illegal reference " 616 "(r_address (0x%x) field of relocation entry %lu in " 617 "lazy symbol pointer section (%.16s,%.16s) is not a " 618 "multiple of 4)", (unsigned int)r_address, i, 619 s->segname, s->sectname); 620 continue; 621 } 622 if(r_length != 2){ 623 error_with_cur_obj("malformed object, illegal reference " 624 "(r_length (0x%x) field of relocation entry %lu in " 625 "lazy symbol pointer section (%.16s,%.16s) is not 2 " 626 "(long))", (unsigned int)r_length, i, s->segname, 627 s->sectname); 628 continue; 629 } 630 if(r_pcrel != 0){ 631 error_with_cur_obj("malformed object, illegal reference " 632 "(r_pcrel (0x%x) field of relocation entry %lu in lazy " 633 "symbol pointer section (%.16s,%.16s) is not 0 " 634 "(FALSE))", (unsigned int)r_pcrel, i, s->segname, 635 s->sectname); 636 continue; 637 } 638 if(r_type != 0){ 639 error_with_cur_obj("malformed object, illegal reference " 640 "(r_type (0x%x) field of relocation entry %lu in lazy " 641 "symbol pointer section (%.16s,%.16s) is not 0 " 642 "(VANILLA))", (unsigned int)r_type, i, s->segname, 643 s->sectname); 644 continue; 645 } 646 if(r_scattered != 0){ 647 error_with_cur_obj("malformed object, illegal reference " 648 "(relocation entry %lu in lazy symbol pointer section " 649 "(%.16s,%.16s) is a scattered type)", i, s->segname, 650 s->sectname); 651 continue; 652 } 653 if(r_extern == 0 && r_symbolnum == R_ABS){ 654 error_with_cur_obj("malformed object, illegal reference " 655 "(reference from a lazy symbol pointer section (%.16s," 656 "%.16s) relocation entry (%lu) which is not to a " 657 "symbol stub section)", s->segname, s->sectname, i); 658 continue; 659 } 660 } 661 /* 662 * Assumed the symbol for this relocation entry is defined (always 663 * true for local relocation entries). Then reset the variable 664 * "defined" correctly if this is an external relocation entry based 665 * on if the symbol is defined, where it is defined and the output 666 * file type. 667 */ 668 defined = TRUE; 669 force_extern_reloc = FALSE; 670 if(output_for_dyld && r_extern){ 671 /* 672 * This is an external relocation entry. So the value to be 673 * added to the item to be relocated is the value of the symbol. 674 * r_symbolnum is an index into the input file's symbol table 675 * of the symbol being refered to. The symbol must be an 676 * undefined or coalesced symbol to be used in an external 677 * relocation entry. 678 */ 679 if(r_symbolnum >= cur_obj->symtab->nsyms){ 680 error_with_cur_obj("r_symbolnum (%lu) field of external " 681 "relocation entry %lu in section (%.16s,%.16s) out of " 682 "range", r_symbolnum, i, s->segname, s->sectname); 683 continue; 684 } 685 undefined_map = bsearch(&r_symbolnum, 686 cur_obj->undefined_maps, cur_obj->nundefineds, 687 sizeof(struct undefined_map), 688 (int (*)(const void *, const void *))undef_bsearch); 689 if(undefined_map != NULL){ 690 merged_symbol = undefined_map->merged_symbol; 691 } 692 else{ 693 if((nlists[r_symbolnum].n_type & N_EXT) != N_EXT){ 694 error_with_cur_obj("r_symbolnum (%lu) field of " 695 "external relocation entry %lu in section " 696 "(%.16s,%.16s) refers to a non-external symbol", 697 r_symbolnum, i, s->segname, s->sectname); 698 continue; 699 } 700 /* 701 * We must allow and create references to defined global 702 * coalesced symbols with external relocation entries so 703 * that the dynamic linker can relocate all references 704 * to the same symbol. 705 */ 706 if((nlists[r_symbolnum].n_type & N_TYPE) == N_SECT && 707 (cur_obj->section_maps[nlists[r_symbolnum]. 708 n_sect-1].s->flags & SECTION_TYPE) == S_COALESCED){ 709 merged_symbol = lookup_symbol(strings + 710 nlists[r_symbolnum].n_un.n_strx); 711 if(merged_symbol->name_len == 0){ 712 fatal("internal error, in indirect_section_merge() " 713 "failed to lookup coalesced symbol %s", 714 strings + nlists[r_symbolnum].n_un.n_strx); 715 } 716 if(((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT && 717 keep_private_externs == FALSE) || 718 dynamic == FALSE || 719 (output_for_dyld && has_dynamic_linker_command)) 720 force_extern_reloc = FALSE; 721 else 722 force_extern_reloc = TRUE; 723 } 724 else{ 725 if(nlists[r_symbolnum].n_type != (N_EXT | N_UNDF)){ 726 error_with_cur_obj("r_symbolnum (%lu) field of " 727 "external relocation entry %lu in section " 728 "(%.16s,%.16s) refers to a non-undefined " 729 "symbol", r_symbolnum, i, 730 section_map->s->segname, 731 section_map->s->sectname); 732 return; 733 } 734 print_obj_name(cur_obj); 735 fatal("internal error, in indirect_section_merge()" 736 " symbol index %lu in above file not in " 737 "undefined map", r_symbolnum); 738 } 739 } 740 /* 741 * If this is an indirect symbol resolve indirection (all chains 742 * of indirect symbols have been resolved so that they point at 743 * a symbol that is not an indirect symbol). 744 */ 745 if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR) 746 merged_symbol = (struct merged_symbol *) 747 merged_symbol->nlist.n_value; 748 /* 749 * For multi module dynamic shared library format files the 750 * merged sections that could have had external relocation 751 * entries must be resolved to private extern symbols. This is 752 * because for multi module MH_DYLIB files all modules share the 753 * merged sections and the entire section gets relocated when 754 * the library is mapped in. So the above restriction assures 755 * the merged section will get relocated properly and can be 756 * shared amoung library modules. 757 */ 758 if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ 759 /* 760 * If the symbol is undefined or not a private extern it is 761 * an error for in this section for a MH_DYLIB file. 762 */ 763 if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) || 764 merged_symbol->nlist.n_type == (N_EXT | N_PBUD) || 765 (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && 766 merged_symbol->defined_in_dylib == TRUE)){ 767 if(merged_symbol->error_flagged_for_dylib == 0){ 768 error_with_cur_obj("illegal undefined reference " 769 "for multi module MH_DYLIB output file to " 770 "symbol: %s from section (%.16s,%.16s) " 771 "relocation entry: %lu", 772 merged_symbol->nlist.n_un.n_name, s->segname, 773 s->sectname, i); 774 merged_symbol->error_flagged_for_dylib = 1; 775 } 776 } 777 else if((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT){ 778 if(merged_symbol->error_flagged_for_dylib == 0){ 779 error_with_cur_obj("illegal external reference for " 780 "multi module MH_DYLIB output file to symbol: " 781 "%s (not a private extern symbol) from section " 782 "(%.16s,%.16s) relocation entry: %lu", 783 merged_symbol->nlist.n_un.n_name, 784 s->segname, s->sectname, i); 785 merged_symbol->error_flagged_for_dylib = 1; 786 } 787 } 788 } 789 else{ 790 if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) || 791 merged_symbol->nlist.n_type == (N_EXT | N_PBUD) || 792 (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && 793 merged_symbol->defined_in_dylib == TRUE)) 794 defined = FALSE; 795 else 796 defined = TRUE; 797 } 798 } 799 if(reloc_has_pair(arch_flag.cputype, r_type)) 800 pair = 1; 801 else 802 pair = 0; 803#ifndef RLD 804 /* 805 * If saving relocation entries see if this relocation entry is for 806 * an item that is going to be in the output file and if so count it 807 * as one of the output relocation entries. 808 */ 809 if(output_for_dyld && 810 fine_reloc_offset_in_output(section_map, r_address)){ 811 /* 812 * Mark this section as being relocated (staticly). 813 */ 814 if(dead_strip == FALSE || redo_live == TRUE) 815 ms->relocated = TRUE; 816 if(r_extern == 0) 817 pic = (enum bool) 818 (reloc_is_sectdiff(arch_flag.cputype, r_type) || 819 (r_pcrel == 1 && r_symbolnum != NO_SECT)); 820 else 821 pic = (enum bool) 822 (r_pcrel == 1 && 823 (merged_symbol->nlist.n_type & N_TYPE) == N_SECT); 824 /* 825 * The number of relocation entries in the output file is based 826 * on one of three different cases: 827 * The output file is a multi module dynamic shared library 828 * The output file has a dynamic linker load command 829 * The output does not have a dynamic linker load command 830 */ 831 if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ 832 /* 833 * For multi module dynamic shared library files there are 834 * no external relocation entries that will be left as 835 * external as checked above. Only non-position-independent 836 * local relocation entries are kept. Modules of multi 837 * module dylibs are not linked together and can only be 838 * slid keeping all sections relative to each other the 839 * same. 840 */ 841 if(pic == FALSE) 842 ms->nlocrel += 1 + pair; 843 } 844 else if(has_dynamic_linker_command){ 845 /* 846 * For an file with a dynamic linker load command only 847 * external relocation entries for undefined symbols are 848 * kept. This output file is a fixed address and can't be 849 * moved. 850 */ 851 if(r_extern){ 852 if(defined == FALSE) 853 ms->nextrel += 1 + pair; 854 /* 855 * As of the PowerPC port, relocation entries for 856 * lazy symbol pointers can be external so when the 857 * the symbol is defined if we are doing prebinding and 858 * this is for a lazy symbol pointer then this will 859 * turn into a local relocation entry and we save it 860 * so we can undo the prebinding if needed. 861 */ 862 else if(save_lazy_symbol_pointer_relocs == TRUE && 863 section_type == S_LAZY_SYMBOL_POINTERS) 864 ms->nlocrel += 1 + pair; 865 } 866 /* 867 * Even though the file can't be moved we may be trying to 868 * prebind. If we are prebinging we need the local 869 * relocation entries for lazy symbol pointers to be saved 870 * so dyld will have the info to undo this if it fails. 871 */ 872 else if(save_lazy_symbol_pointer_relocs == TRUE && 873 section_type == S_LAZY_SYMBOL_POINTERS){ 874 ms->nlocrel += 1 + pair; 875 } 876 } 877 else{ 878 /* 879 * For an file without a dynamic linker load command 880 * external relocation entries for undefined symbols are 881 * kept and locals that are non-position-independent are 882 * kept. This file can only be slid keeping all sections 883 * relative to each other the same. 884 */ 885 if(r_extern){ 886 if(defined == FALSE || force_extern_reloc == TRUE) 887 ms->nextrel += 1 + pair; 888 else if(pic == FALSE) 889 ms->nlocrel += 1 + pair; 890 } 891 else if(pic == FALSE) 892 ms->nlocrel += 1 + pair; 893 } 894 } 895 else if(save_reloc && 896 fine_reloc_offset_in_output(section_map, r_address)){ 897 ms->s.nreloc += 1 + pair; 898 nreloc += 1 + pair; 899 } 900#endif /* !defined(RLD) */ 901 i += pair; 902 } 903 /* 904 * If the the number of relocation entries is not zero mark this section 905 * as being relocated (staticly). 906 */ 907 if(ms->s.nreloc != 0){ 908 if(dead_strip == FALSE || redo_live == TRUE) 909 ms->relocated = TRUE; 910 } 911 912 /* 913 * Third deal with the symbol table entries for local symbols and N_STAB 914 * symbols in this section in this object file. Now that it has been 915 * determined for which items the contents will be used from this 916 * object file. If when -dead_strip is specified we have to wait to 917 * do this until we are called a second time when redo_live is TRUE and 918 * all the fine_relocs have had their live field set. 919 */ 920 if(dead_strip == FALSE || redo_live == TRUE){ 921 /* determine the section number this has in this object */ 922 for(nsect = 0; nsect < cur_obj->nsection_maps; nsect++) 923 if(s == cur_obj->section_maps[nsect].s) 924 break; 925 nsect++; /* section numbers start at 1 (not zero) */ 926 /* set up a pointer to the string table */ 927 strings = (char *)(cur_obj->obj_addr + cur_obj->symtab->stroff); 928 discard_local_symbols_for_section(nsect, nlists, strings, s, 929 section_map); 930 } 931} 932 933static 934unsigned long 935lookup_indirect_item( 936struct merged_symbol *merged_symbol, 937struct object_file *obj, 938unsigned long index, 939struct indirect_section_data *data, 940unsigned long stride, 941enum bool *new) 942{ 943 unsigned long hashval, output_offset; 944 struct indirect_item_block **p, *indirect_item_block; 945 struct indirect_item *indirect_item; 946 struct indirect_item_bucket *bp; 947 948 if(data->hashtable == NULL){ 949 data->hashtable = allocate(sizeof(struct indirect_item_bucket *) * 950 INDIRECT_SECTION_HASHSIZE); 951 memset(data->hashtable, '\0', 952 sizeof(struct indirect_item_bucket *) * 953 INDIRECT_SECTION_HASHSIZE); 954 } 955#if defined(DEBUG) && defined(PROBE_COUNT) 956 data->nprobes++; 957#endif 958 hashval = ((unsigned long)merged_symbol) % INDIRECT_SECTION_HASHSIZE; 959 for(bp = data->hashtable[hashval]; bp; bp = bp->next){ 960#if defined(DEBUG) && defined(PROBE_COUNT) 961 data->nprobes++; 962#endif 963 if(bp->indirect_item->merged_symbol == merged_symbol && 964 merged_symbol != NULL){ 965 *new = FALSE; 966 return(bp->output_offset); 967 } 968 } 969 970 bp = allocate(sizeof(struct indirect_item_bucket)); 971 output_offset = 0; 972 for(p = &(data->indirect_item_blocks); 973 *p ; 974 p = &(indirect_item_block->next)){ 975 976 indirect_item_block = *p; 977 if(indirect_item_block->used != INDIRECT_SECTION_BLOCK_SIZE){ 978 indirect_item = indirect_item_block->indirect_items + 979 indirect_item_block->used; 980 indirect_item->merged_symbol = merged_symbol; 981 indirect_item->obj = obj; 982 indirect_item->index = index; 983 984 bp->indirect_item = indirect_item; 985 bp->output_offset = output_offset + 986 indirect_item_block->used * stride; 987 bp->next = data->hashtable[hashval]; 988 data->hashtable[hashval] = bp; 989 990 indirect_item_block->used++; 991 *new = TRUE; 992 return(bp->output_offset); 993 } 994 output_offset += indirect_item_block->used * stride; 995 } 996 *p = allocate(sizeof(struct indirect_item_block)); 997 indirect_item_block = *p; 998 indirect_item = indirect_item_block->indirect_items; 999 indirect_item->merged_symbol = merged_symbol; 1000 indirect_item->obj = obj; 1001 indirect_item->index = index; 1002 indirect_item_block->used = 1; 1003 indirect_item_block->next = NULL; 1004 1005 bp->indirect_item = indirect_item; 1006 bp->output_offset = output_offset; 1007 bp->next = data->hashtable[hashval]; 1008 data->hashtable[hashval] = bp; 1009 1010 *new = TRUE; 1011 return(bp->output_offset); 1012} 1013 1014/* 1015 * indirect_section_order() enters indirect symbols from the order_file from the 1016 * merged section structure. Since this is called before any call to 1017 * indirect_section_merge() and it enters the indirect symbols in the order of 1018 * the file it causes the section to be ordered. 1019 */ 1020__private_extern__ 1021void 1022indirect_section_order( 1023struct indirect_section_data *data, 1024struct merged_section *ms) 1025{ 1026#ifndef RLD 1027 kern_return_t r; 1028#ifdef __MWERKS__ 1029 struct indirect_section_data *dummy1; 1030 struct merged_section *dummy2; 1031 dummy1 = data; 1032 dummy2 = ms; 1033#endif 1034 1035 warning("section ordering for indirect sections not supported (" 1036 "-sectorder %s %s %s ignored)", ms->s.segname, ms->s.sectname, 1037 ms->order_filename); 1038 /* 1039 * Deallocate the memory for the load order file now that it is 1040 * nolonger needed. 1041 */ 1042 if((r = vm_deallocate(mach_task_self(), (vm_address_t) 1043 ms->order_addr, ms->order_size)) != KERN_SUCCESS) 1044 mach_fatal(r, "can't vm_deallocate() memory for -sectorder " 1045 "file: %s for section (%.16s,%.16s)", 1046 ms->order_filename, ms->s.segname, 1047 ms->s.sectname); 1048 ms->order_addr = NULL; 1049#else /* RLD */ 1050#ifdef __MWERKS__ 1051 struct indirect_section_data *dummy1; 1052 struct merged_section *dummy2; 1053 dummy1 = data; 1054 dummy2 = ms; 1055#endif 1056#endif /* RLD */ 1057} 1058 1059/* 1060 * indirect_section_reset_live() is called when -dead_strip is specified after 1061 * the indirect sections the input objects are merged. It clears out 1062 * the indirect_section_data so the live indirect items can be re-merged (by 1063 * later calling indirect_section_merge() with redo_live == TRUE. 1064 */ 1065__private_extern__ 1066void 1067indirect_section_reset_live( 1068struct indirect_section_data *data, 1069struct merged_section *ms) 1070{ 1071 /* 1072 * reset the total number of indirect symbol table entries in the 1073 * output file. Really needs to happen only once. But placing it 1074 * here it will get reset once for each merged section. 1075 */ 1076 nindirectsyms = 0; 1077 1078 /* reset the merge section size back to zero */ 1079 ms->s.size = 0; 1080 1081 /* reset the count of relocation entries for this merged section */ 1082 if(output_for_dyld){ 1083 ms->nlocrel = 0; 1084 ms->nextrel = 0; 1085 } 1086 else if(save_reloc){ 1087 nreloc -= ms->s.nreloc; 1088 ms->s.nreloc = 0; 1089 } 1090 1091 /* clear out the previously merged data */ 1092 indirect_section_free(data); 1093} 1094 1095#ifndef RLD 1096/* 1097 * indirect_live_ref() is called by walk_references() as part of the live 1098 * marking pass when -dead_strip is specified to get the ref when a 1099 * indirect section is referenced. The reference is specified by fine_reloc, 1100 * map and obj. This routine sets the ref struct passed to it for the 1101 * reference if there is one and returns TRUE else it returns FALSE. 1102 */ 1103__private_extern__ 1104enum bool 1105indirect_live_ref( 1106struct fine_reloc *fine_reloc, 1107struct section_map *map, 1108struct object_file *obj, 1109struct ref *r) 1110{ 1111 unsigned long index, value, r_symbolnum; 1112 struct nlist *nlists; 1113 char *contents; 1114 1115 if((map->s->flags & SECTION_TYPE) != S_SYMBOL_STUBS && 1116 (map->s->flags & SECTION_TYPE) != S_LAZY_SYMBOL_POINTERS && 1117 (map->s->flags & SECTION_TYPE) != S_NON_LAZY_SYMBOL_POINTERS) 1118 fatal("internal error: indirect_live_ref() called with map not for " 1119 "indirect section"); 1120 1121 if(fine_reloc->local_symbol == TRUE){ 1122 /* 1123 * Indirect table entries which refer to local defined symbols are 1124 * allowed only in symbol stub and lazy pointer sections so they can 1125 * always be removed and never created on output. When this happens 1126 * the fine_reloc has use_contents set to FALSE and the symbol index 1127 * of the local symbol stored in output_offset. 1128 */ 1129 if(fine_reloc->use_contents == FALSE){ 1130 if((map->s->flags & SECTION_TYPE) == 1131 S_NON_LAZY_SYMBOL_POINTERS){ 1132 fatal("internal error: indirect_live_ref() called " 1133 "with fine_reloc for non-lazy pointer with " 1134 "local_symbol == TRUE and use_contents == " 1135 "FALSE"); 1136 } 1137 index = fine_reloc->output_offset; 1138 nlists = (struct nlist *)(obj->obj_addr + 1139 obj->symtab->symoff); 1140 r_symbolnum = r_symbolnum_from_r_value(nlists[index].n_value, 1141 obj); 1142 r->map = &(obj->section_maps[r_symbolnum - 1]); 1143 r->fine_reloc = fine_reloc_for_input_offset(r->map, 1144 nlists[index].n_value - r->map->s->addr); 1145 r->obj = obj; 1146 r->merged_symbol = NULL; 1147 return(TRUE); 1148 } 1149 else{ 1150 /* 1151 * Both local_symbol is TRUE and use_contents is TRUE. This 1152 * happens for INDIRECT_SYMBOL_LOCAL and INDIRECT_SYMBOL_ABS. 1153 * In this case we need to get the reference from the indirect 1154 * symbol table entry (the section contents). The contents of 1155 * the non-lazy pointer has the address of the item being 1156 * referenced. If it is INDIRECT_SYMBOL_LOCAL then it will be 1157 * in this object. If it is INDIRECT_SYMBOL_ABS we will not 1158 * return a reference. If we have a INDIRECT_SYMBOL_ABS then 1159 * we will return the ref_type set to LIVE_REF_NONE. 1160 */ 1161 if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS || 1162 (map->s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) 1163 fatal("internal error: indirect_live_ref() called " 1164 "with fine_reloc for stub or lazy pointer " 1165 "with local_symbol == TRUE and use_contents " 1166 "== TRUE"); 1167 if(fine_reloc->indirect_symbol_local == TRUE){ 1168 contents = obj->obj_addr + map->s->offset; 1169 memcpy(&value, contents + fine_reloc->input_offset, 4); 1170 if(obj->swapped) 1171 value = SWAP_LONG(value); 1172 r_symbolnum = r_symbolnum_from_r_value(value, obj); 1173 r->map = &(obj->section_maps[r_symbolnum - 1]); 1174 r->fine_reloc = fine_reloc_for_input_offset(r->map, 1175 value - r->map->s->addr); 1176 r->obj = obj; 1177 r->merged_symbol = NULL; 1178 return(TRUE); 1179 } 1180 else{ 1181 /* 1182 * Note: that fine_relocs for indirect symbol which are 1183 * INDIRECT_SYMBOL_LOCAL and INDIRECT_SYMBOL_ABS have 1184 * local_symbol set to TRUE. 1185 */ 1186 return(FALSE); 1187 } 1188 } 1189 } 1190 else{ 1191 /* 1192 * External symbols just set the ref's merged_symbol field. 1193 */ 1194 r->merged_symbol = fine_reloc->merged_symbol; 1195 r->fine_reloc = NULL; 1196 r->map = NULL; 1197 r->obj = NULL; 1198 return(TRUE); 1199 } 1200} 1201#endif /* !defined(RLD) */ 1202 1203/* 1204 * indirect_section_free() free()'s up all space used by the data block except 1205 * the data block itself. 1206 */ 1207__private_extern__ 1208void 1209indirect_section_free( 1210struct indirect_section_data *data) 1211{ 1212 unsigned long i; 1213 struct indirect_item_bucket *bp, *next_bp; 1214 struct indirect_item_block *indirect_item_block, 1215 *next_indirect_item_block; 1216 1217 /* 1218 * Free all data for this block. 1219 */ 1220 if(data->hashtable != NULL){ 1221 for(i = 0; i < INDIRECT_SECTION_HASHSIZE; i++){ 1222 for(bp = data->hashtable[i]; bp; ){ 1223 next_bp = bp->next; 1224 free(bp); 1225 bp = next_bp; 1226 } 1227 } 1228 free(data->hashtable); 1229 data->hashtable = NULL; 1230 } 1231 for(indirect_item_block = data->indirect_item_blocks; 1232 indirect_item_block; 1233 indirect_item_block = next_indirect_item_block){ 1234 1235 next_indirect_item_block = indirect_item_block->next; 1236 free(indirect_item_block); 1237 } 1238 data->indirect_item_blocks = NULL; 1239} 1240#endif /* !defined(SA_RLD) */ 1241 1242/* 1243 * legal_reference() determines if the specified reference is legal with respect 1244 * to the correct usage of symbol stub sections and lazy symbol pointer sections 1245 * (as parts of these section can be removed by the link editor and we must make 1246 * sure that these things are correctly being referenced so removing them will 1247 * produce a correct object file). The specified reference comes from a 1248 * relocation entry and is specified as section maps and offsets FROM the place 1249 * of reference to the item being refered TO and the relocation entry index 1250 * causing the reference. It returns TRUE if the reference is legal if not it 1251 * prints the appropate error message and returns FALSE. 1252 */ 1253__private_extern__ 1254enum bool 1255legal_reference( 1256struct section_map *from_map, 1257unsigned long from_offset, 1258struct section_map *to_map, 1259unsigned long to_offset, 1260unsigned long from_reloc_index, 1261enum bool sectdiff_reloc) 1262{ 1263#ifndef SA_RLD 1264 unsigned long to_section_type, from_section_type; 1265 unsigned long *indirect_symtab; 1266 struct fine_reloc *to_fine_reloc, *from_fine_reloc; 1267 struct merged_symbol *merged_symbol; 1268 unsigned long stride; 1269 1270 from_section_type = from_map->s->flags & SECTION_TYPE; 1271 /* 1272 * If we are not using the block where this reference is coming from 1273 * then we don't care if this is an illegal reference or not. 1274 */ 1275 if(from_section_type == S_COALESCED){ 1276 from_fine_reloc = 1277 fine_reloc_for_input_offset(from_map, from_offset); 1278 if(from_fine_reloc->use_contents == FALSE) 1279 return(TRUE); 1280 } 1281 1282 to_section_type = to_map->s->flags & SECTION_TYPE; 1283 /* 1284 * If this is a coalesced section then the reference may not be to this 1285 * coalesced section if the referenced block's contents is not used, 1286 * because the block could have been for a weak definition symbol. 1287 */ 1288 if(to_section_type == S_COALESCED){ 1289 to_fine_reloc = fine_reloc_for_input_offset(to_map, to_offset); 1290 /* 1291 * If this reference is to a local symbol then it is ok to reference 1292 * this coalesced symbol directly from anywhere. 1293 */ 1294 if(to_fine_reloc->local_symbol == TRUE) 1295 return(TRUE); 1296 if(to_fine_reloc->use_contents == FALSE){ 1297 merged_symbol = to_fine_reloc->merged_symbol; 1298 if(merged_symbol->defined_in_dylib == TRUE){ 1299 if(sectdiff_reloc == TRUE && dynamic == TRUE){ 1300 error_with_cur_obj("illegal reference for -dynamic " 1301 "code (section difference reference from section " 1302 "(%.16s,%.16s) relocation entry (%lu) " 1303 "to symbol: %s defined in dylib: %s)", 1304 from_map->s->segname, from_map->s->sectname, 1305 from_reloc_index, merged_symbol->nlist.n_un.n_name, 1306 merged_symbol->definition_object->file_name); 1307 return(FALSE); 1308 } 1309 to_section_type = S_REGULAR; 1310 } 1311 else if((merged_symbol->nlist.n_type & N_TYPE) == N_SECT){ 1312 if(merged_symbols_relocated == FALSE) 1313 to_section_type = merged_symbol->definition_object-> 1314 section_maps[merged_symbol->nlist.n_sect - 1].s-> 1315 flags & SECTION_TYPE; 1316 else 1317 to_section_type = 1318 pass2_nsect_merged_symbol_section_type( 1319 merged_symbol); 1320 } 1321 else{ 1322 if(sectdiff_reloc == TRUE && dynamic == TRUE){ 1323 if((merged_symbol->nlist.n_type & N_TYPE) == N_ABS){ 1324 error_with_cur_obj("illegal reference for -dynamic " 1325 "code (section difference reference from " 1326 "section (%.16s,%.16s) relocation entry (%lu) " 1327 "to absolute symbol: %s)", 1328 from_map->s->segname, from_map->s->sectname, 1329 from_reloc_index, 1330 merged_symbol->nlist.n_un.n_name); 1331 return(FALSE); 1332 } 1333 } 1334 to_section_type = S_REGULAR; 1335 } 1336 } 1337 } 1338 1339 /* 1340 * To allow the dynamic linker to use the same coalesced symbol through 1341 * out the program all references to coalesced symbols must be 1342 * relocatable to the same coalesced symbol. Most references are done 1343 * indirectly through symbol stubs and non-lazy pointers, static 1344 * initialization of data references are done directly. The only type 1345 * direct reference that can't be relocated by the dynamic linker is 1346 * a reference through a section difference relocation entry because 1347 * it is pic and does not make it the output_for_dyld files. This is 1348 * bad code generation except for the case the reference is TO the 1349 * same block the reference is from or to a block with a local symbol. 1350 * The first is usually the picbase of a routine in a coalesced section 1351 * and the second allows for unwind tables to reference private extern 1352 * coalesced symbols. 1353 */ 1354 if(dynamic == TRUE && to_section_type == S_COALESCED && 1355 sectdiff_reloc == TRUE && (from_map != to_map || 1356 fine_reloc_for_input_offset(from_map, from_offset) != 1357 fine_reloc_for_input_offset(to_map, to_offset)) && 1358 fine_reloc_for_input_offset(to_map, to_offset)->local_symbol == 1359 FALSE){ 1360 error_with_cur_obj("malformed object, illegal reference for " 1361 "-dynamic code (reference to a coalesced section (%.16s," 1362 "%.16s) from section (%.16s,%.16s) relocation entry (%lu))", 1363 to_map->s->segname, to_map->s->sectname, from_map->s->segname, 1364 from_map->s->sectname, from_reloc_index); 1365 return(FALSE); 1366 } 1367 1368 /* 1369 * If the reference is not to or from a symbol stub section or a 1370 * lazy symbol pointer section it is legal as far as used of these 1371 * sections goes. 1372 */ 1373 if(to_section_type != S_SYMBOL_STUBS && 1374 to_section_type != S_LAZY_SYMBOL_POINTERS && 1375 from_section_type != S_SYMBOL_STUBS && 1376 from_section_type != S_LAZY_SYMBOL_POINTERS) 1377 return(TRUE); 1378 1379 /* 1380 * See if this reference is to a symbol stub section. 1381 */ 1382 if(to_section_type == S_SYMBOL_STUBS){ 1383 /* 1384 * For references to a symbol stub section that are made from any 1385 * thing but a lazy pointer section the reference must be made to 1386 * the start of a symbol stub in that section. 1387 */ 1388 if(from_section_type != S_LAZY_SYMBOL_POINTERS){ 1389 if((to_offset % to_map->s->reserved2) != 0){ 1390 /* 1391 * A reference to a symbol stub section may be made from the 1392 * same symbol stub section from the same stub which is what 1393 * happens for a pic style symbol stub. 1394 */ 1395 if(from_section_type == S_SYMBOL_STUBS && 1396 from_map == to_map && 1397 from_offset / from_map->s->reserved2 == 1398 to_offset / to_map->s->reserved2) 1399 return(TRUE); 1400 error_with_cur_obj("malformed object, illegal reference " 1401 "(reference to a symbol stub not at the start of the " 1402 "stub from section (%.16s,%.16s) relocation entry " 1403 "(%lu))", from_map->s->segname, from_map->s->sectname, 1404 from_reloc_index); 1405 return(FALSE); 1406 } 1407 else 1408 return(TRUE); 1409 } 1410 else{ 1411 /* 1412 * This reference is to a symbol stub section from a lazy 1413 * pointer section. The stub being referenced and the pointer 1414 * must both have the same indirect symbol. By same in this 1415 * case we check for the same indirect symbol table entry 1416 * (that is the same index into the symbol table). 1417 */ 1418 indirect_symtab = (unsigned long *)(cur_obj->obj_addr + 1419 cur_obj->dysymtab->indirectsymoff); 1420 stride = 4; 1421 if(indirect_symtab[from_map->s->reserved1 + from_offset / 1422 stride] != 1423 indirect_symtab[to_map->s->reserved1 + to_offset / 1424 to_map->s->reserved2]){ 1425 error_with_cur_obj("malformed object, illegal reference " 1426 "(reference to symbol stub in section (%.16s,%.16s) " 1427 "at address 0x%x from lazy pointer section " 1428 "(%.16s,%.16s) relocation entry (%lu) with non-" 1429 "matching indirect symbols)", to_map->s->segname, 1430 to_map->s->sectname, 1431 (unsigned int)(to_map->s->addr + to_offset), 1432 from_map->s->segname, from_map->s->sectname, 1433 from_reloc_index); 1434 return(FALSE); 1435 } 1436 else 1437 return(TRUE); 1438 } 1439 } 1440 1441 /* 1442 * See if this reference is to a lazy symbol pointer section. 1443 */ 1444 if(to_section_type == S_LAZY_SYMBOL_POINTERS){ 1445 /* 1446 * Legal references to lazy pointer sections can only be made from a 1447 * symbol stub section. 1448 */ 1449 if(from_section_type != S_SYMBOL_STUBS){ 1450 error_with_cur_obj("malformed object, illegal reference " 1451 "(reference to a lazy symbol pointer section from section " 1452 "(%.16s,%.16s) relocation entry (%lu) which is not a " 1453 "symbol stub section)", from_map->s->segname, 1454 from_map->s->sectname, from_reloc_index); 1455 return(FALSE); 1456 } 1457 else{ 1458 /* 1459 * This reference is to a lazy pointer section from a symbol 1460 * stub section. The pointer being referenced and the stub 1461 * must both have the same indirect symbol. By same in this 1462 * case we check for the same indirect symbol table entry 1463 * (that is the same index into the symbol table). 1464 */ 1465 indirect_symtab = (unsigned long *)(cur_obj->obj_addr + 1466 cur_obj->dysymtab->indirectsymoff); 1467 stride = (arch_flag.cputype == CPU_TYPE_POWERPC64 ? 8 : 4); 1468 if(indirect_symtab[from_map->s->reserved1 + from_offset / 1469 from_map->s->reserved2] != 1470 indirect_symtab[to_map->s->reserved1 + to_offset / stride]){ 1471 error_with_cur_obj("malformed object, illegal reference " 1472 "(reference to lazy symbol pointer section " 1473 "(%.16s,%.16s) at address 0x%x from symbol stub " 1474 "section (%.16s,%.16s) relocation entry (%lu) with " 1475 "non-matching indirect symbols)", 1476 to_map->s->segname, to_map->s->sectname, 1477 (unsigned int)(to_map->s->addr + to_offset), 1478 from_map->s->segname, from_map->s->sectname, 1479 from_reloc_index); 1480 return(FALSE); 1481 } 1482 else 1483 return(TRUE); 1484 } 1485 } 1486 1487 /* 1488 * See if this reference is from a symbol stub section. 1489 */ 1490 if(from_section_type == S_SYMBOL_STUBS){ 1491 /* 1492 * At this point we know this reference from a symbol stub section 1493 * is not to lazy symbol pointer section. The only thing else this 1494 * section should be referencing is the stub binding helper routine. 1495 */ 1496 return(TRUE); 1497 } 1498#endif /* !defined(SA_RLD) */ 1499 return(TRUE); 1500} 1501 1502#ifndef SA_RLD 1503/* 1504 * output_indirect_symbols() copies the indirect symbol table into the output 1505 * file. 1506 */ 1507__private_extern__ 1508void 1509output_indirect_symbols( 1510void) 1511{ 1512 unsigned long i, nindirect_symbols; 1513 uint32_t *indirect_symbols; 1514 struct merged_segment **p, *msg; 1515 struct merged_section **content, *ms; 1516 struct indirect_section_data *data; 1517 struct indirect_item_block **q, *indirect_item_block; 1518 struct indirect_item *indirect_item; 1519 1520 if(nindirectsyms == 0) 1521 return; 1522 if(strip_level == STRIP_ALL) 1523 fatal("can't use -s with input files containing indirect symbols " 1524 "(output file must contain at least global symbols, for " 1525 "maximum stripping use -x)"); 1526 indirect_symbols = (uint32_t *)(output_addr + 1527 output_dysymtab_info.dysymtab_command.indirectsymoff); 1528 nindirect_symbols = 0; 1529 p = &merged_segments; 1530 while(*p){ 1531 msg = *p; 1532 content = &(msg->content_sections); 1533 while(*content){ 1534 ms = *content; 1535 if((ms->s.flags & SECTION_TYPE) == S_SYMBOL_STUBS || 1536 (ms->s.flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS || 1537 (ms->s.flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS){ 1538 data = (struct indirect_section_data *)ms->literal_data; 1539 ms->s.reserved1 = nindirect_symbols; 1540 for(q = &(data->indirect_item_blocks); 1541 *q ; 1542 q = &(indirect_item_block->next)){ 1543 1544 indirect_item_block = *q; 1545 for(i = 0; i < indirect_item_block->used; i++){ 1546 indirect_item = indirect_item_block-> 1547 indirect_items + i; 1548 if(indirect_item->merged_symbol != NULL){ 1549 /* 1550 * If this is a non-lazy symbol pointer section 1551 * and the symbol is a private extern then 1552 * change the indirect symbol to 1553 * INDIRECT_SYMBOL_LOCAL or 1554 * INDIRECT_SYMBOL_ABS. 1555 */ 1556 if((ms->s.flags & SECTION_TYPE) == 1557 S_NON_LAZY_SYMBOL_POINTERS && 1558 (indirect_item->merged_symbol-> 1559 nlist.n_type & N_PEXT) == N_PEXT && 1560 keep_private_externs == FALSE){ 1561 if((indirect_item->merged_symbol-> 1562 nlist.n_type & N_TYPE) == N_ABS) 1563 indirect_symbols[nindirect_symbols++] = 1564 INDIRECT_SYMBOL_ABS; 1565 else 1566 indirect_symbols[nindirect_symbols++] = 1567 INDIRECT_SYMBOL_LOCAL; 1568 } 1569 else{ 1570 indirect_symbols[nindirect_symbols++] = 1571 merged_symbol_output_index( 1572 indirect_item->merged_symbol); 1573 } 1574 } 1575 else{ 1576 if(indirect_item->index == 1577 INDIRECT_SYMBOL_LOCAL || 1578 indirect_item->index == 1579 INDIRECT_SYMBOL_ABS){ 1580 indirect_symbols[nindirect_symbols++] = 1581 indirect_item->index; 1582 } 1583 else{ 1584 indirect_symbols[nindirect_symbols++] = 1585 local_symbol_output_index( 1586 indirect_item->obj, 1587 indirect_item->index); 1588 } 1589 } 1590 } 1591 } 1592 } 1593 content = &(ms->next); 1594 } 1595 p = &(msg->next); 1596 } 1597 if(nindirect_symbols != nindirectsyms) 1598 fatal("internal error, nindirect_symbols != nindirectsyms in " 1599 "output_indirect_symbols()"); 1600 if(host_byte_sex != target_byte_sex) 1601 swap_indirect_symbols(indirect_symbols, nindirect_symbols, 1602 target_byte_sex); 1603#ifndef RLD 1604 output_flush(output_dysymtab_info.dysymtab_command.indirectsymoff, 1605 nindirect_symbols * sizeof(uint32_t)); 1606#endif /* !defined(RLD) */ 1607} 1608#endif /* !defined(SA_RLD) */ 1609