/* coff object file format
- Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1997
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
Free Software Foundation, Inc.
This file is part of GAS.
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+#define OBJ_HEADER "obj-coff.h"
+
#include "as.h"
#include "obstack.h"
#include "subsegs.h"
#define KEEP_RELOC_INFO
#endif
+static void obj_coff_bss PARAMS ((int));
const char *s_get_name PARAMS ((symbolS * s));
static symbolS *def_symbol_in_progress;
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);
}
}
return symbolP;
}
+/* We accept the .bss directive to set the section for backward
+ compatibility with earlier versions of gas. */
+
+static void
+obj_coff_bss (ignore)
+ int ignore;
+{
+ if (*input_line_pointer == '\n')
+ subseg_new (".bss", get_absolute_expression ());
+ else
+ s_lcomm (0);
+}
+/* Handle .weak. This is a GNU extension. */
+
+static void
+obj_coff_weak (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+
+#ifdef BFD_ASSEMLER
+ S_SET_WEAK (symbolP);
+#endif
+
+#ifdef TE_PE
+ S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
+#else
+ S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT);
+#endif
+
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+
+ demand_empty_rest_of_line ();
+}
#ifdef BFD_ASSEMBLER
{
combined_entry_type *entry, *p;
- entry = &coffsymbol (sym->bsym)->native[1];
- p = coffsymbol (val->bsym)->native;
+ entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
+ p = coffsymbol (symbol_get_bfdsym (val))->native;
entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
entry->fix_end = 1;
}
{
combined_entry_type *entry, *p;
- entry = &coffsymbol (sym->bsym)->native[1];
- p = coffsymbol (val->bsym)->native;
+ entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
+ p = coffsymbol (symbol_get_bfdsym (val))->native;
entry->u.auxent.x_sym.x_tagndx.p = p;
entry->fix_tag = 1;
}
S_GET_DATA_TYPE (sym)
symbolS *sym;
{
- return coffsymbol (sym->bsym)->native->u.syment.n_type;
+ return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
}
int
symbolS *sym;
int val;
{
- coffsymbol (sym->bsym)->native->u.syment.n_type = val;
+ coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
return val;
}
S_GET_STORAGE_CLASS (sym)
symbolS *sym;
{
- return coffsymbol (sym->bsym)->native->u.syment.n_sclass;
+ return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
}
int
symbolS *sym;
int val;
{
- coffsymbol (sym->bsym)->native->u.syment.n_sclass = val;
+ coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
return val;
}
S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
- /* take the most we have */
- S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
+ {
+ /* take the most we have */
+ S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
+ }
if (S_GET_NUMBER_AUXILIARY (debug) > 0)
{
/* Move all the auxiliary information. */
- /* @@ How many fields do we want to preserve? Would it make more
- sense to pick and choose those we want to copy? Should look
- into this further.... [raeburn:19920512.2209EST] */
- alent *linenos;
- linenos = coffsymbol (normal->bsym)->lineno;
- memcpy ((char *) &coffsymbol (normal->bsym)->native,
- (char *) &coffsymbol (debug->bsym)->native,
- S_GET_NUMBER_AUXILIARY(debug) * AUXESZ);
- coffsymbol (normal->bsym)->lineno = linenos;
+ memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
+ (S_GET_NUMBER_AUXILIARY (debug)
+ * sizeof (*SYM_AUXINFO (debug))));
}
/* Move the debug flags. */
S_SET_STORAGE_CLASS (symbolP, C_FILE);
S_SET_NUMBER_AUXILIARY (symbolP, 1);
- symbolP->bsym->flags = BSF_DEBUGGING;
+ symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
#ifndef NO_LISTING
{
\f
void
-obj_symbol_new_hook (symbolP)
+coff_obj_symbol_new_hook (symbolP)
symbolS *symbolP;
{
- char underscore = 0; /* Symbol has leading _ */
+ long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
+ char * s = (char *) xmalloc (sz);
+
+ memset (s, 0, sz);
+ coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
- {
- long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
- char *s = (char *) bfd_alloc_by_size_t (stdoutput, sz);
- memset (s, 0, sz);
- coffsymbol (symbolP->bsym)->native = (combined_entry_type *) s;
- }
S_SET_DATA_TYPE (symbolP, T_NULL);
S_SET_STORAGE_CLASS (symbolP, 0);
S_SET_NUMBER_AUXILIARY (symbolP, 0);
if (S_IS_STRING (symbolP))
SF_SET_STRING (symbolP);
- if (!underscore && S_IS_LOCAL (symbolP))
+
+ if (S_IS_LOCAL (symbolP))
SF_SET_LOCAL (symbolP);
}
int offset;
int num;
{
- struct line_no *new_line = (struct line_no *) bfd_alloc_by_size_t (stdoutput,
- sizeof (struct line_no));
+ struct line_no *new_line =
+ (struct line_no *) xmalloc (sizeof (struct line_no));
if (!current_lineno_sym)
{
abort ();
{
if (line_nos)
{
- coffsymbol (current_lineno_sym->bsym)->lineno = (alent *) line_nos;
+ coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
+ (alent *) line_nos;
coff_n_line_nos++;
line_nos = 0;
}
if (! appline && def_symbol_in_progress != NULL)
{
- as_warn (".ln pseudo-op inside .def/.endef: ignored.");
+ as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
demand_empty_rest_of_line ();
return;
}
add_lineno (frag_now, frag_now_fix (), l);
}
+ if (appline)
+ new_logical_line ((char *) NULL, l - 1);
+
#ifndef NO_LISTING
{
extern int listing;
if (def_symbol_in_progress != NULL)
{
- as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
+ as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
symbol_name_length = strlen (symbol_name);
symbol_name_copy = xmalloc (symbol_name_length + 1);
strcpy (symbol_name_copy, symbol_name);
+#ifdef tc_canonicalize_symbol_name
+ symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
+#endif
/* Initialize the new symbol */
def_symbol_in_progress = symbol_make (symbol_name_copy);
- def_symbol_in_progress->sy_frag = &zero_address_frag;
+ symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
S_SET_VALUE (def_symbol_in_progress, 0);
if (S_IS_STRING (def_symbol_in_progress))
int ignore;
{
symbolS *symbolP;
+
/* DIM BUG FIX sac@cygnus.com */
dim_index = 0;
if (def_symbol_in_progress == NULL)
{
- as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
+ as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
CONST char *name;
S_SET_SEGMENT (def_symbol_in_progress, text_section);
- name = bfd_asymbol_name (def_symbol_in_progress->bsym);
+ name = S_GET_NAME (def_symbol_in_progress);
if (name[1] == 'b' && name[2] == 'f')
{
if (! in_function ())
- as_warn ("`%s' symbol without preceding function", name);
+ as_warn (_("`%s' symbol without preceding function"), name);
/* SA_SET_SYM_LNNO (def_symbol_in_progress, 12345);*/
/* Will need relocating */
SF_SET_PROCESS (def_symbol_in_progress);
break;
case C_EXT:
+ case C_WEAKEXT:
+#ifdef TE_PE
+ case C_NT_WEAK:
+#endif
case C_STAT:
case C_LABEL:
/* Valid but set somewhere else (s_comm, s_lcomm, colon) */
break;
+ default:
case C_USTATIC:
case C_EXTDEF:
case C_ULABEL:
- as_warn ("unexpected storage class %d",
+ as_warn (_("unexpected storage class %d"),
S_GET_STORAGE_CLASS (def_symbol_in_progress));
break;
} /* switch on storage class */
if (def_symbol_in_progress == NULL)
{
- as_warn (".dim pseudo-op used outside of .def/.endef: ignored.");
+ as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
break;
default:
- as_warn ("badly formed .dim directive ignored");
+ as_warn (_("badly formed .dim directive ignored"));
/* intentional fallthrough */
case '\n':
case ';':
{
if (def_symbol_in_progress == NULL)
{
- as_warn (".size pseudo-op used outside of .def/.endef ignored.");
+ as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
{
if (def_symbol_in_progress == NULL)
{
- as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
+ as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
if (def_symbol_in_progress == NULL)
{
- 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 ();
return;
}
symbol_name = input_line_pointer;
name_end = get_symbol_end ();
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
+
/* 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,
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);
+ as_warn (_("tag not found for .tag %s"), symbol_name);
} /* not defined */
SF_SET_TAGGED (def_symbol_in_progress);
{
if (def_symbol_in_progress == NULL)
{
- as_warn (".type pseudo-op used outside of .def/.endef ignored.");
+ as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
{
if (def_symbol_in_progress == NULL)
{
- as_warn (".val pseudo-op used outside of .def/.endef ignored.");
+ as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
char *symbol_name = input_line_pointer;
char name_end = get_symbol_end ();
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
if (!strcmp (symbol_name, "."))
{
- def_symbol_in_progress->sy_frag = frag_now;
+ symbol_set_frag (def_symbol_in_progress, frag_now);
S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
/* If the .val is != from the .def (e.g. statics) */
}
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_op_symbol = NULL;
- def_symbol_in_progress->sy_value.X_add_number = 0;
+ expressionS exp;
+
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = symbol_find_or_make (symbol_name);
+ exp.X_op_symbol = NULL;
+ exp.X_add_number = 0;
+ symbol_set_value_expression (def_symbol_in_progress, &exp);
/* If the segment is undefined when the forward reference is
resolved, then copy the segment id from the forward
}
void
-obj_read_begin_hook ()
+coff_obj_read_begin_hook ()
{
/* These had better be the same. Usually 18 bytes. */
#ifndef BFD_HEADERS
if (!block_stack)
block_stack = stack_init (512, sizeof (symbolS*));
- if (!S_IS_DEFINED (symp) && S_GET_STORAGE_CLASS (symp) != C_STAT)
+ if (S_IS_WEAK (symp))
+ {
+#ifdef TE_PE
+ S_SET_STORAGE_CLASS (symp, C_NT_WEAK);
+#else
+ S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
+#endif
+ }
+
+ if (!S_IS_DEFINED (symp)
+ && !S_IS_WEAK (symp)
+ && S_GET_STORAGE_CLASS (symp) != C_STAT)
S_SET_STORAGE_CLASS (symp, C_EXT);
if (!SF_GET_DEBUG (symp))
symbolS *begin;
begin = *(symbolS **) stack_pop (block_stack);
if (begin == 0)
- as_warn ("mismatched .eb");
+ as_warn (_("mismatched .eb"));
else
next_set_end = begin;
}
coff_last_function = symp;
if (S_GET_NUMBER_AUXILIARY (symp) < 1)
S_SET_NUMBER_AUXILIARY (symp, 1);
- auxp = &coffsymbol (symp->bsym)->native[1].u.auxent;
+ auxp =
+ &coffsymbol (symbol_get_bfdsym (symp))->native[1].u.auxent;
memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
}
if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
{
if (coff_last_function == 0)
- as_fatal ("C_EFCN symbol out of scope");
+ as_fatal (_("C_EFCN symbol out of scope"));
SA_SET_SYM_FSIZE (coff_last_function,
(long) (S_GET_VALUE (symp)
- S_GET_VALUE (coff_last_function)));
*punt = 1;
if (SF_GET_FUNCTION (symp))
- symp->bsym->flags |= BSF_FUNCTION;
+ symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
/* more ... */
}
/* This is pretty horrible, but we have to set *punt correctly in
order to call SA_SET_SYM_ENDNDX correctly. */
if (! symp->sy_used_in_reloc
- && ((symp->bsym->flags & BSF_SECTION_SYM) != 0
+ && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
|| (! S_IS_EXTERNAL (symp)
&& ! symp->sy_tc.output
&& S_GET_STORAGE_CLASS (symp) != C_FILE)))
if (set_end != (symbolS *) NULL
&& ! *punt
- && ((symp->bsym->flags & BSF_NOT_AT_END) != 0
+ && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
|| (S_IS_DEFINED (symp)
&& ! S_IS_COMMON (symp)
&& (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
coff_last_bf = symp;
}
- if (coffsymbol (symp->bsym)->lineno)
+ if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
{
int i;
struct line_no *lptr;
alent *l;
- lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno;
+ lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
for (i = 0; lptr; lptr = lptr->next)
i++;
- lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno;
+ lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
/* We need i entries for line numbers, plus 1 for the first
entry which BFD will override, plus 1 for the last zero
entry (a marker for BFD). */
- l = (alent *) bfd_alloc_by_size_t (stdoutput, (i + 2) * sizeof (alent));
- coffsymbol (symp->bsym)->lineno = l;
+ l = (alent *) xmalloc ((i + 2) * sizeof (alent));
+ coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
l[i + 1].line_number = 0;
l[i + 1].u.sym = NULL;
for (; i > 0; i--)
fixS *fixp = seginfo->fix_root;
while (fixp)
{
+ if (! fixp->fx_done)
+ nrelocs++;
fixp = fixp->fx_next;
- nrelocs++;
}
}
if (bfd_get_section_size_before_reloc (sec) == 0
}
void
-coff_frob_file ()
+coff_frob_file_after_relocs ()
{
bfd_map_over_sections (stdoutput, coff_adjust_section_syms, (char*) 0);
}
* 'w' for data
* 'd' (apparently m88k for data)
* 'x' for text
+ * 'r' for read-only data
* But if the argument is not a quoted string, treat it as a
* subsegment number.
*/
case 'd':
case 'w': flags &=~ SEC_READONLY; break;
case 'x': flags |= SEC_CODE; break;
+ case 'r': flags |= SEC_READONLY; break;
case 'i': /* STYP_INFO */
case 'l': /* STYP_LIB */
case 'o': /* STYP_OVER */
- as_warn ("unsupported section attribute '%c'",
+ as_warn (_("unsupported section attribute '%c'"),
*input_line_pointer);
break;
default:
- as_warn("unknown section attribute '%c'",
+ as_warn(_("unknown section attribute '%c'"),
*input_line_pointer);
break;
}
if (flags != SEC_NO_FLAGS)
{
+ flagword oldflags;
+
+ oldflags = bfd_get_section_flags (stdoutput, sec);
+ oldflags &= SEC_LINK_ONCE | SEC_LINK_DUPLICATES;
+ flags |= oldflags;
+
if (! bfd_set_section_flags (stdoutput, sec, flags))
- as_warn ("error setting flags for \"%s\": %s",
+ as_warn (_("error setting flags for \"%s\": %s"),
bfd_section_name (stdoutput, sec),
bfd_errmsg (bfd_get_error ()));
}
for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
{
- printf("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n",
+ printf(_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
(unsigned long) symbolP,
S_GET_NAME(symbolP),
(long) S_GET_DATA_TYPE(symbolP),
static void obj_coff_lcomm PARAMS ((int));
static void obj_coff_text PARAMS ((int));
static void obj_coff_data PARAMS ((int));
-static void obj_coff_bss PARAMS ((int));
static void obj_coff_ident PARAMS ((int));
void obj_coff_section PARAMS ((int));
return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum).seg_t;
}
-
-
/* calculate the size of the frag chain and fill in the section header
to contain all of it, also fill in the addr of the sections */
static unsigned int
size = frag->fr_address;
if (frag->fr_address != size)
{
- fprintf (stderr, "Out of step\n");
+ fprintf (stderr, _("Out of step\n"));
size = frag->fr_address;
}
break;
case rs_align:
case rs_align_code:
- size += frag->fr_fix;
- size += relax_align (size, frag->fr_offset);
+ {
+ addressT off;
+
+ size += frag->fr_fix;
+ off = relax_align (size, frag->fr_offset);
+ if (frag->fr_subtype != 0 && off > frag->fr_subtype)
+ off = 0;
+ size += off;
+ }
break;
default:
BAD_CASE (frag->fr_type);
while (symbol_ptr->sy_value.X_op == O_symbol
&& (! S_IS_DEFINED (symbol_ptr)
|| S_IS_COMMON (symbol_ptr)))
- symbol_ptr = symbol_ptr->sy_value.X_add_symbol;
+ {
+ symbolS *n;
+
+ /* We must avoid looping, as that can occur
+ with a badly written program. */
+ n = symbol_ptr->sy_value.X_add_symbol;
+ if (n == symbol_ptr)
+ break;
+ symbol_ptr = n;
+ }
/* Turn the segment of the symbol into an offset. */
if (symbol_ptr)
{
- resolve_symbol_value (symbol_ptr);
+ resolve_symbol_value (symbol_ptr, 1);
if (! symbol_ptr->sy_resolved)
{
char *file;
if (expr_symbol_where (symbol_ptr, &file, &line))
as_bad_where (file, line,
- "unresolved relocation");
+ _("unresolved relocation"));
else
- as_bad ("bad relocation: symbol `%s' not in symbol table",
+ as_bad (_("bad relocation: symbol `%s' not in symbol table"),
S_GET_NAME (symbol_ptr));
}
dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
unsigned int i;
char buffer[1000];
char buffero[1000];
+#ifdef COFF_LONG_SECTION_NAMES
+ unsigned long string_size = 4;
+#endif
bfd_seek (abfd, 0, 0);
for (i = SEG_E0; i < SEG_LAST; i++)
{
-#ifdef COFF_LONG_SECTION_NAMES
- unsigned long string_size = 4;
-#endif
-
if (segment_info[i].scnhdr.s_name[0])
{
unsigned int size;
&(segment_info[i].scnhdr),
buffer);
if (size == 0)
- as_bad ("bfd_coff_swap_scnhdr_out failed");
+ as_bad (_("bfd_coff_swap_scnhdr_out failed"));
bfd_write (buffer, size, 1, abfd);
}
}
}
/* At the same time, relocate all symbols to their output value */
+#ifndef TE_PE
val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
+ S_GET_VALUE (symbolP));
+#else
+ val = S_GET_VALUE (symbolP);
+#endif
S_SET_VALUE (symbolP, val);
}
void
-obj_symbol_new_hook (symbolP)
+coff_obj_symbol_new_hook (symbolP)
symbolS *symbolP;
{
char underscore = 0; /* Symbol has leading _ */
if (! appline && def_symbol_in_progress != NULL)
{
- as_warn (".ln pseudo-op inside .def/.endef: ignored.");
+ as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
demand_empty_rest_of_line ();
return;
} /* wrong context */
l = get_absolute_expression ();
c_line_new (0, frag_now_fix (), l, frag_now);
+
+ if (appline)
+ new_logical_line ((char *) NULL, l - 1);
+
#ifndef NO_LISTING
{
extern int listing;
if (def_symbol_in_progress != NULL)
{
- as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
+ as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
symbol_name_length = strlen (symbol_name);
symbol_name_copy = xmalloc (symbol_name_length + 1);
strcpy (symbol_name_copy, symbol_name);
+#ifdef tc_canonicalize_symbol_name
+ symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
+#endif
/* Initialize the new symbol */
#ifdef STRIP_UNDERSCORE
dim_index = 0;
if (def_symbol_in_progress == NULL)
{
- as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
+ as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
{ /* .bf */
if (function_lineoff < 0)
{
- fprintf (stderr, "`.bf' symbol without preceding function\n");
+ fprintf (stderr, _("`.bf' symbol without preceding function\n"));
} /* missing function symbol */
SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
break;
case C_EXT:
+ case C_WEAKEXT:
+#ifdef TE_PE
+ case C_NT_WEAK:
+#endif
case C_STAT:
case C_LABEL:
/* Valid but set somewhere else (s_comm, s_lcomm, colon) */
case C_USTATIC:
case C_EXTDEF:
case C_ULABEL:
- as_warn ("unexpected storage class %d", S_GET_STORAGE_CLASS (def_symbol_in_progress));
+ as_warn (_("unexpected storage class %d"), S_GET_STORAGE_CLASS (def_symbol_in_progress));
break;
} /* switch on storage class */
if (def_symbol_in_progress == NULL)
{
- as_warn (".dim pseudo-op used outside of .def/.endef: ignored.");
+ as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
break;
default:
- as_warn ("badly formed .dim directive ignored");
+ as_warn (_("badly formed .dim directive ignored"));
/* intentional fallthrough */
case '\n':
case ';':
{
if (def_symbol_in_progress == NULL)
{
- as_warn (".size pseudo-op used outside of .def/.endef ignored.");
+ as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
{
if (def_symbol_in_progress == NULL)
{
- as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
+ as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
if (def_symbol_in_progress == NULL)
{
- 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 ();
return;
}
S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
symbol_name = input_line_pointer;
name_end = get_symbol_end ();
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
/* Assume that the symbol referred to by .tag is always defined.
This was a bad assumption. I've added find_or_make. xoxorich. */
(long) 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);
+ as_warn (_("tag not found for .tag %s"), symbol_name);
} /* not defined */
SF_SET_TAGGED (def_symbol_in_progress);
{
if (def_symbol_in_progress == NULL)
{
- as_warn (".type pseudo-op used outside of .def/.endef ignored.");
+ as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
{
if (def_symbol_in_progress == NULL)
{
- as_warn (".val pseudo-op used outside of .def/.endef ignored.");
+ as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
demand_empty_rest_of_line ();
return;
} /* if not inside .def/.endef */
char *symbol_name = input_line_pointer;
char name_end = get_symbol_end ();
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
+
if (!strcmp (symbol_name, "."))
{
def_symbol_in_progress->sy_frag = frag_now;
#endif /* TE_PE */
void
-obj_read_begin_hook ()
+coff_obj_read_begin_hook ()
{
/* These had better be the same. Usually 18 bytes. */
#ifndef BFD_HEADERS
{
if (symbolP->sy_mri_common)
{
- if (S_GET_STORAGE_CLASS (symbolP) == C_EXT)
- as_bad ("%s: global symbols not supported in common sections",
+ if (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+ || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT)
+ as_bad (_("%s: global symbols not supported in common sections"),
S_GET_NAME (symbolP));
symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
continue;
S_SET_SEGMENT (symbolP, SEG_E0);
} /* push data into text */
- resolve_symbol_value (symbolP);
+ resolve_symbol_value (symbolP, 1);
if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
{
register symbolS *begin_symbolP;
begin_symbolP = *(symbolS **) stack_pop (block_stack);
if (begin_symbolP == (symbolS *) 0)
- as_warn ("mismatched .eb");
+ as_warn (_("mismatched .eb"));
else
SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
}
/* I don't even know if this is needed for sdb. But
the standard assembler generates it, so... */
if (last_functionP == (symbolS *) 0)
- as_fatal ("C_EFCN symbol out of scope");
+ as_fatal (_("C_EFCN symbol out of scope"));
SA_SET_SYM_FSIZE (last_functionP,
(long) (S_GET_VALUE (symbolP) -
S_GET_VALUE (last_functionP)));
} /* no one points at the first .file symbol */
} /* if debug or tag or eos or file */
+#ifdef tc_frob_coff_symbol
+ tc_frob_coff_symbol (symbolP);
+#endif
+
/* We must put the external symbols apart. The loader
does not bomb if we do not. But the references in
the endndx field for a .bb symbol are not corrected
}
else if (!S_IS_DEFINED (symbolP)
&& !S_IS_DEBUG (symbolP)
- && !SF_GET_STATICS (symbolP) &&
- S_GET_STORAGE_CLASS (symbolP) == C_EXT)
- { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
+ && !SF_GET_STATICS (symbolP)
+ && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+ || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT))
+ {
/* if external, Remove from the list */
symbolS *hold = symbol_previous (symbolP);
else if (! S_IS_DEBUG (symbolP)
&& ! SF_GET_STATICS (symbolP)
&& ! SF_GET_FUNCTION (symbolP)
- && S_GET_STORAGE_CLASS (symbolP) == C_EXT)
+ && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK))
{
symbolS *hold = symbol_previous (symbolP);
symbolS **tail;
{
unsigned int symbol_number = 0;
- symbolS *symbolP;
- for (symbolP = *head; *head != NULL;)
+ while (*head != NULL)
{
symbolS *tmp = *head;
tie_tags ()
{
unsigned int symbol_number = 0;
-
symbolS *symbolP;
- for (symbolP = symbol_rootP; symbolP; symbolP =
- symbol_next (symbolP))
+
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
{
symbolP->sy_number = symbol_number;
-
-
if (SF_GET_TAGGED (symbolP))
{
SA_SET_SYM_TAGNDX
symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
}
- return symbol_number;
+ return symbol_number;
}
static void
* order :
* . .file symbol
* . debug entries for functions
- * . fake symbols for the sections, including.text .data and .bss
+ * . fake symbols for the sections, including .text .data and .bss
* . defined symbols
* . undefined symbols
* But this is not mandatory. The only important point is to put the
* undefined symbols at the end of the list.
*/
+ /* Is there a .file symbol ? If not insert one at the beginning. */
if (symbol_rootP == NULL
|| S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
{
c_dot_file_symbol ("fake");
}
- /* Is there a .file symbol ? If not insert one at the beginning. */
/*
* Build up static symbols for the sections, they are filled in later
if (abfd == 0)
{
- as_perror ("FATAL: Can't create %s", out_file_name);
+ as_perror (_("FATAL: Can't create %s"), out_file_name);
exit (EXIT_FAILURE);
}
bfd_set_format (abfd, bfd_object);
#define SUB_SEGMENT_ALIGN(SEG) 1
#endif
#ifdef md_do_align
- {
- static char nop = NOP_OPCODE;
- md_do_align (SUB_SEGMENT_ALIGN (now_seg), &nop, 1, alignment_done);
- }
+ md_do_align (SUB_SEGMENT_ALIGN (now_seg), (char *) NULL, 0, 0,
+ alignment_done);
#endif
- frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE);
+ frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE, 0);
#ifdef md_do_align
alignment_done:
#endif
/* I think the section alignment is only used on the i960; the
i960 needs it, and it should do no harm on other targets. */
+#ifdef ALIGNMENT_IN_S_FLAGS
+ segment_info[i].scnhdr.s_flags |= (section_alignment[i] & 0xF) << 8;
+#else
segment_info[i].scnhdr.s_align = 1 << section_alignment[i];
+#endif
if (i == SEG_E0)
H_SET_TEXT_SIZE (&headers, size);
/* Recent changes to write need this, but where it should
go is up to Ken.. */
if (bfd_close_all_done (abfd) == false)
- as_fatal ("Can't close %s: %s", out_file_name,
+ as_fatal (_("Can't close %s: %s"), out_file_name,
bfd_errmsg (bfd_get_error ()));
#else
{
if (i == SEG_LAST)
{
- as_bad ("Too many new sections; can't add \"%s\"", name);
+ as_bad (_("Too many new sections; can't add \"%s\""), name);
return now_seg;
}
* 'w' for data
* 'd' (apparently m88k for data)
* 'x' for text
+ * 'r' for read-only data
* But if the argument is not a quoted string, treat it as a
* subsegment number.
*/
case 'd':
case 'w': flags |= STYP_DATA; break;
case 'x': flags |= STYP_TEXT; break;
+ case 'r': flags |= STYP_LIT; break;
default:
- as_warn("unknown section attribute '%c'",
+ as_warn(_("unknown section attribute '%c'"),
*input_line_pointer);
break;
}
subseg_new (".data", get_absolute_expression ());
}
-static void
-obj_coff_bss (ignore)
- int ignore;
-{
- if (*input_line_pointer == '\n') /* .bss */
- subseg_new(".bss", get_absolute_expression());
- else /* .bss id,expr */
- obj_coff_lcomm(0);
-}
-
static void
obj_coff_ident (ignore)
int ignore;
/* Make sure that the symbol is first on the symbol chain */
if (symbol_rootP != symbolP)
{
- if (symbolP == symbol_lastP)
- {
- symbol_lastP = symbol_lastP->sy_previous;
- } /* if it was the last thing on the list */
-
symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
- symbol_rootP = symbolP;
- } /* if not first on the list */
-
+ }
} /* c_dot_file_symbol() */
/*
{
symbolS *symbolP;
- symbolP = symbol_new (name, idx,
- 0,
- &zero_address_frag);
+ symbolP = symbol_find_base (name, DO_NOT_STRIP);
+ if (symbolP == NULL)
+ symbolP = symbol_new (name, idx, 0, &zero_address_frag);
+ else
+ {
+ /* Mmmm. I just love violating interfaces. Makes me feel...dirty. */
+ S_SET_SEGMENT (symbolP, idx);
+ symbolP->sy_frag = &zero_address_frag;
+ }
S_SET_STORAGE_CLASS (symbolP, C_STAT);
S_SET_NUMBER_AUXILIARY (symbolP, 1);
SF_SET_STATICS (symbolP);
+#ifdef TE_DELTA
+ /* manfred@s-direktnet.de: section symbols *must* have the LOCAL bit cleared,
+ which is set by the new definition of LOCAL_LABEL in tc-m68k.h. */
+ SF_CLEAR_LOCAL (symbolP);
+#endif
#ifdef TE_PE
/* If the .linkonce pseudo-op was used for this section, we must
store the information in the auxiliary entry for the section
SKIP_WHITESPACE ();
if (*input_line_pointer != ',')
{
- as_bad ("Expected comma after name");
+ as_bad (_("Expected comma after name"));
ignore_rest_of_line ();
return;
}
if (*input_line_pointer == '\n')
{
- as_bad ("Missing size expression");
+ as_bad (_("Missing size expression"));
return;
}
input_line_pointer++;
if ((temp = get_absolute_expression ()) < 0)
{
- as_warn ("lcomm length (%d.) <0! Ignored.", temp);
+ as_warn (_("lcomm length (%d.) <0! Ignored."), temp);
ignore_rest_of_line ();
return;
}
subseg_set (SEG_E2, 1);
symbolP->sy_frag = frag_now;
p = frag_var(rs_org, 1, 1, (relax_substateT)0, symbolP,
- temp, (char *)0);
+ (offsetT) temp, (char *) 0);
*p = 0;
subseg_set (current_seg, current_subseg); /* restore current seg */
S_SET_SEGMENT(symbolP, SEG_E2);
}
}
else
- as_bad("Symbol %s already defined", name);
+ as_bad(_("Symbol %s already defined"), name);
demand_empty_rest_of_line();
#endif
if (!SF_GET_BALNAME (tc_get_bal_of_call (add_symbolP)))
{
as_bad_where (fixP->fx_file, fixP->fx_line,
- "No 'bal' entry point for leafproc %s",
+ _("No 'bal' entry point for leafproc %s"),
S_GET_NAME (add_symbolP));
continue;
}
/* Make sure the symbols have been resolved; this may not have
happened if these are expression symbols. */
if (add_symbolP != NULL && ! add_symbolP->sy_resolved)
- resolve_symbol_value (add_symbolP);
+ resolve_symbol_value (add_symbolP, 1);
+
+ if (add_symbolP != NULL)
+ {
+ /* If this fixup is against a symbol which has been equated
+ to another symbol, convert it to the other symbol. */
+ if (add_symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (add_symbolP)
+ || S_IS_COMMON (add_symbolP)))
+ {
+ while (add_symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (add_symbolP)
+ || S_IS_COMMON (add_symbolP)))
+ {
+ symbolS *n;
+
+ /* We must avoid looping, as that can occur with a
+ badly written program. */
+ n = add_symbolP->sy_value.X_add_symbol;
+ if (n == add_symbolP)
+ break;
+ add_number += add_symbolP->sy_value.X_add_number;
+ add_symbolP = n;
+ }
+ fixP->fx_addsy = add_symbolP;
+ fixP->fx_offset = add_number;
+ }
+ }
+
if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved)
- resolve_symbol_value (sub_symbolP);
+ resolve_symbol_value (sub_symbolP, 1);
if (add_symbolP != NULL
&& add_symbolP->sy_mri_common)
{
#ifndef TC_M68K
as_bad_where (fixP->fx_file, fixP->fx_line,
- "Negative of non-absolute symbol %s",
+ _("Negative of non-absolute symbol %s"),
S_GET_NAME (sub_symbolP));
#endif
add_number -= S_GET_VALUE (sub_symbolP);
if (fixP->fx_tcbit)
{
as_bad_where (fixP->fx_file, fixP->fx_line,
- "callj to difference of 2 symbols");
+ _("callj to difference of 2 symbols"));
}
#endif /* TC_I960 */
add_number += S_GET_VALUE (add_symbolP) -
else
{
as_bad_where (fixP->fx_file, fixP->fx_line,
- "Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld.",
+ _("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld."),
segment_name (S_GET_SEGMENT (sub_symbolP)),
S_GET_NAME (sub_symbolP),
(long) (fragP->fr_address + where));
add_number += S_GET_VALUE (add_symbolP);
add_number -= md_pcrel_from (fixP);
-#if defined (TC_I386) || defined (TE_LYNX)
- /* On the 386 we must adjust by the segment vaddr as
- well. Ian Taylor. */
- add_number -= segP->scnhdr.s_vaddr;
-#endif
+
+ /* We used to do
+ add_number -= segP->scnhdr.s_vaddr;
+ if defined (TC_I386) || defined (TE_LYNX). I now
+ think that was an error propagated from the case when
+ we are going to emit the relocation. If we are not
+ going to emit the relocation, then we just want to
+ set add_number to the difference between the symbols.
+ This is a case that would only arise when there is a
+ PC relative reference from a section other than .text
+ to a symbol defined in the same section, and the
+ reference is not relaxed. Since jump instructions on
+ the i386 are relaxed, this could only arise with a
+ call instruction. */
+
pcrel = 0; /* Lie. Don't want further pcrel processing. */
if (!TC_FORCE_RELOCATION (fixP))
{
* relocation.
*/
as_bad_where (fixP->fx_file, fixP->fx_line,
- "can't use COBR format with external label");
+ _("can't use COBR format with external label"));
fixP->fx_addsy = NULL;
fixP->fx_done = 1;
continue;
} /* COBR */
#endif /* TC_I960 */
-#if (defined (TC_I386) || defined (TE_LYNX) || defined (TE_AUX)) && !defined(TE_PE)
+#if ((defined (TC_I386) || defined (TE_LYNX) || defined (TE_AUX)) && !defined(TE_PE)) || defined (COFF_COMMON_ADDEND)
/* 386 COFF uses a peculiar format in which the
value of a common symbol is stored in the .text
segment (I've checked this on SVR3.2 and SCO
3.2.2) Ian Taylor <ian@cygnus.com>. */
+ /* This is also true for 68k COFF on sysv machines
+ (Checked on Motorola sysv68 R3V6 and R3V7.1, and also on
+ UNIX System V/M68000, Release 1.0 from ATT/Bell Labs)
+ Philippe De Muyter <phdm@info.ucl.ac.be>. */
if (S_IS_COMMON (add_symbolP))
add_number += S_GET_VALUE (add_symbolP);
#endif
#endif
} /* if pcrel */
+#ifdef MD_APPLY_FIX3
+ md_apply_fix3 (fixP, (valueT *) &add_number, this_segment_type);
+#else
+ md_apply_fix (fixP, add_number);
+#endif
+
if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow)
{
#ifndef TC_M88K
&& ((add_number & ~0xFF)
|| (fixP->fx_signed && (add_number & 0x80)))
&& ((add_number & ~0xFF) != (-1 & ~0xFF)
- || (fixP->fx_signed && (add_number & 0x80) == 0)))
+ || (add_number & 0x80) == 0))
|| (size == 2
&& ((add_number & ~0xFFFF)
|| (fixP->fx_signed && (add_number & 0x8000)))
&& ((add_number & ~0xFFFF) != (-1 & ~0xFFFF)
- || (fixP->fx_signed && (add_number & 0x8000) == 0))))
+ || (add_number & 0x8000) == 0)))
{
as_bad_where (fixP->fx_file, fixP->fx_line,
- "Value of %ld too large for field of %d bytes at 0x%lx",
+ _("Value of %ld too large for field of %d bytes at 0x%lx"),
(long) add_number, size,
(unsigned long) (fragP->fr_address + where));
}
&& size == 2
&& add_number > 0x7fff)
as_bad_where (fixP->fx_file, fixP->fx_line,
- "Signed .word overflow; switch may be too large; %ld at 0x%lx",
+ _("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 */
- /* Once this fix has been applied, we don't have to output
- anything nothing more need be done. */
-#ifdef MD_APPLY_FIX3
- md_apply_fix3 (fixP, &add_number, this_segment_type);
-#else
- md_apply_fix (fixP, add_number);
-#endif
} /* For each fixS in this segment. */
} /* fixup_segment() */
/* FIXME: We ignore the MRI short attribute. */
{"section.s", obj_coff_section, 0},
{"sect.s", obj_coff_section, 0},
+ /* We accept the .bss directive for backward compatibility with
+ earlier versions of gas. */
+ {"bss", obj_coff_bss, 0},
+ {"weak", obj_coff_weak, 0},
#ifndef BFD_ASSEMBLER
{"use", obj_coff_section, 0},
{"text", obj_coff_text, 0},
{"data", obj_coff_data, 0},
- {"bss", obj_coff_bss, 0},
{"lcomm", obj_coff_lcomm, 0},
{"ident", obj_coff_ident, 0},
#else
{"optim", s_ignore, 0}, /* For sun386i cc (?) */
{"ident", s_ignore, 0}, /* we don't yet handle this. */
#endif
+ {"version", s_ignore, 0},
{"ABORT", s_abort, 0},
#ifdef TC_M88K
/* The m88k uses sdef instead of def. */
#endif
{NULL} /* end sentinel */
}; /* obj_pseudo_table */
+\f
+#ifdef BFD_ASSEMBLER
+
+/* Support for a COFF emulation. */
+
+static void
+coff_pop_insert ()
+{
+ pop_insert (obj_pseudo_table);
+}
+
+static int
+coff_sec_sym_ok_for_reloc (sec)
+ asection *sec;
+{
+ return 0;
+}
+
+static void
+no_func ()
+{
+ abort ();
+}
+
+const struct format_ops coff_format_ops =
+{
+ bfd_target_coff_flavour,
+ 0,
+ 1,
+ coff_frob_symbol,
+ no_func,
+ coff_frob_file_after_relocs,
+ 0, 0,
+ 0, 0,
+ 0,
+#if 0
+ obj_generate_asm_lineno,
+#else
+ no_func,
+#endif
+#if 0
+ obj_stab,
+#else
+ no_func,
+#endif
+ coff_sec_sym_ok_for_reloc,
+ coff_pop_insert,
+#if 0
+ obj_set_ext,
+#else
+ no_func,
+#endif
+ coff_obj_read_begin_hook,
+ coff_obj_symbol_new_hook,
+};
+
+#endif