summaryrefslogtreecommitdiff
path: root/bfd/elf32-avr.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2007-01-25 09:32:41 +0000
committerNick Clifton <nickc@redhat.com>2007-01-25 09:32:41 +0000
commitaf7cac5f279d6cb96c0ba02bf49e7393519acf47 (patch)
tree9b26c34cb161bb94e320d72a909d12c96b9d73bb /bfd/elf32-avr.c
parentdcd1e79ddcc4b4da032189057095c93aba5304d7 (diff)
downloadbinutils-redhat-af7cac5f279d6cb96c0ba02bf49e7393519acf47.tar.gz
PR binutils/3874
* elf32-avr.c (avr_link_hash_table): Check to make sure that the hash table was created by elf32_avr_link_hash_table_create before using it. (elf32_avr_link_hash_newfunc): New function. Just pass the call through to _bfd_elf_link_hash_newfunc. (elf32_avr_link_hash_table_create): Use elf32_avr_link_hash_newfunc instead of _bfd_elf_link_hash_newfunc. (elf32_avr_relocate_section): Check for the hash table pointer being NULL. (elf32_avr_relax_section, avr_build_one_stub, elf32_avr_setup_params, get_local_syms, elf32_avr_size_stubs, elf32_avr_build_stubs): Likewise.
Diffstat (limited to 'bfd/elf32-avr.c')
-rw-r--r--bfd/elf32-avr.c63
1 files changed, 45 insertions, 18 deletions
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c
index 40cc0830fb..18f2b953d8 100644
--- a/bfd/elf32-avr.c
+++ b/bfd/elf32-avr.c
@@ -1,5 +1,5 @@
/* AVR-specific support for 32-bit ELF
- Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007
Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
@@ -103,7 +103,9 @@ struct elf32_avr_link_hash_table
/* Various hash macros and functions. */
#define avr_link_hash_table(p) \
- ((struct elf32_avr_link_hash_table *) ((p)->hash))
+ /* PR 3874: Check that we have an AVR style hash table before using it. */\
+ ((p)->hash->table.newfunc != elf32_avr_link_hash_newfunc ? NULL : \
+ ((struct elf32_avr_link_hash_table *) ((p)->hash)))
#define avr_stub_hash_entry(ent) \
((struct elf32_avr_stub_hash_entry *)(ent))
@@ -587,6 +589,18 @@ stub_hash_newfunc (struct bfd_hash_entry *entry,
return entry;
}
+/* This function is just a straight passthrough to the real
+ function in linker.c. Its prupose is so that its address
+ can be compared inside the avr_link_hash_table macro. */
+
+static struct bfd_hash_entry *
+elf32_avr_link_hash_newfunc (struct bfd_hash_entry * entry,
+ struct bfd_hash_table * table,
+ const char * string)
+{
+ return _bfd_elf_link_hash_newfunc (entry, table, string);
+}
+
/* Create the derived linker hash table. The AVR ELF port uses the derived
hash table to keep information specific to the AVR ELF linker (without
using static variables). */
@@ -602,7 +616,7 @@ elf32_avr_link_hash_table_create (bfd *abfd)
return NULL;
if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd,
- _bfd_elf_link_hash_newfunc,
+ elf32_avr_link_hash_newfunc,
sizeof (struct elf_link_hash_entry)))
{
free (htab);
@@ -1139,7 +1153,7 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
Elf_Internal_Rela * relend;
struct elf32_avr_link_hash_table * htab = avr_link_hash_table (info);
- if (info->relocatable)
+ if (info == NULL || info->relocatable)
return TRUE;
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
@@ -1560,6 +1574,8 @@ elf32_avr_relax_section (bfd *abfd,
struct elf32_avr_link_hash_table *htab;
htab = avr_link_hash_table (link_info);
+ if (htab == NULL)
+ return FALSE;
/* Assume nothing changes. */
*again = FALSE;
@@ -2364,6 +2380,8 @@ avr_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
info = (struct bfd_link_info *) in_arg;
htab = avr_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
target = hsh->target_value;
@@ -2454,8 +2472,10 @@ elf32_avr_setup_params (struct bfd_link_info *info,
bfd_vma pc_wrap_around,
bfd_boolean call_ret_replacement)
{
- struct elf32_avr_link_hash_table *htab = avr_link_hash_table(info);
+ struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
+ if (htab == NULL)
+ return;
htab->stub_sec = avr_stub_section;
htab->stub_bfd = avr_stub_bfd;
htab->no_stubs = no_stubs;
@@ -2485,7 +2505,7 @@ elf32_avr_setup_section_lists (bfd *output_bfd,
bfd_size_type amt;
struct elf32_avr_link_hash_table *htab = avr_link_hash_table(info);
- if (htab->no_stubs)
+ if (htab == NULL || htab->no_stubs)
return 0;
/* Count the number of input BFDs and find the top input section id. */
@@ -2547,6 +2567,9 @@ get_local_syms (bfd *input_bfd, struct bfd_link_info *info)
Elf_Internal_Sym *local_syms, **all_local_syms;
struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
+ if (htab == NULL)
+ return -1;
+
/* We want to read in symbol extension records only once. To do this
we need to read in the local symbols in parallel and save them for
later use; so hold pointers to the local symbols in an array. */
@@ -2596,21 +2619,23 @@ elf32_avr_size_stubs (bfd *output_bfd,
struct bfd_link_info *info,
bfd_boolean is_prealloc_run)
{
- struct elf32_avr_link_hash_table *htab;
- int stub_changed = 0;
+ struct elf32_avr_link_hash_table *htab;
+ int stub_changed = 0;
- htab = avr_link_hash_table (info);
+ htab = avr_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
- /* At this point we initialize htab->vector_base
- To the start of the text output section. */
- htab->vector_base = htab->stub_sec->output_section->vma;
+ /* At this point we initialize htab->vector_base
+ To the start of the text output section. */
+ htab->vector_base = htab->stub_sec->output_section->vma;
- if (get_local_syms (info->input_bfds, info))
- {
- if (htab->all_local_syms)
- goto error_ret_free_local;
- return FALSE;
- }
+ if (get_local_syms (info->input_bfds, info))
+ {
+ if (htab->all_local_syms)
+ goto error_ret_free_local;
+ return FALSE;
+ }
if (ADD_DUMMY_STUBS_FOR_DEBUGGING)
{
@@ -2856,6 +2881,8 @@ elf32_avr_build_stubs (struct bfd_link_info *info)
bfd_size_type total_size = 0;
htab = avr_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
/* In case that there were several stub sections: */
for (stub_sec = htab->stub_bfd->sections;