* as.h: If __GNUC__ and inline are both undefined, define inline away.

* write.c (cvt_frag_to_fill): Don't assume that fr_var for rs_align or rs_org
frags will be 1.
(relax_segment): For rs_align, if fr_var is not 1, complain if
required padding is not a multiple of the size of the pad pattern.
(fixup_segment): Leave gp-relative relocations alone.  For pcrel relocations
referring to the same segment, clear fx_pcrel when clearing fx_addsy.
* as.h: Adjust comments on rs_align.

* write.c, config/obj-{aout,bout,coff*}.c, config/tc-sparc.c: Query the fx_done
field instead of fx_addsy to see if the fixup still needs to be applied.  Set
fx_done and clear fx_addsy both, for now.  If TC_HANDLES_FX_DONE isn't defined,
assume md_apply_fix will only clear fx_addsy, and set fx_done accordingly after
returning.
* config/tc-sparc.h (TC_HANDLES_FX_DONE): Define.

* config/obj-coff.c (dot_text_symbol, dot_data_symbol, dot_bss_symbol): Defined
here, static.

* config/obj-aout.c [BFD_ASSEMBLER]: Undef NO_RELOC before including aout/aout64.h.

* write.c (write_object_file): If EMIT_SECTION_SYMBOLS is false, don't write
out a section symbol even if it's used in a relocation; assume relocations will
handle section numbers somehow.  Rename "punt_it" label to "punt_it_if_unused"
to reflect it's true use.
(EMIT_SECTION_SYMBOLS): Default to 1.
(adjust_reloc_syms): Don't create a new symbol for an absolute
reference; just use the absolute section symbol.
(write_relocs): Make printout of reloc values dependent on flag DEBUG3, not
DEBUG2.
* config/obj-aout.h (EMIT_SECTION_SYMBOLS): Define as 0.
* config/obj-ecoff.h (EMIT_SECTION_SYMBOLS): Ditto.
This commit is contained in:
Ken Raeburn
1994-01-28 01:21:53 +00:00
parent a98b5a1d52
commit 98c6bbbe43
6 changed files with 266 additions and 310 deletions

View File

