* 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

@ -79,6 +79,10 @@
#endif #endif
#endif /* ! __STDC__ */ #endif /* ! __STDC__ */
#if !defined (__GNUC__) && !defined (inline)
#define inline
#endif
#ifndef FOPEN_WB #ifndef FOPEN_WB
#include "fopen-same.h" #include "fopen-same.h"
#endif #endif
@ -228,7 +232,7 @@ typedef enum _relax_state
constant length frag. */ constant length frag. */
rs_fill = 1, rs_fill = 1,
/* Align: Fr_offset: power of 2. 1 variable char: fill character. */ /* Align: Fr_offset: power of 2. Variable chars: fill pattern. */
rs_align, rs_align,
/* Org: Fr_offset, fr_symbol: address. 1 variable char: fill /* Org: Fr_offset, fr_symbol: address. 1 variable char: fill

View File

@ -93,7 +93,7 @@ obj_emit_relocations (where, fixP, segment_address_in_file)
{ {
for (; fixP; fixP = fixP->fx_next) for (; fixP; fixP = fixP->fx_next)
{ {
if (fixP->fx_addsy != NULL if (fixP->fx_done == 0
|| fixP->fx_r_type != NO_RELOC) || fixP->fx_r_type != NO_RELOC)
{ {
tc_bout_fix_to_chars (*where, fixP, segment_address_in_file); tc_bout_fix_to_chars (*where, fixP, segment_address_in_file);

View File

@ -1,5 +1,5 @@
/* coff object file format /* coff object file format
Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
This file is part of GAS. This file is part of GAS.
@ -22,7 +22,6 @@
#include "obstack.h" #include "obstack.h"
#ifndef BFD_ASSEMBLER #ifndef BFD_ASSEMBLER
lineno *lineno_rootP;
const short seg_N_TYPE[] = const short seg_N_TYPE[] =
{ /* in: segT out: N_TYPE bits */ { /* in: segT out: N_TYPE bits */
@ -31,11 +30,8 @@ const short seg_N_TYPE[] =
C_DATA_SECTION, C_DATA_SECTION,
C_BSS_SECTION, C_BSS_SECTION,
C_UNDEF_SECTION, /* SEG_UNKNOWN */ C_UNDEF_SECTION, /* SEG_UNKNOWN */
C_UNDEF_SECTION, /* SEG_ABSENT */
C_UNDEF_SECTION, /* SEG_PASS1 */
C_UNDEF_SECTION, /* SEG_GOOF */ C_UNDEF_SECTION, /* SEG_GOOF */
C_UNDEF_SECTION, /* SEG_BIG */ C_UNDEF_SECTION, /* SEG_EXPR */
C_UNDEF_SECTION, /* SEG_DIFFERENCE */
C_DEBUG_SECTION, /* SEG_DEBUG */ C_DEBUG_SECTION, /* SEG_DEBUG */
C_NTV_SECTION, /* SEG_NTV */ C_NTV_SECTION, /* SEG_NTV */
C_PTV_SECTION, /* SEG_PTV */ C_PTV_SECTION, /* SEG_PTV */
@ -62,7 +58,7 @@ const segT N_TYPE_seg[32] =
}; };
#endif #endif
char *s_get_name PARAMS ((symbolS * s)); const char *s_get_name PARAMS ((symbolS * s));
static symbolS *tag_find_or_make PARAMS ((char *name)); static symbolS *tag_find_or_make PARAMS ((char *name));
static symbolS *tag_find PARAMS ((char *name)); static symbolS *tag_find PARAMS ((char *name));
#ifdef BFD_HEADERS #ifdef BFD_HEADERS
@ -71,29 +67,30 @@ static void obj_coff_section_header_append PARAMS ((char **where, struct interna
static void obj_coff_section_header_append PARAMS ((char **where, SCNHDR * header)); static void obj_coff_section_header_append PARAMS ((char **where, SCNHDR * header));
#endif #endif
static void obj_coff_def PARAMS ((int what)); static void obj_coff_def PARAMS ((int what));
static void obj_coff_dim PARAMS ((void)); static void obj_coff_dim PARAMS ((int));
static void obj_coff_endef PARAMS ((void)); static void obj_coff_endef PARAMS ((int));
static void obj_coff_line PARAMS ((void)); static void obj_coff_line PARAMS ((int));
static void obj_coff_ln PARAMS ((int)); static void obj_coff_ln PARAMS ((int));
static void obj_coff_scl PARAMS ((void)); static void obj_coff_scl PARAMS ((int));
static void obj_coff_size PARAMS ((void)); static void obj_coff_size PARAMS ((int));
static void obj_coff_stab PARAMS ((int what)); static void obj_coff_tag PARAMS ((int));
static void obj_coff_tag PARAMS ((void)); static void obj_coff_type PARAMS ((int));
static void obj_coff_type PARAMS ((void)); static void obj_coff_val PARAMS ((int));
static void obj_coff_val PARAMS ((void));
static void tag_init PARAMS ((void)); static void tag_init PARAMS ((void));
static void tag_insert PARAMS ((char *name, symbolS * symbolP)); static void tag_insert PARAMS ((const char *name, symbolS * symbolP));
#ifdef BFD_ASSEMBLER #ifdef BFD_ASSEMBLER
static void SA_SET_SYM_ENDNDX PARAMS ((symbolS *, symbolS *)); static void SA_SET_SYM_ENDNDX PARAMS ((symbolS *, symbolS *));
static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *)); static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
#endif #endif
int line_base;
static struct hash_control *tag_hash; static struct hash_control *tag_hash;
static symbolS *def_symbol_in_progress; static symbolS *def_symbol_in_progress;
static symbolS *dot_text_symbol;
static symbolS *dot_data_symbol;
static symbolS *dot_bss_symbol;
const pseudo_typeS obj_pseudo_table[] = const pseudo_typeS obj_pseudo_table[] =
{ {
#ifndef IGNORE_DEBUG #ifndef IGNORE_DEBUG
@ -123,16 +120,6 @@ const pseudo_typeS obj_pseudo_table[] =
{"ident", s_ignore, 0}, /* we don't yet handle this. */ {"ident", s_ignore, 0}, /* we don't yet handle this. */
/* stabs aka a.out aka b.out directives for debug symbols.
Currently ignored silently. Except for .line at which
we guess from context. */
{"desc", s_ignore, 0}, /* def */
{"stabd", obj_coff_stab, 'd'},/* stabs */
{"stabn", obj_coff_stab, 'n'},/* stabs */
{"stabs", obj_coff_stab, 's'},/* stabs */
/* stabs-in-coff (?) debug pseudos (ignored) */
{"optim", s_ignore, 0}, /* For sun386i cc (?) */ {"optim", s_ignore, 0}, /* For sun386i cc (?) */
/* other stuff */ /* other stuff */
{"ABORT", s_abort, 0}, {"ABORT", s_abort, 0},
@ -207,6 +194,38 @@ SA_SET_SYM_TAGNDX (sym, val)
entry->fix_tag = 1; entry->fix_tag = 1;
} }
static int
S_GET_DATA_TYPE (sym)
symbolS *sym;
{
return coffsymbol (sym->bsym)->native->u.syment.n_type;
}
static int
S_SET_DATA_TYPE (sym, val)
symbolS *sym;
int val;
{
coffsymbol (sym->bsym)->native->u.syment.n_type = val;
return val;
}
int
S_GET_STORAGE_CLASS (sym)
symbolS *sym;
{
return coffsymbol (sym->bsym)->native->u.syment.n_sclass;
}
int
S_SET_STORAGE_CLASS (sym, val)
symbolS *sym;
int val;
{
coffsymbol (sym->bsym)->native->u.syment.n_sclass = val;
return val;
}
#else /* ! BFD_ASSEMBLER */ #else /* ! BFD_ASSEMBLER */
/* Relocation. */ /* Relocation. */
@ -247,7 +266,7 @@ obj_emit_relocations (where, fixP, segment_address_in_file)
fixS *p; fixS *p;
for (count = 0, p = fixP; p; p = p->fx_next) for (count = 0, p = fixP; p; p = p->fx_next)
if (p->fx_addsy) if (!p->fx_done)
count++; count++;
if (!count) if (!count)
return; return;
@ -268,7 +287,8 @@ obj_emit_relocations (where, fixP, segment_address_in_file)
for (i = 0; fixP; fixP = fixP->fx_next) for (i = 0; fixP; fixP = fixP->fx_next)
{ {
if (symbolP = fixP->fx_addsy) symbolP = fixP->fx_addsy;
if (!fixP->fx_done)
{ {
int rtype_ok = 0; int rtype_ok = 0;
#if defined(TC_M68K) #if defined(TC_M68K)
@ -297,7 +317,7 @@ obj_emit_relocations (where, fixP, segment_address_in_file)
ri_table[i].r_type = (fixP->fx_pcrel ri_table[i].r_type = (fixP->fx_pcrel
? R_IPRMED ? R_IPRMED
: R_RELLONG); : R_RELLONG);
callj_table[i] = fixP->fx_callj ? 1 : 0; callj_table[i] = fixP->fx_tcbit ? 1 : 0;
rtype_ok = 1; rtype_ok = 1;
#endif #endif
#if defined(TC_A29K) #if defined(TC_A29K)
@ -387,9 +407,7 @@ obj_emit_relocations (where, fixP, segment_address_in_file)
#ifdef TC_I960 #ifdef TC_I960
free (callj_table); free (callj_table);
#endif #endif
}
return;
} /* obj_emit_relocations() */
/* Coff file generation & utilities */ /* Coff file generation & utilities */
@ -470,9 +488,7 @@ obj_header_append (where, headers)
obj_coff_section_header_append (where, &text_section_header); obj_coff_section_header_append (where, &text_section_header);
obj_coff_section_header_append (where, &data_section_header); obj_coff_section_header_append (where, &data_section_header);
obj_coff_section_header_append (where, &bss_section_header); obj_coff_section_header_append (where, &bss_section_header);
}
return;
} /* obj_header_append() */
#endif /* ! BFD_HEADERS */ #endif /* ! BFD_HEADERS */
@ -592,8 +608,7 @@ obj_symbol_to_chars (where, symbolP)
}; /* for each aux in use */ }; /* for each aux in use */
#endif /* BFD_HEADERS */ #endif /* BFD_HEADERS */
return; }
} /* obj_symbol_to_chars() */
#ifdef BFD_HEADERS #ifdef BFD_HEADERS
static void static void
@ -651,9 +666,7 @@ obj_coff_section_header_append (where, header)
append (where, (char *) header, sizeof (*header)); append (where, (char *) header, sizeof (*header));
#endif /* CROSS_COMPILE */ #endif /* CROSS_COMPILE */
}
return;
} /* obj_coff_section_header_append() */
#endif #endif
void void
@ -727,7 +740,7 @@ c_symbol_merge (debug, normal)
/* Move the debug flags. */ /* Move the debug flags. */
SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug)); SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
} /* c_symbol_merge() */ }
static symbolS *previous_file_symbol; static symbolS *previous_file_symbol;
void void
@ -828,8 +841,9 @@ c_section_symbol (name, value, length, nreloc, nlnno)
SF_SET_STATICS (symbolP); SF_SET_STATICS (symbolP);
return (char *) symbolP; return (char *) symbolP;
} /* c_section_symbol() */ }
#ifndef BFD_ASSEMBLER
void void
c_section_header (header, c_section_header (header,
name, name,
@ -882,19 +896,30 @@ c_section_header (header,
? STYP_BSS ? STYP_BSS
: STYP_INFO); : STYP_INFO);
} }
#endif
/* Line number handling */ /* Line number handling */
int line_base;
#ifdef BFD_ASSEMBLER #ifdef BFD_ASSEMBLER
/* Symbol of last function, which we should hang line#s off of. */ /* Symbol of last function, which we should hang line#s off of. */
symbolS *function_lineoff; static symbolS *line_fsym;
#define in_function() (line_fsym != 0)
#define clear_function() (line_fsym = 0)
#define set_function(F) (line_fsym = (F), add_linesym (F))
#else #else
/* Offset in line#s where the last function started (the odd entry for /* Offset in line#s where the last function started (the odd entry for
line #0). */ line #0). */
int function_lineoff = -1; static int function_lineoff = -1;
#define in_function() (function_lineoff >= 0)
#define clear_function() (function_lineoff = -1)
#define set_function(F) (function_lineoff = c_line_new ((long) (F), 0, &zero_address_frag))
int text_lineno_number; int text_lineno_number;
@ -903,10 +928,9 @@ int text_lineno_number;
text_lineno_number by write.c. */ text_lineno_number by write.c. */
int our_lineno_number; int our_lineno_number;
lineno *lineno_rootP;
lineno *lineno_lastP; lineno *lineno_lastP;
#endif
#ifndef BFD_ASSEMBLER
int int
c_line_new (paddr, line_number, frag) c_line_new (paddr, line_number, frag)
long paddr; long paddr;
@ -927,22 +951,20 @@ c_line_new (paddr, line_number, frag)
lineno_lastP = new_line; lineno_lastP = new_line;
return LINESZ * our_lineno_number++; return LINESZ * our_lineno_number++;
} }
#endif
void void
obj_emit_lineno (where, line, file_start) obj_emit_lineno (where, line, file_start)
char **where; char **where;
#ifndef BFD_ASSEMBLER /* sigh */
lineno *line; lineno *line;
#endif
char *file_start; char *file_start;
{ {
#ifndef BFD_ASSEMBLER
#ifdef BFD_HEADERS #ifdef BFD_HEADERS
struct bfd_internal_lineno *line_entry; struct bfd_internal_lineno *line_entry;
#else #else
LINENO *line_entry; LINENO *line_entry;
#endif #endif
char *where2 = *where;
for (; line; line = line->next) for (; line; line = line->next)
{ {
line_entry = &line->line; line_entry = &line->line;
@ -961,38 +983,32 @@ obj_emit_lineno (where, line, file_start)
symbolP = (symbolS *) line_entry->l_addr.l_symndx; symbolP = (symbolS *) line_entry->l_addr.l_symndx;
line_entry->l_addr.l_symndx = symbolP->sy_number; line_entry->l_addr.l_symndx = symbolP->sy_number;
symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = *where - file_start; symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = where2 - file_start;
}
} /* if this is a function linno */
#ifdef BFD_HEADERS #ifdef BFD_HEADERS
*where += bfd_coff_swap_lineno_out (stdoutput, line_entry, *where); where2 += bfd_coff_swap_lineno_out (stdoutput, line_entry, where2);
#else #else
/* No matter which member of the union we process, they are /* No matter which member of the union we process, they are
both long. */ both long. */
#ifdef CROSS_COMPILE md_number_to_chars (where2, line_entry->l_addr.l_paddr, sizeof (line_entry->l_addr.l_paddr));
md_number_to_chars (*where, line_entry->l_addr.l_paddr, sizeof (line_entry->l_addr.l_paddr)); where2 += sizeof (line_entry->l_addr.l_paddr);
*where += sizeof (line_entry->l_addr.l_paddr);
md_number_to_chars (*where, line_entry->l_lnno, sizeof (line_entry->l_lnno)); md_number_to_chars (where2, line_entry->l_lnno, sizeof (line_entry->l_lnno));
*where += sizeof (line_entry->l_lnno); where2 += sizeof (line_entry->l_lnno);
#ifdef TC_I960 #ifdef TC_I960
**where = '0'; *where2++ = '0';
++*where; *where2++ = '0';
**where = '0';
++*where;
#endif /* TC_I960 */ #endif /* TC_I960 */
#else /* CROSS_COMPILE */
append (where, (char *) line_entry, LINESZ);
#endif /* CROSS_COMPILE */
#endif /* BFD_HEADERS */ #endif /* BFD_HEADERS */
} /* for each line number */ }
#else /* BFD_ASSEMBLER */ *where = where2;
abort ();
#endif /* BFD_ASSEMBLER */
} }
#endif /* ! BFD_ASSEMBLER */
void void
obj_symbol_new_hook (symbolP) obj_symbol_new_hook (symbolP)
symbolS *symbolP; symbolS *symbolP;
@ -1035,6 +1051,7 @@ obj_symbol_new_hook (symbolP)
SF_SET_LOCAL (symbolP); SF_SET_LOCAL (symbolP);
} }
/* stack stuff */ /* stack stuff */
stack * stack *
stack_init (chunk_size, element_size) stack_init (chunk_size, element_size)
@ -1081,7 +1098,7 @@ stack_push (st, element)
memcpy (st->data + st->pointer, element, st->element_size); memcpy (st->data + st->pointer, element, st->element_size);
st->pointer += st->element_size; st->pointer += st->element_size;
return st->data + st->pointer; return st->data + st->pointer;
} /* stack_push() */ }
char * char *
stack_pop (st) stack_pop (st)
@ -1158,11 +1175,14 @@ obj_coff_ln (appline)
} }
l = get_absolute_expression (); l = get_absolute_expression ();
if (!appline)
{
#ifdef BFD_ASSEMBLER #ifdef BFD_ASSEMBLER
add_lineno (frag_now, frag_now_fix (), l); add_lineno (frag_now, frag_now_fix (), l);
#else #else
c_line_new (frag_now_fix (), l, frag_now); c_line_new (frag_now_fix (), l, frag_now);
#endif #endif
}
#ifndef NO_LISTING #ifndef NO_LISTING
{ {
@ -1178,7 +1198,7 @@ obj_coff_ln (appline)
#endif #endif
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
} /* obj_coff_ln() */ }
/* /*
* def() * def()
@ -1241,6 +1261,7 @@ obj_coff_def (what)
#endif #endif
def_symbol_in_progress->sy_frag = &zero_address_frag; def_symbol_in_progress->sy_frag = &zero_address_frag;
S_SET_VALUE (def_symbol_in_progress, 0);
if (S_IS_STRING (def_symbol_in_progress)) if (S_IS_STRING (def_symbol_in_progress))
SF_SET_STRING (def_symbol_in_progress); SF_SET_STRING (def_symbol_in_progress);
@ -1252,7 +1273,7 @@ obj_coff_def (what)
unsigned int dim_index; unsigned int dim_index;
static void static void
obj_coff_endef () obj_coff_endef (ignored)
{ {
symbolS *symbolP; symbolS *symbolP;
/* DIM BUG FIX sac@cygnus.com */ /* DIM BUG FIX sac@cygnus.com */
@ -1300,20 +1321,16 @@ obj_coff_endef ()
#endif #endif
if (name[1] == 'b' && name[2] == 'f') if (name[1] == 'b' && name[2] == 'f')
{ {
if (function_lineoff < 0) if (! in_function ())
as_warn ("`%s' symbol without preceding function", name); as_warn ("`%s' symbol without preceding function", name);
#ifdef BFD_ASSEMBLER #ifdef BFD_ASSEMBLER
abort (); /* SA_SET_SYM_LNNO (def_symbol_in_progress, 12345);*/
#else #else
SA_GET_SYM_LNNOPTR (def_symbol_in_progress) = function_lineoff; SA_GET_SYM_LNNOPTR (def_symbol_in_progress) = function_lineoff;
#endif #endif
/* Will need relocating */ /* Will need relocating */
SF_SET_PROCESS (def_symbol_in_progress); SF_SET_PROCESS (def_symbol_in_progress);
#ifdef BFD_ASSEMBLER clear_function ();
function_lineoff = 0;
#else
function_lineoff = -1;
#endif
} }
} }
break; break;
@ -1425,13 +1442,7 @@ obj_coff_endef ()
if (SF_GET_FUNCTION (def_symbol_in_progress)) if (SF_GET_FUNCTION (def_symbol_in_progress))
{ {
know (sizeof (def_symbol_in_progress) <= sizeof (long)); know (sizeof (def_symbol_in_progress) <= sizeof (long));
#ifdef BFD_ASSEMBLER set_function (def_symbol_in_progress);
function_lineoff = def_symbol_in_progress;
add_linesym (def_symbol_in_progress);
#else
function_lineoff = c_line_new ((long) def_symbol_in_progress, 0,
&zero_address_frag);
#endif
SF_SET_PROCESS (def_symbol_in_progress); SF_SET_PROCESS (def_symbol_in_progress);
if (symbolP == NULL) if (symbolP == NULL)
@ -1439,18 +1450,17 @@ obj_coff_endef ()
/* That is, if this is the first time we've seen the /* That is, if this is the first time we've seen the
function... */ function... */
symbol_table_insert (def_symbol_in_progress); symbol_table_insert (def_symbol_in_progress);
} /* definition follows debug */ } /* definition follows debug */
} /* Create the line number entry pointing to the function being defined */ } /* Create the line number entry pointing to the function being defined */
def_symbol_in_progress = NULL; def_symbol_in_progress = NULL;
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
return;
} }
static void static void
obj_coff_dim () obj_coff_dim (ignored)
{ {
register int dim_index; int dim_index;
if (def_symbol_in_progress == NULL) if (def_symbol_in_progress == NULL)
{ {
@ -1464,11 +1474,11 @@ obj_coff_dim ()
for (dim_index = 0; dim_index < DIMNUM; dim_index++) for (dim_index = 0; dim_index < DIMNUM; dim_index++)
{ {
SKIP_WHITESPACES (); SKIP_WHITESPACES ();
SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index, get_absolute_expression ()); SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
get_absolute_expression ());
switch (*input_line_pointer) switch (*input_line_pointer)
{ {
case ',': case ',':
input_line_pointer++; input_line_pointer++;
break; break;
@ -1480,40 +1490,36 @@ obj_coff_dim ()
case ';': case ';':
dim_index = DIMNUM; dim_index = DIMNUM;
break; break;
} /* switch on following character */ }
} /* for each dimension */ }
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
return; }
} /* obj_coff_dim() */
static void static void
obj_coff_line () obj_coff_line (ignored)
{ {
int this_base; int this_base;
if (def_symbol_in_progress == NULL) if (def_symbol_in_progress == NULL)
{ {
/* Probably stabs-style line? */
obj_coff_ln (0); obj_coff_ln (0);
return; return;
} /* if it looks like a stabs style line */ }
this_base = get_absolute_expression (); this_base = get_absolute_expression ();
if (this_base > line_base) if (this_base > line_base)
{ line_base = this_base;
line_base = this_base;
}
S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
SA_SET_SYM_LNNO (def_symbol_in_progress, line_base); SA_SET_SYM_LNNO (def_symbol_in_progress, line_base);
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
return; }
} /* obj_coff_line() */
static void static void
obj_coff_size () obj_coff_size (ignored)
{ {
if (def_symbol_in_progress == NULL) if (def_symbol_in_progress == NULL)
{ {
@ -1525,11 +1531,10 @@ obj_coff_size ()
S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ()); SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
return; }
} /* obj_coff_size() */
static void static void
obj_coff_scl () obj_coff_scl (ignored)
{ {
if (def_symbol_in_progress == NULL) if (def_symbol_in_progress == NULL)
{ {
@ -1540,11 +1545,10 @@ obj_coff_scl ()
S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ()); S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
return; }
} /* obj_coff_scl() */
static void static void
obj_coff_tag () obj_coff_tag (ignored)
{ {
char *symbol_name; char *symbol_name;
char name_end; char name_end;
@ -1554,16 +1558,16 @@ obj_coff_tag ()
as_warn (".tag pseudo-op used outside of .def/.endef ignored."); as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
return; return;
} /* if not inside .def/.endef */ }
S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
symbol_name = input_line_pointer; symbol_name = input_line_pointer;
name_end = get_symbol_end (); name_end = get_symbol_end ();
/* Assume that the symbol referred to by .tag is always defined. */ /* Assume that the symbol referred to by .tag is always defined.
/* This was a bad assumption. I've added find_or_make. xoxorich. */ This was a bad assumption. I've added find_or_make. xoxorich. */
SA_SET_SYM_TAGNDX (def_symbol_in_progress, SA_SET_SYM_TAGNDX (def_symbol_in_progress,
(long) tag_find_or_make (symbol_name)); tag_find_or_make (symbol_name));
if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L) if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
{ {
as_warn ("tag not found for .tag %s", symbol_name); as_warn ("tag not found for .tag %s", symbol_name);
@ -1573,10 +1577,10 @@ obj_coff_tag ()
*input_line_pointer = name_end; *input_line_pointer = name_end;
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
} /* obj_coff_tag() */ }
static void static void
obj_coff_type () obj_coff_type (ignored)
{ {
if (def_symbol_in_progress == NULL) if (def_symbol_in_progress == NULL)
{ {
@ -1594,11 +1598,10 @@ obj_coff_type ()
} /* is a function */ } /* is a function */
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
return; }
} /* obj_coff_type() */
static void static void
obj_coff_val () obj_coff_val (ignored)
{ {
if (def_symbol_in_progress == NULL) if (def_symbol_in_progress == NULL)
{ {
@ -1620,11 +1623,11 @@ obj_coff_val ()
} }
else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name)) else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
{ {
def_symbol_in_progress->sy_value.X_op = O_symbol;
def_symbol_in_progress->sy_value.X_add_symbol = def_symbol_in_progress->sy_value.X_add_symbol =
symbol_find_or_make (symbol_name); symbol_find_or_make (symbol_name);
def_symbol_in_progress->sy_value.X_subtract_symbol = NULL; def_symbol_in_progress->sy_value.X_op_symbol = NULL;
def_symbol_in_progress->sy_value.X_add_number = 0; def_symbol_in_progress->sy_value.X_add_number = 0;
def_symbol_in_progress->sy_value.X_seg = undefined_section;
/* If the segment is undefined when the forward reference is /* If the segment is undefined when the forward reference is
resolved, then copy the segment id from the forward resolved, then copy the segment id from the forward
@ -1640,8 +1643,7 @@ obj_coff_val ()
} /* if symbol based */ } /* if symbol based */
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
return; }
} /* obj_coff_val() */
/* /*
* Maintain a list of the tagnames of the structres. * Maintain a list of the tagnames of the structres.
@ -1651,23 +1653,21 @@ static void
tag_init () tag_init ()
{ {
tag_hash = hash_new (); tag_hash = hash_new ();
return; }
} /* tag_init() */
static void static void
tag_insert (name, symbolP) tag_insert (name, symbolP)
CONST char *name; const char *name;
symbolS *symbolP; symbolS *symbolP;
{ {
register char *error_string; const char *error_string;
if (*(error_string = hash_jam (tag_hash, name, (char *) symbolP))) if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
{ {
as_fatal ("Inserting \"%s\" into structure table failed: %s", as_fatal ("Inserting \"%s\" into structure table failed: %s",
name, error_string); name, error_string);
} }
return; }
} /* tag_insert() */
static symbolS * static symbolS *
tag_find_or_make (name) tag_find_or_make (name)
@ -1684,8 +1684,8 @@ tag_find_or_make (name)
symbol_table_insert (symbolP); symbol_table_insert (symbolP);
} /* not found */ } /* not found */
return (symbolP); return symbolP;
} /* tag_find_or_make() */ }
static symbolS * static symbolS *
tag_find (name) tag_find (name)
@ -1695,8 +1695,8 @@ tag_find (name)
if (*name == '_') if (*name == '_')
name++; name++;
#endif /* STRIP_UNDERSCORE */ #endif /* STRIP_UNDERSCORE */
return ((symbolS *) hash_find (tag_hash, name)); return (symbolS *) hash_find (tag_hash, name);
} /* tag_find() */ }
void void
obj_read_begin_hook () obj_read_begin_hook ()
@ -1709,6 +1709,7 @@ obj_read_begin_hook ()
tag_init (); tag_init ();
} }
#ifndef BFD_ASSEMBLER
void void
obj_crawl_symbol_chain (headers) obj_crawl_symbol_chain (headers)
object_headers *headers; object_headers *headers;
@ -1742,17 +1743,16 @@ obj_crawl_symbol_chain (headers)
{ {
know (!previous_file_symbol); know (!previous_file_symbol);
c_dot_file_symbol ("fake"); c_dot_file_symbol ("fake");
} /* Is there a .file symbol ? If not insert one at the beginning. */ } /* Is there a .file symbol? If not, insert one at the beginning. */
/* /*
* Build up static symbols for .text, .data and .bss * Build up static symbols for .text, .data and .bss
*/ */
dot_text_symbol = (symbolS *) dot_text_symbol = (symbolS *) c_section_symbol (".text",
c_section_symbol (".text", 0,
0, H_GET_TEXT_SIZE (headers),
H_GET_TEXT_SIZE (headers), 0 /*text_relocation_number*/,
0 /*text_relocation_number */ , 0 /*text_lineno_number */);
0 /*text_lineno_number */ );
#ifdef TE_I386AIX #ifdef TE_I386AIX
symbol_remove (dot_text_symbol, &symbol_rootP, &symbol_lastP); symbol_remove (dot_text_symbol, &symbol_rootP, &symbol_lastP);
symbol_append (dot_text_symbol, previous_file_symbol, symbol_append (dot_text_symbol, previous_file_symbol,
@ -2055,8 +2055,6 @@ obj_crawl_symbol_chain (headers)
} /* for each line number */ } /* for each line number */
H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
return;
} }
/* /*
@ -2110,12 +2108,12 @@ obj_pre_write_hook (headers)
/* Count the number of relocation entries for text and data */ /* Count the number of relocation entries for text and data */
for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
{ {
if (fixP->fx_addsy) if (!fixP->fx_done)
{ {
++text_relocation_number; ++text_relocation_number;
#ifdef TC_I960 #ifdef TC_I960
/* two relocs per callj under coff. */ /* two relocs per callj under coff. */
if (fixP->fx_callj) if (fixP->fx_tcbit)
{ {
++text_relocation_number; ++text_relocation_number;
} /* if callj and not already fixed. */ } /* if callj and not already fixed. */
@ -2127,7 +2125,6 @@ obj_pre_write_hook (headers)
++text_relocation_number; ++text_relocation_number;
} }
#endif #endif
} /* if not yet fixed */ } /* if not yet fixed */
} /* for each fix */ } /* for each fix */
@ -2139,7 +2136,7 @@ obj_pre_write_hook (headers)
for (fixP = data_fix_root; fixP; fixP = fixP->fx_next) for (fixP = data_fix_root; fixP; fixP = fixP->fx_next)
{ {
if (fixP->fx_addsy) if (!fixP->fx_done)
{ {
++data_relocation_number; ++data_relocation_number;
} /* if still relocatable */ } /* if still relocatable */
@ -2150,9 +2147,7 @@ obj_pre_write_hook (headers)
++data_relocation_number; ++data_relocation_number;
} }
#endif #endif
}
} /* for each fix */
SA_SET_SCN_NRELOC (dot_data_symbol, data_relocation_number); SA_SET_SCN_NRELOC (dot_data_symbol, data_relocation_number);
/* Assign the size of the section */ /* Assign the size of the section */
@ -2193,9 +2188,8 @@ obj_pre_write_hook (headers)
/* symbol table size allready set */ /* symbol table size allready set */
H_SET_SIZEOF_OPTIONAL_HEADER (headers, OBJ_COFF_AOUTHDRSZ); H_SET_SIZEOF_OPTIONAL_HEADER (headers, OBJ_COFF_AOUTHDRSZ);
/* do not added the F_RELFLG for the standard COFF. /* Do not added the F_RELFLG for the standard COFF. The AIX linker
* The AIX linker complain on file with relocation info striped flag. complain on file with relocation info striped flag. */
*/
#ifdef KEEP_RELOC_INFO #ifdef KEEP_RELOC_INFO
H_SET_FLAGS (headers, (text_lineno_number == 0 ? F_LNNO : 0) H_SET_FLAGS (headers, (text_lineno_number == 0 ? F_LNNO : 0)
| BYTE_ORDERING); | BYTE_ORDERING);
@ -2253,89 +2247,7 @@ obj_pre_write_hook (headers)
0, /* No line number information */ 0, /* No line number information */
section_alignment[(int) SEG_BSS]); section_alignment[(int) SEG_BSS]);
} }
#endif
/* This is a copy from aout. All I do is neglect to actually build the symbol. */
static void
obj_coff_stab (what)
int what;
{
char *string;
expressionS e;
int goof = 0; /* TRUE if we have aborted. */
int length;
int saved_type = 0;
long longint;
symbolS *symbolP = 0;
if (what == 's')
{
string = demand_copy_C_string (&length);
SKIP_WHITESPACE ();
if (*input_line_pointer == ',')
{
input_line_pointer++;
}
else
{
as_bad ("I need a comma after symbol's name");
goof = 1;
} /* better be a comma */
} /* skip the string */
/*
* Input_line_pointer->after ','. String->symbol name.
*/
if (!goof)
{
if (get_absolute_expression_and_terminator (&longint) != ',')
{
as_bad ("I want a comma after the n_type expression");
goof = 1;
input_line_pointer--; /* Backup over a non-',' char. */
} /* on error */
} /* no error */
if (!goof)
{
if (get_absolute_expression_and_terminator (&longint) != ',')
{
as_bad ("I want a comma after the n_other expression");
goof = 1;
input_line_pointer--; /* Backup over a non-',' char. */
} /* on error */
} /* no error */
if (!goof)
{
get_absolute_expression ();
if (what == 's' || what == 'n')
{
if (*input_line_pointer != ',')
{
as_bad ("I want a comma after the n_desc expression");
goof = 1;
}
else
{
input_line_pointer++;
} /* on goof */
} /* not stabd */
} /* no error */
expression (&e);
if (goof)
{
ignore_rest_of_line ();
}
else
{
demand_empty_rest_of_line ();
} /* on error */
} /* obj_coff_stab() */
#ifdef BFD_ASSEMBLER #ifdef BFD_ASSEMBLER
static static
@ -2343,26 +2255,26 @@ unsigned long
align (val, exp) align (val, exp)
{ {
int n = (1 << exp) - 1; int n = (1 << exp) - 1;
printf ("align (%x, %x)\n", val, exp);
val = (val + n) & ~n; val = (val + n) & ~n;
return val; return val;
} }
void void
coff_check_file_symbols (symp, punt) coff_frob_symbol (symp, punt)
symbolS *symp; symbolS *symp;
int *punt; int *punt;
{ {
static symbolS *last_functionP, *last_tagP; static symbolS *last_functionP, *last_tagP;
static stack *block_stack; static stack *block_stack;
if (current_lineno_sym)
add_linesym ((symbolS *) 0);
if (!block_stack) if (!block_stack)
block_stack = stack_init (512, sizeof (symbolS*)); block_stack = stack_init (512, sizeof (symbolS*));
#if 1
if (!S_IS_DEFINED (symp) && S_GET_STORAGE_CLASS (symp) != C_STAT) if (!S_IS_DEFINED (symp) && S_GET_STORAGE_CLASS (symp) != C_STAT)
S_SET_STORAGE_CLASS (symp, C_EXT); S_SET_STORAGE_CLASS (symp, C_EXT);
#endif
if (!SF_GET_DEBUG (symp)) if (!SF_GET_DEBUG (symp))
{ {
@ -2435,7 +2347,9 @@ coff_check_file_symbols (symp, punt)
S_SET_VALUE (symp, 0); S_SET_VALUE (symp, 0);
} }
} }
if (SF_GET_LOCAL (symp)) if (S_IS_EXTERNAL (symp))
S_SET_STORAGE_CLASS (symp, C_EXT);
else if (SF_GET_LOCAL (symp))
*punt = 1; *punt = 1;
/* more ... */ /* more ... */
} }
@ -2492,7 +2406,6 @@ DEFUN_VOID(obj_coff_section)
exp = 0; exp = 0;
} }
printf ("change_to_section(`%s',%d,%x)\n", section_name, len,exp);
*section_name_end = c; *section_name_end = c;
} }
@ -2505,14 +2418,12 @@ coff_frob_file ()
assert (previous_file_symbol == 0); assert (previous_file_symbol == 0);
c_dot_file_symbol ("fake"); c_dot_file_symbol ("fake");
} }
if (current_lineno_sym)
add_linesym ((symbolS *) 0);
} }
#endif /* BFD_ASSEMBLER */ #endif /* BFD_ASSEMBLER */
#ifdef DEBUG #ifdef DEBUG
/* for debugging */ /* for debugging */
CONST char * const char *
s_get_name (s) s_get_name (s)
symbolS *s; symbolS *s;
{ {

View File

@ -332,9 +332,7 @@ DEFUN (count_entries_in_chain, (idx),
{ {
if (TC_COUNT_RELOC (fixup_ptr)) if (TC_COUNT_RELOC (fixup_ptr))
{ {
#ifdef TC_A29K #ifdef TC_A29K
if (fixup_ptr->fx_r_type == RELOC_CONSTH) if (fixup_ptr->fx_r_type == RELOC_CONSTH)
nrelocs += 2; nrelocs += 2;
else else
@ -2419,9 +2417,8 @@ DEFUN (fixup_segment, (segP, this_segment_type),
#ifdef TC_I960 #ifdef TC_I960
if (fixP->fx_tcbit && TC_S_IS_CALLNAME (add_symbolP)) if (fixP->fx_tcbit && TC_S_IS_CALLNAME (add_symbolP))
{ {
/* Relocation should be done via the /* Relocation should be done via the associated 'bal' entry
associated 'bal' entry point point symbol. */
symbol. */
if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP))) if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP)))
{ {
@ -2430,7 +2427,7 @@ DEFUN (fixup_segment, (segP, this_segment_type),
continue; continue;
} }
fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP); fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
} /* callj relocation */ }
#endif #endif
sub_symbolP = fixP->fx_subsy; sub_symbolP = fixP->fx_subsy;
add_number = fixP->fx_offset; add_number = fixP->fx_offset;
@ -2461,9 +2458,9 @@ DEFUN (fixup_segment, (segP, this_segment_type),
&& (SEG_NORMAL (add_symbol_segment) && (SEG_NORMAL (add_symbol_segment)
|| (add_symbol_segment == SEG_ABSOLUTE))) || (add_symbol_segment == SEG_ABSOLUTE)))
{ {
/* Difference of 2 symbols from same segment. */ /* Difference of 2 symbols from same segment. Can't
/* Can't make difference of 2 undefineds: 'value' means */ make difference of 2 undefineds: 'value' means
/* something different for N_UNDF. */ something different for N_UNDF. */
#ifdef TC_I960 #ifdef TC_I960
/* Makes no sense to use the difference of 2 arbitrary symbols /* Makes no sense to use the difference of 2 arbitrary symbols
as the target of a call instruction. */ as the target of a call instruction. */
@ -2477,6 +2474,7 @@ DEFUN (fixup_segment, (segP, this_segment_type),
add_symbolP = NULL; add_symbolP = NULL;
fixP->fx_addsy = NULL; fixP->fx_addsy = NULL;
fixP->fx_done = 1;
} }
else else
{ {
@ -2536,7 +2534,8 @@ DEFUN (fixup_segment, (segP, this_segment_type),
add_number -= segP->scnhdr.s_vaddr; add_number -= segP->scnhdr.s_vaddr;
#endif #endif
pcrel = 0; /* Lie. Don't want further pcrel processing. */ pcrel = 0; /* Lie. Don't want further pcrel processing. */
fixP->fx_addsy = NULL; /* No relocations please. */ fixP->fx_addsy = NULL;
fixP->fx_done = 1;
} }
else else
{ {
@ -2548,6 +2547,7 @@ DEFUN (fixup_segment, (segP, this_segment_type),
#endif /* TC_I960 */ #endif /* TC_I960 */
add_number += S_GET_VALUE (add_symbolP); add_number += S_GET_VALUE (add_symbolP);
fixP->fx_addsy = NULL; fixP->fx_addsy = NULL;
fixP->fx_done = 1;
add_symbolP = NULL; add_symbolP = NULL;
break; break;
default: default:
@ -2572,7 +2572,8 @@ DEFUN (fixup_segment, (segP, this_segment_type),
* relocation. * relocation.
*/ */
as_bad ("can't use COBR format with external label"); as_bad ("can't use COBR format with external label");
fixP->fx_addsy = NULL; /* No relocations please. */ fixP->fx_addsy = NULL;
fixP->fx_done = 1;
continue; continue;
} /* COBR */ } /* COBR */
#endif /* TC_I960 */ #endif /* TC_I960 */

View File

@ -53,3 +53,5 @@ extern void ecoff_frob_file PARAMS ((void));
/* At the moment we don't want to do any stabs processing in read.c. */ /* At the moment we don't want to do any stabs processing in read.c. */
#define OBJ_PROCESS_STAB(what, string, type, other, desc) \ #define OBJ_PROCESS_STAB(what, string, type, other, desc) \
ecoff_stab ((what), (string), (type), (other), (desc)) ecoff_stab ((what), (string), (type), (other), (desc))
#define EMIT_SECTION_SYMBOLS 0

View File

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