aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.h
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1995-09-01 18:08:28 +0000
committerIan Lance Taylor <ian@airs.com>1995-09-01 18:08:28 +0000
commit0cb705689dfa2158883f11f34bbf1ede2523e51b (patch)
tree70503c58950fbea4448dba0e41105f21bcd49d71 /bfd/elflink.h
parentf6feefe4488cbd6927fcf3c040322d599d12f946 (diff)
downloadgdb-0cb705689dfa2158883f11f34bbf1ede2523e51b.zip
gdb-0cb705689dfa2158883f11f34bbf1ede2523e51b.tar.gz
gdb-0cb705689dfa2158883f11f34bbf1ede2523e51b.tar.bz2
* elflink.h (elf_link_add_object_symbols): Handle indirect and
warning symbols. If any section is named .gnu.warning.XXX, treat the contents as a warning to be issued if the symbol XXX is referenced. (elf_link_output_extsym): For an indirect or warning symbol, just output the symbol it points to.
Diffstat (limited to 'bfd/elflink.h')
-rw-r--r--bfd/elflink.h72
1 files changed, 64 insertions, 8 deletions
diff --git a/bfd/elflink.h b/bfd/elflink.h
index b625ae0..ec12292 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -258,6 +258,52 @@ elf_link_add_object_symbols (abfd, info)
add_symbol_hook = get_elf_backend_data (abfd)->elf_add_symbol_hook;
collect = get_elf_backend_data (abfd)->collect;
+ /* As a GNU extension, any input sections which are named
+ .gnu.warning.SYMBOL are treated as warning symbols for the given
+ symbol. This differs from .gnu.warning sections, which generate
+ warnings when they are included in an output file. */
+ if (! info->shared)
+ {
+ asection *s;
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+
+ name = bfd_get_section_name (abfd, s);
+ if (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0)
+ {
+ char *msg;
+ bfd_size_type sz;
+
+ sz = bfd_section_size (abfd, s);
+ msg = (char *) bfd_alloc (abfd, sz);
+ if (msg == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ goto error_return;
+ }
+
+ if (! bfd_get_section_contents (abfd, s, msg, (file_ptr) 0, sz))
+ goto error_return;
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd,
+ name + sizeof ".gnu.warning." - 1,
+ BSF_WARNING, s, (bfd_vma) 0, msg, false, collect,
+ (struct bfd_link_hash_entry **) NULL)))
+ goto error_return;
+
+ if (! info->relocateable)
+ {
+ /* Clobber the section size so that the warning does
+ not get copied into the output file. */
+ s->_raw_size = 0;
+ }
+ }
+ }
+ }
+
/* A stripped shared library might only have a dynamic symbol table,
not a regular symbol table. In that case we can still go ahead
and link using the dynamic symbol table. */
@@ -507,7 +553,7 @@ elf_link_add_object_symbols (abfd, info)
asection *sec;
flagword flags;
const char *name;
- struct elf_link_hash_entry *h = NULL;
+ struct elf_link_hash_entry *h;
boolean definition;
boolean new_weakdef;
@@ -607,6 +653,10 @@ elf_link_add_object_symbols (abfd, info)
goto error_return;
*sym_hash = h;
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
/* If we are looking at a dynamic object, and this is a
definition, we need to see if it has already been defined
by some other object. If it has, we want to use the
@@ -649,13 +699,19 @@ elf_link_add_object_symbols (abfd, info)
false, collect, (struct bfd_link_hash_entry **) sym_hash)))
goto error_return;
+ h = *sym_hash;
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ *sym_hash = h;
+
new_weakdef = false;
if (dynamic
&& definition
&& (flags & BSF_WEAK) != 0
&& ELF_ST_TYPE (sym.st_info) != STT_FUNC
&& info->hash->creator->flavour == bfd_target_elf_flavour
- && (*sym_hash)->weakdef == NULL)
+ && h->weakdef == NULL)
{
/* Keep a list of all weak defined non function symbols from
a dynamic object, using the weakdef field. Later in this
@@ -669,15 +725,15 @@ elf_link_add_object_symbols (abfd, info)
dynamic object, and we will be using that previous
definition anyhow. */
- (*sym_hash)->weakdef = weaks;
- weaks = *sym_hash;
+ h->weakdef = weaks;
+ weaks = h;
new_weakdef = true;
}
/* Get the alignment of a common symbol. */
if (sym.st_shndx == SHN_COMMON
- && (*sym_hash)->root.type == bfd_link_hash_common)
- (*sym_hash)->root.u.c.p->alignment_power = bfd_log2 (sym.st_value);
+ && h->root.type == bfd_link_hash_common)
+ h->root.u.c.p->alignment_power = bfd_log2 (sym.st_value);
if (info->hash->creator->flavour == bfd_target_elf_flavour)
{
@@ -2451,8 +2507,8 @@ elf_link_output_extsym (h, data)
case bfd_link_hash_indirect:
case bfd_link_hash_warning:
- /* I have no idea how these should be handled. */
- return true;
+ return (elf_link_output_extsym
+ ((struct elf_link_hash_entry *) h->root.u.i.link, data));
}
/* If this symbol should be put in the .dynsym section, then put it