PR binutils/3874
authorNick Clifton <nickc@redhat.com>
Thu, 25 Jan 2007 09:32:41 +0000 (09:32 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 25 Jan 2007 09:32:41 +0000 (09:32 +0000)
* 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.

bfd/ChangeLog
bfd/elf32-avr.c

index 6b2a418..33fcec6 100644 (file)
@@ -1,3 +1,20 @@
+2007-01-25  Nick Clifton  <nickc@redhat.com>
+
+       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.
+
 2007-01-16  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/3831
index 40cc083..18f2b95 100644 (file)
@@ -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;