static long fixup_segment PARAMS ((fixS * fixP, segT this_segment_type));
#endif
static relax_addressT relax_align PARAMS ((relax_addressT addr, int align));
+#if defined (BFD_ASSEMBLER) || ! defined (BFD)
+static fragS *chain_frchains_together_1 PARAMS ((segT, struct frchain *));
+#endif
+#ifdef BFD_ASSEMBLER
+static void chain_frchains_together PARAMS ((bfd *, segT, PTR));
+static void cvt_frag_to_fill PARAMS ((segT, fragS *));
+static void relax_and_size_seg PARAMS ((bfd *, asection *, PTR));
+static void adjust_reloc_syms PARAMS ((bfd *, asection *, PTR));
+static void write_relocs PARAMS ((bfd *, asection *, PTR));
+static void write_contents PARAMS ((bfd *, asection *, PTR));
+static void set_symtab PARAMS ((void));
+#endif
+#if defined (BFD_ASSEMBLER) || (! defined (BFD) && ! defined (OBJ_AOUT))
+static void merge_data_into_text PARAMS ((void));
+#endif
+#if ! defined (BFD_ASSEMBLER) && ! defined (BFD)
+static void cvt_frag_to_fill PARAMS ((object_headers *, segT, fragS *));
+static void remove_subsegs PARAMS ((frchainS *, int, fragS **, fragS **));
+static void relax_and_size_all_segments PARAMS ((void));
+#endif
/*
* fix_new()
/* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if
the difference expression cannot immediately be reduced. */
{
- extern symbolS *make_expr_symbol ();
symbolS *stmp = make_expr_symbol (exp);
exp->X_op = O_symbol;
exp->X_op_symbol = 0;
#if !defined (BFD) && !defined (BFD_ASSEMBLER)
-void
+static void
remove_subsegs (head, seg, root, last)
frchainS *head;
int seg;
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);
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. */
}
#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
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. */
for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
{
+ /* At this point we have linked all the frags into a single
+ chain. However, cvt_frag_to_fill may call md_convert_frag
+ which may call fix_new. We need to ensure that fix_new adds
+ the fixup to the right section. */
+ if (fragP == data_frag_root)
+ subseg_change (SEG_DATA, 0);
+
cvt_frag_to_fill (&headers, SEG_TEXT, fragP);
/* Some assert macros don't work with # directives mixed in. */
for (symp = symbol_rootP; symp; symp = symbol_next (symp))
if (!symp->sy_resolved)
- resolve_symbol_value (symp);
+ resolve_symbol_value (symp, 1);
}
PROGRESS (1);
symp->sy_resolved = 1;
}
else
- resolve_symbol_value (symp);
+ resolve_symbol_value (symp, 1);
}
/* Skip symbols which were equated to undefined or common
#ifdef TC_GENERIC_RELAX_TABLE
+static int is_dnrange PARAMS ((fragS *, fragS *));
+
/* Subroutines of relax_segment. */
static int
is_dnrange (f1, f2)
- struct frag *f1;
- struct frag *f2;
+ fragS *f1;
+ fragS *f2;
{
for (; f1; f1 = f1->fr_next)
if (f1->fr_next == f2)
/*#else*/
/* This machine doesn't want to use pcrel_adjust.
In that case, pcrel_adjust should be zero. */
-/* assert (fragP->fr_pcrel_adjust == 0);*/
+/* assert (fragP->fr_targ.ns32k.pcrel_adjust == 0);*/
#endif
#ifdef md_prepare_relax_scan /* formerly called M68K_AIM_KLUDGE */
md_prepare_relax_scan (fragP, address, aim, this_state, this_type);
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;
#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;
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)
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
}
/* for debugging */
extern int indent_level;
-extern void print_symbol_value_1 ();
void
print_fixup (fixp)