1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#ifdef SHLIB
24#include "shlib.h"
25#endif /* SHLIB */
26/*
27 * This file contains the routines that deal with indirect sections (both
28 * lazy and non-lazy symbol pointer sections as well as symbol stub sections).
29 */
30#include <stdlib.h>
31#if !(defined(KLD) && defined(__STATIC__))
32#include <stdio.h>
33#include <mach/mach.h>
34#else /* defined(KLD) && defined(__STATIC__) */
35#include <mach/kern_return.h>
36#endif /* !(defined(KLD) && defined(__STATIC__)) */
37#include <stdarg.h>
38#include <string.h>
39#include "stuff/openstep_mach.h"
40#include <mach-o/loader.h>
41#include <mach-o/nlist.h>
42#include <mach-o/stab.h>
43#include <mach-o/reloc.h>
44#include <mach-o/ppc/reloc.h>
45#include <mach-o/hppa/reloc.h>
46#include "stuff/arch.h"
47#include "stuff/reloc.h"
48
49#include "ld.h"
50#include "live_refs.h"
51#include "objects.h"
52#include "sections.h"
53#include "pass2.h"
54#include "generic_reloc.h"
55#include "pass1.h"
56#include "symbols.h"
57#include "layout.h"
58#include "coalesced_sections.h"
59#include "dylibs.h"
60
61/*
62 * coalesced_section_merge() merges items from a coalesced section from the
63 * specified section in the current object file (cur_obj).  When redo_live is
64 * FALSE it allocates a fine relocation map and sets the fine_relocs field in
65 * the section_map to it (as well as the count).
66 *
67 * When redo_live is FALSE after all the items for this section in this object
68 * file have been merged two more things are done.  First the number of
69 * relocation entries that will be in the output file is adjusted (incremented)
70 * based on which items are used from this object's section.  Second the number
71 * of local symbol table entries and the size of the string table is adjusted
72 * (decremented) based on the which symbols are in the items from this object's
73 * section that will be in the resulting object file.
74 *
75 * When redo_live is TRUE it re-merges only the live items from a coalesced
76 * section from the specified section in the current object file (cur_obj).
77 */
78__private_extern__
79void
80coalesced_section_merge(
81void *data,
82struct merged_section *ms,
83struct section *s,
84struct section_map *section_map,
85enum bool redo_live)
86{
87    unsigned long i, j, nsect, count;
88    struct nlist *object_symbols;
89    char *object_strings;
90    enum bool start_section;
91    struct load_order *load_orders;
92    struct fine_reloc *fine_relocs;
93    struct merged_symbol *merged_symbol;
94    struct relocation_info *relocs, reloc;
95    struct scattered_relocation_info *sreloc, *spair_reloc;
96    unsigned long r_address, r_pcrel, r_length, r_type, pair_r_type, r_extern,
97		  r_symbolnum, r_scattered, pair, r_value;
98    struct undefined_map *undefined_map;
99#ifndef RLD
100    enum bool pic;
101#endif
102    enum bool defined, force_extern_reloc;
103
104	pair_r_type = 0;
105	/*
106	 * If the size of the section is zero there is nothing to merge.
107	 */
108	if(s->size == 0)
109	    return;
110
111	merged_symbol = NULL;
112
113	/*
114	 * Figure out the nsect in the object file we are about to merge.
115	 * This is so we can count the symbols that match this nsect which
116	 * are defined in this section.
117	 */
118	nsect = 0;
119	for(i = 0; i < cur_obj->nsection_maps; i++){
120	    if(&(cur_obj->section_maps[i]) == section_map){
121		nsect = i + 1;
122		break;
123	    }
124	}
125	if(nsect == 0){
126	    fatal("internal error: coalesced_section_merge() called "
127		"with bad section_map for section (%.16s,%.16s)",
128		s->segname, s->sectname);
129	}
130
131	/*
132	 * Count the number of symbols in this section in this object file.
133	 * Check to see if there is a symbol at the beginning of the section.
134	 * and that all symbols defined in this section are global.
135	 */
136	count = 0;
137	start_section = FALSE;
138	if(cur_obj->symtab != NULL){
139	    object_symbols = (struct nlist *)(cur_obj->obj_addr +
140					      cur_obj->symtab->symoff);
141	    object_strings = (char *)(cur_obj->obj_addr +
142				      cur_obj->symtab->stroff);
143	}
144	else{
145	    object_symbols = NULL;
146	    object_strings = NULL;
147	}
148	if(redo_live == TRUE)
149	    goto set_load_orders;
150
151	if(cur_obj->symtab != NULL){
152	    for(i = 0; i < cur_obj->symtab->nsyms; i++){
153		if((object_symbols[i].n_type & N_TYPE) == N_SECT &&
154		    object_symbols[i].n_sect == nsect &&
155		   (object_symbols[i].n_type & N_STAB) == 0){
156		    count++;
157/*
158 * Allow private extern and local symbols.
159 */
160#ifdef notdef
161		    if((object_symbols[i].n_type & (N_EXT|N_PEXT)) ==
162		       (N_EXT|N_PEXT)){
163			error_with_cur_obj("malformed object (symbol: %s in "
164			    "S_COALESCE section (%.16s,%.16s) can't be a "
165			    "private extern symbol)",
166			    object_strings + object_symbols[i].n_un.n_strx,
167			    s->segname, s->sectname);
168			return;
169		    }
170		    if((object_symbols[i].n_type & N_EXT) != N_EXT){
171			error_with_cur_obj("malformed object (symbol: %s in "
172			    "S_COALESCE section (%.16s,%.16s) not an external "
173			    "symbol)",
174			    object_strings + object_symbols[i].n_un.n_strx,
175			    s->segname, s->sectname);
176			return;
177		    }
178#endif
179		    if(object_symbols[i].n_value == s->addr)
180			start_section = TRUE;
181		}
182	    }
183	}
184	if(start_section == FALSE){
185	    error_with_cur_obj("malformed object (section (%.16s,%.16s) no "
186		"symbol at start of coalesced section)",s->segname,s->sectname);
187	    return;
188	}
189
190set_load_orders:
191	/*
192	 * Allocate a load order map for the symbols in this section.
193	 * We are not ordering the section but simpily needing to figure out
194	 * the sizes and offsets of each symbol and a load order map is now
195	 * this is normally done.
196	 */
197	if(redo_live == FALSE){
198	    load_orders = allocate(sizeof(struct load_order) * count);
199	    memset(load_orders, '\0', sizeof(struct load_order) * count);
200	    section_map->load_orders = load_orders;
201	    section_map->nload_orders = count;
202	}
203	else{
204	    load_orders = section_map->load_orders;
205	    count = section_map->nload_orders;
206	    goto deal_with_contents;
207	}
208
209	/*
210	 * Fill in symbol names and values the load order map for this section
211	 * in this object file.
212	 */
213	j = 0;
214	for(i = 0; i < cur_obj->symtab->nsyms; i++){
215	    if((object_symbols[i].n_type & N_TYPE) == N_SECT &&
216	        object_symbols[i].n_sect == nsect &&
217	       (object_symbols[i].n_type & N_STAB) == 0){
218		load_orders[j].name = object_strings +
219			      object_symbols[i].n_un.n_strx;
220		load_orders[j].value =
221			      object_symbols[i].n_value;
222		/*
223		 * We fill in the 'global_coalesced_symbol' field with a
224		 * boolean test of if the symbol is external or not.  See
225		 * below where this is used.
226		 */
227		load_orders[j].global_coalesced_symbol =
228			      (object_symbols[i].n_type & N_EXT) == N_EXT;
229		j++;
230	    }
231	}
232
233#ifdef DEBUG
234	if(debug & (1 << 14))
235	    print_load_order(load_orders, count, ms,
236			     cur_obj, "names and values");
237#endif /* DEBUG */
238
239	/*
240	 * Sort the load order map by symbol value so the
241	 * size and input offset fields can be set.
242	 */
243	qsort(load_orders,
244	      count,
245	      sizeof(struct load_order),
246	      (int (*)(const void *, const void *))qsort_load_order_values);
247	/*
248	 * Set the input offset and size fields.
249	 */
250	for(i = 0; i < count - 1; i++){
251	    load_orders[i].input_offset =
252			   load_orders[i].value -
253			   s->addr;
254	    load_orders[i].input_size =
255			   load_orders[i + 1].value -
256			   load_orders[i].value;
257	}
258	load_orders[i].input_offset =
259			   load_orders[i].value -
260			   s->addr;
261	load_orders[i].input_size =
262			   s->addr + s->size -
263			   load_orders[i].value;
264#ifdef DEBUG
265	if(debug & (1 << 15))
266	    print_load_order(load_orders, count, ms,
267			     cur_obj, "sizes and offsets");
268#endif /* DEBUG */
269
270deal_with_contents:
271	/*
272	 * First deal with the contents of section for each symbol and determine
273	 * based on the symbol if the contents will be used from this object or
274	 * used from a previously merged object.  This information is encoded
275	 * into the fine_reloc structures for each item.
276	 */
277	if(redo_live == FALSE){
278	    fine_relocs = allocate(count * sizeof(struct fine_reloc));
279	    memset(fine_relocs, '\0', count * sizeof(struct fine_reloc));
280	    section_map->fine_relocs = fine_relocs;
281	    section_map->nfine_relocs = count;
282	}
283	else{
284            fine_relocs = section_map->fine_relocs;
285            count = section_map->nfine_relocs;
286	}
287	for(i = 0; i < count; i++){
288	    if(redo_live == FALSE)
289		fine_relocs[i].input_offset = load_orders[i].input_offset;
290	    /*
291	     * We previously filled in the 'global_coalesced_symbol' field with
292	     * a boolean test of if the symbol is external or not.  See above
293	     * where this is done.
294	     */
295	    if(load_orders[i].global_coalesced_symbol == TRUE){
296		merged_symbol = lookup_symbol(load_orders[i].name);
297		if(merged_symbol->name_len == 0)
298		    fatal("internal error, coalesced_section_merge() failed in "
299			  "looking up external symbol: %s",load_orders[i].name);
300		/*
301		 * If the merged symbol comes from this object then this
302		 * object's contents will be used.  If not it won't.
303		 */
304		if(merged_symbol->definition_object == cur_obj){
305		    if(redo_live == FALSE){
306			fine_relocs[i].use_contents = TRUE;
307			fine_relocs[i].indirect_defined = FALSE;
308		    }
309		    if(redo_live == FALSE || fine_relocs[i].live == TRUE){
310			/* align size before using it to assign output offset */
311			ms->s.size = align_to_input_mod(ms->s.size,
312						fine_relocs[i].input_offset,
313						ms->s.align);
314			fine_relocs[i].output_offset = ms->s.size;
315			ms->s.size += load_orders[i].input_size;
316		    }
317		}
318		else{
319		    if(redo_live == FALSE){
320			fine_relocs[i].use_contents = FALSE;
321			fine_relocs[i].indirect_defined = FALSE;
322			fine_relocs[i].merged_symbol = merged_symbol;
323		    }
324		}
325		/*
326		 * We want to set local_symbol to TRUE if this symbol is a
327		 * private extern symbol so that section difference relocation
328		 * entries to it are not flagged as illegal references.
329		 */
330		if((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT){
331		    if(redo_live == FALSE)
332			fine_relocs[i].local_symbol = TRUE;
333		}
334		else{
335		    if(redo_live == FALSE)
336			fine_relocs[i].local_symbol = FALSE;
337		}
338	    }
339	    else{
340		/*
341		 * This is a local or private_extern symbol so keep its
342		 * contents.
343		 */
344		if(redo_live == FALSE){
345		    fine_relocs[i].use_contents = TRUE;
346		    fine_relocs[i].local_symbol = TRUE;
347		    fine_relocs[i].indirect_defined = FALSE;
348		}
349		if(redo_live == FALSE || fine_relocs[i].live == TRUE){
350		    /* align size before using it to assign output offset */
351		    ms->s.size = align_to_input_mod(ms->s.size,
352					            fine_relocs[i].input_offset,
353					            ms->s.align);
354		    fine_relocs[i].output_offset = ms->s.size;
355		    ms->s.size += load_orders[i].input_size;
356		}
357	    }
358	}
359
360#ifdef COALESCE_DEBUG
361	/*
362	 * For debugging print out the fine relocs we created for this section.
363	 */
364	printf("Fine relocs created for coalesced section (%.16s,%.16s) in ",
365	       s->segname, s->sectname);
366	print_obj_name(cur_obj);
367	printf("\n");
368	for(i = 0; i < count; i++){
369	    printf("fine_relocs[%lu] load_orders[%lu].name = %s\n",
370		   i, i, load_orders[i].name);
371	    printf("\tuse_contents = %s\n", fine_relocs[i].use_contents == TRUE
372		   ? "TRUE" : "FALSE");
373	    printf("\tlocal_symbol = %s\n", fine_relocs[i].local_symbol == TRUE
374		   ? "TRUE" : "FALSE");
375	    printf("\tinput_offset = %d\n", fine_relocs[i].input_offset);
376	    if(fine_relocs[i].use_contents == TRUE)
377		printf("\toutput_offset = %ld\n", fine_relocs[i].output_offset);
378	    else{
379		merged_symbol = fine_relocs[i].merged_symbol;
380		printf("\t%s from ", merged_symbol->nlist.n_un.n_name);
381		print_obj_name(merged_symbol->definition_object);
382		printf("\n");
383	    }
384	}
385#endif
386
387	/*
388	 * Second deal with the relocation entries for the section in this
389	 * object file.  Now that it has been determined for which items the
390	 * contents will be used from this object file.
391	 */
392
393	/*
394	 * This loop loops through the relocation entries and using the
395	 * use_contents field (via a call to fine_reloc_offset_in_output())		 * of the fine_relocs just created determines how many relocation
396	 * entries will be in the output for this section of this object file.
397	 */
398	relocs = (struct relocation_info *)(cur_obj->obj_addr + s->reloff);
399	for(i = 0; i < s->nreloc; i++){
400	    reloc = relocs[i];
401	    if(cur_obj->swapped &&
402	       section_map->input_relocs_already_swapped == FALSE)
403		swap_relocation_info(&reloc, 1, host_byte_sex);
404	    /*
405	     * Break out the fields of the relocation entry we need here.
406	     */
407	    if((reloc.r_address & R_SCATTERED) != 0){
408		sreloc = (struct scattered_relocation_info *)(&reloc);
409		r_scattered = 1;
410		r_address = sreloc->r_address;
411		r_pcrel = sreloc->r_pcrel;
412		r_length = sreloc->r_length;
413		r_type = sreloc->r_type;
414		r_extern = 0;
415		r_value = sreloc->r_value;
416		/* calculate the r_symbolnum (n_sect) from the r_value */
417		r_symbolnum = 0;
418		for(j = 0; j < cur_obj->nsection_maps; j++){
419		    if(r_value >= cur_obj->section_maps[j].s->addr &&
420		       r_value < cur_obj->section_maps[j].s->addr +
421				 cur_obj->section_maps[j].s->size){
422			r_symbolnum = j + 1;
423			break;
424		    }
425		}
426		if(r_symbolnum == 0){
427		    /*
428		     * The edge case where the last address past then end of
429		     * of the last section is referenced.
430		     */
431		    for(j = 0; j < cur_obj->nsection_maps; j++){
432			if(r_value == cur_obj->section_maps[j].s->addr +
433				      cur_obj->section_maps[j].s->size){
434			    r_symbolnum = j + 1;
435			    break;
436			}
437		    }
438		    if(r_symbolnum == 0){
439			error_with_cur_obj("r_value (0x%x) field of relocation "
440			    "entry %lu in section (%.16s,%.16s) out of range",
441			    (unsigned int)r_value, i, section_map->s->segname,
442			    section_map->s->sectname);
443			return;
444		    }
445		}
446	    }
447	    else{
448		r_scattered = 0;
449		r_address = reloc.r_address;
450		r_pcrel = reloc.r_pcrel;
451		r_length = reloc.r_length;
452		r_type = reloc.r_type;
453		r_extern = reloc.r_extern;
454		r_symbolnum = reloc.r_symbolnum;
455	    }
456	    /*
457	     * Make sure that this is not a stray PAIR relocation entry.
458	     */
459	    if(r_type == reloc_pair_r_type(arch_flag.cputype)){
460		error_with_cur_obj("malformed object (stray relocation PAIR "
461		    "entry (%lu) in section (%.16s,%.16s))", i, s->segname,
462		    s->sectname);
463		continue;
464	    }
465	    /*
466	     * The r_address field is really an offset into the contents of the
467	     * section and must reference something inside the section.
468	     */
469	    if(r_address >= s->size){
470		error_with_cur_obj("malformed object (r_address (0x%x) field "
471		    "of relocation entry %ld in section (%.16s,%.16s) out of "
472		    "range)",(unsigned int)r_address, i,s->segname,s->sectname);
473		continue;
474	    }
475	    /*
476	     * If this relocation entry is suppose to have a PAIR make sure it
477	     * does.
478	     */
479	    if(reloc_has_pair(arch_flag.cputype, r_type)){
480		if(i + 1 < s->nreloc){
481		    reloc = relocs[i + 1];
482		    if(cur_obj->swapped &&
483		       section_map->input_relocs_already_swapped == FALSE)
484			swap_relocation_info(&reloc, 1, host_byte_sex);
485		    if((reloc.r_address & R_SCATTERED) != 0){
486			spair_reloc = (struct scattered_relocation_info *)
487                                      &reloc;
488                        pair_r_type = spair_reloc->r_type;
489		    }
490		    else{
491                        pair_r_type = reloc.r_type;
492		    }
493		}
494		if(i + 1 >= s->nreloc ||
495		   pair_r_type != reloc_pair_r_type(arch_flag.cputype)){
496		    error_with_cur_obj("malformed object (relocation entry "
497			"(%lu) in section (%.16s,%.16s) missing following "
498			"associated PAIR entry)", i, s->segname, s->sectname);
499                    continue;
500                }
501	    }
502
503	    /*
504	     * Assumed the symbol for this relocation entry is defined (always
505	     * true for local relocation entries).  Then reset the variable
506	     * "defined" correctly if this is an external relocation entry based
507	     * on if the symbol is defined, where it is defined and the output
508	     * file type.
509	     */
510	    defined = TRUE;
511	    force_extern_reloc = FALSE;
512	    if(output_for_dyld && r_extern){
513		/*
514		 * This is an external relocation entry.  So the value to be
515		 * added to the item to be relocated is the value of the symbol.
516		 * r_symbolnum is an index into the input file's symbol table
517		 * of the symbol being refered to.  The symbol must be an
518		 * undefined symbol to be used in an external relocation entry
519		 * or a global coalesced symbol.
520		 */
521		if(r_symbolnum >= cur_obj->symtab->nsyms){
522		    error_with_cur_obj("r_symbolnum (%lu) field of external "
523			"relocation entry %lu in section (%.16s,%.16s) out of "
524			"range", r_symbolnum, i, s->segname, s->sectname);
525		    continue;
526		}
527		undefined_map = bsearch(&r_symbolnum, cur_obj->undefined_maps,
528		    cur_obj->nundefineds, sizeof(struct undefined_map),
529		    (int (*)(const void *, const void *))undef_bsearch);
530		if(undefined_map != NULL){
531		    merged_symbol = undefined_map->merged_symbol;
532		    /*
533		     * We must allow and create references to defined global
534		     * coalesced symbols with external relocation entries so
535		     * that the dynamic linker can relocate all references to
536		     * the same symbol.
537		     */
538		    if((merged_symbol->nlist.n_type & N_TYPE) == N_SECT &&
539		       (merged_symbol->definition_object->section_maps[
540			merged_symbol->nlist.n_sect - 1].s->flags &
541			SECTION_TYPE) == S_COALESCED){
542			if(((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT &&
543			    keep_private_externs == FALSE) ||
544			   dynamic == FALSE ||
545			   (output_for_dyld && has_dynamic_linker_command))
546			    force_extern_reloc = FALSE;
547			else
548			    force_extern_reloc = TRUE;
549		    }
550		}
551		else{
552		    if((object_symbols[r_symbolnum].n_type & N_EXT) != N_EXT){
553			error_with_cur_obj("r_symbolnum (%lu) field of external"
554			    " relocation entry %lu in section (%.16s,%.16s) "
555			    "refers to a non-external symbol", r_symbolnum, i,
556			    section_map->s->segname, section_map->s->sectname);
557			return;
558		    }
559		    /*
560		     * We must allow and create references to defined global
561		     * coalesced symbols with external relocation entries so
562		     * that the dynamic linker can relocate all references to
563		     * the same symbol.
564		     */
565		    if((object_symbols[r_symbolnum].n_type & N_TYPE) ==
566			N_SECT &&
567		       (cur_obj->section_maps[object_symbols[r_symbolnum].
568			n_sect-1].s->flags & SECTION_TYPE) == S_COALESCED){
569			merged_symbol = lookup_symbol(object_strings +
570				     object_symbols[r_symbolnum].n_un.n_strx);
571			if(merged_symbol->name_len == 0){
572			    fatal("internal error, in coalesced_section_merge()"
573				  " failed to lookup coalesced symbol %s",
574				  object_strings +
575				  object_symbols[r_symbolnum].n_un.n_strx);
576			}
577			/*
578			 * While the .o file's symbol is a coalesced symbol, it
579			 * may have been weak and the merged symbol now being
580			 * used is not a coalesced symbol. In that case we don't
581			 * force an external relocation entry.
582			 */
583			if(((merged_symbol->nlist.n_type & N_TYPE) == N_SECT &&
584			    (merged_symbol->definition_object->section_maps[
585			      merged_symbol->nlist.n_sect-1].
586			      s->flags & SECTION_TYPE) != S_COALESCED) ||
587			  ((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT &&
588			    keep_private_externs == FALSE) ||
589			    dynamic == FALSE ||
590			   (output_for_dyld && has_dynamic_linker_command))
591			    force_extern_reloc = FALSE;
592			else
593			    force_extern_reloc = TRUE;
594		    }
595		    else{
596			if(object_symbols[r_symbolnum].n_type !=
597			   (N_EXT | N_UNDF)){
598			    error_with_cur_obj("r_symbolnum (%lu) field of "
599				"external relocation entry %lu in section "
600				"(%.16s,%.16s) refers to a non-undefined "
601				"symbol", r_symbolnum, i,
602				section_map->s->segname,
603				section_map->s->sectname);
604			    return;
605			}
606			print_obj_name(cur_obj);
607			fatal("internal error, in coalesced_section_merge() "
608			    "symbol index %lu in above file not in undefined "
609			    "map", r_symbolnum);
610		    }
611		}
612		/*
613		 * If this is an indirect symbol resolve indirection (all chains
614		 * of indirect symbols have been resolved so that they point at
615		 * a symbol that is not an indirect symbol).
616		 */
617		if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR)
618		    merged_symbol = (struct merged_symbol *)
619				    merged_symbol->nlist.n_value;
620		/*
621		 * Is the merged symbol for this external relocation entry
622		 * defined in the output file.
623		 */
624		if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) ||
625		   merged_symbol->nlist.n_type == (N_EXT | N_PBUD) ||
626		   (merged_symbol->nlist.n_type == (N_EXT | N_INDR) &&
627		    merged_symbol->defined_in_dylib == TRUE))
628		    defined = FALSE;
629		else
630		    defined = TRUE;
631	    }
632	    if(reloc_has_pair(arch_flag.cputype, r_type))
633		pair = 1;
634	    else
635		pair = 0;
636
637	    /*
638	     * For output_for_dyld PPC_RELOC_JBSR and HPPA_RELOC_JBSR's are
639	     * never put out.
640	     */
641	    if(output_for_dyld &&
642	       ((arch_flag.cputype == CPU_TYPE_POWERPC &&
643		 r_type == PPC_RELOC_JBSR) ||
644	        (arch_flag.cputype == CPU_TYPE_HPPA &&
645		 r_type == HPPA_RELOC_JBSR)) ){
646		i += pair;
647		continue;
648	    }
649#ifndef RLD
650	    /*
651	     * If saving relocation entries see if this relocation entry is for
652	     * an item that is going to be in the output file and if so count it
653	     * as one of the output relocation entries.
654	     */
655	    if(output_for_dyld &&
656	       fine_reloc_offset_in_output(section_map, r_address)){
657		/*
658		 * Mark this section as being relocated (staticly).
659		 */
660		if(dead_strip == FALSE || redo_live == TRUE)
661		    ms->relocated = TRUE;
662		if(r_extern == 0)
663		    pic = (enum bool)
664			  (reloc_is_sectdiff(arch_flag.cputype, r_type) ||
665			   (r_pcrel == 1 && r_symbolnum != NO_SECT));
666		else
667		    pic = (enum bool)
668			  (r_pcrel == 1 &&
669			   (merged_symbol->nlist.n_type & N_TYPE) == N_SECT);
670		/*
671		 * The number of relocation entries in the output file is based
672		 * on one of three different cases:
673		 *  The output file is a multi module dynamic shared library
674		 *  The output file has a dynamic linker load command
675		 *  The output does not have a dynamic linker load command
676		 */
677		if(filetype == MH_DYLIB && multi_module_dylib == TRUE){
678		    /*
679		     * For a multi module dynamic shared library the modules are
680		     * kept separate so external relocation entries on input
681		     * will be external relocation entries on output.  For local
682		     * relocation entries only non-position-independent local
683		     * relocation entries are kept.  Modules of dylibs are not
684		     * linked together and can only be slid keeping all sections
685		     * relative to each other the same.
686		     */
687		    if(r_extern && (merged_symbol->nlist.n_type & N_PEXT) == 0)
688			section_map->nextrel += 1 + pair;
689		    else if(pic == FALSE)
690			section_map->nlocrel += 1 + pair;
691		}
692		else if(has_dynamic_linker_command){
693		    /*
694		     * For an file with a dynamic linker load command only
695		     * external relocation entries for undefined symbols are
696		     * kept.  This output file is a fixed address and can't be
697		     * moved.
698		     */
699		    if(r_extern && defined == FALSE)
700			section_map->nextrel += 1 + pair;
701		}
702		else{
703		    /*
704		     * For an file without a dynamic linker load command
705		     * external relocation entries for undefined symbols are
706		     * kept and locals that are non-position-independent are
707		     * kept.  This file can only be slid keeping all sections
708		     * relative to each other the same.
709		     */
710		    if(r_extern && (merged_symbol->nlist.n_type & N_PEXT) == 0){
711			if(defined == FALSE || force_extern_reloc == TRUE)
712			    section_map->nextrel += 1 + pair;
713			else if(pic == FALSE)
714			    section_map->nlocrel += 1 + pair;
715		    }
716		    else if(pic == FALSE)
717			section_map->nlocrel += 1 + pair;
718		}
719	    }
720	    else if(save_reloc &&
721	            fine_reloc_offset_in_output(section_map, r_address)){
722		ms->s.nreloc += 1 + pair;
723		nreloc += 1 + pair;
724	    }
725#endif /* !defined(RLD) */
726	    i += pair;
727	}
728	/*
729	 * If the the number of relocation entries is not zero mark this section
730	 * as being relocated (staticly).
731	 */
732	if(ms->s.nreloc != 0){
733	    if(dead_strip == FALSE || redo_live == TRUE)
734		ms->relocated = TRUE;
735	}
736
737	/*
738	 * Third deal with the symbol table entries for local symbols and N_STAB
739	 * symbols in this section in this object file.  Now that it has been
740	 * determined for which items the contents will be used from this
741	 * object file.
742	 *
743	 * When -dead_strip this can't be called when redo_live is FALSE as the
744	 * live marking has not been done yet. And when TRUE will get called for
745	 * all sections including coalesced sections as part of
746	 * count_live_symbols() calling removed_dead_local_symbols_in_section().
747	 */
748	if(dead_strip == FALSE)
749	    discard_local_symbols_for_section(nsect, object_symbols,
750					      object_strings, s, section_map);
751
752	/*
753	 * The load_orders are free()'ed if -dead_strip is not specified.  Or
754	 * if this the second time we are called, when redo_live == TRUE, we
755	 * are done with the load_orders so they can be free()'ed at this point.
756	 */
757	if(dead_strip == FALSE || redo_live == TRUE){
758	    free(load_orders);
759	    section_map->load_orders = NULL;
760	    section_map->nload_orders = 0;
761	}
762}
763
764__private_extern__
765void
766coalesced_section_order(
767void *data,
768struct merged_section *ms)
769{
770#ifndef RLD
771    kern_return_t r;
772#ifdef __MWERKS__
773    struct coalesced_section_data *dummy1;
774    struct merged_section *dummy2;
775        dummy1 = data;
776        dummy2 = ms;
777#endif
778
779	warning("section ordering for coalesced sections not supported ("
780		"-sectorder %s %s %s ignored)", ms->s.segname, ms->s.sectname,
781		ms->order_filename);
782	/*
783	 * Deallocate the memory for the load order file now that it is
784	 * nolonger needed.
785	 */
786	if((r = vm_deallocate(mach_task_self(), (vm_address_t)
787	    ms->order_addr, ms->order_size)) != KERN_SUCCESS)
788	    mach_fatal(r, "can't vm_deallocate() memory for -sectorder "
789		       "file: %s for section (%.16s,%.16s)",
790		       ms->order_filename, ms->s.segname,
791		       ms->s.sectname);
792	ms->order_addr = NULL;
793#else /* RLD */
794#ifdef __MWERKS__
795    struct coalesced_section_data *dummy1;
796    struct merged_section *dummy2;
797        dummy1 = data;
798        dummy2 = ms;
799#endif
800#endif /* RLD */
801}
802
803/*
804 * coalesced_section_reset_live() is called when -dead_strip is specified after
805 * the coalesced sections the input objects are merged. It resets the merged
806 * section size and the count of relocation entries back to zero so the live
807 * coalesced items can be re-merged (by later calling coalesced_section_merge()
808 * with redo_live == TRUE.
809 */
810__private_extern__
811void
812coalesced_section_reset_live(
813void *data,
814struct merged_section *ms)
815{
816	/* reset the merge section size back to zero */
817	ms->s.size = 0;
818
819	/* reset the count of relocation entries for this merged section */
820	if(output_for_dyld){
821	    ms->nlocrel = 0;
822	    ms->nextrel = 0;
823	}
824	else if(save_reloc){
825	    nreloc -= ms->s.nreloc;
826	    ms->s.nreloc = 0;
827	}
828}
829