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