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#if defined(__MWERKS__) && !defined(__private_extern__) 24#define __private_extern__ __declspec(private_extern) 25#endif 26 27/* 28 * Global types, variables and routines declared in the file sections.c. 29 * 30 * The following include file need to be included before this file: 31 * #include <sys/loader.h> 32 * #include "ld.h" 33 * #include "objects.h" 34 */ 35 36/* 37 * The fields of the segment command in a merged segment are set and 38 * maintained as follows: 39 * cmd set in layout_segments() (layout) 40 * cmdsize set in layout_segments() (layout) 41 * segname set when the merged segment is created (pass1) 42 * vmaddr set in process_segments() or layout_segments() (layout) 43 * vmsize set in layout_segments() (layout) 44 * fileoff set in layout_segments() (layout) 45 * filesize set in layout_segments() (layout) 46 * maxprot set in process_segments() or layout_segments() (layout) 47 * initprot set in process_segments() or layout_segments() (layout) 48 * nsects incremented as each section is merged (pass1) 49 * flags set to 0 in process_segments and SG_NORELOC 50 * conditionally or'ed in in pass2() (pass2) 51 */ 52struct merged_segment { 53 struct segment_command sg; /* The output file's segment structure. */ 54 struct merged_section /* The list of section that contain contents */ 55 *content_sections; /* that is non-zerofill sections. */ 56 struct merged_section /* The list of zerofill sections. */ 57 *zerofill_sections; 58 char *filename; /* File this segment is in, the output file */ 59 /* or a fixed VM shared library */ 60 enum bool addr_set; /* TRUE when address of this segment is set */ 61 enum bool prot_set; /* TRUE when protection of this segment is set*/ 62 enum bool split_dylib; /* TRUE when this segment is from a dylib */ 63 /* which is MH_SPLIT_SEGS */ 64 enum bool debug_only; /* TRUE if segment contains sections with the */ 65 /* S_ATTR_DEBUG attribute */ 66#ifdef RLD 67 long set_num; /* Object set this segment first appears in. */ 68#endif /* RLD */ 69 struct merged_segment *next;/* The next segment in the list. */ 70}; 71 72/* 73 * The fields of the section structure in a merged section are set and 74 * maintained as follows: 75 * sectname set when the merged segment is created (pass1) 76 * segname set when the merged segment is created (pass1) 77 * addr set in layout_segments (layout) 78 * size accumulated to the total size (pass1) 79 * offset set in layout_segments (layout) 80 * align merged to the maximum alignment (pass1) 81 * reloff set in layout_segments (layout) 82 * nreloc accumulated to the total count (pass1) 83 * flags set when the merged segment is created (pass1) 84 * reserved1 zeroed when created in merged_section (pass1) 85 * reserved2 zeroed when created in merged_section (pass1) 86 */ 87struct merged_section { 88 struct section s; /* The output file's section structure. */ 89 unsigned long output_sectnum;/* Section number in the output file. */ 90 unsigned long output_nrelocs;/* The current number of relocation entries */ 91 /* written to the output file in pass2 for */ 92 /* this section */ 93 /* These two fields are used to help set the SG_NORELOC flag */ 94 enum bool relocated; /* This section was relocated */ 95 enum bool referenced; /* This section was referenced by a relocation*/ 96 /* entry (local or through a symbol). */ 97 /* The literal_* fields are used only if this section is a literal section*/ 98 void (*literal_merge)(); /* The routine to merge the literals. */ 99 void (*literal_output)(); /* The routine to write the literals. */ 100 void (*literal_free)(); /* The routine to free the literals. */ 101 void (*literal_order)(); /* The routine to order the literals. */ 102 void (*literal_reset_live)(); /* The routine to reset literal data before 103 only the live literals are re-merged */ 104 void *literal_data; /* A pointer to a block of data to help merge */ 105 /* and hold the literals. */ 106 /* These three fields are used only if this section is created from a file*/ 107 char *contents_filename; /* File name for the contents of the section */ 108 /* if it is created from a file, else NULL */ 109 char *file_addr; /* address the above file is mapped at */ 110 unsigned long file_size; /* size of above file as returned by stat(2) */ 111 112 /* These three fields are used only if this section has a -sectorder file */ 113 char *order_filename; /* File name that contains the order that */ 114 /* symbols are to loaded in this section */ 115 char *order_addr; /* address the above file is mapped at */ 116 unsigned long order_size; /* size of above file as returned by stat(2) */ 117 struct order_load_map /* the load map for printing with -M */ 118 *order_load_maps; 119 unsigned long 120 norder_load_maps; /* size of the above map */ 121#ifdef RLD 122 long set_num; /* Object set this section first appears in. */ 123#endif /* RLD */ 124 /* These four are used for output_for_dyld only if this is a non-regular 125 section that will have relocation entries */ 126 unsigned long iextrel; /* index into output external reloc entries */ 127 unsigned long nextrel; /* number of output external reloc entries */ 128 unsigned long ilocrel; /* index into output local reloc entries */ 129 unsigned long nlocrel; /* number of output local reloc entries */ 130 struct merged_section *next;/* The next section in the list. */ 131}; 132 133/* 134 * This is the load map (-M) for sections that have had their sections orders 135 * with -sectorder option. 136 */ 137struct order_load_map { 138 char *archive_name; /* archive name */ 139 char *object_name; /* object name */ 140 char *symbol_name; /* symbol name */ 141 unsigned long value; /* symbol's value */ 142 struct section_map 143 *section_map; /* section map to relocate symbol's value */ 144 unsigned long size; /* size of symbol in the input file */ 145 unsigned long order; /* order the symbol appears in the section */ 146 struct load_order *load_order; /* the load_order for this map entry */ 147}; 148 149/* the pointer to the head of the output file's section list */ 150__private_extern__ struct merged_segment *merged_segments; 151#ifdef RLD 152__private_extern__ struct merged_segment *original_merged_segments; 153#endif /* RLD */ 154 155/* the total number relocation entries */ 156__private_extern__ unsigned long nreloc; 157 158/* 159 * This is set to TRUE if any of the input objects do not have the 160 * MH_SUBSECTIONS_VIA_SYMBOLS bit set in the mach_header flags field. 161 */ 162__private_extern__ enum bool some_non_subsection_via_symbols_objects; 163 164__private_extern__ void merge_sections( 165 void); 166__private_extern__ void remove_debug_segments( 167 void); 168__private_extern__ void merge_literal_sections( 169 enum bool redo_live); 170__private_extern__ void layout_ordered_sections( 171 void); 172__private_extern__ enum bool is_literal_output_offset_live( 173 struct merged_section *ms, 174 unsigned long output_offset); 175__private_extern__ void parse_order_line( 176 char *line, 177 char **archive_name, 178 char **object_name, 179 char **symbol_name, 180 struct merged_section *ms, 181 unsigned long line_number); 182__private_extern__ void resize_live_sections( 183 void); 184__private_extern__ void relayout_relocs( 185 void); 186__private_extern__ void output_literal_sections( 187 void); 188__private_extern__ void output_sections_from_files( 189 void); 190__private_extern__ void output_section( 191 struct section_map *map); 192__private_extern__ unsigned long pass2_nsect_merged_symbol_section_type( 193 struct merged_symbol *merged_symbol); 194__private_extern__ void nop_pure_instruction_scattered_sections( 195 void); 196__private_extern__ void flush_scatter_copied_sections( 197 void); 198__private_extern__ void live_marking( 199 void); 200__private_extern__ struct fine_reloc *get_fine_reloc_for_merged_symbol( 201 struct merged_symbol *merged_symbol, 202 struct section_map **local_map); 203__private_extern__ unsigned long r_symbolnum_from_r_value( 204 unsigned long r_value, 205 struct object_file *obj); 206__private_extern__ struct merged_section *create_merged_section( 207 struct section *s); 208__private_extern__ struct merged_segment *lookup_merged_segment( 209 char *segname); 210__private_extern__ struct merged_section *lookup_merged_section( 211 char *segname, 212 char *sectname); 213__private_extern__ enum bool is_merged_symbol_coalesced( 214 struct merged_symbol *merged_symbol); 215__private_extern__ int qsort_load_order_values( 216 const struct load_order *load_order1, 217 const struct load_order *load_order2); 218__private_extern__ unsigned long align_to_input_mod( 219 unsigned long output_offset, 220 unsigned long input_offset, 221 unsigned long align); 222#ifdef RLD 223__private_extern__ void reset_merged_sections( 224 void); 225__private_extern__ void zero_merged_sections_sizes( 226 void); 227__private_extern__ void remove_merged_sections( 228 void); 229#endif /* RLD */ 230 231#ifdef DEBUG 232__private_extern__ void print_merged_sections( 233 char *string); 234__private_extern__ void print_merged_section_stats( 235 void); 236__private_extern__ void print_name_arrays( 237 void); 238__private_extern__ void print_load_order( 239 struct load_order *load_order, 240 unsigned long nload_order, 241 struct merged_section *ms, 242 struct object_file *object_file, 243 char *string); 244#endif /* DEBUG */ 245