aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>1998-08-31 16:52:18 +0000
committerRichard Henderson <rth@redhat.com>1998-08-31 16:52:18 +0000
commit11e07ad09a2fa160cff274d5ac751eab7727b3c6 (patch)
tree59a719cd6a985d5768178e0a8ca725954363a4c0 /gas
parent4a634a0bcb03d62cdfb838b5d48326c005368551 (diff)
downloadgdb-11e07ad09a2fa160cff274d5ac751eab7727b3c6.zip
gdb-11e07ad09a2fa160cff274d5ac751eab7727b3c6.tar.gz
gdb-11e07ad09a2fa160cff274d5ac751eab7727b3c6.tar.bz2
* config/obj-elf.c (obj_elf_vtable_inherit): Print error message
before we clobber the symbol involved.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/obj-elf.c167
2 files changed, 142 insertions, 30 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 1a53773..050be27 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+Mon Aug 31 09:51:14 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_vtable_inherit): Print error message
+ before we clobber the symbol involved.
+
Mon Aug 31 10:58:06 1998 Catherine Moore <clm@cygnus.com>
* config/tc-arm.c: Remove OBJ_ELF definitions for
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 7a49f89..c90887e 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -1,5 +1,5 @@
/* ELF object file format
- Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -67,6 +67,8 @@ static void obj_elf_weak PARAMS ((int));
static void obj_elf_local PARAMS ((int));
static void obj_elf_common PARAMS ((int));
static void obj_elf_symver PARAMS ((int));
+static void obj_elf_vtable_inherit PARAMS ((int));
+static void obj_elf_vtable_entry PARAMS ((int));
static void obj_elf_data PARAMS ((int));
static void obj_elf_text PARAMS ((int));
static void obj_elf_subsection PARAMS ((int));
@@ -95,6 +97,10 @@ static const pseudo_typeS elf_pseudo_table[] =
/* A GNU extension to change subsection only. */
{"subsection", obj_elf_subsection, 0},
+ /* These are GNU extensions to aid in garbage collecting C++ vtables. */
+ {"vtable_inherit", obj_elf_vtable_inherit, 0},
+ {"vtable_entry", obj_elf_vtable_entry, 0},
+
/* These are used for dwarf. */
{"2byte", cons, 2},
{"4byte", cons, 4},
@@ -265,14 +271,14 @@ obj_elf_common (ignore)
SKIP_WHITESPACE ();
if (*input_line_pointer != ',')
{
- as_bad ("Expected comma after symbol-name");
+ as_bad (_("Expected comma after symbol-name"));
ignore_rest_of_line ();
return;
}
input_line_pointer++; /* skip ',' */
if ((temp = get_absolute_expression ()) < 0)
{
- as_bad (".COMMon length (%d.) <0! Ignored.", temp);
+ as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
ignore_rest_of_line ();
return;
}
@@ -282,7 +288,7 @@ obj_elf_common (ignore)
*p = c;
if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
{
- as_bad ("Ignoring attempt to re-define symbol");
+ as_bad (_("Ignoring attempt to re-define symbol"));
ignore_rest_of_line ();
return;
}
@@ -290,7 +296,7 @@ obj_elf_common (ignore)
{
if (S_GET_VALUE (symbolP) != size)
{
- as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
+ as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
}
}
@@ -313,7 +319,7 @@ obj_elf_common (ignore)
if (temp < 0)
{
temp = 0;
- as_warn ("Common alignment negative; 0 assumed");
+ as_warn (_("Common alignment negative; 0 assumed"));
}
}
if (symbolP->local)
@@ -332,7 +338,7 @@ obj_elf_common (ignore)
for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
if (temp != 1)
{
- as_bad ("Common alignment not a power of 2");
+ as_bad (_("Common alignment not a power of 2"));
ignore_rest_of_line ();
return;
}
@@ -395,7 +401,7 @@ obj_elf_common (ignore)
p++;
c = *p;
*p = '\0';
- as_bad ("bad .common segment %s", input_line_pointer + 1);
+ as_bad (_("bad .common segment %s"), input_line_pointer + 1);
*p = c;
input_line_pointer = p;
ignore_rest_of_line ();
@@ -580,7 +586,7 @@ obj_elf_section (xxx)
p++;
if (p == input_line_pointer)
{
- as_warn ("Missing section name");
+ as_warn (_("Missing section name"));
ignore_rest_of_line ();
return;
}
@@ -645,7 +651,7 @@ obj_elf_section (xxx)
break;
default:
{
- char *bad_msg = "Bad .section directive: want a,w,x in string";
+ char *bad_msg = _("Bad .section directive: want a,w,x in string");
#ifdef md_elf_section_letter
int md_attr = md_elf_section_letter (*input_line_pointer, &bad_msg);
if (md_attr)
@@ -694,7 +700,7 @@ obj_elf_section (xxx)
else
#endif
{
- as_warn ("Unrecognized section type");
+ as_warn (_("Unrecognized section type"));
ignore_rest_of_line ();
}
}
@@ -708,7 +714,7 @@ obj_elf_section (xxx)
SKIP_WHITESPACE ();
if (*input_line_pointer != '#')
{
- as_warn ("Bad .section directive - character following name is not '#'");
+ as_warn (_("Bad .section directive - character following name is not '#'"));
ignore_rest_of_line ();
return;
}
@@ -740,7 +746,7 @@ obj_elf_section (xxx)
else
#endif
{
- as_warn ("Unrecognized section attribute");
+ as_warn (_("Unrecognized section attribute"));
ignore_rest_of_line ();
return;
}
@@ -761,7 +767,7 @@ obj_elf_section (xxx)
if (type == SHT_NULL)
type = special_sections[i].type;
else if (type != special_sections[i].type)
- as_warn ("Setting incorrect section type for %s", string);
+ as_warn (_("Setting incorrect section type for %s"), string);
if ((attr &~ special_sections[i].attributes) != 0)
{
@@ -771,7 +777,7 @@ obj_elf_section (xxx)
the output file. */
if (strcmp (string, ".note") != 0
|| attr != SHF_ALLOC)
- as_warn ("Setting incorrect section attributes for %s",
+ as_warn (_("Setting incorrect section attributes for %s"),
string);
}
attr |= special_sections[i].attributes;
@@ -800,6 +806,10 @@ obj_elf_section (xxx)
#endif
}
+ /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
+ if (type == SHT_NOBITS)
+ seg_info (sec)->bss = 1;
+
bfd_set_section_flags (stdoutput, sec, flags);
/* Add a symbol for this section to the symbol table. */
@@ -892,7 +902,7 @@ obj_elf_previous (ignore)
{
if (previous_section == 0)
{
- as_bad (".previous without corresponding .section; ignored");
+ as_bad (_(".previous without corresponding .section; ignored"));
return;
}
@@ -918,7 +928,7 @@ obj_elf_line (ignore)
demand_empty_rest_of_line ();
}
-/* This handle the .symver pseudo-op, which is used to specify a
+/* This handles the .symver pseudo-op, which is used to specify a
symbol version. The syntax is ``.symver NAME,SYMVERNAME''.
SYMVERNAME may contain ELF_VER_CHR ('@') characters. This
pseudo-op causes the assembler to emit a symbol named SYMVERNAME
@@ -941,7 +951,7 @@ obj_elf_symver (ignore)
if (sym->sy_obj.versioned_name != NULL)
{
- as_bad ("multiple .symver directives for symbol `%s'",
+ as_bad (_("multiple .symver directives for symbol `%s'"),
S_GET_NAME (sym));
ignore_rest_of_line ();
return;
@@ -950,7 +960,7 @@ obj_elf_symver (ignore)
SKIP_WHITESPACE ();
if (*input_line_pointer != ',')
{
- as_bad ("expected comma after name in .symver");
+ as_bad (_("expected comma after name in .symver"));
ignore_rest_of_line ();
return;
}
@@ -971,7 +981,7 @@ obj_elf_symver (ignore)
if (strchr (sym->sy_obj.versioned_name, ELF_VER_CHR) == NULL)
{
- as_bad ("missing version name in `%s' for symbol `%s'",
+ as_bad (_("missing version name in `%s' for symbol `%s'"),
sym->sy_obj.versioned_name, S_GET_NAME (sym));
ignore_rest_of_line ();
return;
@@ -980,6 +990,103 @@ obj_elf_symver (ignore)
demand_empty_rest_of_line ();
}
+/* This handles the .vtable_inherit pseudo-op, which is used to indicate
+ to the linker the hierarchy in which a particular table resides. The
+ syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */
+
+static void
+obj_elf_vtable_inherit (ignore)
+{
+ char *cname, *pname;
+ symbolS *csym, *psym;
+ char c, bad = 0;
+
+ cname = input_line_pointer;
+ c = get_symbol_end ();
+ csym = symbol_find (cname);
+
+ /* GCFIXME: should check that we don't have two .vtable_inherits for
+ the same child symbol. Also, we can currently only do this if the
+ child symbol is already exists and is placed in a fragment. */
+
+ if (csym == NULL || csym->sy_frag == NULL)
+ {
+ as_bad ("expected `%s' to have already been set for .vtable_inherit",
+ cname);
+ bad = 1;
+ }
+
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after name in .vtable_inherit");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (input_line_pointer[0] == '0'
+ && (input_line_pointer[1] == '\0'
+ || isspace(input_line_pointer[1])))
+ {
+ psym = section_symbol (absolute_section);
+ ++input_line_pointer;
+ }
+ else
+ {
+ pname = input_line_pointer;
+ c = get_symbol_end ();
+ psym = symbol_find_or_make (pname);
+ *input_line_pointer = c;
+ }
+
+ demand_empty_rest_of_line ();
+
+ if (bad)
+ return;
+
+ assert (csym->sy_value.X_op == O_constant);
+ fix_new (csym->sy_frag, csym->sy_value.X_add_number, 0, psym, 0, 0,
+ BFD_RELOC_VTABLE_INHERIT);
+}
+
+/* This handles the .vtable_entry pseudo-op, which is used to indicate
+ to the linker that a vtable slot was used. The syntax is
+ ".vtable_entry tablename, offset". */
+
+static void
+obj_elf_vtable_entry (ignore)
+{
+ char *name;
+ symbolS *sym;
+ offsetT offset;
+ char c;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ sym = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after name in .vtable_entry");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+ offset = get_absolute_expression ();
+
+ fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
+ BFD_RELOC_VTABLE_ENTRY);
+
+ demand_empty_rest_of_line ();
+}
+
void
obj_read_begin_hook ()
{
@@ -1064,7 +1171,7 @@ obj_elf_version (ignore)
}
else
{
- as_bad ("Expected quoted string");
+ as_bad (_("Expected quoted string"));
}
demand_empty_rest_of_line ();
}
@@ -1085,7 +1192,7 @@ obj_elf_size (ignore)
if (*input_line_pointer != ',')
{
*p = 0;
- as_bad ("expected comma after name `%s' in .size directive", name);
+ as_bad (_("expected comma after name `%s' in .size directive"), name);
*p = c;
ignore_rest_of_line ();
return;
@@ -1094,7 +1201,7 @@ obj_elf_size (ignore)
expression (&exp);
if (exp.X_op == O_absent)
{
- as_bad ("missing expression in .size directive");
+ as_bad (_("missing expression in .size directive"));
exp.X_op = O_constant;
exp.X_add_number = 0;
}
@@ -1154,7 +1261,7 @@ obj_elf_type (ignore)
|| strcmp (typename, "STT_OBJECT") == 0)
type = BSF_OBJECT;
else
- as_bad ("ignoring unrecognized symbol type \"%s\"", typename);
+ as_bad (_("ignoring unrecognized symbol type \"%s\""), typename);
*input_line_pointer = c;
@@ -1324,7 +1431,7 @@ elf_frob_symbol (symp, puntp)
+ symp->sy_obj.size->X_add_number));
break;
default:
- as_bad (".size expression too complicated to fix up");
+ as_bad (_(".size expression too complicated to fix up"));
break;
}
free (symp->sy_obj.size);
@@ -1355,7 +1462,7 @@ elf_frob_symbol (symp, puntp)
know (p != NULL);
if (p[1] == ELF_VER_CHR)
{
- as_bad ("invalid attempt to declare external version name as default in symbol `%s'",
+ as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
symp->sy_obj.versioned_name);
*puntp = true;
}
@@ -1398,7 +1505,7 @@ elf_frob_symbol (symp, puntp)
if (symp->bsym->flags & BSF_WEAK)
{
if (S_IS_COMMON (symp))
- as_bad ("Symbol `%s' can not be both weak and common",
+ as_bad (_("Symbol `%s' can not be both weak and common"),
S_GET_NAME (symp));
}
@@ -1481,7 +1588,7 @@ elf_frob_file_after_relocs ()
debug.external_ext = debug.external_ext_end = NULL;
if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
elf_get_extr, elf_set_index))
- as_fatal ("Failed to set up debugging information: %s",
+ as_fatal (_("Failed to set up debugging information: %s"),
bfd_errmsg (bfd_get_error ()));
sec = bfd_get_section_by_name (stdoutput, ".mdebug");
@@ -1497,7 +1604,7 @@ elf_frob_file_after_relocs ()
if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
(file_ptr) 0, (bfd_size_type) 0))
- as_fatal ("Can't start writing .mdebug section: %s",
+ as_fatal (_("Can't start writing .mdebug section: %s"),
bfd_errmsg (bfd_get_error ()));
know (stdoutput->output_has_begun == true);
@@ -1505,7 +1612,7 @@ elf_frob_file_after_relocs ()
if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
sec->filepos))
- as_fatal ("Could not write .mdebug section: %s",
+ as_fatal (_("Could not write .mdebug section: %s"),
bfd_errmsg (bfd_get_error ()));
}
#endif /* NEED_ECOFF_DEBUG */