@@ -1,5 +1,5 @@
/* write.c - emit .o file
Copyright (C) 1986, 1987, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright (C) 1986, 87, 90, 91, 92, 93, 1994 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -126,6 +126,7 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
fixP->fx_addnumber = 0;
fixP->tc_fix_data = NULL;
fixP->fx_tcbit = 0;
fixP->fx_done = 0;
#ifdef TC_something
fixP->fx_bsr = 0;
@@ -354,12 +355,10 @@ cvt_frag_to_fill (headers, fragP)
HANDLE_ALIGN (fragP);
#endif
fragP->fr_type = rs_fill;
know (fragP->fr_var == 1);
know (fragP->fr_next != NULL);
fragP->fr_offset = (fragP->fr_next->fr_address
- fragP->fr_address
- fragP->fr_fix);
- fragP->fr_fix) / fragP->fr_var;
break;
case rs_fill:
@@ -506,6 +505,10 @@ dump_section_relocs (abfd, sec, stream_)
#define dump_section_relocs(ABFD,SEC,STREAM) (void)(ABFD,SEC,STREAM)
#endif
#ifndef EMIT_SECTION_SYMBOLS
#define EMIT_SECTION_SYMBOLS 1
#endif
static void
adjust_reloc_syms (abfd, sec, xxx)
bfd *abfd;
@@ -521,11 +524,12 @@ adjust_reloc_syms (abfd, sec, xxx)
dump_section_relocs (abfd, sec, stderr);
for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
if (fixp->fx_addsy)
if (fixp->fx_done)
/* ignore it */;
else if (fixp->fx_addsy)
{
symbolS *sym = fixp->fx_addsy;
asection *symsec = sym->bsym->section;
segment_info_type *symseginfo = seg_info (symsec);
/* If it's one of these sections, assume the symbol is
definitely going to be output. The code in
@@ -542,7 +546,7 @@ adjust_reloc_syms (abfd, sec, xxx)
/* Since we're reducing to section symbols, don't attempt to reduce
anything that's already using one. */
if (sym->bsym == symsec->symbol)
if (sym->bsym->flags & BSF_SECTION_SYM)
{
fixp->fx_addsy->sy_used_in_reloc = 1;
continue;
@@ -588,8 +592,7 @@ adjust_reloc_syms (abfd, sec, xxx)
static symbolS *abs_sym;
if (!abs_sym)
{
abs_sym = symbol_new ("*absolute0zero*", &bfd_abs_section, 0,
&zero_address_frag);
abs_sym = section_symbol (absolute_section);
abs_sym->sy_used_in_reloc = 1;
}
fixp->fx_addsy = abs_sym;
@@ -610,6 +613,7 @@ write_relocs (abfd, sec, xxx)
unsigned int n;
arelent **relocs;
fixS *fixp;
char *err;
/* If seginfo is NULL, we did not create this section; don't do
anything with it. */
@@ -635,10 +639,8 @@ write_relocs (abfd, sec, xxx)
char *data;
bfd_reloc_status_type s;
if (fixp->fx_addsy == 0)
if (fixp->fx_done)
{
/* @@ Need some other flag to indicate which have already
been performed... */
n--;
continue;
}
@@ -665,7 +667,7 @@ write_relocs (abfd, sec, xxx)
we want it to operate. We can't just do it by fudging reloc->address,
since that might be used in the calculations(?). */
s = bfd_perform_relocation (stdoutput, reloc, data - reloc->address,
sec, stdoutput);
sec, stdoutput, &err);
switch (s)
{
case bfd_reloc_ok:
@@ -689,10 +691,8 @@ write_relocs (abfd, sec, xxx)
bfd_reloc_status_type s;
int j;
if (fixp->fx_addsy == 0)
if (fixp->fx_done)
{
/* @@ Need some other flag to indicate which have already
been performed... */
n--;
continue;
}
@@ -709,15 +709,15 @@ write_relocs (abfd, sec, xxx)
abort ();
for (j = 0; reloc[j]; j++)
{
s = bfd_perform_relocation (stdoutput, reloc[j],
s = bfd_perform_relocation (stdoutput, reloc[j],
data - reloc[0]->address,
sec, stdoutput);
sec, stdoutput, &err);
switch (s)
{
case bfd_reloc_ok:
break;
default:
as_fatal ("bad return from bfd_perform_relocation");
case bfd_reloc_ok:
break;
default:
as_fatal ("bad return from bfd_perform_relocation");
}
}
}
@@ -730,7 +730,8 @@ write_relocs (abfd, sec, xxx)
bfd_set_section_flags (abfd, sec,
(bfd_get_section_flags (abfd, sec)
& (flagword) ~SEC_RELOC));
#ifdef DEBUG2
#ifdef DEBUG3
{
int i;
arelent *r;
@@ -1345,7 +1346,7 @@ write_object_file ()
int punt = 0;
obj_frob_symbol (symp, punt);
if (punt)
goto punt_it;
goto punt_it_if_unused;
}
#endif
#ifdef tc_frob_symbol
@@ -1353,18 +1354,25 @@ write_object_file ()
int punt = 0;
tc_frob_symbol (symp, punt);
if (punt)
goto punt_it;
goto punt_it_if_unused;
}
#endif
if (! EMIT_SECTION_SYMBOLS
&& (symp->bsym->flags & BSF_SECTION_SYM))
goto punt_it;
/* If we don't want to keep this symbol, splice it out of the
chain now. */
if (S_IS_LOCAL (symp))
{
punt_it:
#if defined (obj_frob_symbol) || defined (tc_frob_symbol)
punt_it_if_unused:
#endif
if (! symp->sy_used_in_reloc)
{
symbolS *prev, *next;
punt_it:
prev = symbol_previous (symp);
next = symbol_next (symp);
#ifdef DEBUG_SYMS
@@ -1427,7 +1435,6 @@ write_object_file ()
}
}
#ifdef obj_frob_file
/* If obj_frob_file changes the symbol value at this point, it is
responsible for moving the changed value into symp->bsym->value
@@ -1521,7 +1528,16 @@ relax_segment (segment_frag_root, segment)
break;
case rs_align:
address += relax_align (address, (int) fragP->fr_offset);
{
int offset = relax_align (address, (int) fragP->fr_offset);
if (offset % fragP->fr_var != 0)
{
as_bad ("alignment padding (%d bytes) not a multiple of %d",
offset, fragP->fr_var);
offset -= (offset % fragP->fr_var);
}
address += offset;
}
break;
case rs_org:
@@ -1903,7 +1919,9 @@ fixup_segment (fixP, this_segment_type)
as to whether or not a relocation will be needed to
handle this fixup. */
if (!TC_FORCE_RELOCATION (fixP))
fixP->fx_addsy = NULL;
{
fixP->fx_addsy = NULL;
}
}
else
{
@@ -1931,6 +1949,13 @@ fixup_segment (fixP, this_segment_type)
sub_symbolP = 0;
fixP->fx_subsy = 0;
}
#endif
#ifdef BFD_ASSEMBLER
else if (fixP->fx_r_type == BFD_RELOC_GPREL32
|| fixP->fx_r_type == BFD_RELOC_GPREL16)
{
/* Leave it alone. */
}
#endif
else
{
@@ -1969,7 +1994,10 @@ fixup_segment (fixP, this_segment_type)
as to whether or not a relocation will be needed to
handle this fixup. */
if (!TC_FORCE_RELOCATION (fixP))
fixP->fx_addsy = NULL;
{
fixP->fx_pcrel = 0;
fixP->fx_addsy = NULL;
}
}
else
{
@@ -2005,12 +2033,8 @@ fixup_segment (fixP, this_segment_type)
* relocation.
*/
as_bad ("can't use COBR format with external label");
/* Let the target machine make the final determination
as to whether or not a relocation will be needed to
handle this fixup. */
if (!TC_FORCE_RELOCATION (fixP))
fixP->fx_addsy = NULL;
fixP->fx_addsy = NULL;
fixP->fx_done = 1;
continue;
} /* COBR */
#endif /* TC_I960 */
@@ -2038,18 +2062,19 @@ fixup_segment (fixP, this_segment_type)
{
fixP->fx_addsy = &abs_symbol;
++seg_reloc_count;
} /* if there's an add_symbol */
} /* if pcrel */
}
}
if (!fixP->fx_bit_fixP && size > 0)
{
valueT mask = 0;
/* set all bits to one */
mask--;
/* Technically speaking, combining these produces an
undefined result if size is sizeof (valueT), though I
think these two half-way operations should both be
defined. */
/* Technically, combining these produces an undefined result
if size is sizeof (valueT), though I think these two
half-way operations should both be defined. And the
compiler should be able to combine them if it's valid on
the host architecture. */
mask <<= size * 4;
mask <<= size * 4;
if ((add_number & mask) != 0
@@ -2079,12 +2104,25 @@ fixup_segment (fixP, this_segment_type)
#endif
} /* not a bit fix */
if (!fixP->fx_done)
{
#ifdef BFD_ASSEMBLER
md_apply_fix (fixP, &add_number);
md_apply_fix (fixP, &add_number);
#else
md_apply_fix (fixP, add_number);
md_apply_fix (fixP, add_number);
#endif
#ifndef TC_HANDLES_FX_DONE
/* If the tc-* files haven't been converted, assume it's handling
it the old way, where a null fx_addsy means that the fix has
been applied completely, and no further work is needed. */
if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
fixP->fx_done = 1;
#endif
}
#ifdef TC_VALIDATE_FIX
skip:
#endif
;
} /* For each fixS in this segment. */