diff options
Diffstat (limited to 'gas/write.c')
-rw-r--r-- | gas/write.c | 117 |
1 files changed, 78 insertions, 39 deletions
diff --git a/gas/write.c b/gas/write.c index 71b5fec..7df2d3c 100644 --- a/gas/write.c +++ b/gas/write.c @@ -502,6 +502,22 @@ cvt_frag_to_fill (headersP, sec, fragP) case rs_fill: break; + case rs_leb128: + { + valueT value = S_GET_VALUE (fragP->fr_symbol); + int size; + + size = output_leb128 (fragP->fr_literal + fragP->fr_fix, value, + fragP->fr_subtype); + + fragP->fr_fix += size; + fragP->fr_type = rs_fill; + fragP->fr_var = 0; + fragP->fr_offset = 0; + fragP->fr_symbol = NULL; + } + break; + case rs_machine_dependent: #ifdef BFD_ASSEMBLER md_convert_frag (stdoutput, sec, fragP); @@ -695,9 +711,9 @@ adjust_reloc_syms (abfd, sec, xxx) symbols, though, since they are not in the regular symbol table. */ if (sym != NULL && ! sym->sy_resolved) - resolve_symbol_value (sym); + resolve_symbol_value (sym, 1); if (fixp->fx_subsy != NULL && ! fixp->fx_subsy->sy_resolved) - resolve_symbol_value (fixp->fx_subsy); + resolve_symbol_value (fixp->fx_subsy, 1); /* If this symbol is equated to an undefined symbol, convert the fixup to being against that symbol. */ @@ -1301,10 +1317,47 @@ set_symtab () } #endif +/* Finish the subsegments. After every sub-segment, we fake an + ".align ...". This conforms to BSD4.2 brane-damage. We then fake + ".fill 0" because that is the kind of frag that requires least + thought. ".align" frags like to have a following frag since that + makes calculating their intended length trivial. */ + +#ifndef SUB_SEGMENT_ALIGN +#ifdef BFD_ASSEMBLER +#define SUB_SEGMENT_ALIGN(SEG) (0) +#else +#define SUB_SEGMENT_ALIGN(SEG) (2) +#endif +#endif + +void +subsegs_finish () +{ + struct frchain *frchainP; + + for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next) + { + subseg_set (frchainP->frch_seg, frchainP->frch_subseg); + frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE, 0); + + /* frag_align will have left a new frag. + Use this last frag for an empty ".fill". + + For this segment ... + Create a last frag. Do not leave a "being filled in frag". */ + + frag_wane (frag_now); + frag_now->fr_fix = 0; + know (frag_now->fr_next == NULL); + } +} + +/* Write the object file. */ + void write_object_file () { - struct frchain *frchainP; /* Track along all frchains. */ #if ! defined (BFD_ASSEMBLER) || ! defined (WORKING_DOT_WORD) fragS *fragP; /* Track along all frags. */ #endif @@ -1339,34 +1392,6 @@ write_object_file () vms_check_for_main (); #endif /* OBJ_VMS */ - /* After every sub-segment, we fake an ".align ...". This conforms to - BSD4.2 brane-damage. We then fake ".fill 0" because that is the kind of - frag that requires least thought. ".align" frags like to have a - following frag since that makes calculating their intended length - trivial. - - @@ Is this really necessary?? */ -#ifndef SUB_SEGMENT_ALIGN -#ifdef BFD_ASSEMBLER -#define SUB_SEGMENT_ALIGN(SEG) (0) -#else -#define SUB_SEGMENT_ALIGN(SEG) (2) -#endif -#endif - for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next) - { - subseg_set (frchainP->frch_seg, frchainP->frch_subseg); - frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE, 0); - /* frag_align will have left a new frag. - Use this last frag for an empty ".fill". - - For this segment ... - Create a last frag. Do not leave a "being filled in frag". */ - frag_wane (frag_now); - frag_now->fr_fix = 0; - know (frag_now->fr_next == NULL); - } - /* From now on, we don't care about sub-segments. Build one frag chain for each segment. Linked thru fr_next. */ @@ -1711,7 +1736,7 @@ write_object_file () for (symp = symbol_rootP; symp; symp = symbol_next (symp)) if (!symp->sy_resolved) - resolve_symbol_value (symp); + resolve_symbol_value (symp, 1); } PROGRESS (1); @@ -1768,7 +1793,7 @@ write_object_file () symp->sy_resolved = 1; } else - resolve_symbol_value (symp); + resolve_symbol_value (symp, 1); } /* Skip symbols which were equated to undefined or common @@ -2094,6 +2119,12 @@ relax_segment (segment_frag_root, segment) break; #endif + case rs_leb128: + /* Initial guess is always 1; doing otherwise can result in + stable solutions that are larger than the minimum. */ + address += fragP->fr_offset = 1; + break; + default: BAD_CASE (fragP->fr_type); break; @@ -2283,6 +2314,18 @@ relax_segment (segment_frag_root, segment) #endif break; + case rs_leb128: + { + valueT value; + int size; + + value = resolve_symbol_value (fragP->fr_symbol, 0); + size = sizeof_leb128 (value, fragP->fr_subtype); + growth = size - fragP->fr_offset; + fragP->fr_offset = size; + } + break; + default: BAD_CASE (fragP->fr_type); break; @@ -2390,7 +2433,7 @@ fixup_segment (fixP, this_segment_type) if (sub_symbolP) { - resolve_symbol_value (sub_symbolP); + resolve_symbol_value (sub_symbolP, 1); if (add_symbolP == NULL || add_symbol_segment == absolute_section) { if (add_symbolP != NULL) @@ -2588,15 +2631,11 @@ fixup_segment (fixP, this_segment_type) else { seg_reloc_count++; -/* start-sanitize-v850 */ #if !(defined (TC_V850) && defined (OBJ_ELF)) -/* end-sanitize-v850 */ #if !(defined (TC_M68K) && defined (OBJ_ELF)) -#if !defined (TC_I386) || !(defined (OBJ_ELF) || defined (OBJ_COFF)) +#if !defined (TC_I386) || !(defined (OBJ_ELF) || defined (OBJ_COFF)) || defined (TE_PE) add_number += S_GET_VALUE (add_symbolP); -/* start-sanitize-v850 */ #endif -/* end-sanitize-v850 */ #endif #endif } |