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 4 byte literals sections. 28 * A literal in this section must beable to me moved freely with respect to 29 * other literals. This means relocation must not reach outside the size of 30 * the literal. The size of this this type of section must be a multiple of 31 * 4 bytes in all input files. 32 */ 33#include <stdlib.h> 34#if !(defined(KLD) && defined(__STATIC__)) 35#include <stdio.h> 36#include <mach/mach.h> 37#else /* defined(KLD) && defined(__STATIC__) */ 38#include <mach/kern_return.h> 39#endif /* !(defined(KLD) && defined(__STATIC__)) */ 40#include <stdarg.h> 41#include <string.h> 42#include <mach-o/loader.h> 43#include "stuff/bool.h" 44#include "stuff/bytesex.h" 45 46#include "ld.h" 47#include "live_refs.h" 48#include "objects.h" 49#include "sections.h" 50#include "4byte_literals.h" 51#include "8byte_literals.h" 52#include "pass2.h" 53 54/* 55 * literal4_merge() merges 4 byte literals from the specified section in the 56 * current object file (cur_obj). When redo_live is FALSE it allocates a fine 57 * relocation map and sets the fine_relocs field in the section_map to it (as 58 * well as the count). When redo_live is TRUE it re-merges only the live 59 * cstrings based on the live bit in the previouly allocated fine_relocs. 60 */ 61__private_extern__ 62void 63literal4_merge( 64struct literal4_data *data, 65struct merged_section *ms, 66struct section *s, 67struct section_map *section_map, 68enum bool redo_live) 69{ 70 unsigned long nliteral4s, i; 71 struct literal4 *literal4s; 72 struct fine_reloc *fine_relocs; 73 74 if(s->size == 0){ 75 if(redo_live == FALSE){ 76 section_map->fine_relocs = NULL; 77 section_map->nfine_relocs = 0; 78 } 79 return; 80 } 81 /* 82 * Calculate the number of literals so the size of the fine relocation 83 * structures can be allocated. 84 */ 85 if(s->size % 4 != 0){ 86 error_with_cur_obj("4 byte literal section (%.16s,%.16s) size is " 87 "not a multiple of 4 bytes", ms->s.segname, 88 ms->s.sectname); 89 return; 90 } 91 nliteral4s = s->size / 4; 92#ifdef DEBUG 93 if(redo_live == FALSE){ 94 data->nfiles++; 95 data->nliterals += nliteral4s; 96 } 97#endif /* DEBUG */ 98 99 /* 100 * We will be called the first time with redo_live == FALSE and will 101 * just merge the cstrings from the input file and create the 102 * fine_relocs. 103 */ 104 if(redo_live == FALSE){ 105 fine_relocs = allocate(nliteral4s * sizeof(struct fine_reloc)); 106 memset(fine_relocs, '\0', nliteral4s * sizeof(struct fine_reloc)); 107 108 /* 109 * lookup and enter each 4 byte literal in the section and record 110 * the offsets in the input file and in the output file. 111 */ 112 literal4s = (struct literal4 *)(cur_obj->obj_addr + s->offset); 113 for(i = 0; i < nliteral4s; i++){ 114 fine_relocs[i].input_offset = i * 4; 115 fine_relocs[i].output_offset = 116 lookup_literal4(literal4s[i], data, ms); 117 } 118 section_map->fine_relocs = fine_relocs; 119 section_map->nfine_relocs = nliteral4s; 120 } 121 else{ 122 /* 123 * redo_live == TRUE and this is being called a second time after 124 * all the literals were previouly merged when -dead_strip is 125 * specified. So now we walk the fine_relocs and only re-merge the 126 * live literals. 127 */ 128 fine_relocs = section_map->fine_relocs; 129 nliteral4s = section_map->nfine_relocs; 130 literal4s = (struct literal4 *)(cur_obj->obj_addr + s->offset); 131 for(i = 0; i < nliteral4s; i++){ 132 if(fine_relocs[i].live == TRUE){ 133 fine_relocs[i].output_offset = 134 lookup_literal4(literal4s[i], data, ms); 135 } 136 else{ 137 fine_relocs[i].output_offset = 0; 138 } 139 } 140 } 141} 142 143/* 144 * literal4_order() enters 4 byte literals from the order_file from the merged 145 * section structure. Since this is called before any call to literal4_merge 146 * and it enters the literals in the order of the file it causes the section 147 * to be ordered. 148 */ 149__private_extern__ 150void 151literal4_order( 152struct literal4_data *data, 153struct merged_section *ms) 154{ 155#ifndef RLD 156 unsigned long i, line_number, output_offset, nliteral4_order_lines; 157 struct literal4 literal4; 158 struct literal4_order_line *literal4_order_lines; 159 160 /* 161 * If -dead_strip is specified allocate the needed structures so that 162 * the order of the live literals can be recreated later by 163 * literal4_reset_live(). Allocate a literal4_order_line for each 164 * line as the maximum that will needed. 165 */ 166 literal4_order_lines = NULL; 167 if(dead_strip == TRUE){ 168 line_number = 1; 169 i = 0; 170 while(i < ms->order_size){ 171 while(i < ms->order_size && ms->order_addr[i] != '\n') 172 i++; 173 if(i < ms->order_size && ms->order_addr[i] == '\n') 174 i++; 175 line_number++; 176 } 177 data->literal4_load_order_data = 178 allocate(sizeof(struct literal4_load_order_data)); 179 literal4_order_lines = allocate(sizeof(struct literal4_order_line) * 180 (line_number - 1)); 181 data->literal4_load_order_data->literal4_order_lines = 182 literal4_order_lines; 183 } 184 185 line_number = 1; 186 i = 0; 187 nliteral4_order_lines = 0; 188 while(i < ms->order_size){ 189 if(get_hex_from_sectorder(ms, &i, &(literal4.long0), line_number) == 190 TRUE){ 191 output_offset = lookup_literal4(literal4, data, ms); 192 if(dead_strip == TRUE){ 193 literal4_order_lines[nliteral4_order_lines].literal4 = 194 literal4; 195 literal4_order_lines[nliteral4_order_lines].line_number = 196 line_number; 197 literal4_order_lines[nliteral4_order_lines].output_offset = 198 output_offset; 199 nliteral4_order_lines++; 200 } 201 } 202 while(i < ms->order_size && ms->order_addr[i] != '\n') 203 i++; 204 if(i < ms->order_size && ms->order_addr[i] == '\n') 205 i++; 206 line_number++; 207 } 208 209 if(dead_strip == TRUE) 210 data->literal4_load_order_data->nliteral4_order_lines = 211 nliteral4_order_lines; 212#endif /* !defined(RLD) */ 213} 214 215/* 216 * literal4_reset_live() is called when -dead_strip is specified after all the 217 * literals from the input objects are merged. It clears out the literal4_data 218 * so the live literals can be re-merged (by later calling literal4_merge() with 219 * redo_live == TRUE. In here we first merge in the live literals from the 220 * order file if any. 221 */ 222__private_extern__ 223void 224literal4_reset_live( 225struct literal4_data *data, 226struct merged_section *ms) 227{ 228#ifndef RLD 229 unsigned long i, nliteral4_order_lines, line_number; 230 struct literal4_order_line *literal4_order_lines; 231 enum bool live; 232 233 /* reset the merge section size back to zero */ 234 ms->s.size = 0; 235 236 /* clear out the previously merged data */ 237 literal4_free(data); 238 239 /* 240 * If this merged section has an order file we need to re-merged only 241 * the live literal4s from that order file. 242 */ 243 if(ms->order_filename != NULL){ 244 literal4_order_lines = 245 data->literal4_load_order_data->literal4_order_lines; 246 nliteral4_order_lines = 247 data->literal4_load_order_data->nliteral4_order_lines; 248 for(i = 0; i < nliteral4_order_lines; i++){ 249 /* 250 * Figure out if this literal4 order line's output_index is live 251 * and if so re-merge the literal4 literal. 252 */ 253 live = is_literal_output_offset_live( 254 ms, literal4_order_lines[i].output_offset); 255 line_number = literal4_order_lines[i].line_number; 256 if(live){ 257 (void)lookup_literal4(literal4_order_lines[i].literal4, 258 data, ms); 259 } 260 else{ 261 if(sectorder_detail == TRUE) 262 warning("specification of 4-byte literal in -sectorder " 263 "file: %s on line %lu for section (%.16s,%.16s)" 264 " not used (dead stripped)", ms->order_filename, 265 line_number, ms->s.segname, ms->s.sectname); 266 } 267 } 268 269 /* deallocate the various data structures no longer needed */ 270 free(data->literal4_load_order_data->literal4_order_lines); 271 free(data->literal4_load_order_data); 272 data->literal4_load_order_data = NULL; 273 } 274#endif /* !defined(RLD) */ 275} 276 277/* 278 * lookup_literal4() looks up the 4 byte literal passed to it in the 279 * literal4_data passed to it and returns the offset the 4 byte literal will 280 * have in the output file. It creates the blocks to store the literals and 281 * attaches them to the literal4_data passed to it. The total size of the 282 * section is accumulated in ms->s.size which is the merged section for this 283 * literal section. The literal is aligned to the alignment in the merged 284 * section (ms->s.align). 285 */ 286__private_extern__ 287unsigned long 288lookup_literal4( 289struct literal4 literal4, 290struct literal4_data *data, 291struct merged_section *ms) 292{ 293 struct literal4_block **p, *literal4_block; 294 unsigned long align_multiplier, output_offset, i; 295 296 align_multiplier = 1; 297 if((1 << ms->s.align) > 4) 298 align_multiplier = (1 << ms->s.align) / 4; 299 300 output_offset = 0; 301 for(p = &(data->literal4_blocks); *p ; p = &(literal4_block->next)){ 302 literal4_block = *p; 303 for(i = 0; i < literal4_block->used; i++){ 304 if(literal4.long0 == literal4_block->literal4s[i].long0) 305 return(output_offset + i * 4 * align_multiplier); 306 } 307 if(literal4_block->used != LITERAL4_BLOCK_SIZE){ 308 literal4_block->literal4s[i].long0 = literal4.long0; 309 literal4_block->used++; 310 ms->s.size += 4 * align_multiplier; 311 return(output_offset + i * 4 * align_multiplier); 312 } 313 output_offset += literal4_block->used * 4 * align_multiplier; 314 } 315 *p = allocate(sizeof(struct literal4_block)); 316 literal4_block = *p; 317 literal4_block->used = 1; 318 literal4_block->literal4s[0].long0 = literal4.long0; 319 literal4_block->next = NULL; 320 321 ms->s.size += 4 * align_multiplier; 322 return(output_offset); 323} 324 325/* 326 * literal4_output() copies the 4 byte literals for the data passed to it into 327 * the output file's buffer. The pointer to the merged section passed to it is 328 * used to tell where in the output file this section goes. Then this routine 329 * calls literal4_free to free() up all space used by the data block except the 330 * data block itself. 331 */ 332__private_extern__ 333void 334literal4_output( 335struct literal4_data *data, 336struct merged_section *ms) 337{ 338 unsigned long align_multiplier, i, offset; 339 struct literal4_block **p, *literal4_block; 340 341 align_multiplier = 1; 342 if((1 << ms->s.align) > 4) 343 align_multiplier = (1 << ms->s.align) / 4; 344 345 /* 346 * Copy the literals into the output file. 347 */ 348 offset = ms->s.offset; 349 for(p = &(data->literal4_blocks); *p ;){ 350 literal4_block = *p; 351 for(i = 0; i < literal4_block->used; i++){ 352 memcpy(output_addr + offset, 353 literal4_block->literal4s + i, 354 sizeof(struct literal4)); 355 offset += 4 * align_multiplier; 356 } 357 p = &(literal4_block->next); 358 } 359#ifndef RLD 360 output_flush(ms->s.offset, offset - ms->s.offset); 361#endif /* !defined(RLD) */ 362} 363 364/* 365 * literal4_free() free()'s up all space used by the data block except the 366 * data block itself. 367 */ 368__private_extern__ 369void 370literal4_free( 371struct literal4_data *data) 372{ 373 struct literal4_block *literal4_block, *next_literal4_block; 374 375 /* 376 * Free all data for this block. 377 */ 378 for(literal4_block = data->literal4_blocks; literal4_block ;){ 379 next_literal4_block = literal4_block->next; 380 free(literal4_block); 381 literal4_block = next_literal4_block; 382 } 383 data->literal4_blocks = NULL; 384} 385 386#ifdef DEBUG 387/* 388 * print_literal4_data() prints a literal4_data. Used for debugging. 389 */ 390__private_extern__ 391void 392print_literal4_data( 393struct literal4_data *data, 394char *indent) 395{ 396 unsigned long i; 397 struct literal4_block **p, *literal4_block; 398 399 print("%s4 byte literal data at 0x%x\n", indent, (unsigned int)data); 400 if(data == NULL) 401 return; 402 print("%s literal4_blocks 0x%x\n", indent, 403 (unsigned int)(data->literal4_blocks)); 404 for(p = &(data->literal4_blocks); *p ; p = &(literal4_block->next)){ 405 literal4_block = *p; 406 print("%s\tused %lu\n", indent, literal4_block->used); 407 print("%s\tnext 0x%x\n", indent, 408 (unsigned int)(literal4_block->next)); 409 print("%s\tliteral4s\n", indent); 410 for(i = 0; i < literal4_block->used; i++){ 411 print("%s\t 0x%08x\n", indent, 412 (unsigned int)(literal4_block->literal4s[i].long0)); 413 } 414 } 415} 416 417/* 418 * literal4_data_stats() prints the literal4_data stats. Used for tuning. 419 */ 420__private_extern__ 421void 422literal4_data_stats( 423struct literal4_data *data, 424struct merged_section *ms) 425{ 426 if(data == NULL) 427 return; 428 print("literal4 section (%.16s,%.16s) contains:\n", 429 ms->s.segname, ms->s.sectname); 430 print(" %u merged literals \n", ms->s.size / 4); 431 print(" from %lu files and %lu total literals from those " 432 "files\n", data->nfiles, data->nliterals); 433 print(" average number of literals per file %g\n", 434 (double)((double)data->nliterals / (double)(data->nfiles))); 435} 436#endif /* DEBUG */ 437