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