From 64ee10b619d964d076beec103b1400a84bf1bc69 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 25 Jan 2007 09:32:41 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 17 +++++++++++++ bfd/elf32-avr.c | 63 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 18 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6b2a418ff5c..33fcec6ac40 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,20 @@ +2007-01-25 Nick Clifton + + 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 PR ld/3831 diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 40cc0830fb7..18f2b953d8e 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 @@ -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; -- 2.30.2