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