|
|
1.1 root 1: /* layout.c (was part of write.c in original GAS version)
2: Copyright (C) 1986,1987 Free Software Foundation, Inc.
3:
4: This file is part of GAS, the GNU Assembler.
5:
6: GAS is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 1, or (at your option)
9: any later version.
10:
11: GAS is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GAS; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20: #include <stdlib.h>
21: #include <string.h>
22: #include "stuff/round.h"
23: #include "as.h"
24: #include "sections.h"
25: #include "frags.h"
26: #include "symbols.h"
27: #include "fixes.h"
28: #include "messages.h"
29: #include "expr.h"
30: #include "md.h"
31: #include "obstack.h"
32:
33: static void fixup_section(
34: fixS *fixP,
35: int nsect);
36: static void relax_section(
37: struct frag *section_frag_root,
38: int nsect);
39: static relax_addressT relax_align(
40: relax_addressT address,
41: long alignment);
42: static int is_down_range(
43: struct frag *f1,
44: struct frag *f2);
45:
46: /*
47: * layout_addresses() is called after all the assembly code has been read and
48: * fragments, symbols and fixups have been created. This routine sets the
49: * address of the fragments and symbols. Then it does the fixups of the frags
50: * and prepares the fixes so relocation entries can be created from them.
51: */
52: void
53: layout_addresses(
54: void)
55: {
56: struct frchain *frchainP;
57: fragS *fragP;
58: relax_addressT slide, tmp;
59: symbolS *symbolP;
60:
61: if(frchain_root == NULL)
62: return;
63:
64: /*
65: * If there is any current frag close it off.
66: */
67: if(frag_now != NULL && frag_now->fr_fix == 0){
68: frag_now->fr_fix = obstack_next_free(&frags) -
69: frag_now->fr_literal;
70: frag_wane(frag_now);
71: }
72:
73: /*
74: * For every section, add a last ".fill 0" frag that will later be used
75: * as the ending address of that section.
76: */
77: for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
78: /*
79: * We must do the obstack_finish(), so the next object we put on
80: * obstack frags will not appear to start at the fr_literal of the
81: * current frag. Also, it ensures that the next object will begin
82: * on a address that is aligned correctly for the engine that runs
83: * the assembler.
84: */
85: obstack_finish(&frags);
86:
87: /*
88: * Make a fresh frag for the last frag.
89: */
90: frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG);
91: memset(frag_now, '\0', SIZEOF_STRUCT_FRAG);
92: frag_now->fr_next = NULL;
93: obstack_finish(&frags);
94:
95: /*
96: * Append the new frag to current frchain.
97: */
98: frchainP->frch_last->fr_next = frag_now;
99: frchainP->frch_last = frag_now;
100: frag_wane(frag_now);
101:
102: }
103:
104: /*
105: * Now set the relitive addresses of frags within the section by
106: * relaxing each section. That is all sections will start at address
107: * zero and addresses of the frags in that section will increase from
108: * there.
109: */
110: for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
111: if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL)
112: continue;
113: /*
114: * This is done so in case md_estimate_size_before_relax() (called
115: * by relax_section) wants to make fixSs they are for this
116: * section.
117: */
118: frchain_now = frchainP;
119:
120: relax_section(frchainP->frch_root, frchainP->frch_nsect);
121: }
122:
123: /*
124: * Now set the absolute addresses of all frags by sliding the frags in
125: * each non-zerofill section by the address ranges taken up by the
126: * sections before it.
127: */
128: slide = 0;
129: for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
130: if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL)
131: continue;
132: slide = round(slide, 1 << frchainP->frch_section.align);
133: tmp = frchainP->frch_last->fr_address;
134: if(slide != 0){
135: for(fragP = frchainP->frch_root; fragP; fragP = fragP->fr_next){
136: fragP->fr_address += slide;
137: }
138: }
139: slide += tmp;
140: }
141: /*
142: * Now with the non-zerofill section addresses set set all of the
143: * addresses of the zerofill sections. Comming in the fr_address is
144: * the size of the section and going out it is the start address. This
145: * will make layout_symbols() work out naturally. The only funky thing
146: * is that section numbers do not end up in address order.
147: */
148: for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
149: if((frchainP->frch_section.flags & SECTION_TYPE) != S_ZEROFILL)
150: continue;
151: slide = round(slide, 1 << frchainP->frch_section.align);
152:
153: tmp = frchainP->frch_root->fr_address;
154: frchainP->frch_root->fr_address = slide;
155: frchainP->frch_last->fr_address = tmp + slide;
156: slide += tmp;
157: }
158:
159: /*
160: * Set the symbol addresses based on there frag's address.
161: * First forward references are handled.
162: */
163: for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){
164: if(symbolP->sy_forward != NULL){
165: if(symbolP->sy_nlist.n_type & N_STAB)
166: symbolP->sy_other = symbolP->sy_forward->sy_other;
167: symbolP->sy_value += symbolP->sy_forward->sy_value +
168: symbolP->sy_forward->sy_frag->fr_address;
169: symbolP->sy_forward = 0;
170: }
171: }
172: for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){
173: symbolP->sy_value += symbolP->sy_frag->fr_address;
174: }
175:
176: /*
177: * At this point the addresses of frags now reflect addresses we use in
178: * the object file and the symbol values are correct.
179: * Scan the frags, converting any ".org"s and ".align"s to ".fill"s.
180: * Also converting any machine-dependent frags using md_convert_frag();
181: */
182: for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
183: /*
184: * This is done so any fixes created by md_convert_frag() are for
185: * this section.
186: */
187: frchain_now = frchainP;
188:
189: for(fragP = frchainP->frch_root; fragP; fragP = fragP->fr_next){
190: switch(fragP->fr_type){
191: case rs_align:
192: case rs_org:
193: fragP->fr_type = rs_fill;
194: know(fragP->fr_var == 1);
195: know(fragP->fr_next != NULL);
196: fragP->fr_offset = fragP->fr_next->fr_address -
197: fragP->fr_address -
198: fragP->fr_fix;
199: break;
200:
201: case rs_fill:
202: break;
203:
204: case rs_machine_dependent:
205: md_convert_frag(fragP);
206: /*
207: * After md_convert_frag, we make the frag into a ".fill 0"
208: * md_convert_frag() should set up any fixSs and constants
209: * required.
210: */
211: frag_wane(fragP);
212: break;
213:
214: default:
215: BAD_CASE(fragP->fr_type);
216: break;
217: }
218: }
219: }
220:
221: /*
222: * For each section do the fixups for the frags.
223: */
224: for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
225: fixup_section(frchainP->frch_fix_root, frchainP->frch_nsect);
226: }
227: }
228:
229: /*
230: * fixup_section() does the fixups of the frags and prepares the fixes so
231: * relocation entries can be created from them. The fixups cause the contents
232: * of the frag to have the value for the fixup expression. A fix structure that
233: * ends up with a non NULL fx_addsy will have a relocation entry created for it.
234: */
235: static
236: void
237: fixup_section(
238: fixS *fixP,
239: int nsect)
240: {
241: symbolS *add_symbolP;
242: symbolS *sub_symbolP;
243: long value;
244: int size;
245: char *place;
246: long where;
247: char pcrel;
248: fragS *fragP;
249: int add_symbol_N_TYPE;
250: int add_symbol_nsect;
251:
252: /*
253: * The general fix expression is "fx_addsy - fx_subsy + fx_offset".
254: * The goal is to put the result of this expression into the frag at
255: * "place" for size "size". The value of the expression is calculated
256: * in the variable "value" and starts with just the fx_offset.
257: */
258: for( ; fixP != NULL; fixP = fixP->fx_next){
259: fragP = fixP->fx_frag;
260: know(fragP);
261: where = fixP->fx_where;
262: place = fragP->fr_literal + where;
263: size = fixP->fx_size;
264: add_symbolP = fixP->fx_addsy;
265: sub_symbolP = fixP->fx_subsy;
266: value = fixP->fx_offset;
267: pcrel = fixP->fx_pcrel;
268:
269: add_symbol_N_TYPE = 0;
270: add_symbol_nsect = 0;
271:
272: if(add_symbolP != NULL){
273: add_symbol_N_TYPE = add_symbolP->sy_type & N_TYPE;
274: if(add_symbol_N_TYPE == N_SECT)
275: add_symbol_nsect = add_symbolP->sy_other;
276: }
277:
278: /*
279: * Is there a subtract symbol?
280: */
281: if(sub_symbolP){
282: /* is it just -sym ? */
283: if(add_symbolP == NULL){
284: if(sub_symbolP->sy_type != N_ABS)
285: as_warn("Negative of non-absolute symbol %s",
286: sub_symbolP->sy_name);
287: value -= sub_symbolP->sy_value;
288: fixP->fx_subsy = NULL;
289: }
290: /*
291: * There are both an add symbol and a subtract symbol at this
292: * point.
293: *
294: * If both symbols are absolute then just calculate the
295: * value of the fix expression and no relocation entry will be
296: * needed.
297: */
298: else if((sub_symbolP->sy_type & N_TYPE) == N_ABS &&
299: (add_symbolP->sy_type & N_TYPE) == N_ABS){
300: value += add_symbolP->sy_value - sub_symbolP->sy_value;
301: add_symbolP = NULL;
302: fixP->fx_addsy = NULL; /* no relocation entry */
303: fixP->fx_subsy = NULL;
304: }
305: /*
306: * If both symbols are defined in a section then calculate the
307: * value of the fix expression and let a section difference
308: * relocation entry be created.
309: */
310: else if((sub_symbolP->sy_type & N_TYPE) == N_SECT &&
311: (add_symbolP->sy_type & N_TYPE) == N_SECT){
312: /*
313: * If we are allowed to use the new features that are
314: * incompatible with 3.2 then just calculate the value and
315: * let this create a SECTDIFF relocation type.
316: */
317: if(flagseen['k']){
318: value += add_symbolP->sy_value - sub_symbolP->sy_value;
319: goto down;
320: }
321: else{
322: /*
323: * This logic works only if the two symbols can't later
324: * be separated by scattered loading. To make sure that
325: * this can't happen we would have to make sure all
326: * symbols associated with addresses between these two
327: * symbols including the add symbol are of the Lx form
328: * and the -L flag is not see so they will not appear
329: * in the output (if they are not in the output then the
330: * link editor can't separate the chain of frags by
331: * scattered loading). Since this code does not make
332: * sure of this it is broken. But this is a known bug
333: * in the NeXT 3.2 and earilier releases so this code is
334: * if'ed !flagseen['k'] and will make it compatable with
335: * 3.2 and previous releases.
336: */
337: if(sub_symbolP->sy_other == add_symbolP->sy_other){
338: value += add_symbolP->sy_value -
339: sub_symbolP->sy_value;
340: add_symbolP = NULL;
341: fixP->fx_addsy = NULL; /* no relocation entry */
342: fixP->fx_subsy = NULL;
343: }
344: else{
345: as_warn("Can't emit reloc {- symbol \"%s\"} @ file "
346: "address %ld.", sub_symbolP->sy_name,
347: fragP->fr_address + where);
348: }
349: }
350: }
351: /*
352: * If the subtract symbol is absolute subtract it's value from
353: * the fix expression and let a relocation entry get created
354: * that is not a section difference type.
355: */
356: else if(sub_symbolP->sy_type == N_ABS){
357: value -= sub_symbolP->sy_value;
358: fixP->fx_subsy = NULL; /* no SECTDIFF relocation entry */
359: }
360: /*
361: * At this point we have something we can't generate a
362: * relocation entry for (two undefined symbols, etc.).
363: */
364: else{
365: as_warn("Can't emit reloc {- symbol \"%s\"} @ file "
366: "address %ld.", sub_symbolP->sy_name,
367: fragP->fr_address + where);
368: }
369: }
370:
371: /*
372: * If a there is an add symbol in the fixup expression then add
373: * the symbol value into the fixup expression's value.
374: */
375: if(add_symbolP){
376: /*
377: * If this symbol is in this section and is pc-relative and we
378: * do not want to force a pc-relative relocation entry (to
379: * support scattered loading) then just calculate the value.
380: */
381: if(add_symbol_nsect == nsect &&
382: pcrel && !(fixP->fx_pcrel_reloc)){
383: /*
384: * This fixup was made when the symbol's section was
385: * unknown, but it is now in this section. So we know how
386: * to do the address without relocation.
387: */
388: value += add_symbolP->sy_value;
389: value -= size + where + fragP->fr_address;
390: pcrel = 0; /* Lie. Don't want further pcrel processing. */
391: fixP->fx_addsy = NULL; /* No relocations please. */
392: /*
393: * It would be nice to check that the address does not
394: * overflow.
395: * I didn't do this check because:
396: * + It is machine dependent in the general case (eg 32032)
397: * + Compiler output will never need this checking, so why
398: * slow down the usual case?
399: */
400: }
401: else{
402: switch(add_symbol_N_TYPE){
403: case N_ABS:
404: value += add_symbolP->sy_value;
405: fixP->fx_addsy = NULL; /* no relocation entry */
406: add_symbolP = NULL;
407: break;
408:
409: case N_SECT:
410: value += add_symbolP->sy_value;
411: break;
412:
413: case N_UNDF:
414: break;
415:
416: default:
417: BAD_CASE(add_symbol_N_TYPE);
418: break;
419: }
420: }
421: }
422: down:
423: /*
424: * If the fixup expression is pc-relative then the value of the pc
425: * will be added to the expression when the machine executes the
426: * the instruction so we adjust the fixup expression's value by
427: * subtracting off the pc value (where) and adjust for insn size.
428: */
429: if(pcrel){
430: value -= size + where + fragP->fr_address;
431: if(add_symbolP == NULL){
432: fixP->fx_addsy = &abs_symbol; /* force relocation entry */
433: }
434: }
435:
436: if((size == 1 && (value & 0xffffff00) &&
437: ((value & 0xffffff80) != 0xffffff80)) ||
438: (size == 2 && (value & 0xffff8000) &&
439: ((value & 0xffff8000) != 0xffff8000)))
440: as_warn("Fixup of %ld too large for field width of %d",
441: value, size);
442:
443: /*
444: * Now place the fix expression's value in the place for the size.
445: * And save the fix expression's value to be used when creating
446: * a relocation entry if required.
447: */
448: md_number_to_imm(place, value, size, fixP, nsect);
449: fixP->fx_value = value;
450: }
451: }
452:
453:
454: /*
455: * relax_section() here we set the fr_address values in the frags.
456: * After this, all frags in this segment have addresses that are correct
457: * relative to the section (that is the section starts at address zero).
458: * After all of the sections have been processed by this call and their sizes
459: * are know then they can be slid to their final address.
460: */
461: static
462: void
463: relax_section(
464: struct frag *frag_root,
465: int nsect)
466: {
467: struct frag *fragP;
468: relax_addressT address;
469:
470: long stretch; /* May be any size, 0 or negative. */
471: /* Cumulative number of addresses we have */
472: /* relaxed this pass. */
473: /* We may have relaxed more than one address. */
474: long stretched; /* Have we stretched on this pass? */
475: /* This is 'cuz stretch may be zero, when,
476: in fact some piece of code grew, and
477: another shrank. If a branch instruction
478: doesn't fit anymore, we need another pass */
479:
480: const relax_typeS *this_type;
481: const relax_typeS *start_type;
482: relax_substateT next_state;
483: relax_substateT this_state;
484:
485: long growth;
486: long was_address;
487: long offset;
488: symbolS *symbolP;
489: long target;
490: long after;
491: long aim;
492:
493: growth = 0;
494:
495: /*
496: * For each frag in segment count and store (a 1st guess of) fr_address.
497: */
498: address = 0;
499: for(fragP = frag_root; fragP != NULL; fragP = fragP->fr_next){
500: fragP->fr_address = address;
501: address += fragP->fr_fix;
502: switch(fragP->fr_type){
503: case rs_fill:
504: address += fragP->fr_offset * fragP->fr_var;
505: break;
506:
507: case rs_align:
508: address += relax_align(address, fragP->fr_offset);
509: break;
510:
511: case rs_org:
512: /*
513: * Assume .org is nugatory. It will grow with 1st relax.
514: */
515: break;
516:
517: case rs_machine_dependent:
518: address += md_estimate_size_before_relax(fragP, nsect);
519: break;
520:
521: default:
522: BAD_CASE(fragP->fr_type);
523: break;
524: }
525: }
526:
527: /*
528: * Do relax().
529: * Make repeated passes over the chain of frags allowing each frag to
530: * grow if needed. On each pass each frag's address is incremented by
531: * the accumulated growth, kept in stretched. Passes are continued
532: * until there is no stretch on the previous pass.
533: */
534: do{
535: stretch = 0;
536: stretched = 0;
537: for(fragP = frag_root; fragP != NULL; fragP = fragP->fr_next){
538: was_address = fragP->fr_address;
539: fragP->fr_address += stretch;
540: address = fragP->fr_address;
541: symbolP = fragP->fr_symbol;
542: offset = fragP->fr_offset;
543: switch(fragP->fr_type){
544: case rs_fill: /* .fill never relaxes. */
545: growth = 0;
546: break;
547:
548: case rs_align:
549: growth = relax_align((relax_addressT)
550: (address + fragP->fr_fix), offset) -
551: relax_align((relax_addressT)
552: (was_address + fragP->fr_fix), offset);
553: break;
554:
555: case rs_org:
556: target = offset;
557: if(symbolP != NULL){
558: know(((symbolP->sy_type & N_TYPE) == N_ABS) ||
559: ((symbolP->sy_type & N_TYPE) == N_SECT));
560: know(symbolP->sy_frag);
561: know((symbolP->sy_type & N_TYPE) != N_ABS ||
562: symbolP->sy_frag == &zero_address_frag );
563: target += symbolP->sy_value +
564: symbolP->sy_frag->fr_address;
565: }
566: know(fragP->fr_next);
567: after = fragP->fr_next->fr_address;
568: /*
569: * Growth may be negative, but variable part of frag cannot
570: * have < 0 chars. That is, we can't .org backwards.
571: */
572: growth = ((target - after ) > 0) ? (target - after) : 0;
573:
574: growth -= stretch; /* This is an absolute growth factor */
575: break;
576:
577: case rs_machine_dependent:
578: this_state = fragP->fr_subtype;
579: this_type = md_relax_table + this_state;
580: start_type = this_type;
581:
582: target = offset;
583: if(symbolP){
584: know(((symbolP->sy_type & N_TYPE) == N_ABS) ||
585: ((symbolP->sy_type & N_TYPE) == N_SECT));
586: know(symbolP->sy_frag);
587: know((symbolP->sy_type & N_TYPE) != N_ABS ||
588: symbolP->sy_frag == &zero_address_frag);
589:
590: target += symbolP->sy_value +
591: symbolP->sy_frag->fr_address;
592: /*
593: * If frag has yet to be reached on this pass,
594: * assume it will move by STRETCH just as we did.
595: * If this is not so, it will be because some frag
596: * between grows, and that will force another pass.
597: */
598: if(symbolP->sy_frag->fr_address >= was_address &&
599: is_down_range(fragP, symbolP->sy_frag))
600: target += stretch;
601: }
602: aim = target - address - fragP->fr_fix;
603: if(aim < 0){
604: /* Look backwards. */
605: for(next_state = this_type->rlx_more; next_state; ){
606: if(aim >= this_type->rlx_backward)
607: next_state = 0;
608: else{ /* Grow to next state. */
609: this_state = next_state;
610: this_type = md_relax_table + this_state;
611: next_state = this_type->rlx_more;
612: }
613: }
614: }
615: else{
616: /* Look forwards. */
617: for(next_state = this_type->rlx_more; next_state; ){
618: if(aim <= this_type->rlx_forward)
619: next_state = 0;
620: else{ /* Grow to next state. */
621: this_state = next_state;
622: this_type = md_relax_table + this_state;
623: next_state = this_type->rlx_more;
624: }
625: }
626: }
627: if((growth = this_type->rlx_length -start_type->rlx_length))
628: fragP->fr_subtype = this_state;
629: break;
630:
631: default:
632: BAD_CASE(fragP->fr_type);
633: break;
634: }
635: if(growth) {
636: stretch += growth;
637: stretched++;
638: }
639: } /* For each frag in the segment. */
640: }while(stretched); /* Until nothing further to relax. */
641:
642: /*
643: * We now have valid fr_address'es for each frag. All fr_address's
644: * are correct, relative to their own section. We have made all the
645: * fixS for this section that will be made.
646: */
647: }
648:
649: /*
650: * Relax_align. Advance location counter to next address that has 'alignment'
651: * lowest order bits all 0s.
652: */
653: static
654: relax_addressT /* How many addresses does the .align take? */
655: relax_align(
656: relax_addressT address, /* Address now. */
657: long alignment) /* Alignment (binary). */
658: {
659: relax_addressT mask;
660: relax_addressT new_address;
661:
662: mask = ~ ( (~0) << alignment );
663: new_address = (address + mask) & (~ mask);
664: return(new_address - address);
665: }
666:
667: /*
668: * is_down_range() is used in relax_section() to determine it one fragment is
669: * after another to know if it will also be moved if the first is moved.
670: */
671: static
672: int
673: is_down_range(
674: struct frag *f1,
675: struct frag *f2)
676: {
677: while(f1){
678: if(f1->fr_next == f2)
679: return(1);
680: f1 = f1->fr_next;
681: }
682: return(0);
683: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.