Submitted By: Robert Connolly (ashes) Date: 2007-05-07 Initial Package Version: 2.17 Upstream Status: From Upstream Origin: cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src \ co -rbinutils-2_17 binutils cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src \ co -rbinutils-2_17-branch binutils diff -pNur -x CVS binutils-2_17/ binutils-2_17-branch/ Description: This is the binutils-2_17-branch (bug fix branch) update. This patch should be updated periodically. bfd/Makefile.{am,in} commented out "RELEASE=y". I reversed that, and removed the ChangeLog for it. bfd/ChangeLog: 2006-12-11 Eric Botcazou * elflink.c (bfd_elf_gc_sections): Also search for corresponding sections with .gnu.linkonce.t. prefix. 2006-08-08 Nick Clifton PR binutils/2724 * coffcode.h (coff_new_section_hook): Only modify the section symbol of sections which were created by the user. 2006-07-19 Alan Modra * bfd-in.h (enum notice_asneeded_action): Define. * bfd-in2.h: Regenerate. * elflink.c (elf_link_add_object_symbols): Call linker "notice" function with NULL name for as-needed handling. 2006-07-12 Matthew R. Dempsky * cpu-m68k.c (bfd_m68k_compatible): Handle CPU32. binutils/ChangeLog: 2006-08-15 Nick Clifton PR binutils/3039 * wrstabs.c (stab_tag_type): Initialize 'size'. gas/ChangeLog: 2006-07-19 Mat Hostetter * symbols.c (report_op_error): Fix pasto. Don't use as_bad_where when file and line unknown. ld/ChangeLog: 2006-07-19 Alan Modra * ld.h (handle_asneeded_cref): Declare. * ldcref.c: Include objalloc.h. (old_table, old_tab, alloc_mark): New variables. (tabsize, entsize, refsize, old_symcount): Likewise. (add_cref): Use bfd_hash_allocate for refs. (handle_asneeded_cref): New function. * ldmain.c (notice): Call handle_asneeded_cref for NULL name. 2006-07-04 Daniel Jacobowitz Backport: 2006-05-19 Alan Modra * ldlang.c (lang_size_sections_1): Don't check mem regions for os->ignored sections. ld/testsuite/ChangeLog: 2006-07-12 Richard Sandiford * ld-m68k/merge-ok-1c.d: New test. * ld-m68k/m68k.exp: Run it. 2006-07-04 Daniel Jacobowitz Backport: 2006-05-19 Alan Modra * ld-scripts/empty-orphan.d: Update again. * ld-scripts/empty-orphan.t: Discard .reginfo. * ld-scripts/empty-orphan.d: Update. diff -pNur -x CVS binutils-2_17/bfd/bfd-in.h binutils-2_17-branch/bfd/bfd-in.h --- binutils-2_17/bfd/bfd-in.h 2006-03-16 07:20:15.000000000 -0500 +++ binutils-2_17-branch/bfd/bfd-in.h 2006-07-18 22:37:04.000000000 -0400 @@ -636,6 +636,12 @@ enum dynamic_lib_link_class { DYN_NO_NEEDED = 8 }; +enum notice_asneeded_action { + notice_as_needed, + notice_not_needed, + notice_needed +}; + extern bfd_boolean bfd_elf_record_link_assignment (bfd *, struct bfd_link_info *, const char *, bfd_boolean, bfd_boolean); diff -pNur -x CVS binutils-2_17/bfd/bfd-in2.h binutils-2_17-branch/bfd/bfd-in2.h --- binutils-2_17/bfd/bfd-in2.h 2006-03-25 19:38:42.000000000 -0500 +++ binutils-2_17-branch/bfd/bfd-in2.h 2006-07-18 22:37:04.000000000 -0400 @@ -643,6 +643,12 @@ enum dynamic_lib_link_class { DYN_NO_NEEDED = 8 }; +enum notice_asneeded_action { + notice_as_needed, + notice_not_needed, + notice_needed +}; + extern bfd_boolean bfd_elf_record_link_assignment (bfd *, struct bfd_link_info *, const char *, bfd_boolean, bfd_boolean); diff -pNur -x CVS binutils-2_17/bfd/coffcode.h binutils-2_17-branch/bfd/coffcode.h --- binutils-2_17/bfd/coffcode.h 2005-10-25 13:40:09.000000000 -0400 +++ binutils-2_17-branch/bfd/coffcode.h 2006-08-08 04:19:57.000000000 -0400 @@ -1546,9 +1546,6 @@ static const unsigned int coff_section_a static bfd_boolean coff_new_section_hook (bfd * abfd, asection * section) { - combined_entry_type *native; - bfd_size_type amt; - section->alignment_power = COFF_DEFAULT_SECTION_ALIGNMENT_POWER; #ifdef RS6000COFF_C @@ -1560,27 +1557,34 @@ coff_new_section_hook (bfd * abfd, asect section->alignment_power = bfd_xcoff_data_align_power (abfd); #endif - /* Allocate aux records for section symbols, to store size and - related info. - - @@ The 10 is a guess at a plausible maximum number of aux entries - (but shouldn't be a constant). */ - amt = sizeof (combined_entry_type) * 10; - native = bfd_zalloc (abfd, amt); - if (native == NULL) - return FALSE; - - /* We don't need to set up n_name, n_value, or n_scnum in the native - symbol information, since they'll be overridden by the BFD symbol - anyhow. However, we do need to set the type and storage class, - in case this symbol winds up getting written out. The value 0 - for n_numaux is already correct. */ - - native->u.syment.n_type = T_NULL; - native->u.syment.n_sclass = C_STAT; + /* PR binutils/2724: Only real sections have a symbol that + has the coff_symbol_type structure allocated for it. */ + if (! bfd_is_const_section (section)) + { + combined_entry_type *native; + bfd_size_type amt; + + /* Allocate aux records for section symbols, to store size and + related info. + + @@ The 10 is a guess at a plausible maximum number of aux entries + (but shouldn't be a constant). */ + amt = sizeof (combined_entry_type) * 10; + native = bfd_zalloc (abfd, amt); + if (native == NULL) + return FALSE; - coffsymbol (section->symbol)->native = native; + /* We don't need to set up n_name, n_value, or n_scnum in the native + symbol information, since they'll be overridden by the BFD symbol + anyhow. However, we do need to set the type and storage class, + in case this symbol winds up getting written out. The value 0 + for n_numaux is already correct. */ + native->u.syment.n_type = T_NULL; + native->u.syment.n_sclass = C_STAT; + coffsymbol (section->symbol)->native = native; + } + coff_set_custom_section_alignment (abfd, section, coff_section_alignment_table, coff_section_alignment_table_size); diff -pNur -x CVS binutils-2_17/bfd/cpu-m68k.c binutils-2_17-branch/bfd/cpu-m68k.c --- binutils-2_17/bfd/cpu-m68k.c 2006-03-25 05:24:27.000000000 -0500 +++ binutils-2_17-branch/bfd/cpu-m68k.c 2006-07-12 08:55:21.000000000 -0400 @@ -202,6 +202,9 @@ bfd_m68k_compatible (const bfd_arch_info if (a->mach <= bfd_mach_m68060 && b->mach <= bfd_mach_m68060) /* Merge m68k machine. */ return a->mach > b->mach ? a : b; + else if (a->mach == bfd_mach_cpu32 && b->mach == bfd_mach_cpu32) + /* CPU32 is compatible with itself. */ + return a; else if (a->mach >= bfd_mach_mcf_isa_a_nodiv && b->mach >= bfd_mach_mcf_isa_a_nodiv) { diff -pNur -x CVS binutils-2_17/bfd/elflink.c binutils-2_17-branch/bfd/elflink.c --- binutils-2_17/bfd/elflink.c 2006-05-22 11:07:06.000000000 -0400 +++ binutils-2_17-branch/bfd/elflink.c 2006-12-11 09:52:39.000000000 -0500 @@ -3496,6 +3496,13 @@ elf_link_add_object_symbols (bfd *abfd, if (alloc_mark == NULL) goto error_free_vers; + /* Make a special call to the linker "notice" function to + tell it that we are about to handle an as-needed lib. */ + if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, + notice_as_needed)) + return FALSE; + + /* Clone the symbol table and sym hashes. Remember some pointers into the symbol table, and dynamic symbol count. */ old_hash = (char *) old_tab + tabsize; @@ -4169,6 +4176,12 @@ elf_link_add_object_symbols (bfd *abfd, } } + /* Make a special call to the linker "notice" function to + tell it that symbols added for crefs may need to be removed. */ + if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, + notice_not_needed)) + return FALSE; + free (old_tab); objalloc_free_block ((struct objalloc *) htab->root.table.memory, alloc_mark); @@ -4179,6 +4192,9 @@ elf_link_add_object_symbols (bfd *abfd, if (old_tab != NULL) { + if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, + notice_needed)) + return FALSE; free (old_tab); old_tab = NULL; } @@ -9239,7 +9255,8 @@ bfd_elf_gc_sections (bfd *abfd, struct b if (bfd_get_flavour (sub) != bfd_target_elf_flavour) continue; - /* Keep .gcc_except_table.* if the associated .text.* is + /* Keep .gcc_except_table.* if the associated .text.* (or the + associated .gnu.linkonce.t.* if .text.* doesn't exist) is marked. This isn't very nice, but the proper solution, splitting .eh_frame up and using comdat doesn't pan out easily due to needing special relocs to handle the @@ -9255,12 +9272,23 @@ bfd_elf_gc_sections (bfd *abfd, struct b asection *fn_text; len = strlen (o->name + 18) + 1; - fn_name = bfd_malloc (len + 6); + fn_name = bfd_malloc (len + 16); if (fn_name == NULL) return FALSE; + + /* Try the first prefix. */ memcpy (fn_name, ".text.", 6); memcpy (fn_name + 6, o->name + 18, len); fn_text = bfd_get_section_by_name (sub, fn_name); + + /* Try the second prefix. */ + if (fn_text == NULL) + { + memcpy (fn_name, ".gnu.linkonce.t.", 16); + memcpy (fn_name + 16, o->name + 18, len); + fn_text = bfd_get_section_by_name (sub, fn_name); + } + free (fn_name); if (fn_text == NULL || !fn_text->gc_mark) continue; diff -pNur -x CVS binutils-2_17/bfd/version.h binutils-2_17-branch/bfd/version.h --- binutils-2_17/bfd/version.h 2006-06-22 20:00:17.000000000 -0400 +++ binutils-2_17-branch/bfd/version.h 2007-05-07 20:00:13.000000000 -0400 @@ -1,3 +1,3 @@ -#define BFD_VERSION_DATE 20060623 +#define BFD_VERSION_DATE 20070508 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_string@ diff -pNur -x CVS binutils-2_17/binutils/wrstabs.c binutils-2_17-branch/binutils/wrstabs.c --- binutils-2_17/binutils/wrstabs.c 2006-03-16 07:20:16.000000000 -0500 +++ binutils-2_17-branch/binutils/wrstabs.c 2006-08-15 08:01:21.000000000 -0400 @@ -1869,7 +1869,7 @@ stab_tag_type (void *p, const char *name { struct stab_write_handle *info = (struct stab_write_handle *) p; long index; - unsigned int size; + unsigned int size = 0; index = stab_get_struct_index (info, name, id, kind, &size); if (index < 0) diff -pNur -x CVS binutils-2_17/gas/symbols.c binutils-2_17-branch/gas/symbols.c --- binutils-2_17/gas/symbols.c 2006-01-09 12:14:40.000000000 -0500 +++ binutils-2_17-branch/gas/symbols.c 2006-07-18 22:06:08.000000000 -0400 @@ -928,13 +928,11 @@ report_op_error (symbolS *symp, symbolS && seg_right != undefined_section) { if (right) - as_bad_where (file, line, - _("invalid sections for operation on `%s' and `%s' setting `%s'"), - S_GET_NAME (left), S_GET_NAME (right), S_GET_NAME (symp)); + as_bad (_("invalid sections for operation on `%s' and `%s' setting `%s'"), + S_GET_NAME (left), S_GET_NAME (right), S_GET_NAME (symp)); else - as_bad_where (file, line, - _("invalid section for operation on `%s' setting `%s'"), - S_GET_NAME (left), S_GET_NAME (symp)); + as_bad (_("invalid section for operation on `%s' setting `%s'"), + S_GET_NAME (left), S_GET_NAME (symp)); } } } diff -pNur -x CVS binutils-2_17/ld/ld.h binutils-2_17-branch/ld/ld.h --- binutils-2_17/ld/ld.h 2005-09-30 07:42:04.000000000 -0400 +++ binutils-2_17-branch/ld/ld.h 2006-07-18 22:37:05.000000000 -0400 @@ -1,6 +1,6 @@ /* ld.h -- general linker header file Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005 + 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. @@ -282,6 +282,7 @@ extern int parsing_defsym; extern int yyparse (void); extern void add_cref (const char *, bfd *, asection *, bfd_vma); +extern bfd_boolean handle_asneeded_cref (bfd *, enum notice_asneeded_action); extern void output_cref (FILE *); extern void check_nocrossrefs (void); extern void ld_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; diff -pNur -x CVS binutils-2_17/ld/ldcref.c binutils-2_17-branch/ld/ldcref.c --- binutils-2_17/ld/ldcref.c 2006-03-16 07:20:16.000000000 -0500 +++ binutils-2_17-branch/ld/ldcref.c 2006-07-18 22:37:05.000000000 -0400 @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street - F #include "sysdep.h" #include "bfdlink.h" #include "libiberty.h" +#include "objalloc.h" #include "ld.h" #include "ldmain.h" @@ -101,6 +102,15 @@ static bfd_boolean cref_initialized; static size_t cref_symcount; +/* Used to take a snapshot of the cref hash table when starting to + add syms from an as-needed library. */ +static struct bfd_hash_entry **old_table; +static unsigned int old_size; +static void *old_tab; +static void *alloc_mark; +static size_t tabsize, entsize, refsize; +static size_t old_symcount; + /* Create an entry in a cref hash table. */ static struct bfd_hash_entry * @@ -165,7 +175,9 @@ add_cref (const char *name, if (r == NULL) { - r = xmalloc (sizeof *r); + r = bfd_hash_allocate (&cref_table.root, sizeof *r); + if (r == NULL) + einfo (_("%X%P: cref alloc failed: %E\n")); r->next = h->refs; h->refs = r; r->abfd = abfd; @@ -182,6 +194,123 @@ add_cref (const char *name, r->def = TRUE; } +/* Called before loading an as-needed library to take a snapshot of + the cref hash table, and after we have loaded or found that the + library was not needed. */ + +bfd_boolean +handle_asneeded_cref (bfd *abfd ATTRIBUTE_UNUSED, + enum notice_asneeded_action act) +{ + unsigned int i; + + if (!cref_initialized) + return TRUE; + + if (act == notice_as_needed) + { + char *old_ent, *old_ref; + + for (i = 0; i < cref_table.root.size; i++) + { + struct bfd_hash_entry *p; + struct cref_hash_entry *c; + struct cref_ref *r; + + for (p = cref_table.root.table[i]; p != NULL; p = p->next) + { + entsize += cref_table.root.entsize; + c = (struct cref_hash_entry *) p; + for (r = c->refs; r != NULL; r = r->next) + refsize += sizeof (struct cref_hash_entry); + } + } + + tabsize = cref_table.root.size * sizeof (struct bfd_hash_entry *); + old_tab = xmalloc (tabsize + entsize + refsize); + + alloc_mark = bfd_hash_allocate (&cref_table.root, 1); + if (alloc_mark == NULL) + return FALSE; + + memcpy (old_tab, cref_table.root.table, tabsize); + old_ent = (char *) old_tab + tabsize; + old_ref = (char *) old_ent + entsize; + old_table = cref_table.root.table; + old_size = cref_table.root.size; + old_symcount = cref_symcount; + + for (i = 0; i < cref_table.root.size; i++) + { + struct bfd_hash_entry *p; + struct cref_hash_entry *c; + struct cref_ref *r; + + for (p = cref_table.root.table[i]; p != NULL; p = p->next) + { + memcpy (old_ent, p, cref_table.root.entsize); + old_ent = (char *) old_ent + cref_table.root.entsize; + c = (struct cref_hash_entry *) p; + for (r = c->refs; r != NULL; r = r->next) + { + memcpy (old_ref, r, sizeof (struct cref_hash_entry)); + old_ref = (char *) old_ref + sizeof (struct cref_hash_entry); + } + } + } + return TRUE; + } + + if (act == notice_not_needed) + { + char *old_ent, *old_ref; + + if (old_tab == NULL) + { + /* The only way old_tab can be NULL is if the cref hash table + had not been initialised when notice_as_needed. */ + bfd_hash_table_free (&cref_table.root); + cref_initialized = FALSE; + return TRUE; + } + + old_ent = (char *) old_tab + tabsize; + old_ref = (char *) old_ent + entsize; + cref_table.root.table = old_table; + cref_table.root.size = old_size; + memcpy (cref_table.root.table, old_tab, tabsize); + cref_symcount = old_symcount; + + for (i = 0; i < cref_table.root.size; i++) + { + struct bfd_hash_entry *p; + struct cref_hash_entry *c; + struct cref_ref *r; + + for (p = cref_table.root.table[i]; p != NULL; p = p->next) + { + memcpy (p, old_ent, cref_table.root.entsize); + old_ent = (char *) old_ent + cref_table.root.entsize; + c = (struct cref_hash_entry *) p; + for (r = c->refs; r != NULL; r = r->next) + { + memcpy (r, old_ref, sizeof (struct cref_hash_entry)); + old_ref = (char *) old_ref + sizeof (struct cref_hash_entry); + } + } + } + + objalloc_free_block ((struct objalloc *) cref_table.root.memory, + alloc_mark); + } + else if (act != notice_needed) + return FALSE; + + free (old_tab); + old_tab = NULL; + return TRUE; +} + /* Copy the addresses of the hash table entries into an array. This is called via cref_hash_traverse. We also fill in the demangled name. */ diff -pNur -x CVS binutils-2_17/ld/ldlang.c binutils-2_17-branch/ld/ldlang.c --- binutils-2_17/ld/ldlang.c 2006-06-08 21:14:53.000000000 -0400 +++ binutils-2_17-branch/ld/ldlang.c 2006-07-04 09:29:24.000000000 -0400 @@ -4207,7 +4207,8 @@ lang_size_sections_1 /* If a loadable section is using the default memory region, and some non default memory regions were defined, issue an error message. */ - if (!IGNORE_SECTION (os->bfd_section) + if (!os->ignored + && !IGNORE_SECTION (os->bfd_section) && ! link_info.relocatable && check_regions && strcmp (os->region->name, diff -pNur -x CVS binutils-2_17/ld/ldmain.c binutils-2_17-branch/ld/ldmain.c --- binutils-2_17/ld/ldmain.c 2006-04-06 14:52:45.000000000 -0400 +++ binutils-2_17-branch/ld/ldmain.c 2006-07-18 22:37:05.000000000 -0400 @@ -1511,6 +1511,13 @@ notice (struct bfd_link_info *info, asection *section, bfd_vma value) { + if (name == NULL) + { + if (command_line.cref || nocrossref_list != NULL) + return handle_asneeded_cref (abfd, value); + return TRUE; + } + if (! info->notice_all || (info->notice_hash != NULL && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL)) diff -pNur -x CVS binutils-2_17/ld/testsuite/ld-m68k/m68k.exp binutils-2_17-branch/ld/testsuite/ld-m68k/m68k.exp --- binutils-2_17/ld/testsuite/ld-m68k/m68k.exp 2006-03-25 05:24:27.000000000 -0500 +++ binutils-2_17-branch/ld/testsuite/ld-m68k/m68k.exp 2006-07-12 08:55:21.000000000 -0400 @@ -53,3 +53,4 @@ run_dump_test "merge-error-1d" run_dump_test "merge-error-1e" run_dump_test "merge-ok-1a" run_dump_test "merge-ok-1b" +run_dump_test "merge-ok-1c" diff -pNur -x CVS binutils-2_17/ld/testsuite/ld-m68k/merge-ok-1c.d binutils-2_17-branch/ld/testsuite/ld-m68k/merge-ok-1c.d --- binutils-2_17/ld/testsuite/ld-m68k/merge-ok-1c.d 1969-12-31 19:00:00.000000000 -0500 +++ binutils-2_17-branch/ld/testsuite/ld-m68k/merge-ok-1c.d 2006-07-12 08:55:21.000000000 -0400 @@ -0,0 +1,6 @@ +#source: merge-error-1a.s -march=cpu32 +#source: merge-error-1b.s -march=cpu32 +#ld: -r +#objdump: -p +#... +private flags = 810000: \[cpu32\] diff -pNur -x CVS binutils-2_17/ld/testsuite/ld-scripts/empty-orphan.d binutils-2_17-branch/ld/testsuite/ld-scripts/empty-orphan.d --- binutils-2_17/ld/testsuite/ld-scripts/empty-orphan.d 2005-03-17 11:20:39.000000000 -0500 +++ binutils-2_17-branch/ld/testsuite/ld-scripts/empty-orphan.d 2006-07-04 09:29:24.000000000 -0400 @@ -1,3 +1,6 @@ #source: empty-orphan.s #ld: -T empty-orphan.t -#error: no memory region specified for loadable section +#readelf: -l --wide +#... + +LOAD +[x0-9a-f]+ [x0]+70000000 [x0]+70000000 [x0]+(2|4|8|10|20|40|80) .* +#pass diff -pNur -x CVS binutils-2_17/ld/testsuite/ld-scripts/empty-orphan.t binutils-2_17-branch/ld/testsuite/ld-scripts/empty-orphan.t --- binutils-2_17/ld/testsuite/ld-scripts/empty-orphan.t 2005-03-17 11:20:39.000000000 -0500 +++ binutils-2_17-branch/ld/testsuite/ld-scripts/empty-orphan.t 2006-07-04 09:29:24.000000000 -0400 @@ -17,5 +17,6 @@ SECTIONS .text : { *(.text) } > text_mem : text_phdr .data : { *(.data) } > data_mem : data_phdr .bss : { *(.bss) } > data_mem : data_phdr + /DISCARD/ : { *(.reginfo) } /* .orphan_data is an orphan */ }