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 do relocation for the ppc. 28 */ 29#include <stdlib.h> 30#if !(defined(KLD) && defined(__STATIC__)) 31#include <stdio.h> 32#include <mach/mach.h> 33#else /* defined(KLD) && defined(__STATIC__) */ 34#include <mach/kern_return.h> 35#endif /* !(defined(KLD) && defined(__STATIC__)) */ 36#include <string.h> 37#include <stdarg.h> 38#include <mach-o/loader.h> 39#include <mach-o/reloc.h> 40#include <mach-o/ppc/reloc.h> 41#include <mach-o/nlist.h> 42#include "stuff/bool.h" 43#include "stuff/bytesex.h" 44 45#include "ld.h" 46#include "live_refs.h" 47#include "objects.h" 48#include "sections.h" 49#include "pass1.h" 50#include "symbols.h" 51#include "pass2.h" 52#include "generic_reloc.h" 53#include "ppc_reloc.h" 54#include "indirect_sections.h" 55#include "dylibs.h" 56 57#define U_ABS(l) (((long)(l))<0 ? (unsigned long)(-(l)) : (l)) 58 59/* 60 * ppc_reloc() relocates the contents of the specified section for the 61 * relocation entries using the section map from the current object (cur_obj). 62 * 63 * Or if refs is not NULL it is being called by to get the addresses or 64 * merged_symbols from the item being referenced by the relocation entry(s) at 65 * reloc_index. This is used by mark_fine_relocs_references_live() when 66 * -dead_strip is specified to determined what is being referenced and is only 67 * called when all sections have fine_relocs (that is why refs is only filled 68 * in when nfine_relocs != 0). When refs is not NULL, only refs is filled in 69 * and returned and the contents are not relocated. 70 */ 71__private_extern__ 72void 73ppc_reloc( 74char *contents, 75struct relocation_info *relocs, 76struct section_map *section_map, 77struct live_refs *refs, 78unsigned long reloc_index) 79{ 80 unsigned long i, j, symbolnum, value, input_pc, output_pc; 81 unsigned long instruction, immediate; 82 struct nlist *nlists; 83 char *strings; 84 enum bool force_extern_reloc; 85 struct undefined_map *undefined_map; 86 struct merged_symbol *merged_symbol; 87 struct section_map *local_map, *pair_local_map; 88 struct relocation_info *reloc, *pair_reloc; 89 struct scattered_relocation_info *sreloc, *spair_reloc; 90 unsigned long r_address, r_symbolnum, r_pcrel, r_length, r_extern, 91 r_scattered, r_value, pair_r_symbolnum, pair_r_value; 92 enum reloc_type_ppc r_type, pair_r_type; 93 unsigned long other_half; 94 unsigned long offset; 95 unsigned long br14_disp_sign; 96 97#if defined(DEBUG) || defined(RLD) 98 /* 99 * The compiler "warnings: ... may be used uninitialized in this 100 * function" can safely be ignored 101 */ 102 merged_symbol = NULL; 103 local_map = NULL; 104 instruction = 0; 105 other_half = 0; 106 immediate = 0; 107 offset = 0; 108 pair_r_symbolnum = 0; 109 pair_r_value = 0; 110 pair_local_map = NULL; 111#endif /* defined(DEBUG) || defined(RLD) */ 112 113 if(refs != NULL) 114 memset(refs, '\0', sizeof(struct live_refs)); 115 else 116 reloc_index = 0; 117 for(i = reloc_index; i < section_map->s->nreloc; i++){ 118 br14_disp_sign = 0; 119 force_extern_reloc = FALSE; 120 /* 121 * Break out the fields of the relocation entry and set pointer to 122 * the type of relocation entry it is (for updating later). 123 */ 124 if((relocs[i].r_address & R_SCATTERED) != 0){ 125 sreloc = (struct scattered_relocation_info *)(relocs + i); 126 reloc = NULL; 127 r_scattered = 1; 128 r_address = sreloc->r_address; 129 r_pcrel = sreloc->r_pcrel; 130 r_length = sreloc->r_length; 131 r_value = sreloc->r_value; 132 r_type = (enum reloc_type_ppc)sreloc->r_type; 133 r_extern = 0; 134 /* 135 * Since the r_value field is reserved in a PPC_RELOC_PAIR 136 * type to report the correct error a check for a stray 137 * PPC_RELOC_PAIR relocation types needs to be done before 138 * it is assumed that r_value is legal. A PPC_RELOC_PAIR 139 * only follows PPC_RELOC_{HI16,LO16,HA16,LO14,JBSR,SECTDIFF, 140 * HI16_SECTDIFF,LO16_SECTDIFF,HA16_SECTDIFF} relocation types 141 * and it is an error to see one otherwise. 142 */ 143 if(r_type == PPC_RELOC_PAIR){ 144 error_with_cur_obj("stray relocation PPC_RELOC_PAIR entry " 145 "(%lu) in section (%.16s,%.16s)", i, 146 section_map->s->segname, section_map->s->sectname); 147 continue; 148 } 149 /* calculate the r_symbolnum (n_sect) from the r_value */ 150 r_symbolnum = 0; 151 for(j = 0; j < cur_obj->nsection_maps; j++){ 152 if(r_value >= cur_obj->section_maps[j].s->addr && 153 r_value < cur_obj->section_maps[j].s->addr + 154 cur_obj->section_maps[j].s->size){ 155 r_symbolnum = j + 1; 156 break; 157 } 158 } 159 if(r_symbolnum == 0){ 160 /* 161 * The edge case where the last address past then end of 162 * of the last section is referenced. 163 */ 164 for(j = 0; j < cur_obj->nsection_maps; j++){ 165 if(r_value == cur_obj->section_maps[j].s->addr + 166 cur_obj->section_maps[j].s->size){ 167 r_symbolnum = j + 1; 168 break; 169 } 170 } 171 if(r_symbolnum == 0){ 172 error_with_cur_obj("r_value (0x%x) field of relocation " 173 "entry %lu in section (%.16s,%.16s) out of range", 174 (unsigned int)r_value, i, section_map->s->segname, 175 section_map->s->sectname); 176 return; 177 } 178 } 179 } 180 else{ 181 reloc = relocs + i; 182 sreloc = NULL; 183 r_scattered = 0; 184 r_address = reloc->r_address; 185 r_pcrel = reloc->r_pcrel; 186 r_length = reloc->r_length; 187 r_extern = reloc->r_extern; 188 r_symbolnum = reloc->r_symbolnum; 189 r_type = (enum reloc_type_ppc)reloc->r_type; 190 r_value = 0; 191 } 192 /* 193 * PPC_RELOC_PAIR relocation types only follows PPC_RELOC_{HI16, 194 * LO16,HA16,LO14,JBSR,SECTDIFF,HI16_SECTDIFF,LO16_SECTDIFF, 195 * HA16_SECTDIFF} relocation types and it is an error to see one 196 * otherwise. 197 */ 198 if(r_type == PPC_RELOC_PAIR){ 199 error_with_cur_obj("stray relocation PPC_RELOC_PAIR entry " 200 "(%lu) in section (%.16s,%.16s)", i, 201 section_map->s->segname, section_map->s->sectname); 202 continue; 203 } 204 /* 205 * The r_address field is really an offset into the contents of the 206 * section and must reference something inside the section (Note 207 * that this is not the case for PPC_RELOC_PAIR entries but this 208 * can't be one with the above checks). 209 */ 210 if(r_address >= section_map->s->size){ 211 error_with_cur_obj("r_address (0x%x) field of relocation entry " 212 "%lu in section (%.16s,%.16s) out of range", 213 (unsigned int)r_address, i, section_map->s->segname, 214 section_map->s->sectname); 215 return; 216 } 217 /* 218 * If this relocation type is to have a pair make sure it is there 219 * and then break out it's fields. 220 */ 221 pair_r_type = (enum reloc_type_ppc)0; 222 pair_reloc = NULL; 223 spair_reloc = NULL; 224 if(r_type == PPC_RELOC_HI16 || r_type == PPC_RELOC_LO16 || 225 r_type == PPC_RELOC_HA16 || r_type == PPC_RELOC_LO14 || 226 r_type == PPC_RELOC_JBSR){ 227 if(i + 1 < section_map->s->nreloc){ 228 pair_reloc = relocs + i + 1; 229 if((pair_reloc->r_address & R_SCATTERED) != 0){ 230 spair_reloc = (struct scattered_relocation_info *) 231 pair_reloc; 232 pair_reloc = NULL; 233 pair_r_type = (enum reloc_type_ppc)spair_reloc->r_type; 234 if(r_type == PPC_RELOC_JBSR) 235 other_half = spair_reloc->r_value; 236 else 237 other_half = spair_reloc->r_address & 0xffff; 238 } 239 else{ 240 pair_r_type = (enum reloc_type_ppc)pair_reloc->r_type; 241 if(r_type == PPC_RELOC_JBSR) 242 other_half = pair_reloc->r_address; 243 else 244 other_half = pair_reloc->r_address & 0xffff; 245 } 246 } 247 if((pair_reloc == NULL && spair_reloc == NULL) || 248 pair_r_type != PPC_RELOC_PAIR){ 249 error_with_cur_obj("relocation entry (%lu) in section " 250 "(%.16s,%.16s) missing following associated " 251 "PPC_RELOC_PAIR entry", i, section_map->s->segname, 252 section_map->s->sectname); 253 continue; 254 } 255 } 256 else if(r_type == PPC_RELOC_SECTDIFF || 257 r_type == PPC_RELOC_LOCAL_SECTDIFF || 258 r_type == PPC_RELOC_HI16_SECTDIFF || 259 r_type == PPC_RELOC_LO16_SECTDIFF || 260 r_type == PPC_RELOC_LO14_SECTDIFF || 261 r_type == PPC_RELOC_HA16_SECTDIFF){ 262 if(r_scattered != 1){ 263 error_with_cur_obj("relocation entry (%lu) in section " 264 "(%.16s,%.16s) r_type is PPC_RELOC_SECTDIFF but " 265 "relocation entry not scattered type", i, 266 section_map->s->segname, section_map->s->sectname); 267 continue; 268 } 269 if(i + 1 < section_map->s->nreloc){ 270 pair_reloc = relocs + i + 1; 271 if((pair_reloc->r_address & R_SCATTERED) != 0){ 272 spair_reloc = (struct scattered_relocation_info *) 273 pair_reloc; 274 pair_reloc = NULL; 275 pair_r_type = (enum reloc_type_ppc)spair_reloc->r_type; 276 pair_r_value = spair_reloc->r_value; 277 other_half = spair_reloc->r_address; 278 } 279 else{ 280 error_with_cur_obj("relocation entry (%lu) in section " 281 "(%.16s,%.16s) following associated relocation " 282 "entry not scattered type", i, 283 section_map->s->segname, section_map->s->sectname); 284 continue; 285 } 286 } 287 if((pair_reloc == NULL && spair_reloc == NULL) || 288 pair_r_type != PPC_RELOC_PAIR){ 289 error_with_cur_obj("relocation entry (%lu) in section " 290 "(%.16s,%.16s) missing following associated " 291 "PPC_RELOC_PAIR entry", i, section_map->s->segname, 292 section_map->s->sectname); 293 continue; 294 } 295 /* 296 * Calculate the pair_r_symbolnum (n_sect) from the 297 * pair_r_value. 298 */ 299 pair_r_symbolnum = 0; 300 for(j = 0; j < cur_obj->nsection_maps; j++){ 301 if(pair_r_value >= cur_obj->section_maps[j].s->addr && 302 pair_r_value < cur_obj->section_maps[j].s->addr + 303 cur_obj->section_maps[j].s->size){ 304 pair_r_symbolnum = j + 1; 305 break; 306 } 307 } 308 if(pair_r_symbolnum == 0){ 309 error_with_cur_obj("r_value (0x%x) field of relocation " 310 "entry %lu in section (%.16s,%.16s) out of range", 311 (unsigned int)r_value, i + 1, section_map->s->segname, 312 section_map->s->sectname); 313 return; 314 } 315 } 316 /* 317 * If r_extern is set this relocation entry is an external entry 318 * else it is a local entry (or scattered entry). 319 */ 320 if(r_extern){ 321 /* 322 * This is an external relocation entry. So the value to be 323 * added to the item to be relocated is the value of the symbol. 324 * r_symbolnum is an index into the input file's symbol table 325 * of the symbol being refered to. The symbol must be an 326 * undefined or coalesced symbol to be used in an external 327 * relocation entry. 328 */ 329 if(r_symbolnum >= cur_obj->symtab->nsyms){ 330 error_with_cur_obj("r_symbolnum (%lu) field of external " 331 "relocation entry %lu in section (%.16s,%.16s) out of " 332 "range", r_symbolnum, i, section_map->s->segname, 333 section_map->s->sectname); 334 return; 335 } 336 symbolnum = r_symbolnum; 337 undefined_map = bsearch(&symbolnum, cur_obj->undefined_maps, 338 cur_obj->nundefineds, sizeof(struct undefined_map), 339 (int (*)(const void *, const void *))undef_bsearch); 340 if(undefined_map != NULL){ 341 merged_symbol = undefined_map->merged_symbol; 342 } 343 else{ 344 nlists = (struct nlist *)(cur_obj->obj_addr + 345 cur_obj->symtab->symoff); 346 strings = (char *)(cur_obj->obj_addr + 347 cur_obj->symtab->stroff); 348 if((nlists[symbolnum].n_type & N_EXT) != N_EXT){ 349 error_with_cur_obj("r_symbolnum (%lu) field of external" 350 " relocation entry %lu in section (%.16s,%.16s) " 351 "refers to a non-external symbol", symbolnum, i, 352 section_map->s->segname, section_map->s->sectname); 353 return; 354 } 355 /* 356 * We must allow and create references to defined global 357 * coalesced symbols with external relocation entries so 358 * that the dynamic linker can relocate all references to 359 * the same symbol. 360 */ 361 if((nlists[symbolnum].n_type & N_TYPE) == N_SECT && 362 (cur_obj->section_maps[nlists[symbolnum].n_sect-1]. 363 s->flags & SECTION_TYPE) == S_COALESCED){ 364 merged_symbol = lookup_symbol(strings + 365 nlists[symbolnum].n_un.n_strx); 366 if(merged_symbol->name_len == 0){ 367 fatal("internal error, in ppc_reloc() failed to " 368 "lookup coalesced symbol %s", strings + 369 nlists[symbolnum].n_un.n_strx); 370 } 371 } 372 else{ 373 if((nlists[symbolnum].n_type & N_EXT) != N_EXT || 374 (nlists[symbolnum].n_type & N_TYPE) != N_UNDF){ 375 error_with_cur_obj("r_symbolnum (%lu) field of " 376 "external relocation entry %lu in section " 377 "(%.16s,%.16s) refers to a non-undefined " 378 "symbol", symbolnum, i, section_map->s->segname, 379 section_map->s->sectname); 380 return; 381 } 382 print_obj_name(cur_obj); 383 fatal("internal error, in ppc_reloc() symbol index %lu " 384 "in above file not in undefined map", symbolnum); 385 } 386 } 387 if(refs == NULL && 388 ((merged_symbol->nlist.n_type & N_TYPE) == N_SECT && 389 (get_output_section(merged_symbol->nlist.n_sect)-> 390 flags & SECTION_TYPE) == S_COALESCED)){ 391 if(((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT && 392 keep_private_externs == FALSE) || 393 dynamic == FALSE || 394 (output_for_dyld && has_dynamic_linker_command)) 395 force_extern_reloc = FALSE; 396 else 397 force_extern_reloc = TRUE; 398 } 399 /* 400 * If this is an indirect symbol resolve indirection (all chains 401 * of indirect symbols have been resolved so that they point at 402 * a symbol that is not an indirect symbol). 403 */ 404 if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR) 405 merged_symbol = (struct merged_symbol *) 406 merged_symbol->nlist.n_value; 407 408 /* 409 * If we are being called only to get the references for this 410 * relocation entry fill it in and return. 411 */ 412 if(refs != NULL){ 413 refs->ref1.ref_type = LIVE_REF_SYMBOL; 414 refs->ref1.merged_symbol = merged_symbol; 415 refs->ref2.ref_type = LIVE_REF_NONE; 416 return; 417 } 418 419 /* 420 * If the symbol is undefined (or common) or a global coalesced 421 * symbol where we need to force an external relocation entry 422 * and we are not prebinding no relocation is done. Or if the 423 * output file is a multi module MH_DYLIB no relocation is done 424 * unless the symbol is a private extern or we are prebinding. 425 */ 426 if(((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF) || 427 (force_extern_reloc == TRUE && prebinding == FALSE) || 428 ((filetype == MH_DYLIB && multi_module_dylib == TRUE) && 429 (((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT) && 430 prebinding == FALSE) ) ) 431 value = 0; 432 else{ 433 value = merged_symbol->nlist.n_value; 434 /* 435 * To know which type (local or scattered) of relocation 436 * entry to convert this one to (if relocation entries are 437 * saved) the offset to be added to the symbol's value is 438 * needed to see if it reaches outside the block in which 439 * the symbol is in. In here if the offset is not zero then 440 * it is assumed to reach out of the block and a scattered 441 * relocation entry is used. 442 */ 443 input_pc = section_map->s->addr + r_address; 444 if(r_type == PPC_RELOC_VANILLA){ 445 switch(r_length){ 446 case 0: /* byte */ 447 offset = get_byte((char *)(contents + r_address)); 448 break; 449 case 1: /* word (2 byte) */ 450 offset = get_short((short *)(contents + r_address)); 451 break; 452 case 2: /* long (4 byte) */ 453 offset = get_long((long *)(contents + r_address)); 454 break; 455 default: 456 /* the error check is catched below */ 457 break; 458 } 459 if(r_pcrel) 460 offset += input_pc; 461 } 462 else{ 463 instruction = get_long((long *)(contents + r_address)); 464 switch(r_type){ 465 case PPC_RELOC_HI16: 466 offset = ((instruction & 0xffff) << 16) | 467 other_half; 468 break; 469 case PPC_RELOC_LO16: 470 offset = (other_half << 16) | 471 (instruction & 0xffff); 472 break; 473 case PPC_RELOC_HA16: 474 if((other_half & 0x00008000) != 0) 475 offset = ((instruction & 0xffff) << 16) + 476 (0xffff0000 + other_half); 477 else 478 offset = ((instruction & 0xffff) << 16) + 479 other_half; 480 break; 481 case PPC_RELOC_LO14: 482 offset = (other_half << 16) | 483 (instruction & 0xfffc); 484 break; 485 case PPC_RELOC_BR14: 486 offset = instruction & 0xfffc; 487 /* sign extend if needed */ 488 br14_disp_sign = (offset & 0x8000); 489 if(br14_disp_sign != 0) 490 offset |= 0xffff0000; 491 if(r_pcrel) 492 offset += input_pc; 493 break; 494 case PPC_RELOC_BR24: 495 offset = instruction & 0x03fffffc; 496 /* sign extend if needed */ 497 if((offset & 0x02000000) != 0) 498 offset |= 0xfc000000; 499 if(r_pcrel) 500 offset += input_pc; 501 break; 502 case PPC_RELOC_JBSR: 503 offset = other_half; 504 break; 505 default: 506 /* the error check is catched below */ 507 break; 508 } 509 } 510 } 511 512 if((merged_symbol->nlist.n_type & N_TYPE) == N_SECT) 513 output_sections[merged_symbol->nlist.n_sect]->referenced = 514 TRUE; 515 } 516 else{ 517 /* 518 * This is a local relocation entry (the value to which the item 519 * to be relocated is refering to is defined in section number 520 * r_symbolnum). So the address of that section in the input 521 * file is subtracted and the value of that section in the 522 * output is added to the item being relocated. 523 */ 524 value = 0; 525 /* 526 * If the symbol is not in any section the value to be added to 527 * the item to be relocated is the zero above and any pc 528 * relative change in value added below. 529 */ 530 if(r_symbolnum == R_ABS){ 531 /* 532 * If we are being called only to get the references for 533 * this relocation entry fill in it has none and return. 534 */ 535 if(refs != NULL){ 536 refs->ref1.ref_type = LIVE_REF_NONE; 537 refs->ref2.ref_type = LIVE_REF_NONE; 538 return; 539 } 540 } 541 else{ 542 if(r_symbolnum > cur_obj->nsection_maps){ 543 error_with_cur_obj("r_symbolnum (%lu) field of local " 544 "relocation entry %lu in section (%.16s,%.16s) " 545 "out of range", r_symbolnum, i, 546 section_map->s->segname, section_map->s->sectname); 547 return; 548 } 549 local_map = &(cur_obj->section_maps[r_symbolnum - 1]); 550 local_map->output_section->referenced = TRUE; 551 if(local_map->s->flags & S_ATTR_DEBUG){ 552 error_with_cur_obj("illegal reference to debug section," 553 " from non-debug section (%.16s,%.16s) via " 554 "relocation entry (%lu) to section (%.16s,%.16s)", 555 section_map->s->segname, section_map->s->sectname, 556 i, local_map->s->segname, local_map->s->sectname); 557 return; 558 } 559 pair_local_map = NULL; 560 if(r_type == PPC_RELOC_SECTDIFF || 561 r_type == PPC_RELOC_LOCAL_SECTDIFF || 562 r_type == PPC_RELOC_HI16_SECTDIFF || 563 r_type == PPC_RELOC_LO16_SECTDIFF || 564 r_type == PPC_RELOC_LO14_SECTDIFF || 565 r_type == PPC_RELOC_HA16_SECTDIFF){ 566 pair_local_map = 567 &(cur_obj->section_maps[pair_r_symbolnum - 1]); 568 pair_local_map->output_section->referenced = TRUE; 569 if(pair_local_map->s->flags & S_ATTR_DEBUG){ 570 error_with_cur_obj("illegal reference to debug " 571 "section, from non-debug section (%.16s,%.16s) " 572 "via relocation entry (%lu) to section (%.16s," 573 "%.16s)", section_map->s->segname, 574 section_map->s->sectname, i, 575 pair_local_map->s->segname, 576 pair_local_map->s->sectname); 577 return; 578 } 579 } 580 if(local_map->nfine_relocs == 0 && 581 (pair_local_map == NULL || 582 pair_local_map->nfine_relocs == 0) ){ 583 if(r_type == PPC_RELOC_SECTDIFF || 584 r_type == PPC_RELOC_LOCAL_SECTDIFF || 585 r_type == PPC_RELOC_HI16_SECTDIFF || 586 r_type == PPC_RELOC_LO16_SECTDIFF || 587 r_type == PPC_RELOC_LO14_SECTDIFF || 588 r_type == PPC_RELOC_HA16_SECTDIFF){ 589 value = - local_map->s->addr 590 + (local_map->output_section->s.addr + 591 local_map->offset) 592 + pair_local_map->s->addr 593 - (pair_local_map->output_section->s.addr + 594 pair_local_map->offset); 595 } 596 else{ 597 value = - local_map->s->addr 598 + (local_map->output_section->s.addr + 599 local_map->offset); 600 } 601 } 602 else{ 603 /* 604 * For items to be relocated that refer to a section 605 * with fine relocation the value is set (not adjusted 606 * with addition). So the new value is directly 607 * calculated from the old value. 608 */ 609 if(r_pcrel){ 610 input_pc = section_map->s->addr + 611 r_address; 612 if(section_map->nfine_relocs == 0) 613 output_pc = section_map->output_section->s.addr 614 + section_map->offset + 615 r_address; 616 else 617 output_pc = section_map->output_section->s.addr 618 + 619 fine_reloc_output_offset(section_map, 620 r_address); 621 } 622 else{ 623 input_pc = 0; 624 output_pc = 0; 625 } 626 /* 627 * Get the value of the expresion of the item to be 628 * relocated. 629 */ 630 if(r_type == PPC_RELOC_VANILLA || 631 r_type == PPC_RELOC_SECTDIFF || 632 r_type == PPC_RELOC_LOCAL_SECTDIFF){ 633 switch(r_length){ 634 case 0: /* byte */ 635 value = get_byte((char *)(contents + 636 r_address)); 637 break; 638 case 1: /* word (2 byte) */ 639 value = get_short((short *)(contents + 640 r_address)); 641 break; 642 case 2: /* long (4 byte) */ 643 value = get_long((long *)(contents + 644 r_address)); 645 break; 646 default: 647 /* the error check is catched below */ 648 break; 649 } 650 } 651 else{ 652 instruction = get_long((long *)(contents + 653 r_address)); 654 switch(r_type){ 655 case PPC_RELOC_HI16: 656 case PPC_RELOC_HI16_SECTDIFF: 657 value = ((instruction & 0xffff) << 16) | 658 other_half; 659 break; 660 case PPC_RELOC_LO16: 661 case PPC_RELOC_LO16_SECTDIFF: 662 value = (other_half << 16) | 663 (instruction & 0xffff); 664 break; 665 case PPC_RELOC_HA16: 666 case PPC_RELOC_HA16_SECTDIFF: 667 if((other_half & 0x00008000) != 0) 668 value = ((instruction & 0xffff) << 16) + 669 (0xffff0000 + other_half); 670 else 671 value = ((instruction & 0xffff) << 16) + 672 other_half; 673 break; 674 case PPC_RELOC_LO14: 675 case PPC_RELOC_LO14_SECTDIFF: 676 value = (other_half << 16) | 677 (instruction & 0xfffc); 678 break; 679 case PPC_RELOC_BR14: 680 value = instruction & 0xfffc; 681 br14_disp_sign = (value & 0x8000); 682 if(br14_disp_sign != 0) 683 value |= 0xffff0000; 684 break; 685 case PPC_RELOC_BR24: 686 value = instruction & 0x03fffffc; 687 if((value & 0x02000000) != 0) 688 value |= 0xfc000000; 689 break; 690 case PPC_RELOC_JBSR: 691 value = other_half; 692 break; 693 default: 694 /* the error check is catched below */ 695 break; 696 } 697 } 698 if(r_type == PPC_RELOC_SECTDIFF || 699 r_type == PPC_RELOC_LOCAL_SECTDIFF || 700 r_type == PPC_RELOC_HI16_SECTDIFF || 701 r_type == PPC_RELOC_LO16_SECTDIFF || 702 r_type == PPC_RELOC_LO14_SECTDIFF || 703 r_type == PPC_RELOC_HA16_SECTDIFF){ 704 /* 705 * For PPC_RELOC_SECTDIFF's the item to be 706 * relocated, in value, is the value of the 707 * expression: 708 * r_value - pair_r_value + offset 709 * To set the value of the relocated expression, 710 * it is set from relocating the two r_value's and 711 * adding back in the offset. So here get the 712 * offset from the value of the expression. 713 */ 714 value += input_pc; /* adjust for pcrel */ 715 offset = value - r_value + pair_r_value; 716 717 /* 718 * If we are being called only to get the references 719 * for this relocation entry fill it in and return. 720 */ 721 if(refs != NULL){ 722 fine_reloc_output_ref( 723 local_map, 724 r_value - local_map->s->addr, 725 &(refs->ref1) ); 726 fine_reloc_output_ref( 727 local_map, 728 pair_r_value - local_map->s->addr, 729 &(refs->ref2) ); 730 return; 731 } 732 733 /* 734 * Now build up the value of the relocated 735 * expression one part at a time. First set the 736 * new value to the relocated r_value. 737 */ 738 if(local_map->nfine_relocs != 0){ 739 /* 740 * Check to see if this reference is legal with 741 * respect to indirect sections. 742 */ 743 legal_reference(section_map, r_address, 744 local_map, r_value - local_map->s->addr + 745 offset, i, 746 r_type != PPC_RELOC_LOCAL_SECTDIFF); 747 value = fine_reloc_output_address(local_map, 748 r_value - local_map->s->addr, 749 local_map->output_section->s.addr); 750 } 751 else{ 752 value = local_map->output_section->s.addr + 753 local_map->offset + 754 r_value - local_map->s->addr; 755 } 756 /* Second subtract the relocated pair_r_value. */ 757 if(pair_local_map->nfine_relocs != 0){ 758 /* 759 * Check to see if this reference is legal with 760 * respect to indirect sections. 761 */ 762 legal_reference(section_map, r_address, 763 pair_local_map, pair_r_value - 764 pair_local_map->s->addr, i, TRUE); 765 value -= 766 fine_reloc_output_address(pair_local_map, 767 pair_r_value - pair_local_map->s->addr, 768 pair_local_map->output_section->s.addr); 769 } 770 else{ 771 value -= 772 pair_local_map->output_section->s.addr + 773 pair_local_map->offset + 774 pair_r_value - pair_local_map->s->addr; 775 } 776 /* Third add in the offset. */ 777 value += offset; 778 value -= output_pc; /* adjust for pcrel */ 779 } 780 else{ 781 /* 782 * If the relocation entry is not a scattered 783 * relocation entry then the relocation is based on 784 * the value of value of the expresion of the item 785 * to be relocated. If it is a scattered relocation 786 * entry then the relocation is based on the r_value 787 * in the relocation entry and the offset part of 788 * the expression at the item to be relocated is 789 * extracted so it can be added after the relocation 790 * is done. 791 */ 792 value += input_pc; 793 if(r_scattered == 0){ 794 r_value = value; 795 offset = 0; 796 } 797 else{ 798 offset = value - r_value; 799 } 800 /* 801 * Check to see if this reference is legal with 802 * respect to indirect sections. 803 */ 804 legal_reference(section_map, r_address, local_map, 805 r_value - local_map->s->addr + offset, i, 806 FALSE); 807 808 /* 809 * If we are being called only to get the references 810 * for this relocation entry fill it in and return. 811 */ 812 if(refs != NULL){ 813 fine_reloc_output_ref( 814 local_map, 815 r_value - local_map->s->addr, 816 &(refs->ref1) ); 817 refs->ref2.ref_type = LIVE_REF_NONE; 818 return; 819 } 820 821 value = fine_reloc_output_address(local_map, 822 r_value - local_map->s->addr, 823 local_map->output_section->s.addr); 824 value -= output_pc; 825 value += offset; 826 } 827 if(r_type == PPC_RELOC_VANILLA || 828 r_type == PPC_RELOC_LOCAL_SECTDIFF || 829 r_type == PPC_RELOC_SECTDIFF){ 830 switch(r_length){ 831 case 0: /* byte */ 832 if( (value & 0xffffff00) && 833 ((value & 0xffffff80) != 0xffffff80)) 834 error_with_cur_obj("relocation for entry " 835 "%lu in section (%.16s,%.16s) does not " 836 "fit in 1 byte", i, 837 section_map->s->segname, 838 section_map->s->sectname); 839 set_byte((char *)(contents + r_address), value); 840 break; 841 case 1: /* word (2 byte) */ 842 if( (value & 0xffff0000) && 843 ((value & 0xffff8000) != 0xffff8000)) 844 error_with_cur_obj("relocation for entry " 845 "%lu in section (%.16s,%.16s) does not " 846 "fit in 2 bytes", i, 847 section_map->s->segname, 848 section_map->s->sectname); 849 set_short((short *)(contents + r_address), 850 value); 851 break; 852 case 2: /* long (4 byte) */ 853 set_long((long *)(contents + r_address), value); 854 break; 855 default: 856 error_with_cur_obj("r_length field of " 857 "relocation entry %lu in section (%.16s," 858 "%.16s) invalid", i, 859 section_map->s->segname, 860 section_map->s->sectname); 861 return; 862 } 863 } 864 else{ 865 switch(r_type){ 866 case PPC_RELOC_HI16: 867 case PPC_RELOC_HI16_SECTDIFF: 868 other_half = value & 0xffff; 869 instruction = (instruction & 0xffff0000) | 870 ((value >> 16) & 0xffff); 871 break; 872 case PPC_RELOC_LO16: 873 case PPC_RELOC_LO16_SECTDIFF: 874 other_half = (value >> 16) & 0xffff; 875 instruction = (instruction & 0xffff0000) | 876 (value & 0xffff); 877 break; 878 case PPC_RELOC_HA16: 879 case PPC_RELOC_HA16_SECTDIFF: 880 other_half = value & 0xffff; 881 if((value & 0x00008000) != 0) 882 instruction = (instruction & 0xffff0000) | 883 (((value + 0x00008000) >> 16) & 0xffff); 884 else 885 instruction = (instruction & 0xffff0000) | 886 ((value >> 16) & 0xffff); 887 break; 888 case PPC_RELOC_LO14: 889 case PPC_RELOC_LO14_SECTDIFF: 890 if((value & 0x3) != 0) 891 error_with_cur_obj("relocation error " 892 "for relocation entry %lu in section " 893 "(%.16s,%.16s) (relocated value not a " 894 "multiple of 4 bytes)", i, 895 section_map->s->segname, 896 section_map->s->sectname); 897 other_half = (value >> 16) & 0xffff; 898 instruction = (instruction & 0xffff0003) | 899 (value & 0xfffc); 900 break; 901 case PPC_RELOC_BR14: 902 br14_disp_sign = (instruction & 0x8000); 903 if((value & 0x3) != 0) 904 error_with_cur_obj("relocation error " 905 "for relocation entry %lu in section " 906 "(%.16s,%.16s) (displacement not a " 907 "multiple of 4 bytes)", i, 908 section_map->s->segname, 909 section_map->s->sectname); 910 if((value & 0xffff8000) != 0xffff8000 && 911 (value & 0xffff8000) != 0x00000000) 912 error_with_cur_obj("relocation overflow " 913 "for relocation entry %lu in section " 914 "(%.16s,%.16s) (displacement too large)" 915 , i, section_map->s->segname, 916 section_map->s->sectname); 917 instruction = (instruction & 0xffff0003) | 918 (value & 0xfffc); 919 /* 920 * If this is a predicted branch conditional 921 * (r_length is 3) where the branch condition 922 * is not branch always and the sign of the 923 * displacement is different after relocation 924 * then flip the Y-bit to preserve the sense of 925 * the branch prediction. 926 */ 927 if(r_length == 3 && 928 (instruction & 0xfc000000) == 0x40000000 && 929 (instruction & 0x03e00000) != 0x02800000 && 930 (instruction & 0x00008000) != br14_disp_sign) 931 instruction ^= (1 << 21); 932 break; 933 case PPC_RELOC_BR24: 934 if((value & 0x3) != 0) 935 error_with_cur_obj("relocation error " 936 "for relocation entry %lu in section " 937 "(%.16s,%.16s) (displacement not a " 938 "multiple of 4 bytes)", i, 939 section_map->s->segname, 940 section_map->s->sectname); 941 if((value & 0xfe000000) != 0xfe000000 && 942 (value & 0xfe000000) != 0x00000000) 943 error_with_cur_obj("relocation overflow " 944 "for relocation entry %lu in section " 945 "(%.16s,%.16s) (displacement too large)" 946 , i, section_map->s->segname, 947 section_map->s->sectname); 948 instruction = (instruction & 0xfc000003) | 949 (value & 0x03fffffc); 950 break; 951 case PPC_RELOC_JBSR: 952 other_half = value; 953 954 if(section_map->nfine_relocs == 0) 955 value -= section_map->output_section->s.addr 956 + section_map->offset + r_address; 957 else 958 value -= section_map->output_section->s.addr 959 + fine_reloc_output_offset( 960 section_map, r_address); 961 if(save_reloc == 0 && 962 (output_for_dyld == FALSE || r_extern == 0 || 963 (merged_symbol->nlist.n_type & N_TYPE) != 964 N_UNDF) && 965 (U_ABS(value) <= 0x01ffffff)){ 966 instruction = (instruction & 0xfc000003) | 967 (value & 0x03fffffc); 968 } 969 break; 970 default: 971 error_with_cur_obj("r_type field of " 972 "relocation entry %lu in section (%.16s," 973 "%.16s) invalid", i, 974 section_map->s->segname, 975 section_map->s->sectname); 976 return; 977 } 978 set_long((long *)(contents + r_address), 979 instruction); 980 } 981 982 goto update_reloc; 983 } 984 } 985 } 986 if(r_pcrel){ 987 /* 988 * This is a relocation entry is also pc relative which means 989 * the value of the pc will get added to it when it is executed. 990 * The item being relocated has the value of the pc in the input 991 * file subtracted from it. So to relocate this the value of 992 * pc in the input file is added and then value of the output 993 * pc is subtracted (since the offset into the section remains 994 * constant it is not added in and then subtracted out). 995 */ 996 if(section_map->nfine_relocs == 0) 997 value += + section_map->s->addr /* + r_address */ 998 - (section_map->output_section->s.addr + 999 section_map->offset /* + r_address */); 1000 else 1001 value += + section_map->s->addr + r_address 1002 - (section_map->output_section->s.addr + 1003 fine_reloc_output_offset(section_map, 1004 r_address)); 1005 } 1006 if(r_type == PPC_RELOC_VANILLA || 1007 r_type == PPC_RELOC_LOCAL_SECTDIFF || 1008 r_type == PPC_RELOC_SECTDIFF){ 1009 switch(r_length){ 1010 case 0: /* byte */ 1011 value += get_byte((char *)(contents + r_address)); 1012 if( (value & 0xffffff00) && 1013 ((value & 0xffffff80) != 0xffffff80)) 1014 error_with_cur_obj("relocation for entry %lu in section" 1015 " (%.16s,%.16s) does not fit in 1 byte", i, 1016 section_map->s->segname, section_map->s->sectname); 1017 set_byte((char *)(contents + r_address), value); 1018 break; 1019 case 1: /* word (2 byte) */ 1020 value += get_short((short *)(contents + r_address)); 1021 if( (value & 0xffff0000) && 1022 ((value & 0xffff8000) != 0xffff8000)) 1023 error_with_cur_obj("relocation for entry %lu in section" 1024 " (%.16s,%.16s) does not fit in 2 bytes", i, 1025 section_map->s->segname, section_map->s->sectname); 1026 set_short((short *)(contents + r_address), value); 1027 break; 1028 case 2: /* long (4 byte) */ 1029 value += get_long((long *)(contents + r_address)); 1030 set_long((long *)(contents + r_address), value); 1031 break; 1032 default: 1033 error_with_cur_obj("r_length field of relocation entry %lu " 1034 "in section (%.16s,%.16s) invalid", i, 1035 section_map->s->segname, section_map->s->sectname); 1036 return; 1037 } 1038 } 1039 /* 1040 * Do ppc specific relocation based on the r_type. 1041 */ 1042 else{ 1043 instruction = get_long((long *)(contents + r_address)); 1044 switch(r_type){ 1045 case PPC_RELOC_HI16: 1046 case PPC_RELOC_HI16_SECTDIFF: 1047 immediate = ((instruction & 0xffff) << 16) | 1048 other_half; 1049 immediate += value; 1050 instruction = (instruction & 0xffff0000) | 1051 ((immediate >> 16) & 0xffff); 1052 other_half = immediate & 0xffff; 1053 break; 1054 case PPC_RELOC_LO16: 1055 case PPC_RELOC_LO16_SECTDIFF: 1056 immediate = (other_half << 16) | 1057 (instruction & 0xffff); 1058 immediate += value; 1059 instruction = (instruction & 0xffff0000) | 1060 (immediate & 0xffff); 1061 other_half = (immediate >> 16) & 0xffff; 1062 break; 1063 case PPC_RELOC_HA16: 1064 case PPC_RELOC_HA16_SECTDIFF: 1065 if((other_half & 0x00008000) != 0) 1066 immediate = ((instruction & 0xffff) << 16) + 1067 (0xffff0000 + other_half); 1068 else 1069 immediate = ((instruction & 0xffff) << 16) + 1070 (other_half); 1071 immediate += value; 1072 if((immediate & 0x00008000) != 0) 1073 instruction = (instruction & 0xffff0000) | 1074 (((immediate + 0x00008000) >> 16) & 0xffff); 1075 else 1076 instruction = (instruction & 0xffff0000) | 1077 ((immediate >> 16) & 0xffff); 1078 other_half = immediate & 0xffff; 1079 break; 1080 case PPC_RELOC_LO14: 1081 case PPC_RELOC_LO14_SECTDIFF: 1082 immediate = (other_half << 16) | 1083 (instruction & 0xfffc); 1084 immediate += value; 1085 if((immediate & 0x3) != 0) 1086 error_with_cur_obj("relocation error for relocation " 1087 "entry %lu in section (%.16s,%.16s) (relocated " 1088 "value not a multiple of 4 bytes)", i, 1089 section_map->s->segname, section_map->s->sectname); 1090 instruction = (instruction & 0xffff0003) | 1091 (immediate & 0xfffc); 1092 other_half = (immediate >> 16) & 0xffff; 1093 break; 1094 case PPC_RELOC_BR14: 1095 br14_disp_sign = (instruction & 0x8000); 1096 immediate = instruction & 0xfffc; 1097 if((immediate & 0x8000) != 0) 1098 immediate |= 0xffff0000; 1099 immediate += value; 1100 if((immediate & 0x3) != 0) 1101 error_with_cur_obj("relocation error for relocation " 1102 "entry %lu in section (%.16s,%.16s) (displacement " 1103 "not a multiple of 4 bytes)", i, 1104 section_map->s->segname, section_map->s->sectname); 1105 if((immediate & 0xffff8000) != 0xffff8000 && 1106 (immediate & 0xffff8000) != 0x00000000) 1107 error_with_cur_obj("relocation overflow for relocation " 1108 "entry %lu in section (%.16s,%.16s) (displacement " 1109 "too large)", i, section_map->s->segname, 1110 section_map->s->sectname); 1111 instruction = (instruction & 0xffff0003) | 1112 (immediate & 0xfffc); 1113 /* 1114 * If this is a predicted branch conditional 1115 * (r_length is 3) where the branch condition 1116 * is not branch always and the sign of the 1117 * displacement is different after relocation 1118 * then flip the Y-bit to preserve the sense of 1119 * the branch prediction. 1120 */ 1121 if(r_length == 3 && 1122 (instruction & 0xfc000000) == 0x40000000 && 1123 (instruction & 0x03e00000) != 0x02800000 && 1124 (instruction & 0x00008000) != br14_disp_sign) 1125 instruction ^= (1 << 21); 1126 break; 1127 break; 1128 case PPC_RELOC_BR24: 1129 immediate = instruction & 0x03fffffc; 1130 if((immediate & 0x02000000) != 0) 1131 immediate |= 0xfc000000; 1132 immediate += value; 1133 if((immediate & 0x3) != 0) 1134 error_with_cur_obj("relocation error for relocation " 1135 "entry %lu in section (%.16s,%.16s) (displacement " 1136 "not a multiple of 4 bytes)", i, 1137 section_map->s->segname, section_map->s->sectname); 1138 if((immediate & 0xfe000000) != 0xfe000000 && 1139 (immediate & 0xfe000000) != 0x00000000) 1140 error_with_cur_obj("relocation overflow for relocation " 1141 "entry %lu in section (%.16s,%.16s) (displacement " 1142 "too large)", i, section_map->s->segname, 1143 section_map->s->sectname); 1144 instruction = (instruction & 0xfc000003) | 1145 (immediate & 0x03fffffc); 1146 break; 1147 case PPC_RELOC_JBSR: 1148 value += other_half; 1149 other_half = value; 1150 if(section_map->nfine_relocs == 0) 1151 value += - (section_map->output_section->s.addr + 1152 section_map->offset + r_address); 1153 else 1154 value += - (section_map->output_section->s.addr + 1155 fine_reloc_output_offset(section_map, 1156 r_address)); 1157 if(save_reloc == 0 && 1158 (output_for_dyld == FALSE || r_extern == 0 || 1159 (merged_symbol->nlist.n_type & N_TYPE) != N_UNDF) && 1160 (U_ABS(value) <= 0x01ffffff)){ 1161 instruction = (instruction & 0xfc000003) | 1162 (value & 0x03fffffc); 1163 } 1164 break; 1165 default: 1166 error_with_cur_obj("r_type field of relocation entry %lu " 1167 "in section (%.16s,%.16s) invalid", i, 1168 section_map->s->segname, section_map->s->sectname); 1169 continue; 1170 } 1171 set_long((long *)(contents + r_address), instruction); 1172 } 1173 1174 /* 1175 * If relocation entries are to be saved in the output file then 1176 * update the entry for the output file. 1177 */ 1178update_reloc: 1179 ; 1180#ifndef RLD 1181 if(save_reloc || output_for_dyld){ 1182 if(r_extern){ 1183 /* 1184 * If we are prebinding and this is a lazy pointer section 1185 * change the relocation entry to a PPC_RELOC_PB_LA_PTR 1186 * type. This stuffs the value of the lazy pointer as it 1187 * wouldn't be prebound in the r_value field. So if the 1188 * prebounding can't be used at runtime the value of the 1189 * lazy pointer will get set back to the r_value by dyld. 1190 */ 1191 if(prebinding == TRUE && 1192 (section_map->s->flags & SECTION_TYPE) == 1193 S_LAZY_SYMBOL_POINTERS){ 1194 sreloc = (struct scattered_relocation_info *)reloc; 1195 r_scattered = 1; 1196 sreloc->r_scattered = r_scattered; 1197 sreloc->r_address = r_address; 1198 sreloc->r_pcrel = r_pcrel; 1199 sreloc->r_length = r_length; 1200 sreloc->r_type = PPC_RELOC_PB_LA_PTR; 1201 sreloc->r_value = value; 1202 } 1203 /* 1204 * For external relocation entries that the symbol is 1205 * defined (not undefined or common) but not when we are 1206 * forcing an external relocation entry for a global 1207 * coalesced symbol and if the output file is not a multi 1208 * module MH_DYLIB or the symbol is a private extern, it is 1209 * changed to a local relocation entry using the section 1210 * that symbol is defined in. If still undefined or forcing 1211 * an external relocation entry for a global coalesced 1212 * symbol, then the index of the symbol in the output file 1213 * is set into r_symbolnum. 1214 */ 1215 else if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF && 1216 (merged_symbol->nlist.n_type & N_TYPE) != N_PBUD && 1217 force_extern_reloc == FALSE && 1218 ((filetype != MH_DYLIB || 1219 multi_module_dylib == FALSE) || 1220 (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)){ 1221 reloc->r_extern = 0; 1222 /* 1223 * If this symbol was in the base file then no futher 1224 * relocation can ever be done (the symbols in the base 1225 * file are fixed). Or if the symbol was an absolute 1226 * symbol. 1227 */ 1228 if(merged_symbol->definition_object == base_obj || 1229 (merged_symbol->nlist.n_type & N_TYPE) == N_ABS){ 1230 reloc->r_symbolnum = R_ABS; 1231 } 1232 else{ 1233 /* 1234 * The symbol that this relocation entry is refering 1235 * to is defined so convert this external relocation 1236 * entry into a local or scattered relocation entry. 1237 * If the item to be relocated has an offset added 1238 * to the symbol's value and the output is not for 1239 * dyld make it a scattered relocation entry else 1240 * make it a local relocation entry. 1241 */ 1242 if(offset == 0 || output_for_dyld){ 1243 reloc->r_symbolnum =merged_symbol->nlist.n_sect; 1244 } 1245 else{ 1246 sreloc = (struct scattered_relocation_info *) 1247 reloc; 1248 r_scattered = 1; 1249 sreloc->r_scattered = r_scattered; 1250 sreloc->r_address = r_address; 1251 sreloc->r_pcrel = r_pcrel; 1252 sreloc->r_length = r_length; 1253 sreloc->r_type = r_type; 1254 sreloc->r_value = merged_symbol->nlist.n_value; 1255 } 1256 } 1257 } 1258 else{ 1259 reloc->r_symbolnum = 1260 merged_symbol_output_index(merged_symbol); 1261 } 1262 } 1263 else if(r_scattered == 0){ 1264 /* 1265 * If we are prebinding and this is a lazy pointer section 1266 * change the relocation entry to a PPC_RELOC_PB_LA_PTR 1267 * type. This stuffs the value of the lazy pointer as it 1268 * wouldn't be prebound in the r_value field. So if the 1269 * prebounding can't be used at runtime the value of the 1270 * lazy pointer will get set back to the r_value by dyld. 1271 */ 1272 if(prebinding == TRUE && 1273 (section_map->s->flags & SECTION_TYPE) == 1274 S_LAZY_SYMBOL_POINTERS){ 1275 sreloc = (struct scattered_relocation_info *)reloc; 1276 r_scattered = 1; 1277 sreloc->r_scattered = r_scattered; 1278 sreloc->r_address = r_address; 1279 sreloc->r_pcrel = r_pcrel; 1280 sreloc->r_length = r_length; 1281 sreloc->r_type = PPC_RELOC_PB_LA_PTR; 1282 sreloc->r_value = value; 1283 } 1284 /* 1285 * For local relocation entries the section number is 1286 * changed to the section number in the output file. 1287 */ 1288 else if(reloc->r_symbolnum != R_ABS){ 1289 if(local_map->nfine_relocs == 0){ 1290 reloc->r_symbolnum = 1291 local_map->output_section->output_sectnum; 1292 } 1293 else{ 1294 reloc->r_symbolnum = 1295 fine_reloc_output_sectnum(local_map, 1296 r_value - local_map->s->addr); 1297 } 1298 } 1299 } 1300 else{ 1301 /* 1302 * This is a scattered relocation entry. If the output is 1303 * for dyld convert it to a local relocation entry so as 1304 * to not overflow the 24-bit r_address field in a scattered 1305 * relocation entry. The overflow would happen in 1306 * reloc_output_for_dyld() in sections.c when it adjusts 1307 * the r_address fields of the relocation entries. 1308 */ 1309 if(output_for_dyld){ 1310 reloc = (struct relocation_info *)sreloc; 1311 r_scattered = 0; 1312 reloc->r_address = r_address; 1313 reloc->r_pcrel = r_pcrel; 1314 reloc->r_extern = 0; 1315 reloc->r_length = r_length; 1316 reloc->r_type = r_type; 1317 if(local_map->nfine_relocs == 0){ 1318 reloc->r_symbolnum = 1319 local_map->output_section->output_sectnum; 1320 } 1321 else{ 1322 reloc->r_symbolnum = 1323 fine_reloc_output_sectnum(local_map, 1324 r_value - local_map->s->addr); 1325 } 1326 } 1327 else{ 1328 /* 1329 * For scattered relocation entries the r_value field is 1330 * relocated. 1331 */ 1332 if(local_map->nfine_relocs == 0) 1333 sreloc->r_value += 1334 - local_map->s->addr 1335 + local_map->output_section->s.addr + 1336 local_map->offset; 1337 else 1338 sreloc->r_value = 1339 fine_reloc_output_address(local_map, 1340 r_value - local_map->s->addr, 1341 local_map->output_section->s.addr); 1342 } 1343 } 1344 /* 1345 * If this section that the reloation is being done for has fine 1346 * relocation then the offset in the r_address field has to be 1347 * set to where it will end up in the output file. Otherwise 1348 * it simply has to have the offset to where this contents 1349 * appears in the output file. 1350 */ 1351 if(r_scattered == 0){ 1352 if(section_map->nfine_relocs == 0){ 1353 reloc->r_address += section_map->offset; 1354 } 1355 else{ 1356 reloc->r_address = fine_reloc_output_offset(section_map, 1357 r_address); 1358 } 1359 } 1360 else{ 1361 if(section_map->nfine_relocs == 0){ 1362 /* this can overflow the 24-bit sreloc->r_address */ 1363 sreloc->r_address += section_map->offset; 1364 } 1365 else{ 1366 sreloc->r_address =fine_reloc_output_offset(section_map, 1367 r_address); 1368 } 1369 } 1370 /* 1371 * If their was a paired relocation entry then update the 1372 * paired relocation entry. 1373 */ 1374 if(pair_r_type == PPC_RELOC_PAIR){ 1375 if(pair_reloc != NULL){ 1376 /* 1377 * For a PPC_RELOC_JBSR if the high bit of the "true 1378 * target" address is set we need to use scattered 1379 * relocation entry. Then place the "true target" 1380 * address in the r_value field. 1381 */ 1382 if(r_type == PPC_RELOC_JBSR && 1383 (other_half & 0x80000000) == 0x80000000){ 1384 sreloc = (struct scattered_relocation_info *) 1385 pair_reloc; 1386 r_scattered = 1; 1387 sreloc->r_scattered = r_scattered; 1388 sreloc->r_address = 0; 1389 sreloc->r_pcrel = r_pcrel; 1390 sreloc->r_length = r_length; 1391 sreloc->r_type = PPC_RELOC_PAIR; 1392 sreloc->r_value = other_half; 1393 } 1394 else{ 1395 pair_reloc->r_address = other_half; 1396 } 1397 } 1398 else if(spair_reloc != NULL){ 1399 if(r_type == PPC_RELOC_SECTDIFF || 1400 r_type == PPC_RELOC_LOCAL_SECTDIFF || 1401 r_type == PPC_RELOC_HI16_SECTDIFF || 1402 r_type == PPC_RELOC_LO16_SECTDIFF || 1403 r_type == PPC_RELOC_LO14_SECTDIFF || 1404 r_type == PPC_RELOC_HA16_SECTDIFF){ 1405 /* 1406 * For PPC_RELOC_SECTDIFF relocation entries (which 1407 * are always scattered types) the r_value field is 1408 * relocated. 1409 */ 1410 if(pair_local_map->nfine_relocs == 0) 1411 spair_reloc->r_value += 1412 - pair_local_map->s->addr 1413 + (pair_local_map->output_section->s.addr + 1414 pair_local_map->offset); 1415 else 1416 spair_reloc->r_value = 1417 fine_reloc_output_address(pair_local_map, 1418 pair_r_value - pair_local_map->s->addr, 1419 pair_local_map->output_section->s.addr); 1420 if(r_type == PPC_RELOC_HI16_SECTDIFF || 1421 r_type == PPC_RELOC_LO16_SECTDIFF || 1422 r_type == PPC_RELOC_LO14_SECTDIFF || 1423 r_type == PPC_RELOC_HA16_SECTDIFF) 1424 spair_reloc->r_address = other_half; 1425 } 1426 else{ 1427 if(r_type == PPC_RELOC_JBSR) 1428 spair_reloc->r_value = other_half; 1429 else 1430 spair_reloc->r_address = other_half; 1431 } 1432 } 1433 else{ 1434 fatal("internal error, in ppc_reloc() pair_r_type " 1435 "is PPC_RELOC_PAIR but pair_reloc and spair_reloc " 1436 "are NULL"); 1437 } 1438 } 1439 } 1440#endif /* !defined(RLD) */ 1441 /* 1442 * If their was a paired relocation entry then it has been processed 1443 * so skip it by incrementing the index of the relocation entry that 1444 * is being processed. 1445 */ 1446 if(pair_r_type == PPC_RELOC_PAIR) 1447 i++; 1448 } 1449} 1450