/* 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.
#include "obstack.h"
#ifndef BFD_ASSEMBLER
-lineno *lineno_rootP;
const short seg_N_TYPE[] =
{ /* in: segT out: N_TYPE bits */
C_DATA_SECTION,
C_BSS_SECTION,
C_UNDEF_SECTION, /* SEG_UNKNOWN */
- C_UNDEF_SECTION, /* SEG_ABSENT */
- C_UNDEF_SECTION, /* SEG_PASS1 */
C_UNDEF_SECTION, /* SEG_GOOF */
- C_UNDEF_SECTION, /* SEG_BIG */
- C_UNDEF_SECTION, /* SEG_DIFFERENCE */
+ C_UNDEF_SECTION, /* SEG_EXPR */
C_DEBUG_SECTION, /* SEG_DEBUG */
C_NTV_SECTION, /* SEG_NTV */
C_PTV_SECTION, /* SEG_PTV */
};
#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 PARAMS ((char *name));
#ifdef BFD_HEADERS
static void obj_coff_section_header_append PARAMS ((char **where, SCNHDR * header));
#endif
static void obj_coff_def PARAMS ((int what));
-static void obj_coff_dim PARAMS ((void));
-static void obj_coff_endef PARAMS ((void));
-static void obj_coff_line PARAMS ((void));
+static void obj_coff_dim PARAMS ((int));
+static void obj_coff_endef PARAMS ((int));
+static void obj_coff_line PARAMS ((int));
static void obj_coff_ln PARAMS ((int));
-static void obj_coff_scl PARAMS ((void));
-static void obj_coff_size PARAMS ((void));
-static void obj_coff_stab PARAMS ((int what));
-static void obj_coff_tag PARAMS ((void));
-static void obj_coff_type PARAMS ((void));
-static void obj_coff_val PARAMS ((void));
+static void obj_coff_scl PARAMS ((int));
+static void obj_coff_size PARAMS ((int));
+static void obj_coff_tag PARAMS ((int));
+static void obj_coff_type PARAMS ((int));
+static void obj_coff_val PARAMS ((int));
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
static void SA_SET_SYM_ENDNDX PARAMS ((symbolS *, symbolS *));
static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
#endif
-int line_base;
-
static struct hash_control *tag_hash;
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[] =
{
#ifndef IGNORE_DEBUG
{"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 (?) */
/* other stuff */
{"ABORT", s_abort, 0},
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 */
/* Relocation. */
fixS *p;
for (count = 0, p = fixP; p; p = p->fx_next)
- if (p->fx_addsy)
+ if (!p->fx_done)
count++;
if (!count)
return;
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;
#if defined(TC_M68K)
ri_table[i].r_type = (fixP->fx_pcrel
? R_IPRMED
: R_RELLONG);
- callj_table[i] = fixP->fx_callj ? 1 : 0;
+ callj_table[i] = fixP->fx_tcbit ? 1 : 0;
rtype_ok = 1;
#endif
#if defined(TC_A29K)
#ifdef TC_I960
free (callj_table);
#endif
-
- return;
-} /* obj_emit_relocations() */
+}
/* Coff file generation & utilities */
obj_coff_section_header_append (where, &text_section_header);
obj_coff_section_header_append (where, &data_section_header);
obj_coff_section_header_append (where, &bss_section_header);
-
- return;
-} /* obj_header_append() */
+}
#endif /* ! BFD_HEADERS */
}; /* for each aux in use */
#endif /* BFD_HEADERS */
- return;
-} /* obj_symbol_to_chars() */
+}
#ifdef BFD_HEADERS
static void
append (where, (char *) header, sizeof (*header));
#endif /* CROSS_COMPILE */
-
- return;
-} /* obj_coff_section_header_append() */
+}
#endif
void
/* Move the debug flags. */
SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
-} /* c_symbol_merge() */
+}
static symbolS *previous_file_symbol;
void
SF_SET_STATICS (symbolP);
return (char *) symbolP;
-} /* c_section_symbol() */
+}
+#ifndef BFD_ASSEMBLER
void
c_section_header (header,
name,
? STYP_BSS
: STYP_INFO);
}
+#endif
/* Line number handling */
+int line_base;
+
#ifdef BFD_ASSEMBLER
/* 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
/* Offset in line#s where the last function started (the odd entry for
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;
text_lineno_number by write.c. */
int our_lineno_number;
+lineno *lineno_rootP;
lineno *lineno_lastP;
-#endif
-#ifndef BFD_ASSEMBLER
int
c_line_new (paddr, line_number, frag)
long paddr;
lineno_lastP = new_line;
return LINESZ * our_lineno_number++;
}
-#endif
void
obj_emit_lineno (where, line, file_start)
char **where;
-#ifndef BFD_ASSEMBLER /* sigh */
lineno *line;
-#endif
char *file_start;
{
-#ifndef BFD_ASSEMBLER
#ifdef BFD_HEADERS
struct bfd_internal_lineno *line_entry;
#else
LINENO *line_entry;
#endif
+ char *where2 = *where;
+
for (; line; line = line->next)
{
line_entry = &line->line;
symbolP = (symbolS *) line_entry->l_addr.l_symndx;
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;
-
- } /* if this is a function linno */
+ symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = where2 - file_start;
+ }
#ifdef BFD_HEADERS
- *where += bfd_coff_swap_lineno_out (stdoutput, line_entry, *where);
+ where2 += bfd_coff_swap_lineno_out (stdoutput, line_entry, where2);
#else
/* No matter which member of the union we process, they are
both long. */
-#ifdef CROSS_COMPILE
- md_number_to_chars (*where, line_entry->l_addr.l_paddr, sizeof (line_entry->l_addr.l_paddr));
- *where += sizeof (line_entry->l_addr.l_paddr);
+ md_number_to_chars (where2, line_entry->l_addr.l_paddr, sizeof (line_entry->l_addr.l_paddr));
+ where2 += sizeof (line_entry->l_addr.l_paddr);
- md_number_to_chars (*where, line_entry->l_lnno, sizeof (line_entry->l_lnno));
- *where += sizeof (line_entry->l_lnno);
+ md_number_to_chars (where2, line_entry->l_lnno, sizeof (line_entry->l_lnno));
+ where2 += sizeof (line_entry->l_lnno);
#ifdef TC_I960
- **where = '0';
- ++*where;
- **where = '0';
- ++*where;
+ *where2++ = '0';
+ *where2++ = '0';
#endif /* TC_I960 */
-#else /* CROSS_COMPILE */
- append (where, (char *) line_entry, LINESZ);
-#endif /* CROSS_COMPILE */
#endif /* BFD_HEADERS */
- } /* for each line number */
-#else /* BFD_ASSEMBLER */
- abort ();
-#endif /* BFD_ASSEMBLER */
+ }
+ *where = where2;
}
+#endif /* ! BFD_ASSEMBLER */
+
+\f
void
obj_symbol_new_hook (symbolP)
symbolS *symbolP;
SF_SET_LOCAL (symbolP);
}
+\f
/* stack stuff */
stack *
stack_init (chunk_size, element_size)
memcpy (st->data + st->pointer, element, st->element_size);
st->pointer += st->element_size;
return st->data + st->pointer;
-} /* stack_push() */
+}
char *
stack_pop (st)
}
l = get_absolute_expression ();
+ if (!appline)
+ {
#ifdef BFD_ASSEMBLER
- add_lineno (frag_now, frag_now_fix (), l);
+ add_lineno (frag_now, frag_now_fix (), l);
#else
- c_line_new (frag_now_fix (), l, frag_now);
+ c_line_new (frag_now_fix (), l, frag_now);
#endif
+ }
#ifndef NO_LISTING
{
#endif
demand_empty_rest_of_line ();
-} /* obj_coff_ln() */
+}
/*
* def()
#endif
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))
SF_SET_STRING (def_symbol_in_progress);
unsigned int dim_index;
static void
-obj_coff_endef ()
+obj_coff_endef (ignored)
{
symbolS *symbolP;
/* DIM BUG FIX sac@cygnus.com */
#endif
if (name[1] == 'b' && name[2] == 'f')
{
- if (function_lineoff < 0)
+ if (! in_function ())
as_warn ("`%s' symbol without preceding function", name);
#ifdef BFD_ASSEMBLER
- abort ();
+/* SA_SET_SYM_LNNO (def_symbol_in_progress, 12345);*/
#else
SA_GET_SYM_LNNOPTR (def_symbol_in_progress) = function_lineoff;
#endif
/* Will need relocating */
SF_SET_PROCESS (def_symbol_in_progress);
-#ifdef BFD_ASSEMBLER
- function_lineoff = 0;
-#else
- function_lineoff = -1;
-#endif
+ clear_function ();
}
}
break;
if (SF_GET_FUNCTION (def_symbol_in_progress))
{
know (sizeof (def_symbol_in_progress) <= sizeof (long));
-#ifdef BFD_ASSEMBLER
- 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
+ set_function (def_symbol_in_progress);
SF_SET_PROCESS (def_symbol_in_progress);
if (symbolP == NULL)
/* That is, if this is the first time we've seen the
function... */
symbol_table_insert (def_symbol_in_progress);
- } /* definition follows debug */
- } /* Create the line number entry pointing to the function being defined */
+ } /* definition follows debug */
+ } /* Create the line number entry pointing to the function being defined */
def_symbol_in_progress = NULL;
demand_empty_rest_of_line ();
- return;
}
static void
-obj_coff_dim ()
+obj_coff_dim (ignored)
{
- register int dim_index;
+ int dim_index;
if (def_symbol_in_progress == NULL)
{
for (dim_index = 0; dim_index < DIMNUM; dim_index++)
{
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)
{
-
case ',':
input_line_pointer++;
break;
case ';':
dim_index = DIMNUM;
break;
- } /* switch on following character */
- } /* for each dimension */
+ }
+ }
demand_empty_rest_of_line ();
- return;
-} /* obj_coff_dim() */
+}
static void
-obj_coff_line ()
+obj_coff_line (ignored)
{
int this_base;
if (def_symbol_in_progress == NULL)
{
+ /* Probably stabs-style line? */
obj_coff_ln (0);
return;
- } /* if it looks like a stabs style line */
+ }
this_base = get_absolute_expression ();
if (this_base > line_base)
- {
- line_base = this_base;
- }
-
+ line_base = this_base;
S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
SA_SET_SYM_LNNO (def_symbol_in_progress, line_base);
demand_empty_rest_of_line ();
- return;
-} /* obj_coff_line() */
+}
static void
-obj_coff_size ()
+obj_coff_size (ignored)
{
if (def_symbol_in_progress == NULL)
{
S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
demand_empty_rest_of_line ();
- return;
-} /* obj_coff_size() */
+}
static void
-obj_coff_scl ()
+obj_coff_scl (ignored)
{
if (def_symbol_in_progress == NULL)
{
S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
demand_empty_rest_of_line ();
- return;
-} /* obj_coff_scl() */
+}
static void
-obj_coff_tag ()
+obj_coff_tag (ignored)
{
char *symbol_name;
char name_end;
as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
demand_empty_rest_of_line ();
return;
- } /* if not inside .def/.endef */
+ }
S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
symbol_name = input_line_pointer;
name_end = get_symbol_end ();
- /* Assume that the symbol referred to by .tag is always defined. */
- /* This was a bad assumption. I've added find_or_make. xoxorich. */
+ /* Assume that the symbol referred to by .tag is always defined.
+ This was a bad assumption. I've added find_or_make. xoxorich. */
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)
{
as_warn ("tag not found for .tag %s", symbol_name);
*input_line_pointer = name_end;
demand_empty_rest_of_line ();
-} /* obj_coff_tag() */
+}
static void
-obj_coff_type ()
+obj_coff_type (ignored)
{
if (def_symbol_in_progress == NULL)
{
} /* is a function */
demand_empty_rest_of_line ();
- return;
-} /* obj_coff_type() */
+}
static void
-obj_coff_val ()
+obj_coff_val (ignored)
{
if (def_symbol_in_progress == NULL)
{
}
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 =
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_seg = undefined_section;
/* If the segment is undefined when the forward reference is
resolved, then copy the segment id from the forward
} /* if symbol based */
demand_empty_rest_of_line ();
- return;
-} /* obj_coff_val() */
+}
/*
* Maintain a list of the tagnames of the structres.
tag_init ()
{
tag_hash = hash_new ();
- return;
-} /* tag_init() */
+}
static void
tag_insert (name, symbolP)
- CONST char *name;
+ const char *name;
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",
name, error_string);
}
- return;
-} /* tag_insert() */
+}
static symbolS *
tag_find_or_make (name)
symbol_table_insert (symbolP);
} /* not found */
- return (symbolP);
-} /* tag_find_or_make() */
+ return symbolP;
+}
static symbolS *
tag_find (name)
if (*name == '_')
name++;
#endif /* STRIP_UNDERSCORE */
- return ((symbolS *) hash_find (tag_hash, name));
-} /* tag_find() */
+ return (symbolS *) hash_find (tag_hash, name);
+}
void
obj_read_begin_hook ()
tag_init ();
}
+#ifndef BFD_ASSEMBLER
void
obj_crawl_symbol_chain (headers)
object_headers *headers;
{
know (!previous_file_symbol);
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
*/
- dot_text_symbol = (symbolS *)
- c_section_symbol (".text",
- 0,
- H_GET_TEXT_SIZE (headers),
- 0 /*text_relocation_number */ ,
- 0 /*text_lineno_number */ );
+ dot_text_symbol = (symbolS *) c_section_symbol (".text",
+ 0,
+ H_GET_TEXT_SIZE (headers),
+ 0 /*text_relocation_number*/,
+ 0 /*text_lineno_number */);
#ifdef TE_I386AIX
symbol_remove (dot_text_symbol, &symbol_rootP, &symbol_lastP);
symbol_append (dot_text_symbol, previous_file_symbol,
} /* for each line number */
H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
-
- return;
}
/*
/* Count the number of relocation entries for text and data */
for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
{
- if (fixP->fx_addsy)
+ if (!fixP->fx_done)
{
++text_relocation_number;
#ifdef TC_I960
/* two relocs per callj under coff. */
- if (fixP->fx_callj)
+ if (fixP->fx_tcbit)
{
++text_relocation_number;
} /* if callj and not already fixed. */
++text_relocation_number;
}
#endif
-
} /* if not yet fixed */
} /* for each fix */
for (fixP = data_fix_root; fixP; fixP = fixP->fx_next)
{
- if (fixP->fx_addsy)
+ if (!fixP->fx_done)
{
++data_relocation_number;
} /* if still relocatable */
++data_relocation_number;
}
#endif
-
- } /* for each fix */
-
+ }
SA_SET_SCN_NRELOC (dot_data_symbol, data_relocation_number);
/* Assign the size of the section */
/* symbol table size allready set */
H_SET_SIZEOF_OPTIONAL_HEADER (headers, OBJ_COFF_AOUTHDRSZ);
- /* do not added the F_RELFLG for the standard COFF.
- * The AIX linker complain on file with relocation info striped flag.
- */
+ /* Do not added the F_RELFLG for the standard COFF. The AIX linker
+ complain on file with relocation info striped flag. */
#ifdef KEEP_RELOC_INFO
H_SET_FLAGS (headers, (text_lineno_number == 0 ? F_LNNO : 0)
| BYTE_ORDERING);
0, /* No line number information */
section_alignment[(int) SEG_BSS]);
}
-
-/* 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() */
+#endif
#ifdef BFD_ASSEMBLER
static
align (val, exp)
{
int n = (1 << exp) - 1;
- printf ("align (%x, %x)\n", val, exp);
val = (val + n) & ~n;
return val;
}
void
-coff_check_file_symbols (symp, punt)
+coff_frob_symbol (symp, punt)
symbolS *symp;
int *punt;
{
static symbolS *last_functionP, *last_tagP;
static stack *block_stack;
+ if (current_lineno_sym)
+ add_linesym ((symbolS *) 0);
+
if (!block_stack)
block_stack = stack_init (512, sizeof (symbolS*));
-#if 1
if (!S_IS_DEFINED (symp) && S_GET_STORAGE_CLASS (symp) != C_STAT)
S_SET_STORAGE_CLASS (symp, C_EXT);
-#endif
if (!SF_GET_DEBUG (symp))
{
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;
/* more ... */
}
exp = 0;
}
- printf ("change_to_section(`%s',%d,%x)\n", section_name, len,exp);
*section_name_end = c;
}
assert (previous_file_symbol == 0);
c_dot_file_symbol ("fake");
}
- if (current_lineno_sym)
- add_linesym ((symbolS *) 0);
}
#endif /* BFD_ASSEMBLER */
#ifdef DEBUG
/* for debugging */
-CONST char *
+const char *
s_get_name (s)
symbolS *s;
{
/* 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.
fixP->fx_addnumber = 0;
fixP->tc_fix_data = NULL;
fixP->fx_tcbit = 0;
+ fixP->fx_done = 0;
#ifdef TC_something
fixP->fx_bsr = 0;
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:
#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;
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
/* 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;
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;
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. */
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;
}
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:
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;
}
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");
}
}
}
bfd_set_section_flags (abfd, sec,
(bfd_get_section_flags (abfd, sec)
& (flagword) ~SEC_RELOC));
-#ifdef DEBUG2
+
+#ifdef DEBUG3
{
int i;
arelent *r;
int punt = 0;
obj_frob_symbol (symp, punt);
if (punt)
- goto punt_it;
+ goto punt_it_if_unused;
}
#endif
#ifdef tc_frob_symbol
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
}
}
-
#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
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:
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
{
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
{
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
{
* 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 */
{
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
#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. */