1/*
2 * Copyright (c) 1999 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 generic relocation.  Which can be used
28 * for such machines that have simple 1, 2, and 4 byte relocation lengths.
29 */
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 <stdlib.h>
37#include <string.h>
38#include <stdarg.h>
39#include <mach-o/loader.h>
40#include <mach-o/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 "indirect_sections.h"
54#include "dylibs.h"
55
56/*
57 * generic_reloc() relocates the contents of the specified section for the
58 * relocation entries using the section map from the current object (cur_obj).
59 *
60 * Or if refs is not NULL it is being called by to get the addresses or
61 * merged_symbols from the item being referenced by the relocation entry(s) at
62 * reloc_index. This is used by mark_fine_relocs_references_live() when
63 * -dead_strip is specified to determined what is being referenced and is only
64 * called when all sections have fine_relocs (that is why refs is only filled
65 * in when nfine_relocs != 0). When refs is not NULL, only refs is filled in
66 * and returned and the contents are not relocated.
67 */
68__private_extern__
69void
70generic_reloc(
71char *contents,
72struct relocation_info *relocs,
73struct section_map *section_map,
74long pcrel_at_end_of_disp,
75struct live_refs *refs,
76unsigned long reloc_index)
77{
78    unsigned long i, j, symbolnum, value, input_pc, output_pc;
79    struct nlist *nlists;
80    char *strings;
81    enum bool force_extern_reloc;
82    struct undefined_map *undefined_map;
83    struct merged_symbol *merged_symbol;
84    struct section_map *local_map, *pair_local_map;
85    struct relocation_info *reloc, *pair_reloc;
86    struct scattered_relocation_info *sreloc, *spair_reloc;
87    unsigned long r_address, r_symbolnum, r_pcrel, r_length, r_extern,
88		  r_scattered, r_value, pair_r_symbolnum, pair_r_value;
89    enum reloc_type_generic r_type, pair_r_type;
90    unsigned long offset;
91
92#if defined(DEBUG) || defined(RLD)
93	/*
94	 * The compiler "warnings: `merged_symbol', `local_map' and `offset'
95	 * may be used uninitialized in this function" can safely be ignored
96	 */
97	merged_symbol = NULL;
98	local_map = NULL;
99	offset = 0;
100	pair_r_symbolnum = 0;
101	pair_r_value = 0;
102	pair_local_map = 0;
103#endif /* DEBUG */
104
105	if(refs != NULL)
106	    memset(refs, '\0', sizeof(struct live_refs));
107	else
108	    reloc_index = 0;
109	for(i = reloc_index; i < section_map->s->nreloc; i++){
110	    force_extern_reloc = FALSE;
111	    /*
112	     * Break out the fields of the relocation entry and set pointer to
113	     * the type of relocation entry it is (for updating later).
114	     */
115	    if((relocs[i].r_address & R_SCATTERED) != 0){
116		sreloc = (struct scattered_relocation_info *)(relocs + i);
117		reloc = NULL;
118		r_scattered = 1;
119		r_address = sreloc->r_address;
120		r_pcrel = sreloc->r_pcrel;
121		r_length = sreloc->r_length;
122		r_value = sreloc->r_value;
123		r_type = (enum reloc_type_generic)sreloc->r_type;
124		r_extern = 0;
125		/*
126		 * Since the r_value field is reserved in a GENERIC_RELOC_PAIR
127		 * type to report the correct error a check for a stray
128		 * GENERIC_RELOC_PAIR relocation types needs to be done before
129		 * it is assumed that r_value is legal.  A GENERIC_RELOC_PAIR
130		 * only follows a GENERIC_RELOC_SECTDIFF or
131		 * GENERIC_RELOC_LOCAL_SECTDIFF relocation type and it
132		 * is an error to see one otherwise.
133		 */
134		if(r_type == GENERIC_RELOC_PAIR){
135		    error_with_cur_obj("stray relocation GENERIC_RELOC_PAIR "
136			"entry (%lu) in section (%.16s,%.16s)", i,
137			section_map->s->segname, section_map->s->sectname);
138		    continue;
139		}
140		/* calculate the r_symbolnum (n_sect) from the r_value */
141		r_symbolnum = 0;
142		for(j = 0; j < cur_obj->nsection_maps; j++){
143		    if(r_value >= cur_obj->section_maps[j].s->addr &&
144		       r_value < cur_obj->section_maps[j].s->addr +
145				 cur_obj->section_maps[j].s->size){
146			r_symbolnum = j + 1;
147			break;
148		    }
149		}
150		if(r_symbolnum == 0){
151		    /*
152		     * The edge case where the last address past then end of
153		     * of the last section is referenced.
154		     */
155		    for(j = 0; j < cur_obj->nsection_maps; j++){
156			if(r_value == cur_obj->section_maps[j].s->addr +
157				      cur_obj->section_maps[j].s->size){
158			    r_symbolnum = j + 1;
159			    break;
160			}
161		    }
162		    if(r_symbolnum == 0){
163			error_with_cur_obj("r_value (0x%x) field of relocation "
164			    "entry %lu in section (%.16s,%.16s) out of range",
165			    (unsigned int)r_value, i, section_map->s->segname,
166			    section_map->s->sectname);
167			return;
168		    }
169		}
170	    }
171	    else{
172		reloc = relocs + i;
173		sreloc = NULL;
174		r_scattered = 0;
175		r_address = reloc->r_address;
176		r_pcrel = reloc->r_pcrel;
177		r_length = reloc->r_length;
178		r_extern = reloc->r_extern;
179		r_symbolnum = reloc->r_symbolnum;
180		r_type = (enum reloc_type_generic)reloc->r_type;
181		r_value = 0;
182	    }
183	    /*
184	     * GENERIC_RELOC_PAIR relocation types only follow a
185	     * GENERIC_RELOC_SECTDIFF or GENERIC_RELOC_LOCAL_SECTDIFF
186	     * relocation type and it is an error to
187	     * see one otherwise.
188	     */
189	    if(r_type == GENERIC_RELOC_PAIR){
190		error_with_cur_obj("stray relocation GENERIC_RELOC_PAIR entry "
191		    "(%lu) in section (%.16s,%.16s)", i,
192		    section_map->s->segname, section_map->s->sectname);
193		continue;
194	    }
195	    /*
196	     * The r_address field is really an offset into the contents of the
197	     * section and must reference something inside the section.
198	     */
199	    if(r_address >= section_map->s->size){
200		error_with_cur_obj("r_address (0x%x) field of relocation entry "
201		    "%lu in section (%.16s,%.16s) out of range",
202		    (unsigned int)r_address, i, section_map->s->segname,
203		    section_map->s->sectname);
204		return;
205	    }
206	    /*
207	     * If this relocation type is to have a pair make sure it is there
208	     * and then break out it's fields.  Currently only the relocation
209	     * types GENERIC_RELOC_SECTDIFF and GENERIC_RELOC_LOCAL_SECTDIFF
210	     * can have a pair and itself and it's
211	     * pair must be scattered relocation types.
212	     */
213	    pair_r_type = (enum reloc_type_generic)0;
214	    pair_reloc = NULL;
215	    spair_reloc = NULL;
216	    if(r_type == GENERIC_RELOC_SECTDIFF ||
217	       r_type == GENERIC_RELOC_LOCAL_SECTDIFF){
218		if(r_scattered != 1){
219		    error_with_cur_obj("relocation entry (%lu) in section "
220			"(%.16s,%.16s) r_type is section difference but "
221			"relocation entry not scattered type", i,
222			section_map->s->segname, section_map->s->sectname);
223		    continue;
224		}
225		if(i + 1 < section_map->s->nreloc){
226		    pair_reloc = relocs + i + 1;
227		    if((pair_reloc->r_address & R_SCATTERED) != 0){
228			spair_reloc = (struct scattered_relocation_info *)
229				      pair_reloc;
230			pair_reloc = NULL;
231			pair_r_type = (enum reloc_type_generic)
232				       spair_reloc->r_type;
233			pair_r_value = spair_reloc->r_value;
234		    }
235		    else{
236			error_with_cur_obj("relocation entry (%lu) in section "
237			    "(%.16s,%.16s) following associated relocation "
238			    "entry not scattered type", i,
239			    section_map->s->segname, section_map->s->sectname);
240			continue;
241		    }
242		}
243		if((pair_reloc == NULL && spair_reloc == NULL) ||
244		   pair_r_type != GENERIC_RELOC_PAIR){
245		    error_with_cur_obj("relocation entry (%lu) in section "
246			"(%.16s,%.16s) missing following associated "
247			"GENERIC_RELOC_PAIR entry", i, section_map->s->segname,
248			section_map->s->sectname);
249		    continue;
250		}
251		/*
252		 * Calculate the pair_r_symbolnum (n_sect) from the
253		 * pair_r_value.
254		 */
255		pair_r_symbolnum = 0;
256		for(j = 0; j < cur_obj->nsection_maps; j++){
257		    if(pair_r_value >= cur_obj->section_maps[j].s->addr &&
258		       pair_r_value < cur_obj->section_maps[j].s->addr +
259				 cur_obj->section_maps[j].s->size){
260			pair_r_symbolnum = j + 1;
261			break;
262		    }
263		}
264		if(pair_r_symbolnum == 0){
265		    error_with_cur_obj("r_value (0x%x) field of relocation "
266			"entry %lu in section (%.16s,%.16s) out of range",
267			(unsigned int)r_value, i + 1, section_map->s->segname,
268			section_map->s->sectname);
269		    return;
270		}
271	    }
272	    else if(r_type != GENERIC_RELOC_VANILLA){
273		error_with_cur_obj("r_type field of relocation entry %lu in "
274		    "section (%.16s,%.16s) invalid", i, section_map->s->segname,
275		    section_map->s->sectname);
276		continue;
277	    }
278	    /*
279	     * If r_extern is set this relocation entry is an external entry
280	     * else it is a local entry (or scattered entry).
281	     */
282	    if(r_extern){
283		/*
284		 * This is an external relocation entry.  So the value to be
285		 * added to the item to be relocated is the value of the symbol.
286		 * r_symbolnum is an index into the input file's symbol table
287		 * of the symbol being refered to.  The symbol must be an
288		 * undefined or coalesced symbol to be used in an external
289		 * external relocation entry.
290		 */
291		if(r_symbolnum >= cur_obj->symtab->nsyms){
292		    error_with_cur_obj("r_symbolnum (%lu) field of external "
293			"relocation entry %lu in section (%.16s,%.16s) out of "
294			"range", r_symbolnum, i, section_map->s->segname,
295			section_map->s->sectname);
296		    return;
297		}
298		symbolnum = r_symbolnum;
299		undefined_map = bsearch(&symbolnum, cur_obj->undefined_maps,
300		    cur_obj->nundefineds, sizeof(struct undefined_map),
301		    (int (*)(const void *, const void *))undef_bsearch);
302		if(undefined_map != NULL){
303		    merged_symbol = undefined_map->merged_symbol;
304		}
305		else{
306		    nlists = (struct nlist *)(cur_obj->obj_addr +
307					      cur_obj->symtab->symoff);
308		    strings = (char *)(cur_obj->obj_addr +
309				       cur_obj->symtab->stroff);
310		    if((nlists[symbolnum].n_type & N_EXT) != N_EXT){
311			error_with_cur_obj("r_symbolnum (%lu) field of external"
312			    " relocation entry %lu in section (%.16s,%.16s) "
313			    "refers to a non-external symbol", symbolnum, i,
314			    section_map->s->segname, section_map->s->sectname);
315			return;
316		    }
317		    /*
318		     * We must allow and create references to defined global
319		     * coalesced symbols with external relocation entries so
320		     * that the dynamic linker can relocate all references to
321		     * the same symbol.
322		     */
323		    if((nlists[symbolnum].n_type & N_TYPE) == N_SECT &&
324		       (cur_obj->section_maps[nlists[symbolnum].n_sect-1].
325			s->flags & SECTION_TYPE) == S_COALESCED){
326			merged_symbol = lookup_symbol(strings +
327					     nlists[symbolnum].n_un.n_strx);
328			if(merged_symbol->name_len == 0){
329			    fatal("internal error, in generic_reloc() failed "
330				  "to lookup coalesced symbol %s", strings +
331				  nlists[symbolnum].n_un.n_strx);
332			}
333		    }
334		    else{
335			if((nlists[symbolnum].n_type & N_EXT) != N_EXT ||
336			   (nlists[symbolnum].n_type & N_TYPE) != N_UNDF){
337			    error_with_cur_obj("r_symbolnum (%lu) field of "
338				"external relocation entry %lu in section "
339				"(%.16s,%.16s) refers to a non-undefined "
340				"symbol", symbolnum, i, section_map->s->segname,
341				 section_map->s->sectname);
342			    return;
343			}
344			print_obj_name(cur_obj);
345			fatal("internal error, in generic_reloc() symbol index "
346			      "%lu in above file not in undefined map",
347			      symbolnum);
348		    }
349		}
350		if(refs == NULL &&
351		   ((merged_symbol->nlist.n_type & N_TYPE) == N_SECT &&
352		    (get_output_section(merged_symbol->nlist.n_sect)->
353		     flags & SECTION_TYPE) == S_COALESCED)){
354		    if(((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT &&
355			keep_private_externs == FALSE) ||
356		       dynamic == FALSE ||
357		       (output_for_dyld && has_dynamic_linker_command))
358			force_extern_reloc = FALSE;
359		    else
360			force_extern_reloc = TRUE;
361		}
362		/*
363		 * If this is an indirect symbol resolve indirection (all chains
364		 * of indirect symbols have been resolved so that they point at
365		 * a symbol that is not an indirect symbol).
366		 */
367		if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR)
368		    merged_symbol = (struct merged_symbol *)
369				    merged_symbol->nlist.n_value;
370
371		/*
372		 * If we are being called only to get the references for this
373		 * relocation entry fill it in and return.
374		 */
375		if(refs != NULL){
376		    refs->ref1.ref_type = LIVE_REF_SYMBOL;
377		    refs->ref1.merged_symbol = merged_symbol;
378		    refs->ref2.ref_type = LIVE_REF_NONE;
379		    return;
380		}
381
382		/*
383		 * If the symbol is undefined (or common) or a global coalesced
384		 * symbol where we need to force an external relocation entry
385		 * and we are not prebinding no relocation is done.  Or if the
386		 * output file is a multi module MH_DYLIB no relocation is done
387		 * unless the symbol is a private extern or we are prebinding.
388		 */
389		if(((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF) ||
390		   (force_extern_reloc == TRUE && prebinding == FALSE) ||
391		   ((filetype == MH_DYLIB && multi_module_dylib == TRUE) &&
392		    (((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT) &&
393		     prebinding == FALSE) ) )
394		    value = 0;
395		else{
396		    value = merged_symbol->nlist.n_value;
397		    /*
398		     * To know which type (local or scattered) of relocation
399		     * entry to convert this one to (if relocation entries are
400		     * saved) the offset to be added to the symbol's value is
401		     * needed to see if it reaches outside the block in which
402		     * the symbol is in.  In here if the offset is not zero then
403		     * it is assumed to reach out of the block and a scattered
404		     * relocation entry is used.
405		     */
406		    switch(r_length){
407		    case 0: /* byte */
408			offset = get_byte((char *)(contents + r_address));
409			break;
410		    case 1: /* word (2 byte) */
411			offset = get_short((short *)(contents + r_address));
412			break;
413		    case 2: /* long (4 byte) */
414			offset = get_long((long *)(contents + r_address));
415			break;
416		    default:
417			/* the error check is catched below */
418			break;
419		    }
420		    /*
421		     * If the offset is pc-relative then adjust it.
422		     */
423		    if(r_pcrel){
424			input_pc = section_map->s->addr + r_address;
425			if(pcrel_at_end_of_disp){
426			    switch(r_length){
427			    case 0: /* byte */
428				input_pc += sizeof(char);
429				break;
430			    case 1: /* word (2 byte) */
431				input_pc += sizeof(short);
432				break;
433			    case 2: /* long (4 byte) */
434				input_pc += sizeof(long);
435				break;
436			    default:
437				/* the error check is catched below */
438				break;
439			    }
440			}
441			offset += input_pc;
442		    }
443		}
444
445		if((merged_symbol->nlist.n_type & N_TYPE) == N_SECT)
446		    output_sections[merged_symbol->nlist.n_sect]->referenced =
447									   TRUE;
448	    }
449	    else{
450		/*
451		 * This is a local relocation entry (the value to which the item
452		 * to be relocated is refering to is defined in section number
453		 * r_symbolnum).  So the address of that section in the input
454		 * file is subtracted and the value of that section in the
455		 * output is added to the item being relocated.
456		 */
457		value = 0;
458		/*
459		 * If the symbol is not in any section the value to be added to
460		 * the item to be relocated is the zero above and any pc
461		 * relative change in value added below.
462		 */
463		if(r_symbolnum == R_ABS){
464		    /*
465		     * If we are being called only to get the references for
466		     * this relocation entry fill in it has none and return.
467		     */
468		    if(refs != NULL){
469			refs->ref1.ref_type = LIVE_REF_NONE;
470			refs->ref2.ref_type = LIVE_REF_NONE;
471			return;
472		    }
473		}
474		else{
475		    if(r_symbolnum > cur_obj->nsection_maps){
476			error_with_cur_obj("r_symbolnum (%lu) field of local "
477			    "relocation entry %lu in section (%.16s,%.16s) "
478			    "out of range", r_symbolnum, i,
479			    section_map->s->segname, section_map->s->sectname);
480			return;
481		    }
482		    local_map = &(cur_obj->section_maps[r_symbolnum - 1]);
483		    local_map->output_section->referenced = TRUE;
484		    if(local_map->s->flags & S_ATTR_DEBUG){
485			error_with_cur_obj("illegal reference to debug section,"
486			    " from non-debug section (%.16s,%.16s) via "
487			    "relocation entry (%lu) to section (%.16s,%.16s)",
488			    section_map->s->segname, section_map->s->sectname,
489			    i, local_map->s->segname, local_map->s->sectname);
490			return;
491		    }
492		    pair_local_map = NULL;
493		    if(r_type == GENERIC_RELOC_SECTDIFF ||
494		       r_type == GENERIC_RELOC_LOCAL_SECTDIFF){
495			pair_local_map =
496			    &(cur_obj->section_maps[pair_r_symbolnum - 1]);
497			pair_local_map->output_section->referenced = TRUE;
498			if(pair_local_map->s->flags & S_ATTR_DEBUG){
499			    error_with_cur_obj("illegal reference to debug "
500				"section, from non-debug section (%.16s,%.16s) "
501				"via relocation entry (%lu) to section (%.16s,"
502				"%.16s)", section_map->s->segname,
503				section_map->s->sectname, i,
504				pair_local_map->s->segname,
505				pair_local_map->s->sectname);
506			    return;
507			}
508		    }
509		    if(local_map->nfine_relocs == 0 &&
510		       (pair_local_map == NULL ||
511			pair_local_map->nfine_relocs == 0) ){
512			if(r_type == GENERIC_RELOC_SECTDIFF ||
513			   r_type == GENERIC_RELOC_LOCAL_SECTDIFF){
514			    value = - local_map->s->addr
515				    + (local_map->output_section->s.addr +
516				       local_map->offset)
517				    + pair_local_map->s->addr
518				    - (pair_local_map->output_section->s.addr +
519				       pair_local_map->offset);
520			}
521			else{
522			    value = - local_map->s->addr
523				    + (local_map->output_section->s.addr +
524				       local_map->offset);
525			}
526		    }
527		    else{
528			/*
529			 * For items to be relocated that refer to a section
530			 * with fine relocation the value is set (not adjusted
531			 * with addition).  So the new value is directly
532			 * calculated from the old value.
533			 */
534			if(r_pcrel){
535			    input_pc = section_map->s->addr +
536				       r_address;
537			    if(section_map->nfine_relocs == 0)
538				output_pc = section_map->output_section->s.addr
539					    + section_map->offset +
540					    r_address;
541			    else
542				output_pc = section_map->output_section->s.addr
543					    +
544					fine_reloc_output_offset(section_map,
545								 r_address);
546			    if(pcrel_at_end_of_disp){
547				switch(r_length){
548				case 0: /* byte */
549				    input_pc += sizeof(char);
550				    output_pc += sizeof(char);
551				    break;
552				case 1: /* word (2 byte) */
553				    input_pc += sizeof(short);
554				    output_pc += sizeof(short);
555				    break;
556				case 2: /* long (4 byte) */
557				    input_pc += sizeof(long);
558				    output_pc += sizeof(long);
559				    break;
560				default:
561				    /* the error check is catched below */
562				    break;
563				}
564			    }
565			}
566			else{
567			    input_pc = 0;
568			    output_pc = 0;
569			}
570			/*
571			 * Get the value of the expresion of the item to be
572			 * relocated (errors of r_length are checked later).
573			 */
574			switch(r_length){
575			case 0: /* byte */
576			    value = get_byte((char *)(contents + r_address));
577			    break;
578			case 1: /* word (2 byte) */
579			    value = get_short((short *)(contents + r_address));
580			    break;
581			case 2: /* long (4 byte) */
582			    value = get_long((long *)(contents + r_address));
583			    break;
584			}
585			if(r_type == GENERIC_RELOC_SECTDIFF ||
586			   r_type == GENERIC_RELOC_LOCAL_SECTDIFF){
587			    /*
588			     * For GENERIC_RELOC_SECTDIFF's the item to be
589			     * relocated, in value, is the value of the
590			     * expression:
591			     *     r_value - pair_r_value + offset
592			     * To set the value of the relocated expression,
593			     * it is set from relocating the two r_value's and
594			     * adding back in the offset.  So here get the
595			     * offset from the value of the expression.
596			     */
597			    value += input_pc; /* adjust for pcrel */
598			    offset = value - r_value + pair_r_value;
599
600			    /*
601			     * If we are being called only to get the references
602			     * for this relocation entry fill it in and return.
603			     */
604			    if(refs != NULL){
605				fine_reloc_output_ref(
606				    local_map,
607				    r_value - local_map->s->addr,
608				    &(refs->ref1) );
609				fine_reloc_output_ref(
610				    local_map,
611				    pair_r_value - local_map->s->addr,
612				    &(refs->ref2) );
613				return;
614			    }
615
616			    /*
617			     * Now build up the value of the relocated
618			     * expression one part at a time.  First set the
619			     * new value to the relocated r_value.
620			     */
621		    	    if(local_map->nfine_relocs != 0){
622				/*
623				 * Check to see if this reference is legal with
624				 * respect to indirect sections.
625				 */
626				legal_reference(section_map, r_address,
627				    local_map, r_value - local_map->s->addr +
628				    offset, i,
629				    r_type != GENERIC_RELOC_LOCAL_SECTDIFF);
630				value = fine_reloc_output_address(local_map,
631					    r_value - local_map->s->addr,
632					    local_map->output_section->s.addr);
633			    }
634			    else{
635				value = local_map->output_section->s.addr +
636					local_map->offset +
637					r_value - local_map->s->addr;
638			    }
639			    /* Second subtract the relocated pair_r_value. */
640			    if(pair_local_map->nfine_relocs != 0){
641				/*
642				 * Check to see if this reference is legal with
643				 * respect to indirect sections.
644				 */
645				legal_reference(section_map, r_address,
646				    pair_local_map, pair_r_value -
647				    pair_local_map->s->addr, i, TRUE);
648				value -=
649				    fine_reloc_output_address(pair_local_map,
650					pair_r_value - pair_local_map->s->addr,
651				        pair_local_map->output_section->s.addr);
652			    }
653			    else{
654				value -=
655				    pair_local_map->output_section->s.addr +
656				    pair_local_map->offset +
657				    pair_r_value - pair_local_map->s->addr;
658			    }
659			    /* Third add in the offset. */
660			    value += offset;
661			    value -= output_pc; /* adjust for pcrel */
662			}
663			else{
664			    /*
665			     * If the relocation entry is not a scattered
666			     * relocation entry then the relocation is based on
667			     * the value of value of the expresion of the item
668			     * to be relocated.  If it is a scattered relocation
669			     * entry then the relocation is based on the r_value
670			     * in the relocation entry and the offset part of
671			     * the expression at the item to be relocated is
672			     * extracted so it can be added after the relocation
673			     * is done.
674			     */
675			    value += input_pc;
676			    if(r_scattered == 0){
677				r_value = value;
678				offset = 0;
679			    }
680			    else{
681				offset = value - r_value;
682			    }
683			    /*
684			     * Check to see if this reference is legal with
685			     * respect to indirect sections.
686			     */
687			    legal_reference(section_map, r_address, local_map,
688				    r_value - local_map->s->addr + offset, i,
689				    FALSE);
690
691			    /*
692			     * If we are being called only to get the references
693			     * for this relocation entry fill it in and return.
694			     */
695			    if(refs != NULL){
696				fine_reloc_output_ref(
697				    local_map,
698				    r_value - local_map->s->addr,
699				    &(refs->ref1) );
700				refs->ref2.ref_type = LIVE_REF_NONE;
701				return;
702			    }
703
704			    value = fine_reloc_output_address(local_map,
705					r_value - local_map->s->addr,
706					local_map->output_section->s.addr);
707			    value -= output_pc;
708			    value += offset;
709			}
710			switch(r_length){
711			case 0: /* byte */
712			    if( (value & 0xffffff00) &&
713			       ((value & 0xffffff80) != 0xffffff80))
714				error_with_cur_obj("relocation for entry %lu in"
715				    " section (%.16s,%.16s) does not fit in 1 "
716				    "byte", i, section_map->s->segname,
717				    section_map->s->sectname);
718			    set_byte((char *)(contents + r_address), value);
719			    break;
720			case 1: /* word (2 byte) */
721			    if( (value & 0xffff0000) &&
722			       ((value & 0xffff8000) != 0xffff8000))
723				error_with_cur_obj("relocation for entry %lu in"
724				    " section (%.16s,%.16s) does not fit in 2 "
725				    "bytes", i, section_map->s->segname,
726				    section_map->s->sectname);
727			    set_short((short *)(contents + r_address), value);
728			    break;
729			case 2: /* long (4 byte) */
730			    set_long((long *)(contents + r_address), value);
731			    break;
732			default:
733			    error_with_cur_obj("r_length field of relocation "
734				"entry %lu in section (%.16s,%.16s) invalid",
735				i, section_map->s->segname,
736				section_map->s->sectname);
737			    return;
738			}
739			goto update_reloc;
740		    }
741		}
742	    }
743	    if(r_pcrel){
744		/*
745		 * This is a relocation entry is also pc relative which means
746		 * the value of the pc will get added to it when it is executed.
747		 * The item being relocated has the value of the pc in the input
748		 * file subtracted from it.  So to relocate this the value of
749		 * pc in the input file is added and then value of the output
750		 * pc is subtracted (since the offset into the section remains
751		 * constant it is not added in and then subtracted out).
752		 */
753		if(section_map->nfine_relocs == 0)
754		    value += + section_map->s->addr /* + r_address */
755			     - (section_map->output_section->s.addr +
756				section_map->offset /* + r_address */);
757		else
758		    value += + section_map->s->addr + r_address
759			     - (section_map->output_section->s.addr +
760			        fine_reloc_output_offset(section_map,
761							 r_address));
762	    }
763	    switch(r_length){
764	    case 0: /* byte */
765		value += get_byte((char *)(contents + r_address));
766		if( (value & 0xffffff00) &&
767		   ((value & 0xffffff80) != 0xffffff80))
768		    error_with_cur_obj("relocation for entry %lu in section "
769			"(%.16s,%.16s) does not fit in 1 byte", i,
770			section_map->s->segname, section_map->s->sectname);
771		set_byte((char *)(contents + r_address), value);
772		break;
773	    case 1: /* word (2 byte) */
774		value += get_short((short *)(contents + r_address));
775		if( (value & 0xffff0000) &&
776		   ((value & 0xffff8000) != 0xffff8000))
777		    error_with_cur_obj("relocation for entry %lu in section "
778			"(%.16s,%.16s) does not fit in 2 bytes", i,
779			section_map->s->segname, section_map->s->sectname);
780		set_short((short *)(contents + r_address), value);
781		break;
782	    case 2: /* long (4 byte) */
783		value += get_long((long *)(contents + r_address));
784		set_long((long *)(contents + r_address), value);
785		break;
786	    default:
787		error_with_cur_obj("r_length field of relocation entry %lu in "
788		    "section (%.16s,%.16s) invalid", i,
789		    section_map->s->segname, section_map->s->sectname);
790		return;
791	    }
792	    /*
793	     * If relocation entries are to be saved in the output file then
794	     * update the entry for the output file.
795	     */
796update_reloc:
797	    ;
798#ifndef RLD
799	    if(save_reloc || output_for_dyld){
800		if(r_extern){
801		    /*
802		     * If we are prebinding and this is a lazy pointer section
803		     * change the relocation entry to a GENERIC_RELOC_PB_LA_PTR
804		     * type.  This stuffs the value of the lazy pointer as it
805		     * wouldn't be prebound in the r_value field.  So if the
806		     * prebounding can't be used at runtime the value of the
807		     * lazy pointer will get set back to the r_value by dyld.
808		     */
809		    if(prebinding == TRUE &&
810		       (section_map->s->flags & SECTION_TYPE) ==
811			S_LAZY_SYMBOL_POINTERS){
812			sreloc = (struct scattered_relocation_info *)reloc;
813			r_scattered = 1;
814			sreloc->r_scattered = r_scattered;
815			if((r_address & 0x00ffffff) != r_address)
816			    error_with_cur_obj("Can't create valid output "
817				"file (r_address field of relocation "
818				"entry %lu in section (%.16s,%.16s) would "
819				"overflow)", i, section_map->s->segname,
820				section_map->s->sectname);
821			sreloc->r_address = r_address;
822			sreloc->r_pcrel = r_pcrel;
823			sreloc->r_length = r_length;
824			sreloc->r_type = GENERIC_RELOC_PB_LA_PTR;
825			sreloc->r_value = value;
826		    }
827		    /*
828		     * For external relocation entries that the symbol is
829		     * defined (not undefined or common) but not when we are
830		     * forcing an external relocation entry for a global
831		     * coalesced symbol and if the output file is not a multi
832		     * module MH_DYLIB or the symbol is a private extern, it is
833		     * changed to a local relocation entry using the section
834		     * that symbol is defined in.  If still undefined or forcing
835		     * an external relocation entry for a global coalesced
836		     * symbol, then the index of the symbol in the output file
837		     * is set into r_symbolnum.
838		     */
839		    else if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF &&
840		            (merged_symbol->nlist.n_type & N_TYPE) != N_PBUD &&
841		            force_extern_reloc == FALSE &&
842		            ((filetype != MH_DYLIB ||
843			      multi_module_dylib == FALSE) ||
844			     (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)){
845			reloc->r_extern = 0;
846			/*
847			 * If this symbol was in the base file then no futher
848			 * relocation can ever be done (the symbols in the base
849			 * file are fixed). Or if the symbol was an absolute
850			 * symbol.
851			 */
852			if(merged_symbol->definition_object == base_obj ||
853			   (merged_symbol->nlist.n_type & N_TYPE) == N_ABS){
854				reloc->r_symbolnum = R_ABS;
855			}
856			else{
857			    /*
858			     * The symbol that this relocation entry is refering
859			     * to is defined so convert this external relocation
860			     * entry into a local or scattered relocation entry.
861			     * If the item to be relocated has an offset added
862			     * to the symbol's value and the output is not for
863			     * dyld make it a scattered relocation entry else
864			     * make it a local relocation entry.
865			     */
866			    if(offset == 0 || output_for_dyld){
867				reloc->r_symbolnum =merged_symbol->nlist.n_sect;
868			    }
869			    else{
870				sreloc = (struct scattered_relocation_info *)
871					 reloc;
872				r_scattered = 1;
873				sreloc->r_scattered = r_scattered;
874				if((r_address & 0x00ffffff) != r_address)
875				    error_with_cur_obj("Can't create valid "
876					"output file (r_address field of "
877					"relocation entry %lu in section "
878					"(%.16s,%.16s) would overflow)", i,
879					section_map->s->segname,
880					section_map->s->sectname);
881				sreloc->r_address = r_address;
882				sreloc->r_pcrel = r_pcrel;
883				sreloc->r_length = r_length;
884				sreloc->r_type = 0;
885				sreloc->r_value = merged_symbol->nlist.n_value;
886			    }
887			}
888		    }
889		    else{
890			reloc->r_symbolnum =
891				      merged_symbol_output_index(merged_symbol);
892		    }
893		}
894		else if(r_scattered == 0){
895		    /*
896		     * If we are prebinding and this is a lazy pointer section
897		     * change the relocation entry to a GENERIC_RELOC_PB_LA_PTR
898		     * type.  This stuffs the value of the lazy pointer as it
899		     * wouldn't be prebound in the r_value field.  So if the
900		     * prebounding can't be used at runtime the value of the
901		     * lazy pointer will get set back to the r_value by dyld.
902		     */
903		    if(prebinding == TRUE &&
904		       (section_map->s->flags & SECTION_TYPE) ==
905			S_LAZY_SYMBOL_POINTERS){
906			sreloc = (struct scattered_relocation_info *)reloc;
907			r_scattered = 1;
908			sreloc->r_scattered = r_scattered;
909			if((r_address & 0x00ffffff) != r_address)
910			    error_with_cur_obj("Can't create valid output "
911				"file (r_address field of relocation "
912				"entry %lu in section (%.16s,%.16s) would "
913				"overflow)", i, section_map->s->segname,
914				section_map->s->sectname);
915			sreloc->r_address = r_address;
916			sreloc->r_pcrel = r_pcrel;
917			sreloc->r_length = r_length;
918			sreloc->r_type = GENERIC_RELOC_PB_LA_PTR;
919			sreloc->r_value = value;
920		    }
921		    /*
922		     * For local relocation entries the section number is
923		     * changed to the section number in the output file.
924		     */
925		    else if(reloc->r_symbolnum != R_ABS){
926			if(local_map->nfine_relocs == 0){
927			    reloc->r_symbolnum =
928				      local_map->output_section->output_sectnum;
929			}
930			else{
931			    reloc->r_symbolnum =
932				fine_reloc_output_sectnum(local_map,
933						r_value - local_map->s->addr);
934			}
935		    }
936		}
937		else{
938		    /*
939		     * This is a scattered relocation entry.  If the output is
940		     * for dyld convert it to a local relocation entry so as
941		     * to not overflow the 24-bit r_address field in a scattered
942		     * relocation entry.  The overflow would happen in
943		     * reloc_output_for_dyld() in sections.c when it adjusts
944		     * the r_address fields of the relocation entries.
945		     */
946		    if(output_for_dyld){
947			reloc = (struct relocation_info *)sreloc;
948			r_scattered = 0;
949			reloc->r_address = r_address;
950			reloc->r_pcrel = r_pcrel;
951			reloc->r_extern = 0;
952			reloc->r_length = r_length;
953			reloc->r_type = r_type;
954			if(local_map->nfine_relocs == 0){
955			    reloc->r_symbolnum =
956				      local_map->output_section->output_sectnum;
957			}
958			else{
959			    reloc->r_symbolnum =
960				fine_reloc_output_sectnum(local_map,
961						r_value - local_map->s->addr);
962			}
963		    }
964		    else{
965			/*
966			 * For scattered relocation entries the r_value field is
967			 * relocated.
968			 */
969			if(local_map->nfine_relocs == 0)
970			    sreloc->r_value +=
971					   - local_map->s->addr
972					   + local_map->output_section->s.addr +
973					   local_map->offset;
974			else
975			    sreloc->r_value =
976					fine_reloc_output_address(local_map,
977						r_value - local_map->s->addr,
978					   local_map->output_section->s.addr);
979		    }
980		}
981		/*
982		 * If this section that the reloation is being done for has fine
983		 * relocation then the offset in the r_address field has to be
984		 * set to where it will end up in the output file.  Otherwise
985		 * it simply has to have the offset to where this contents
986		 * appears in the output file.
987		 */
988		if(r_scattered == 0){
989		    if(section_map->nfine_relocs == 0){
990			reloc->r_address += section_map->offset;
991		    }
992		    else{
993			reloc->r_address = fine_reloc_output_offset(section_map,
994								    r_address);
995		    }
996		}
997		else{
998		    if(section_map->nfine_relocs == 0){
999			if(((sreloc->r_address + section_map->offset) &
1000			    0x00ffffff) !=
1001			    sreloc->r_address + section_map->offset)
1002			    error_with_cur_obj("Can't create valid output "
1003				"file (r_address field of relocation "
1004				"entry %lu in section (%.16s,%.16s) would "
1005				"overflow)", i, section_map->s->segname,
1006				section_map->s->sectname);
1007			sreloc->r_address += section_map->offset;
1008		    }
1009		    else{
1010			r_address = fine_reloc_output_offset(section_map,
1011							     r_address);
1012			if((r_address & 0x00ffffff) != r_address)
1013			    error_with_cur_obj("Can't create valid output "
1014				"file (r_address field of relocation "
1015				"entry %lu in section (%.16s,%.16s) would "
1016				"overflow)", i, section_map->s->segname,
1017				section_map->s->sectname);
1018			sreloc->r_address = r_address;
1019		    }
1020		}
1021		/*
1022		 * If their was a paired relocation entry then update the
1023		 * paired relocation entry.
1024		 */
1025		if(pair_r_type == GENERIC_RELOC_PAIR){
1026		    if(spair_reloc != NULL){
1027			/*
1028			 * For scattered relocation entries the r_value field is
1029			 * relocated.
1030			 */
1031			if(pair_local_map->nfine_relocs == 0)
1032			    spair_reloc->r_value +=
1033				- pair_local_map->s->addr
1034				+ (pair_local_map->output_section->s.addr +
1035				   pair_local_map->offset);
1036			else
1037			    spair_reloc->r_value =
1038				fine_reloc_output_address(pair_local_map,
1039				    pair_r_value - pair_local_map->s->addr,
1040				    pair_local_map->output_section->s.addr);
1041		    }
1042		    else{
1043			fatal("internal error, in generic_reloc() pair_r_type "
1044			    "is GENERIC_RELOC_PAIR but spair_reloc is NULL");
1045		    }
1046		}
1047	    }
1048#endif /* !defined(RLD) */
1049	    /*
1050	     * If their was a paired relocation entry then it has been processed
1051	     * so skip it by incrementing the index of the relocation entry that
1052	     * is being processed.
1053	     */
1054	    if(pair_r_type == GENERIC_RELOC_PAIR)
1055		i++;
1056	}
1057}
1058
1059__private_extern__
1060int
1061undef_bsearch(
1062const unsigned long *index,
1063const struct undefined_map *undefined_map)
1064{
1065	return(*index - undefined_map->index);
1066}
1067