aboutsummaryrefslogtreecommitdiff
path: root/gas/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/write.c')
-rw-r--r--gas/write.c117
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
}