static struct frag *bss_last_frag; /* Last frag in segment. */
#endif
+#if ! defined (BFD_ASSEMBLER) && ! defined (BFD)
static object_headers headers;
-long string_byte_count;
static char *the_object_file;
+#endif
+
+long string_byte_count;
char *next_object_file_charP; /* Tracks object file bytes. */
#ifndef OBJ_VMS
offsetT offset, int pcrel,
int r_type));
#endif
+#if defined (BFD_ASSEMBLER) || !defined (BFD)
static long fixup_segment PARAMS ((fixS * fixP, segT this_segment_type));
+#endif
static relax_addressT relax_align PARAMS ((relax_addressT addr, int align));
-void relax_segment PARAMS ((struct frag * seg_frag_root, segT seg_type));
/*
* fix_new()
fixP->fx_callj = 0;
#endif
+ as_where (&fixP->fx_file, &fixP->fx_line);
+
/* Usually, we want relocs sorted numerically, but while
comparing to older versions of gas that have relocs
reverse sorted, it is convenient to have this compile
if (length == 0)
return;
- memcpy (*charPP, fromP, (int) length);
+ memcpy (*charPP, fromP, length);
*charPP += length;
}
#endif /* BFD */
-static void
-cvt_frag_to_fill (x, fragP)
+#if defined (BFD_ASSEMBLER) || !defined (BFD)
+
#ifdef BFD_ASSEMBLER
- segT x;
-#else
- object_headers *x;
-#endif
+static void
+cvt_frag_to_fill (sec, fragP)
+ segT sec;
fragS *fragP;
-{
-#ifdef BFD_ASSEMBLER
- segT sec = x;
#else
- object_headers *headers = x;
+static void
+cvt_frag_to_fill (headers, fragP)
+ object_headers *headers;
+ fragS *fragP;
#endif
-
+{
switch (fragP->fr_type)
{
case rs_align:
}
}
+#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */
+
#ifdef BFD_ASSEMBLER
static void
relax_and_size_seg (abfd, sec, xxx)
if (symsec == &bfd_und_section
|| symsec == &bfd_abs_section
|| bfd_is_com_section (symsec))
- continue;
+ {
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+ continue;
+ }
/* Since we're reducing to section symbols, don't attempt to reduce
anything that's already using one. */
if (sym->bsym == symsec->symbol)
- continue;
+ {
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+ continue;
+ }
/* Is there some other reason we can't adjust this one? (E.g.,
call/bal links in i960-bout symbols.) */
#ifdef obj_fix_adjustable
if (! obj_fix_adjustable (fixp))
+ {
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+ continue;
+ }
+#endif
+
+ /* Is there some other (target cpu dependent) reason we can't adjust
+ this one? (E.g. relocations involving function addresses on
+ the PA. */
+#ifdef tc_fix_adjustable
+ if (! tc_fix_adjustable (fixp))
continue;
#endif
+
/* If the section symbol isn't going to be output, the relocs
at least should still work. If not, figure out what to do
when we run into that case. */
}
symseginfo->sym = fixp->fx_addsy;
}
+ fixp->fx_addsy->sy_used_in_reloc = 1;
}
dump_section_relocs (abfd, sec, stderr);
char *xxx;
{
segment_info_type *seginfo = seg_info (sec);
- unsigned long offset = 0;
- fragS *frags;
- int i, n;
+ int i;
+ unsigned int n;
arelent **relocs;
fixS *fixp;
for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
{
arelent *reloc;
- extern arelent *tc_gen_reloc ();
char *data;
bfd_reloc_status_type s;
/* Pass bogus address so that when bfd_perform_relocation adds
`address' back in, it'll come up with `data', which is where
we want it to operate. */
+ if (reloc->howto->partial_inplace == false
+ && reloc->howto->pcrel_offset == true
+ && reloc->howto->pc_relative == true)
+ {
+ /* bfd_perform_relocation screws this up */
+ reloc->addend += reloc->address;
+ }
s = bfd_perform_relocation (stdoutput, reloc, data - reloc->address,
sec, stdoutput);
switch (s)
for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
{
arelent **reloc;
- extern arelent **tc_gen_reloc ();
char *data;
bfd_reloc_status_type s;
int j;
bfd_set_reloc (stdoutput, sec, relocs, n);
else
bfd_set_section_flags (abfd, sec,
- bfd_get_section_flags (abfd, sec) & ~SEC_RELOC);
+ (bfd_get_section_flags (abfd, sec)
+ & (flagword) ~SEC_RELOC));
#ifdef DEBUG2
{
int i;
{
segment_info_type *seginfo = seg_info (sec);
unsigned long offset = 0;
- fragS *frags;
- int i, n;
- arelent **relocs;
- fixS *fixp;
+ fragS *f;
/* Write out the frags. */
- if (! (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS))
+ if (seginfo == NULL
+ || ! (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS))
return;
- for (frags = seginfo->frchainP->frch_root;
- frags;
- frags = frags->fr_next)
+ for (f = seginfo->frchainP->frch_root;
+ f;
+ f = f->fr_next)
{
int x;
unsigned long fill_size;
char *fill_literal;
long count;
- assert (frags->fr_type == rs_fill);
- if (frags->fr_fix)
+ assert (f->fr_type == rs_fill);
+ if (f->fr_fix)
{
x = bfd_set_section_contents (stdoutput, sec,
- frags->fr_literal, offset,
- frags->fr_fix);
+ f->fr_literal, (file_ptr) offset,
+ (bfd_size_type) f->fr_fix);
assert (x == true);
- offset += frags->fr_fix;
+ offset += f->fr_fix;
}
- fill_literal = frags->fr_literal + frags->fr_fix;
- fill_size = frags->fr_var;
- count = frags->fr_offset;
+ fill_literal = f->fr_literal + f->fr_fix;
+ fill_size = f->fr_var;
+ count = f->fr_offset;
assert (count >= 0);
if (fill_size && count)
while (count--)
{
x = bfd_set_section_contents (stdoutput, sec,
- fill_literal, offset,
+ fill_literal, (file_ptr) offset,
(bfd_size_type) fill_size);
assert (x == true);
offset += fill_size;
}
#endif
-#if defined(BFD_ASSEMBLER) || !defined (BFD)
+#if defined(BFD_ASSEMBLER) || (!defined (BFD) && !defined(OBJ_AOUT))
static void
merge_data_into_text ()
{
data_fix_root = NULL;
#endif
}
-#endif /* BFD_ASSEMBLER || ! BFD */
+#endif /* BFD_ASSEMBLER || (! BFD && ! OBJ_AOUT) */
#if !defined (BFD_ASSEMBLER) && !defined (BFD)
static void
bss_address_frag.fr_address = (H_GET_TEXT_SIZE (&headers) +
H_GET_DATA_SIZE (&headers));
+#endif /* ! OBJ_BOUT */
/* Slide all the frags */
if (bss_frag_root)
} /* for each bss frag */
}
-#endif /* ! OBJ_BOUT */
-
if (bss_last_frag)
H_SET_BSS_SIZE (&headers,
bss_last_frag->fr_address - bss_frag_root->fr_address);
write_object_file ()
{
register struct frchain *frchainP; /* Track along all frchains. */
+#if ! defined (BFD_ASSEMBLER) || ! defined (WORKING_DOT_WORD)
register fragS *fragP; /* Track along all frags. */
+#endif
#if !defined (BFD_ASSEMBLER) && !defined (OBJ_VMS)
long object_file_size;
#endif
#endif
for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
{
-#ifdef BFD_ASSEMBLER
subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
-#else
- subseg_new (frchainP->frch_seg, frchainP->frch_subseg);
-#endif
frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE);
/* frag_align will have left a new frag.
Use this last frag for an empty ".fill".
/* Set up symbol table, and write it out. */
if (symbol_rootP)
{
- int i = 0, n;
+ unsigned int i = 0;
+ unsigned int n;
symbolS *symp;
for (symp = symbol_rootP; symp; symp = symbol_next (symp))
{
- int keep = 0;
-
if (! symp->sy_resolved)
{
if (symp->sy_value.X_op == O_constant)
symp->bsym->flags,
segment_name (symp->bsym->section));
#endif
- {
- int punt = 0;
+ if (! symp->sy_used_in_reloc)
+ {
#ifdef obj_frob_symbol
- obj_frob_symbol (symp, punt);
- if (punt)
- goto punt_it;
+ {
+ int punt = 0;
+ obj_frob_symbol (symp, punt);
+ if (punt)
+ goto punt_it;
+ }
#endif
#ifdef tc_frob_symbol
- tc_frob_symbol (symp, punt);
- if (punt)
- goto punt_it;
+ {
+ int punt = 0;
+ tc_frob_symbol (symp, punt);
+ if (punt)
+ goto punt_it;
+ }
#endif
- }
+ }
+
/* If we don't want to keep this symbol, splice it out of the
chain now. */
- if (S_IS_LOCAL (symp))
+ if (! symp->sy_used_in_reloc
+ && S_IS_LOCAL (symp))
{
symbolS *prev, *next;
+#if defined (obj_frob_symbol) || defined (tc_frob_symbol)
punt_it:
+#endif
prev = symbol_previous (symp);
next = symbol_next (symp);
#ifdef DEBUG_SYMS
continue;
}
+ /* Make sure we really got a value for the symbol. */
+ if (! symp->sy_resolved)
+ {
+ as_bad ("can't resolve value for symbol \"%s\"",
+ S_GET_NAME (symp));
+ symp->sy_resolved = 1;
+ }
+
/* Set the value into the BFD symbol. Up til now the value
has only been kept in the gas symbolS struct. */
symp->bsym->value = S_GET_VALUE (symp);
symbolS *symbolP;
long target;
long after;
- long aim;
was_address = fragP->fr_address;
address = fragP->fr_address += stretch;
if (flagseen['K'])
{
char buf[50];
- sprint_value (buf, lie->addnum);
+ sprint_value (buf, (addressT) lie->addnum);
as_warn (".word %s-%s+%s didn't fit",
S_GET_NAME (lie->add),
S_GET_NAME (lie->sub),
const relax_typeS *start_type;
relax_substateT next_state;
relax_substateT this_state;
+ long aim;
this_state = fragP->fr_subtype;
start_type = this_type = md_relax_table + this_state;
if (symbolP)
{
+#ifndef DIFF_EXPR_OK
#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
|| (S_GET_SEGMENT (symbolP) == SEG_DATA)
|| (S_GET_SEGMENT (symbolP) == SEG_TEXT));
#endif
know (symbolP->sy_frag);
+#endif
know (!(S_GET_SEGMENT (symbolP) == absolute_section)
|| symbolP->sy_frag == &zero_address_frag);
target +=
*/
} /* relax_segment() */
+#if defined (BFD_ASSEMBLER) || !defined (BFD)
+
/* fixup_segment()
Go through all the fixS's in a segment and see which ones can be
if (!add_symbolP)
{
/* Its just -sym */
+ /* @@ Should try converting to pcrel ref to fixed addr. */
if (S_GET_SEGMENT (sub_symbolP) != absolute_section)
as_bad ("Negative of non-absolute symbol %s",
S_GET_NAME (sub_symbolP));
add_symbolP = NULL;
fixP->fx_addsy = NULL;
}
+#if !defined(SEG_DIFF_ALLOWED) && !defined (GLOBAL_DIFF_ALLOWED)
else
{
/* Different segments in subtraction. */
{
add_number -= S_GET_VALUE (sub_symbolP);
}
+#ifdef DIFF_EXPR_OK
+ else if (!pcrel
+ && S_GET_SEGMENT (sub_symbolP) == this_segment_type)
+ {
+ /* Make it pc-relative. */
+ add_number += (md_pcrel_from (fixP)
+ - S_GET_VALUE (sub_symbolP));
+ pcrel = 1;
+ fixP->fx_pcrel = 1;
+ sub_symbolP = 0;
+ fixP->fx_subsy = 0;
+ }
+#endif
else
{
char buf[50];
segment_name (S_GET_SEGMENT (sub_symbolP)),
S_GET_NAME (sub_symbolP), buf);
}
+#else
+ else
+ {
+ seg_reloc_count++;
+ fixP->fx_addnumber = add_number; /* Remember value for emit_reloc */
+ continue;
+ } /* if absolute */
+#endif
}
}
add_number += S_GET_VALUE (add_symbolP);
add_number -= md_pcrel_from (fixP);
pcrel = 0; /* Lie. Don't want further pcrel processing. */
+#ifndef TC_HPPA
fixP->fx_addsy = NULL; /* No relocations please. */
+#endif
}
else
{
seg_reloc_count++;
add_number += S_GET_VALUE (add_symbolP);
}
- } /* if not in local seg */
- } /* if there was a + symbol */
+ }
+ }
if (pcrel)
{
if ((add_number & mask) != 0
&& (add_number & mask) != mask)
{
- char buf[50];
+ char buf[50], buf2[50];
sprint_value (buf, fragP->fr_address + where);
- as_bad ("Value of %d too large for field of %d bytes at %s",
- add_number, size, buf);
+ if (add_number > 1000)
+ sprint_value (buf2, add_number);
+ else
+ sprintf (buf2, "%ld", (long) add_number);
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "Value of %s too large for field of %d bytes at %s",
+ buf2, size, buf);
} /* generic error checking */
#ifdef WARN_SIGNED_OVERFLOW_WORD
/* Warn if a .word value is too large when treated as a signed
if (!flagseen['J']
&& size == 2
&& add_number > 0x7fff)
- as_bad ("Signed .word overflow; switch may be too large; %d at 0x%x",
- add_number, fragP->fr_address + where);
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "Signed .word overflow; switch may be too large; %ld at 0x%lx",
+ (long) add_number,
+ (unsigned long) (fragP->fr_address + where));
#endif
} /* not a bit fix */
return (seg_reloc_count);
}
+#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */
+
/* end of write.c */