From 4fbb74a6055f7d48f09c44064073d3b1e99c6642 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 12 Mar 2008 08:37:09 +0000 Subject: [PATCH] include/elf/ PR 5900 * common.h (SHN_BAD): Delete. (SHN_LORESERVE .. SHN_HIRESERVE): Move to.. * external.h: ..here. * internal.h (SHN_LORESERVE, SHN_HIRESERVE): Define. (SHN_LOPROC, SHN_HIPROC, SHN_LOOS, SHN_HIOS): Define. (SHN_ABS, SHN_COMMON, SHN_XINDEX, SHN_BAD): Define. bfd/ PR 5900 * elf-bfd.h: Include elf/internal.h after elf/external.h. * elfcode.h (elf_swap_symbol_in): Map reserved shndx range. (elf_swap_symbol_out): Adjust SHN_XINDEX test. (elf_swap_ehdr_out): Mask SHN_LORESERVE and SHN_XINDEX to values seen in external structs. (valid_section_index_p): Delete. (elf_object_p): Don't increment section numbers over reserved range. Simplify test for valid sh_link, sh_info and e_shstrndx fields. (elf_write_shdrs_and_ehdr): Mask SHN_LORESERVE and SHN_XINDEX to values seen in external structs. Don't increment section numbers over reserved range. * elf.c (bfd_elf_sym_name): Remove redundant tests on st_shndx. (bfd_section_from_shdr): Likewise. (group_signature): Range check before accessing elf_elfsections. (_bfd_elf_setup_sections): Likewise. (bfd_section_from_shdr): Likewise. (bfd_section_from_shdr): Don't increment section number over reserved sections. (assign_file_positions_for_non_load_sections): Likewise. (assign_file_positions_except_relocs): Likewise. (_bfd_elf_write_object_contents): Likewise. (assign_section_numbers): Likewise. Adjust for changed SHN_*. (prep_headers): Delete unused variable. * elflink.c (bfd_elf_link_record_local_dynamic_symbol): Adjust for changed SHN_* values. (check_dynsym, elf_link_input_bfd): Likewise. (bfd_elf_final_link): Likewise. Don't skip over reserved section range. (elf_fixup_link_order): Check that sh_link field is valid. * elf-hppa.h (elf_hppa_add_symbol_hook): Make "index" unsigned. * elf32-arm.c (elf32_arm_gc_mark_extra_sections): Range check before accesssing elf_elfsections. * elf32-avr.c (elf32_avr_size_stubs): Likewise. * elf32-hppa.c (elf32_hppa_size_stubs): Likewise. * elf32-m68hc1x.c (elf32_m68hc11_size_stubs): Likewise. * elf64-hppa.c (elf64_hppa_check_relocs): Adjust for changed SHN_* defines. Test for SHN_BAD return from _bfd_elf_section_from_bfd_section binutils/ PR 5900 * readelf.c (SECTION_HEADER_INDEX, SECTION_HEADER_NUM): Delete. Remove use throughout file. (SECTION_HEADER): Likewise. (dump_relocations): Don't adjust st_shndx for reserved range. (process_file_header): Mask SHN_XINDEX to values seen in external elf structs. Simplify valid section index tests. (get_32bit_elf_symbols, get_64bit_elf_symbols): Mask SHN_XINDEX. Map reserved st_shndx to internal form. (process_section_groups): Test that group symbol st_shndx is in range, not just non-zero. Delete reserved range check. (get_symbol_index_type): Mask "type" to 16 bits when printing PRC, OS or RSV. gdb/ PR 5900 * elfread.c (elf_symtab_read): Make shndx an unsigned int. * mipsread.c: Include elf/internal.h. (read_alphacoff_dynamic_symtab): Map external reserved sym_shndx to internal range. ld/testsuite/ PR 5900 * ld-elf/sec64k.exp: Update. --- bfd/ChangeLog | 42 +++++++++ bfd/elf-bfd.h | 2 +- bfd/elf-hppa.h | 4 +- bfd/elf.c | 82 ++++++----------- bfd/elf32-arm.c | 4 +- bfd/elf32-avr.c | 17 ++-- bfd/elf32-hppa.c | 18 ++-- bfd/elf32-m68hc1x.c | 9 +- bfd/elf64-hppa.c | 14 +-- bfd/elfcode.h | 69 ++++---------- bfd/elflink.c | 22 +++-- binutils/ChangeLog | 16 ++++ binutils/readelf.c | 199 +++++++++++++++++------------------------ gdb/ChangeLog | 8 ++ gdb/elfread.c | 2 +- gdb/mipsread.c | 3 + include/elf/ChangeLog | 28 ++++-- include/elf/common.h | 17 +--- include/elf/external.h | 17 +++- include/elf/internal.h | 27 +++++- ld/testsuite/ChangeLog | 5 ++ ld/testsuite/ld-elf/sec64k.exp | 12 +-- 22 files changed, 319 insertions(+), 298 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1dca4b7..2171dc9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,47 @@ 2008-03-12 Alan Modra + PR 5900 + * elf-bfd.h: Include elf/internal.h after elf/external.h. + * elfcode.h (elf_swap_symbol_in): Map reserved shndx range. + (elf_swap_symbol_out): Adjust SHN_XINDEX test. + (elf_swap_ehdr_out): Mask SHN_LORESERVE and SHN_XINDEX to values + seen in external structs. + (valid_section_index_p): Delete. + (elf_object_p): Don't increment section numbers over reserved range. + Simplify test for valid sh_link, sh_info and e_shstrndx fields. + (elf_write_shdrs_and_ehdr): Mask SHN_LORESERVE and SHN_XINDEX to values + seen in external structs. Don't increment section numbers over + reserved range. + * elf.c (bfd_elf_sym_name): Remove redundant tests on st_shndx. + (bfd_section_from_shdr): Likewise. + (group_signature): Range check before accessing elf_elfsections. + (_bfd_elf_setup_sections): Likewise. + (bfd_section_from_shdr): Likewise. + (bfd_section_from_shdr): Don't increment section number over + reserved sections. + (assign_file_positions_for_non_load_sections): Likewise. + (assign_file_positions_except_relocs): Likewise. + (_bfd_elf_write_object_contents): Likewise. + (assign_section_numbers): Likewise. Adjust for changed SHN_*. + (prep_headers): Delete unused variable. + * elflink.c (bfd_elf_link_record_local_dynamic_symbol): Adjust + for changed SHN_* values. + (check_dynsym, elf_link_input_bfd): Likewise. + (bfd_elf_final_link): Likewise. Don't skip over reserved section + range. + (elf_fixup_link_order): Check that sh_link field is valid. + * elf-hppa.h (elf_hppa_add_symbol_hook): Make "index" unsigned. + * elf32-arm.c (elf32_arm_gc_mark_extra_sections): Range check before + accesssing elf_elfsections. + * elf32-avr.c (elf32_avr_size_stubs): Likewise. + * elf32-hppa.c (elf32_hppa_size_stubs): Likewise. + * elf32-m68hc1x.c (elf32_m68hc11_size_stubs): Likewise. + * elf64-hppa.c (elf64_hppa_check_relocs): Adjust for changed + SHN_* defines. Test for SHN_BAD return from + _bfd_elf_section_from_bfd_section + +2008-03-12 Alan Modra + * elf-bfd.h (_bfd_elf_section_from_bfd_section): Update prototype. * elf.c (_bfd_elf_section_from_bfd_section): Return unsigned int, SHN_BAD on error. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index b3d1d38..8732710 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -24,8 +24,8 @@ #define _LIBELF_H_ 1 #include "elf/common.h" -#include "elf/internal.h" #include "elf/external.h" +#include "elf/internal.h" #include "bfdlink.h" /* The number of entries in a section is its size divided by the size diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h index c82264b..d2b5dfd 100644 --- a/bfd/elf-hppa.h +++ b/bfd/elf-hppa.h @@ -1,5 +1,5 @@ /* Common code for PA ELF implementations. - Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -1193,7 +1193,7 @@ elf_hppa_add_symbol_hook (bfd *abfd, asection **secp, bfd_vma *valp) { - int index = sym->st_shndx; + unsigned int index = sym->st_shndx; switch (index) { diff --git a/bfd/elf.c b/bfd/elf.c index c697e9e..5ca43eb 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -457,8 +457,7 @@ bfd_elf_sym_name (bfd *abfd, if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION /* Check for a bogus st_shndx to avoid crashing. */ - && isym->st_shndx < elf_numsections (abfd) - && !(isym->st_shndx >= SHN_LORESERVE && isym->st_shndx <= SHN_HIRESERVE)) + && isym->st_shndx < elf_numsections (abfd)) { iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name; shindex = elf_elfheader (abfd)->e_shstrndx; @@ -495,6 +494,8 @@ group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr) /* First we need to ensure the symbol table is available. Make sure that it is a symbol table section. */ + if (ghdr->sh_link >= elf_numsections (abfd)) + return NULL; hdr = elf_elfsections (abfd) [ghdr->sh_link]; if (hdr->sh_type != SHT_SYMTAB || ! bfd_section_from_shdr (abfd, ghdr->sh_link)) @@ -713,8 +714,7 @@ _bfd_elf_setup_sections (bfd *abfd) get the situation where elfsec is 0. */ if (elfsec == 0) { - const struct elf_backend_data *bed - = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); if (bed->link_order_error_handler) bed->link_order_error_handler (_("%B: warning: sh_link not set for section `%A'"), @@ -722,14 +722,17 @@ _bfd_elf_setup_sections (bfd *abfd) } else { - asection *link; + asection *link = NULL; - this_hdr = elf_elfsections (abfd)[elfsec]; + if (elfsec < elf_numsections (abfd)) + { + this_hdr = elf_elfsections (abfd)[elfsec]; + link = this_hdr->bfd_section; + } /* PR 1991, 2008: Some strip/objcopy may leave an incorrect value in sh_link. We don't want to proceed. */ - link = this_hdr->bfd_section; if (link == NULL) { (*_bfd_error_handler) @@ -1518,17 +1521,22 @@ _bfd_elf_stringtab_init (void) bfd_boolean bfd_section_from_shdr (bfd *abfd, unsigned int shindex) { - Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex]; - Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd); - const struct elf_backend_data *bed = get_elf_backend_data (abfd); + Elf_Internal_Shdr *hdr; + Elf_Internal_Ehdr *ehdr; + const struct elf_backend_data *bed; const char *name; - name = bfd_elf_string_from_elf_section (abfd, - elf_elfheader (abfd)->e_shstrndx, + if (shindex >= elf_numsections (abfd)) + return FALSE; + + hdr = elf_elfsections (abfd)[shindex]; + ehdr = elf_elfheader (abfd); + name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx, hdr->sh_name); if (name == NULL) return FALSE; + bed = get_elf_backend_data (abfd); switch (hdr->sh_type) { case SHT_NULL: @@ -1729,8 +1737,7 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) return FALSE; /* Check for a bogus link to avoid crashing. */ - if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE) - || hdr->sh_link >= num_sec) + if (hdr->sh_link >= num_sec) { ((*_bfd_error_handler) (_("%B: invalid link %lu for reloc section %s (index %u)"), @@ -1784,7 +1791,6 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) section, an invalid section, or another reloc section. */ if (hdr->sh_link != elf_onesymtab (abfd) || hdr->sh_info == SHN_UNDEF - || (hdr->sh_info >= SHN_LORESERVE && hdr->sh_info <= SHN_HIRESERVE) || hdr->sh_info >= num_sec || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA) @@ -2771,11 +2777,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) abfd->section_count--; } else - { - if (section_number == SHN_LORESERVE) - section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; - d->this_idx = section_number++; - } + d->this_idx = section_number++; } } } @@ -2785,26 +2787,18 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) d = elf_section_data (sec); if (d->this_hdr.sh_type != SHT_GROUP) - { - if (section_number == SHN_LORESERVE) - section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; - d->this_idx = section_number++; - } + d->this_idx = section_number++; _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name); if ((sec->flags & SEC_RELOC) == 0) d->rel_idx = 0; else { - if (section_number == SHN_LORESERVE) - section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; d->rel_idx = section_number++; _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name); } if (d->rel_hdr2) { - if (section_number == SHN_LORESERVE) - section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; d->rel_idx2 = section_number++; _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name); } @@ -2812,22 +2806,16 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) d->rel_idx2 = 0; } - if (section_number == SHN_LORESERVE) - section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; t->shstrtab_section = section_number++; _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name); elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section; if (bfd_get_symcount (abfd) > 0) { - if (section_number == SHN_LORESERVE) - section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; t->symtab_section = section_number++; _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name); - if (section_number > SHN_LORESERVE - 2) + if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF)) { - if (section_number == SHN_LORESERVE) - section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; t->symtab_shndx_section = section_number++; t->symtab_shndx_hdr.sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), @@ -2835,8 +2823,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1) return FALSE; } - if (section_number == SHN_LORESERVE) - section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; t->strtab_section = section_number++; _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name); } @@ -2846,8 +2832,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) elf_numsections (abfd) = section_number; elf_elfheader (abfd)->e_shnum = section_number; - if (section_number > SHN_LORESERVE) - elf_elfheader (abfd)->e_shnum -= SHN_HIRESERVE + 1 - SHN_LORESERVE; /* Set up the list of section header pointers, in agreement with the indices. */ @@ -2868,7 +2852,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) if (bfd_get_symcount (abfd) > 0) { i_shdrp[t->symtab_section] = &t->symtab_hdr; - if (elf_numsections (abfd) > SHN_LORESERVE) + if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF)) { i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr; t->symtab_shndx_hdr.sh_link = t->symtab_section; @@ -4560,12 +4544,6 @@ assign_file_positions_for_non_load_sections (bfd *abfd, hdr->sh_offset = -1; else off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); - - if (i == SHN_LORESERVE - 1) - { - i += SHN_HIRESERVE + 1 - SHN_LORESERVE; - hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE; - } } /* Now that we have set the section file positions, we can set up @@ -4762,12 +4740,6 @@ assign_file_positions_except_relocs (bfd *abfd, } else off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); - - if (i == SHN_LORESERVE - 1) - { - i += SHN_HIRESERVE + 1 - SHN_LORESERVE; - hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE; - } } } else @@ -4813,12 +4785,10 @@ prep_headers (bfd *abfd) { Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */ - Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ struct elf_strtab_hash *shstrtab; const struct elf_backend_data *bed = get_elf_backend_data (abfd); i_ehdrp = elf_elfheader (abfd); - i_shdrp = elf_elfsections (abfd); shstrtab = _bfd_elf_strtab_init (); if (shstrtab == NULL) @@ -4963,8 +4933,6 @@ _bfd_elf_write_object_contents (bfd *abfd) || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt) return FALSE; } - if (count == SHN_LORESERVE - 1) - count += SHN_HIRESERVE + 1 - SHN_LORESERVE; } /* Write out the section header names. */ diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 1be3346..580d590 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -8043,7 +8043,9 @@ elf32_arm_gc_mark_extra_sections(struct bfd_link_info *info, Elf_Internal_Shdr *hdr; hdr = &elf_section_data (o)->this_hdr; - if (hdr->sh_type == SHT_ARM_EXIDX && hdr->sh_link + if (hdr->sh_type == SHT_ARM_EXIDX + && hdr->sh_link + && hdr->sh_link < elf_numsections (sub) && !o->gc_mark && elf_shdrp[hdr->sh_link]->bfd_section->gc_mark) { diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 5cebbaa..3cbfb75 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, 2007 + Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. Contributed by Denis Chertykov @@ -2757,15 +2757,20 @@ elf32_avr_size_stubs (bfd *output_bfd, /* It's a local symbol. */ Elf_Internal_Sym *sym; Elf_Internal_Shdr *hdr; + unsigned int shndx; sym = local_syms + r_indx; - hdr = elf_elfsections (input_bfd)[sym->st_shndx]; - sym_sec = hdr->bfd_section; if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) sym_value = sym->st_value; - destination = (sym_value + irela->r_addend - + sym_sec->output_offset - + sym_sec->output_section->vma); + shndx = sym->st_shndx; + if (shndx < elf_numsections (input_bfd)) + { + hdr = elf_elfsections (input_bfd)[shndx]; + sym_sec = hdr->bfd_section; + destination = (sym_value + irela->r_addend + + sym_sec->output_offset + + sym_sec->output_section->vma); + } } else { diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 20b16be..7707060 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -1,6 +1,7 @@ /* BFD back-end for HP PA-RISC ELF files. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. Original code by Center for Software Science @@ -2976,15 +2977,20 @@ elf32_hppa_size_stubs /* It's a local symbol. */ Elf_Internal_Sym *sym; Elf_Internal_Shdr *hdr; + unsigned int shndx; sym = local_syms + r_indx; - hdr = elf_elfsections (input_bfd)[sym->st_shndx]; - sym_sec = hdr->bfd_section; if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) sym_value = sym->st_value; - destination = (sym_value + irela->r_addend - + sym_sec->output_offset - + sym_sec->output_section->vma); + shndx = sym->st_shndx; + if (shndx < elf_numsections (input_bfd)) + { + hdr = elf_elfsections (input_bfd)[shndx]; + sym_sec = hdr->bfd_section; + destination = (sym_value + irela->r_addend + + sym_sec->output_offset + + sym_sec->output_section->vma); + } } else { diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c index 9ad82b6..2660c89 100644 --- a/bfd/elf32-m68hc1x.c +++ b/bfd/elf32-m68hc1x.c @@ -450,8 +450,13 @@ elf32_m68hc11_size_stubs (bfd *output_bfd, bfd *stub_bfd, if (!is_far) continue; - hdr = elf_elfsections (input_bfd)[sym->st_shndx]; - sym_sec = hdr->bfd_section; + if (sym->st_shndx >= elf_numsections (input_bfd)) + sym_sec = NULL; + else + { + hdr = elf_elfsections (input_bfd)[sym->st_shndx]; + sym_sec = hdr->bfd_section; + } stub_name = (bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name)); diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index b203205..982d45f 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -1,5 +1,5 @@ /* Support for HPPA 64-bit ELF - Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -625,7 +625,7 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) asection *dlt, *plt, *stubs; char *buf; size_t buf_len; - int sec_symndx; + unsigned int sec_symndx; if (info->relocatable) return TRUE; @@ -677,7 +677,8 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) isymend = local_syms + symtab_hdr->sh_info; for (isym = local_syms; isym < isymend; isym++) { - if (isym->st_shndx > highest_shndx) + if (isym->st_shndx > highest_shndx + && isym->st_shndx < SHN_LORESERVE) highest_shndx = isym->st_shndx; } @@ -723,10 +724,13 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) /* If we did not find a section symbol for this section, then something went terribly wrong above. */ - if (sec_symndx == -1) + if (sec_symndx == SHN_BAD) return FALSE; - sec_symndx = hppa_info->section_syms[sec_symndx]; + if (sec_symndx < SHN_LORESERVE) + sec_symndx = hppa_info->section_syms[sec_symndx]; + else + sec_symndx = 0; } else sec_symndx = 0; diff --git a/bfd/elfcode.h b/bfd/elfcode.h index bbbffe1..c356638 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -189,12 +189,14 @@ elf_swap_symbol_in (bfd *abfd, dst->st_info = H_GET_8 (abfd, src->st_info); dst->st_other = H_GET_8 (abfd, src->st_other); dst->st_shndx = H_GET_16 (abfd, src->st_shndx); - if (dst->st_shndx == SHN_XINDEX) + if (dst->st_shndx == (SHN_XINDEX & 0xffff)) { if (shndx == NULL) return FALSE; dst->st_shndx = H_GET_32 (abfd, shndx->est_shndx); } + else if (dst->st_shndx >= (SHN_LORESERVE & 0xffff)) + dst->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff); return TRUE; } @@ -215,12 +217,12 @@ elf_swap_symbol_out (bfd *abfd, H_PUT_8 (abfd, src->st_info, dst->st_info); H_PUT_8 (abfd, src->st_other, dst->st_other); tmp = src->st_shndx; - if (tmp > SHN_HIRESERVE) + if (tmp >= (SHN_LORESERVE & 0xffff) && tmp < SHN_LORESERVE) { if (shndx == NULL) abort (); H_PUT_32 (abfd, tmp, shndx); - tmp = SHN_XINDEX; + tmp = SHN_XINDEX & 0xffff; } H_PUT_16 (abfd, tmp, dst->st_shndx); } @@ -280,12 +282,12 @@ elf_swap_ehdr_out (bfd *abfd, H_PUT_16 (abfd, src->e_phnum, dst->e_phnum); H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize); tmp = src->e_shnum; - if (tmp >= SHN_LORESERVE) + if (tmp >= (SHN_LORESERVE & 0xffff)) tmp = SHN_UNDEF; H_PUT_16 (abfd, tmp, dst->e_shnum); tmp = src->e_shstrndx; - if (tmp >= SHN_LORESERVE) - tmp = SHN_XINDEX; + if (tmp >= (SHN_LORESERVE & 0xffff)) + tmp = SHN_XINDEX & 0xffff; H_PUT_16 (abfd, tmp, dst->e_shstrndx); } @@ -470,25 +472,6 @@ elf_file_p (Elf_External_Ehdr *x_ehdrp) && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3)); } -/* Determines if a given section index is valid. */ - -static inline bfd_boolean -valid_section_index_p (unsigned index, unsigned num_sections) -{ - /* Note: We allow SHN_UNDEF as a valid section index. */ - if (index < SHN_LORESERVE || index > SHN_HIRESERVE) - return index < num_sections; - - /* We disallow the use of reserved indcies, except for those - with OS or Application specific meaning. The test make use - of the knowledge that: - SHN_LORESERVE == SHN_LOPROC - and - SHN_HIPROC == SHN_LOOS - 1 */ - /* XXX - Should we allow SHN_XINDEX as a valid index here ? */ - return (index >= SHN_LOPROC && index <= SHN_HIOS); -} - /* Check to see if the file associated with ABFD matches the target vector that ABFD points to. @@ -707,7 +690,7 @@ elf_object_p (bfd *abfd) } /* And similarly for the string table index. */ - if (i_ehdrp->e_shstrndx == SHN_XINDEX) + if (i_ehdrp->e_shstrndx == (SHN_XINDEX & 0xffff)) { i_ehdrp->e_shstrndx = i_shdr.sh_link; if (i_ehdrp->e_shstrndx != i_shdr.sh_link) @@ -753,8 +736,6 @@ elf_object_p (bfd *abfd) if (!i_shdrp) goto got_no_match; num_sec = i_ehdrp->e_shnum; - if (num_sec > SHN_LORESERVE) - num_sec += SHN_HIRESERVE + 1 - SHN_LORESERVE; elf_numsections (abfd) = num_sec; amt = sizeof (i_shdrp) * num_sec; elf_elfsections (abfd) = bfd_alloc (abfd, amt); @@ -762,16 +743,7 @@ elf_object_p (bfd *abfd) goto got_no_match; memcpy (i_shdrp, &i_shdr, sizeof (*i_shdrp)); - shdrp = i_shdrp; - shindex = 0; - if (num_sec > SHN_LORESERVE) - { - for ( ; shindex < SHN_LORESERVE; shindex++) - elf_elfsections (abfd)[shindex] = shdrp++; - for ( ; shindex < SHN_HIRESERVE + 1; shindex++) - elf_elfsections (abfd)[shindex] = i_shdrp; - } - for ( ; shindex < num_sec; shindex++) + for (shdrp = i_shdrp, shindex = 0; shindex < num_sec; shindex++) elf_elfsections (abfd)[shindex] = shdrp++; /* Read in the rest of the section header table and convert it @@ -783,13 +755,13 @@ elf_object_p (bfd *abfd) elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); /* Sanity check sh_link and sh_info. */ - if (! valid_section_index_p (i_shdrp[shindex].sh_link, num_sec)) + if (i_shdrp[shindex].sh_link >= num_sec) goto got_wrong_format_error; if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK) || i_shdrp[shindex].sh_type == SHT_RELA || i_shdrp[shindex].sh_type == SHT_REL) - && ! valid_section_index_p (i_shdrp[shindex].sh_info, num_sec)) + && i_shdrp[shindex].sh_info >= num_sec) goto got_wrong_format_error; /* If the section is loaded, but not page aligned, clear @@ -807,7 +779,7 @@ elf_object_p (bfd *abfd) /* A further sanity check. */ if (i_ehdrp->e_shnum != 0) { - if (! valid_section_index_p (i_ehdrp->e_shstrndx, elf_numsections (abfd))) + if (i_ehdrp->e_shstrndx >= elf_numsections (abfd)) { /* PR 2257: We used to just goto got_wrong_format_error here @@ -856,12 +828,8 @@ elf_object_p (bfd *abfd) a dummy placeholder entry, so we ignore it. */ num_sec = elf_numsections (abfd); for (shindex = 1; shindex < num_sec; shindex++) - { - if (! bfd_section_from_shdr (abfd, shindex)) - goto got_no_match; - if (shindex == SHN_LORESERVE - 1) - shindex += SHN_HIRESERVE + 1 - SHN_LORESERVE; - } + if (!bfd_section_from_shdr (abfd, shindex)) + goto got_no_match; /* Set up ELF sections for SHF_GROUP and SHF_LINK_ORDER. */ if (! _bfd_elf_setup_sections (abfd)) @@ -1081,9 +1049,9 @@ elf_write_shdrs_and_ehdr (bfd *abfd) /* Some fields in the first section header handle overflow of ehdr fields. */ - if (i_ehdrp->e_shnum >= SHN_LORESERVE) + if (i_ehdrp->e_shnum >= (SHN_LORESERVE & 0xffff)) i_shdrp[0]->sh_size = i_ehdrp->e_shnum; - if (i_ehdrp->e_shstrndx >= SHN_LORESERVE) + if (i_ehdrp->e_shstrndx >= (SHN_LORESERVE & 0xffff)) i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx; /* at this point we've concocted all the ELF sections... */ @@ -1099,9 +1067,6 @@ elf_write_shdrs_and_ehdr (bfd *abfd) elf_debug_section (count, *i_shdrp); #endif elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count); - - if (count == SHN_LORESERVE - 1) - i_shdrp += SHN_HIRESERVE + 1 - SHN_LORESERVE; } if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0 || bfd_bwrite (x_shdrp, amt, abfd) != amt) diff --git a/bfd/elflink.c b/bfd/elflink.c index ed99a5d..0e42da7 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -618,8 +618,7 @@ bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, } if (entry->isym.st_shndx != SHN_UNDEF - && (entry->isym.st_shndx < SHN_LORESERVE - || entry->isym.st_shndx > SHN_HIRESERVE)) + && entry->isym.st_shndx < SHN_LORESERVE) { asection *s; @@ -8201,13 +8200,14 @@ elf_link_output_sym (struct elf_final_link_info *finfo, static bfd_boolean check_dynsym (bfd *abfd, Elf_Internal_Sym *sym) { - if (sym->st_shndx > SHN_HIRESERVE) + if (sym->st_shndx >= (SHN_LORESERVE & 0xffff) + && sym->st_shndx < SHN_LORESERVE) { /* The gABI doesn't support dynamic symbols in output sections beyond 64k. */ (*_bfd_error_handler) (_("%B: Too many sections: %d (>= %d)"), - abfd, bfd_count_sections (abfd), SHN_LORESERVE); + abfd, bfd_count_sections (abfd), SHN_LORESERVE & 0xffff); bfd_set_error (bfd_error_nonrepresentable_section); return FALSE; } @@ -8951,10 +8951,9 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) /* If this symbol is defined in a section which we are discarding, we don't need to keep it. */ if (isym->st_shndx != SHN_UNDEF - && (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) - && (isec == NULL - || bfd_section_removed_from_list (output_bfd, - isec->output_section))) + && isym->st_shndx < SHN_LORESERVE + && bfd_section_removed_from_list (output_bfd, + isec->output_section)) continue; /* Get the name of the symbol. */ @@ -9778,7 +9777,8 @@ elf_fixup_link_order (bfd *abfd, asection *o) && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass && (elfsec = _bfd_elf_section_from_bfd_section (sub, s)) && elfsec < elf_numsections (sub) - && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER) + && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER + && elf_elfsections (sub)[elfsec]->sh_link < elf_numsections (sub)) { seen_linkorder++; linkorder_sec = s; @@ -10186,7 +10186,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) finfo.symbuf = bfd_malloc (amt); if (finfo.symbuf == NULL) goto error_return; - if (elf_numsections (abfd) > SHN_LORESERVE) + if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF)) { /* Wild guess at number of output symbols. realloc'd as needed. */ amt = 2 * max_sym_count + elf_numsections (abfd) + 1000; @@ -10236,8 +10236,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (!elf_link_output_sym (&finfo, NULL, &elfsym, o, NULL)) goto error_return; } - if (i == SHN_LORESERVE - 1) - i += SHN_HIRESERVE + 1 - SHN_LORESERVE; } } diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 946a010..6649536 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,19 @@ +2008-03-12 Alan Modra + + PR 5900 + * readelf.c (SECTION_HEADER_INDEX, SECTION_HEADER_NUM): Delete. + Remove use throughout file. + (SECTION_HEADER): Likewise. + (dump_relocations): Don't adjust st_shndx for reserved range. + (process_file_header): Mask SHN_XINDEX to values seen in external + elf structs. Simplify valid section index tests. + (get_32bit_elf_symbols, get_64bit_elf_symbols): Mask SHN_XINDEX. + Map reserved st_shndx to internal form. + (process_section_groups): Test that group symbol st_shndx is in + range, not just non-zero. Delete reserved range check. + (get_symbol_index_type): Mask "type" to 16 bits when printing PRC, + OS or RSV. + 2008-03-09 Paul Brook * readelf.c (arm_attr_tag_VFP_arch): Add "VFPv3-D16". diff --git a/binutils/readelf.c b/binutils/readelf.c index 61c085f..ae13b3e 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -276,22 +276,6 @@ static void (*byte_put) (unsigned char *, bfd_vma, int); : ((X)->sh_name >= string_table_length ? "" \ : string_table + (X)->sh_name)) -/* Given st_shndx I, map to section_headers index. */ -#define SECTION_HEADER_INDEX(I) \ - ((I) < SHN_LORESERVE \ - ? (I) \ - : ((I) <= SHN_HIRESERVE \ - ? 0 \ - : (I) - (SHN_HIRESERVE + 1 - SHN_LORESERVE))) - -/* Reverse of the above. */ -#define SECTION_HEADER_NUM(N) \ - ((N) < SHN_LORESERVE \ - ? (N) \ - : (N) + (SHN_HIRESERVE + 1 - SHN_LORESERVE)) - -#define SECTION_HEADER(I) (section_headers + SECTION_HEADER_INDEX (I)) - #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ #define BYTE_GET(field) byte_get (field, sizeof (field)) @@ -1302,16 +1286,9 @@ dump_relocations (FILE *file, if (ELF_ST_TYPE (psym->st_info) == STT_SECTION) { - bfd_vma sec_index = (bfd_vma) -1; - - if (psym->st_shndx < SHN_LORESERVE) - sec_index = psym->st_shndx; - else if (psym->st_shndx > SHN_HIRESERVE) - sec_index = psym->st_shndx - (SHN_HIRESERVE + 1 - - SHN_LORESERVE); - - if (sec_index != (bfd_vma) -1) - sec_name = SECTION_NAME (section_headers + sec_index); + if (psym->st_shndx < elf_header.e_shnum) + sec_name + = SECTION_NAME (section_headers + psym->st_shndx); else if (psym->st_shndx == SHN_ABS) sec_name = "ABS"; else if (psym->st_shndx == SHN_COMMON) @@ -3356,31 +3333,26 @@ process_file_header (void) (long) elf_header.e_shentsize); printf (_(" Number of section headers: %ld"), (long) elf_header.e_shnum); - if (section_headers != NULL && elf_header.e_shnum == 0) + if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF) printf (" (%ld)", (long) section_headers[0].sh_size); putc ('\n', stdout); printf (_(" Section header string table index: %ld"), (long) elf_header.e_shstrndx); - if (section_headers != NULL && elf_header.e_shstrndx == SHN_XINDEX) + if (section_headers != NULL + && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff)) printf (" (%ld)", (long) section_headers[0].sh_link); - else if (elf_header.e_shstrndx != SHN_UNDEF - && (elf_header.e_shstrndx >= elf_header.e_shnum - || (elf_header.e_shstrndx >= SHN_LORESERVE - && elf_header.e_shstrndx <= SHN_HIRESERVE))) + else if (elf_header.e_shstrndx >= elf_header.e_shnum) printf (" "); putc ('\n', stdout); } if (section_headers != NULL) { - if (elf_header.e_shnum == 0) + if (elf_header.e_shnum == SHN_UNDEF) elf_header.e_shnum = section_headers[0].sh_size; - if (elf_header.e_shstrndx == SHN_XINDEX) + if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff)) elf_header.e_shstrndx = section_headers[0].sh_link; - else if (elf_header.e_shstrndx != SHN_UNDEF - && (elf_header.e_shstrndx >= elf_header.e_shnum - || (elf_header.e_shstrndx >= SHN_LORESERVE - && elf_header.e_shstrndx <= SHN_HIRESERVE))) + else if (elf_header.e_shstrndx >= elf_header.e_shnum) elf_header.e_shstrndx = SHN_UNDEF; free (section_headers); section_headers = NULL; @@ -3853,7 +3825,7 @@ get_32bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section) shndx = NULL; if (symtab_shndx_hdr != NULL && (symtab_shndx_hdr->sh_link - == (unsigned long) SECTION_HEADER_NUM (section - section_headers))) + == (unsigned long) (section - section_headers))) { shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset, 1, symtab_shndx_hdr->sh_size, _("symtab shndx")); @@ -3884,9 +3856,11 @@ get_32bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section) psym->st_value = BYTE_GET (esyms[j].st_value); psym->st_size = BYTE_GET (esyms[j].st_size); psym->st_shndx = BYTE_GET (esyms[j].st_shndx); - if (psym->st_shndx == SHN_XINDEX && shndx != NULL) + if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL) psym->st_shndx = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j])); + else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff)) + psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff); psym->st_info = BYTE_GET (esyms[j].st_info); psym->st_other = BYTE_GET (esyms[j].st_other); } @@ -3916,7 +3890,7 @@ get_64bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section) shndx = NULL; if (symtab_shndx_hdr != NULL && (symtab_shndx_hdr->sh_link - == (unsigned long) SECTION_HEADER_NUM (section - section_headers))) + == (unsigned long) (section - section_headers))) { shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset, 1, symtab_shndx_hdr->sh_size, _("symtab shndx")); @@ -3947,9 +3921,11 @@ get_64bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section) psym->st_info = BYTE_GET (esyms[j].st_info); psym->st_other = BYTE_GET (esyms[j].st_other); psym->st_shndx = BYTE_GET (esyms[j].st_shndx); - if (psym->st_shndx == SHN_XINDEX && shndx != NULL) + if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL) psym->st_shndx = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j])); + else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff)) + psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff); psym->st_value = BYTE_GET (esyms[j].st_value); psym->st_size = BYTE_GET (esyms[j].st_size); } @@ -4195,9 +4171,9 @@ process_section_headers (FILE *file) /* Read in the string table, so that we have names to display. */ if (elf_header.e_shstrndx != SHN_UNDEF - && SECTION_HEADER_INDEX (elf_header.e_shstrndx) < elf_header.e_shnum) + && elf_header.e_shstrndx < elf_header.e_shnum) { - section = SECTION_HEADER (elf_header.e_shstrndx); + section = section_headers + elf_header.e_shstrndx; if (section->sh_size != 0) { @@ -4411,7 +4387,7 @@ process_section_headers (FILE *file) if (do_section_details) { printf (" [%2u] %s\n", - SECTION_HEADER_NUM (i), + i, SECTION_NAME (section)); if (is_32bit_elf || do_wide) printf (" %-15.15s ", @@ -4419,7 +4395,7 @@ process_section_headers (FILE *file) } else printf (" [%2u] %-17.17s %-15.15s ", - SECTION_HEADER_NUM (i), + i, SECTION_NAME (section), get_section_type_name (section->sh_type)); @@ -4642,8 +4618,8 @@ process_section_groups (FILE *file) Elf_Internal_Sym *sym; /* Get the symbol table. */ - if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum - || ((sec = SECTION_HEADER (section->sh_link))->sh_type + if (section->sh_link >= elf_header.e_shnum + || ((sec = section_headers + section->sh_link)->sh_type != SHT_SYMTAB)) { error (_("Bad sh_link in group section `%s'\n"), name); @@ -4662,14 +4638,14 @@ process_section_groups (FILE *file) if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) { - bfd_vma sec_index = SECTION_HEADER_INDEX (sym->st_shndx); - if (sec_index == 0) + if (sym->st_shndx == 0 + || sym->st_shndx >= elf_header.e_shnum) { error (_("Bad sh_info in group section `%s'\n"), name); continue; } - group_name = SECTION_NAME (section_headers + sec_index); + group_name = SECTION_NAME (section_headers + sym->st_shndx); strtab_sec = NULL; if (strtab) free (strtab); @@ -4679,8 +4655,7 @@ process_section_groups (FILE *file) else { /* Get the string table. */ - if (SECTION_HEADER_INDEX (symtab_sec->sh_link) - >= elf_header.e_shnum) + if (symtab_sec->sh_link >= elf_header.e_shnum) { strtab_sec = NULL; if (strtab) @@ -4689,7 +4664,7 @@ process_section_groups (FILE *file) strtab_size = 0; } else if (strtab_sec - != (sec = SECTION_HEADER (symtab_sec->sh_link))) + != (sec = section_headers + symtab_sec->sh_link)) { strtab_sec = sec; if (strtab) @@ -4728,27 +4703,20 @@ process_section_groups (FILE *file) entry = byte_get (indices, 4); indices += 4; - if (SECTION_HEADER_INDEX (entry) >= elf_header.e_shnum) + if (entry >= elf_header.e_shnum) { error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"), entry, i, elf_header.e_shnum - 1); continue; } - else if (entry >= SHN_LORESERVE && entry <= SHN_HIRESERVE) - { - error (_("invalid section [%5u] in group section [%5u]\n"), - entry, i); - continue; - } - if (section_headers_groups [SECTION_HEADER_INDEX (entry)] - != NULL) + if (section_headers_groups [entry] != NULL) { if (entry) { error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"), entry, i, - section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index); + section_headers_groups [entry]->group_index); continue; } else @@ -4760,18 +4728,17 @@ process_section_groups (FILE *file) if (!warned) { error (_("section 0 in group section [%5u]\n"), - section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index); + section_headers_groups [entry]->group_index); warned++; } } } - section_headers_groups [SECTION_HEADER_INDEX (entry)] - = group; + section_headers_groups [entry] = group; if (do_section_groups) { - sec = SECTION_HEADER (entry); + sec = section_headers + entry; printf (" [%5u] %s\n", entry, SECTION_NAME (sec)); } @@ -4903,9 +4870,8 @@ process_relocs (FILE *file) is_rela = section->sh_type == SHT_RELA; - if (section->sh_link - && SECTION_HEADER_INDEX (section->sh_link) - < elf_header.e_shnum) + if (section->sh_link != 0 + && section->sh_link < elf_header.e_shnum) { Elf_Internal_Shdr *symsec; Elf_Internal_Sym *symtab; @@ -4913,7 +4879,7 @@ process_relocs (FILE *file) unsigned long strtablen = 0; char *strtab = NULL; - symsec = SECTION_HEADER (section->sh_link); + symsec = section_headers + section->sh_link; if (symsec->sh_type != SHT_SYMTAB && symsec->sh_type != SHT_DYNSYM) continue; @@ -4924,10 +4890,10 @@ process_relocs (FILE *file) if (symtab == NULL) continue; - if (SECTION_HEADER_INDEX (symsec->sh_link) - < elf_header.e_shnum) + if (symsec->sh_link != 0 + && symsec->sh_link < elf_header.e_shnum) { - strsec = SECTION_HEADER (symsec->sh_link); + strsec = section_headers + symsec->sh_link; strtab = get_data (NULL, file, strsec->sh_offset, 1, strsec->sh_size, @@ -5164,8 +5130,8 @@ slurp_ia64_unwind_table (FILE *file, ++relsec) { if (relsec->sh_type != SHT_RELA - || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum - || SECTION_HEADER (relsec->sh_info) != sec) + || relsec->sh_info >= elf_header.e_shnum + || section_headers + relsec->sh_info != sec) continue; if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size, @@ -5223,12 +5189,12 @@ ia64_process_unwind (FILE *file) for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) { if (sec->sh_type == SHT_SYMTAB - && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum) + && sec->sh_link < elf_header.e_shnum) { aux.nsyms = sec->sh_size / sec->sh_entsize; aux.symtab = GET_ELF_SYMBOLS (file, sec); - strsec = SECTION_HEADER (sec->sh_link); + strsec = section_headers + sec->sh_link; aux.strtab = get_data (NULL, file, strsec->sh_offset, 1, strsec->sh_size, _("string table")); aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0; @@ -5263,7 +5229,7 @@ ia64_process_unwind (FILE *file) for (; g != NULL; g = g->next) { - sec = SECTION_HEADER (g->section_index); + sec = section_headers + g->section_index; if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)) break; @@ -5567,8 +5533,8 @@ slurp_hppa_unwind_table (FILE *file, ++relsec) { if (relsec->sh_type != SHT_RELA - || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum - || SECTION_HEADER (relsec->sh_info) != sec) + || relsec->sh_info >= elf_header.e_shnum + || section_headers + relsec->sh_info != sec) continue; if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size, @@ -5629,12 +5595,12 @@ hppa_process_unwind (FILE *file) for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) { if (sec->sh_type == SHT_SYMTAB - && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum) + && sec->sh_link < elf_header.e_shnum) { aux.nsyms = sec->sh_size / sec->sh_entsize; aux.symtab = GET_ELF_SYMBOLS (file, sec); - strsec = SECTION_HEADER (sec->sh_link); + strsec = section_headers + sec->sh_link; aux.strtab = get_data (NULL, file, strsec->sh_offset, 1, strsec->sh_size, _("string table")); aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0; @@ -6600,9 +6566,8 @@ process_version_sections (FILE *file) printf_vma (section->sh_addr); printf (_(" Offset: %#08lx Link: %lx (%s)\n"), (unsigned long) section->sh_offset, section->sh_link, - SECTION_HEADER_INDEX (section->sh_link) - < elf_header.e_shnum - ? SECTION_NAME (SECTION_HEADER (section->sh_link)) + section->sh_link < elf_header.e_shnum + ? SECTION_NAME (section_headers + section->sh_link) : ""); edefs = get_data (NULL, file, section->sh_offset, 1, @@ -6703,9 +6668,8 @@ process_version_sections (FILE *file) printf_vma (section->sh_addr); printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"), (unsigned long) section->sh_offset, section->sh_link, - SECTION_HEADER_INDEX (section->sh_link) - < elf_header.e_shnum - ? SECTION_NAME (SECTION_HEADER (section->sh_link)) + section->sh_link < elf_header.e_shnum + ? SECTION_NAME (section_headers + section->sh_link) : ""); eneed = get_data (NULL, file, section->sh_offset, 1, @@ -6798,21 +6762,20 @@ process_version_sections (FILE *file) Elf_Internal_Shdr *string_sec; long off; - if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum) + if (section->sh_link >= elf_header.e_shnum) break; - link_section = SECTION_HEADER (section->sh_link); + link_section = section_headers + section->sh_link; total = section->sh_size / sizeof (Elf_External_Versym); - if (SECTION_HEADER_INDEX (link_section->sh_link) - >= elf_header.e_shnum) + if (link_section->sh_link >= elf_header.e_shnum) break; found = 1; symbols = GET_ELF_SYMBOLS (file, link_section); - string_sec = SECTION_HEADER (link_section->sh_link); + string_sec = section_headers + link_section->sh_link; strtab = get_data (NULL, file, string_sec->sh_offset, 1, string_sec->sh_size, _("version string table")); @@ -6872,9 +6835,8 @@ process_version_sections (FILE *file) check_def = 1; check_need = 1; - if (SECTION_HEADER_INDEX (symbols[cnt + j].st_shndx) - >= elf_header.e_shnum - || SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type + if (symbols[cnt + j].st_shndx >= elf_header.e_shnum + || section_headers[symbols[cnt + j].st_shndx].sh_type != SHT_NOBITS) { if (symbols[cnt + j].st_shndx == SHN_UNDEF) @@ -7158,11 +7120,11 @@ get_symbol_index_type (unsigned int type) && elf_header.e_machine == EM_MIPS) return "SUND"; else if (type >= SHN_LOPROC && type <= SHN_HIPROC) - sprintf (buff, "PRC[0x%04x]", type); + sprintf (buff, "PRC[0x%04x]", type & 0xffff); else if (type >= SHN_LOOS && type <= SHN_HIOS) - sprintf (buff, "OS [0x%04x]", type); - else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE) - sprintf (buff, "RSV[0x%04x]", type); + sprintf (buff, "OS [0x%04x]", type & 0xffff); + else if (type >= SHN_LORESERVE) + sprintf (buff, "RSV[0x%04x]", type & 0xffff); else sprintf (buff, "%3d", type); break; @@ -7492,11 +7454,11 @@ process_symbol_table (FILE *file) strtab = string_table; strtab_size = string_table_length; } - else if (SECTION_HEADER_INDEX (section->sh_link) < elf_header.e_shnum) + else if (section->sh_link < elf_header.e_shnum) { Elf_Internal_Shdr *string_sec; - string_sec = SECTION_HEADER (section->sh_link); + string_sec = section_headers + section->sh_link; strtab = get_data (NULL, file, string_sec->sh_offset, 1, string_sec->sh_size, _("string table")); @@ -7541,9 +7503,8 @@ process_symbol_table (FILE *file) vers_data = byte_get (data, 2); - is_nobits = (SECTION_HEADER_INDEX (psym->st_shndx) - < elf_header.e_shnum - && SECTION_HEADER (psym->st_shndx)->sh_type + is_nobits = (psym->st_shndx < elf_header.e_shnum + && section_headers[psym->st_shndx].sh_type == SHT_NOBITS); check_def = (psym->st_shndx != SHN_UNDEF); @@ -7922,10 +7883,10 @@ dump_section_as_strings (Elf_Internal_Shdr *section, FILE *file) ++relsec) { if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL) - || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum - || SECTION_HEADER (relsec->sh_info) != section + || relsec->sh_info >= elf_header.e_shnum + || section_headers + relsec->sh_info != section || relsec->sh_size == 0 - || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum) + || relsec->sh_link >= elf_header.e_shnum) continue; printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n")); @@ -8001,10 +7962,10 @@ dump_section_as_bytes (Elf_Internal_Shdr *section, FILE *file) ++relsec) { if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL) - || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum - || SECTION_HEADER (relsec->sh_info) != section + || relsec->sh_info >= elf_header.e_shnum + || section_headers + relsec->sh_info != section || relsec->sh_size == 0 - || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum) + || relsec->sh_link >= elf_header.e_shnum) continue; printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n")); @@ -8333,10 +8294,10 @@ debug_apply_relocations (void *file, Elf_Internal_Sym *sym; if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL) - || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum - || SECTION_HEADER (relsec->sh_info) != section + || relsec->sh_info >= elf_header.e_shnum + || section_headers + relsec->sh_info != section || relsec->sh_size == 0 - || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum) + || relsec->sh_link >= elf_header.e_shnum) continue; is_rela = relsec->sh_type == SHT_RELA; @@ -8358,7 +8319,7 @@ debug_apply_relocations (void *file, if (elf_header.e_machine == EM_SH) is_rela = FALSE; - symsec = SECTION_HEADER (relsec->sh_link); + symsec = section_headers + relsec->sh_link; symtab = GET_ELF_SYMBOLS (file, symsec); for (rp = relocs; rp < relocs + num_relocs; ++rp) @@ -9579,7 +9540,7 @@ process_gnu_liblist (FILE *file) switch (section->sh_type) { case SHT_GNU_LIBLIST: - if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum) + if (section->sh_link >= elf_header.e_shnum) break; elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size, @@ -9587,7 +9548,7 @@ process_gnu_liblist (FILE *file) if (elib == NULL) break; - string_sec = SECTION_HEADER (section->sh_link); + string_sec = section_headers + section->sh_link; strtab = get_data (NULL, file, string_sec->sh_offset, 1, string_sec->sh_size, _("liblist string table")); diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 83ab46b..5e3bce1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2008-03-12 Alan Modra + + PR 5900 + * elfread.c (elf_symtab_read): Make shndx an unsigned int. + * mipsread.c: Include elf/internal.h. + (read_alphacoff_dynamic_symtab): Map external reserved sym_shndx + to internal range. + 2008-03-11 Markus Deuling * win32-nat.c (do_win32_fetch_inferior_registers): Use get_regcache_arch diff --git a/gdb/elfread.c b/gdb/elfread.c index c0dd7fb..5a201c9 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -333,7 +333,7 @@ elf_symtab_read (struct objfile *objfile, int type, NOTE: uweigand-20071112: Synthetic symbols do not have an ELF-private part, so do not touch those. */ - unsigned short shndx = type == ST_SYNTHETIC ? 0 : + unsigned int shndx = type == ST_SYNTHETIC ? 0 : ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx; switch (shndx) diff --git a/gdb/mipsread.c b/gdb/mipsread.c index 4f24462..fdd8634 100644 --- a/gdb/mipsread.c +++ b/gdb/mipsread.c @@ -39,6 +39,7 @@ #include "libcoff.h" /* Private BFD COFF information. */ #include "libecoff.h" /* Private BFD ECOFF information. */ #include "elf/common.h" +#include "elf/internal.h" #include "elf/mips.h" static void @@ -293,6 +294,8 @@ read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets, sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value); sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info); sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx); + if (sym_shndx >= (SHN_LORESERVE & 0xffff)) + sym_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff); isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL); if (sym_shndx == SHN_UNDEF) diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 84888f6..621f48e 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,20 +1,30 @@ 2008-03-12 Alan Modra - * elf/cr16c.h (SHN_CR16C_FCOMMON): Define using SHN_LORESERVE. + PR 5900 + * common.h (SHN_BAD): Delete. + (SHN_LORESERVE .. SHN_HIRESERVE): Move to.. + * external.h: ..here. + * internal.h (SHN_LORESERVE, SHN_HIRESERVE): Define. + (SHN_LOPROC, SHN_HIPROC, SHN_LOOS, SHN_HIOS): Define. + (SHN_ABS, SHN_COMMON, SHN_XINDEX, SHN_BAD): Define. + +2008-03-12 Alan Modra + + * cr16c.h (SHN_CR16C_FCOMMON): Define using SHN_LORESERVE. (SHN_CR16C_NCOMMON): Likewise. - * elf/hppa.h (SHN_PARISC_ANSI_COMMON): Likewise. + * hppa.h (SHN_PARISC_ANSI_COMMON): Likewise. (SHN_PARISC_HUGE_COMMON): Likewise. - * elf/ia64.h (SHN_IA_64_ANSI_COMMON): Likewise. + * ia64.h (SHN_IA_64_ANSI_COMMON): Likewise. (SHN_IA_64_VMS_SYMVEC): Define using SHN_LOOS. - * elf/m32r.h (SHN_M32R_SCOMMON): Define using SHN_LORESERVE. - * elf/mips.h (SHN_MIPS_ACOMMON, SHN_MIPS_TEXT): Likewise. + * m32r.h (SHN_M32R_SCOMMON): Define using SHN_LORESERVE. + * mips.h (SHN_MIPS_ACOMMON, SHN_MIPS_TEXT): Likewise. (SHN_MIPS_DATA, SHN_MIPS_SCOMMON, SHN_MIPS_SUNDEFINED): Likewise. - * elf/score.h (SHN_SCORE_TEXT, SHN_SCORE_DATA): Likewise. + * score.h (SHN_SCORE_TEXT, SHN_SCORE_DATA): Likewise. (SHN_SCORE_SCOMMON): Likewise. - * elf/sparc.h (SHN_BEFORE, SHN_AFTER): Likewise. - * elf/v850.h (SHN_V850_SCOMMON, SHN_V850_TCOMMON): Likewise. + * sparc.h (SHN_BEFORE, SHN_AFTER): Likewise. + * v850.h (SHN_V850_SCOMMON, SHN_V850_TCOMMON): Likewise. (SHN_V850_ZCOMMON): Likewise. - * elf/x86-64.h (SHN_X86_64_LCOMMON): Likewise. + * x86-64.h (SHN_X86_64_LCOMMON): Likewise. 2008-03-03 Pallavi Tambay diff --git a/include/elf/common.h b/include/elf/common.h index b6d981f..314de4e 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -1,6 +1,6 @@ /* ELF support for BFD. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Fred Fish @ Cygnus Support, from information published @@ -496,21 +496,6 @@ #define STT_LOPROC 13 /* Application-specific semantics */ #define STT_HIPROC 15 /* Application-specific semantics */ -/* Special section indices, which may show up in st_shndx fields, among - other places. */ - -#define SHN_UNDEF 0 /* Undefined section reference */ -#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */ -#define SHN_LOPROC 0xFF00 /* Begin range of appl-specific */ -#define SHN_HIPROC 0xFF1F /* End range of appl-specific */ -#define SHN_LOOS 0xFF20 /* OS specific semantics, lo */ -#define SHN_HIOS 0xFF3F /* OS specific semantics, hi */ -#define SHN_ABS 0xFFF1 /* Associated symbol is absolute */ -#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ -#define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */ -#define SHN_HIRESERVE 0xFFFF /* End range of reserved indices */ -#define SHN_BAD ((unsigned) -1) /* Used internally by bfd */ - /* The following constants control how a symbol may be accessed once it has become part of an executable or shared library. */ diff --git a/include/elf/external.h b/include/elf/external.h index 21450f0..3d4ba79 100644 --- a/include/elf/external.h +++ b/include/elf/external.h @@ -1,6 +1,6 @@ /* ELF support for BFD. - Copyright 1991, 1992, 1993, 1995, 1997, 1998, 1999, 2001, 2003, 2005 - Free Software Foundation, Inc. + Copyright 1991, 1992, 1993, 1995, 1997, 1998, 1999, 2001, 2003, 2005, + 2008 Free Software Foundation, Inc. Written by Fred Fish @ Cygnus Support, from information published in "UNIX System V Release 4, Programmers Guide: ANSI C and @@ -35,6 +35,19 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #ifndef _ELF_EXTERNAL_H #define _ELF_EXTERNAL_H +/* Special section indices, which may show up in st_shndx fields, among + other places. */ + +#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */ +#define SHN_LOPROC 0xFF00 /* Begin range of appl-specific */ +#define SHN_HIPROC 0xFF1F /* End range of appl-specific */ +#define SHN_LOOS 0xFF20 /* OS specific semantics, lo */ +#define SHN_HIOS 0xFF3F /* OS specific semantics, hi */ +#define SHN_ABS 0xFFF1 /* Associated symbol is absolute */ +#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ +#define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */ +#define SHN_HIRESERVE 0xFFFF /* End range of reserved indices */ + /* ELF Header (32-bit implementations) */ typedef struct { diff --git a/include/elf/internal.h b/include/elf/internal.h index 93c2315..cacfc63 100644 --- a/include/elf/internal.h +++ b/include/elf/internal.h @@ -1,6 +1,6 @@ /* ELF support for BFD. Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, - 2003, 2006, 2007 Free Software Foundation, Inc. + 2003, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Fred Fish @ Cygnus Support, from information published in "UNIX System V Release 4, Programmers Guide: ANSI C and @@ -37,6 +37,31 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #ifndef _ELF_INTERNAL_H #define _ELF_INTERNAL_H +/* Special section indices, which may show up in st_shndx fields, among + other places. */ + +#undef SHN_UNDEF +#undef SHN_LORESERVE +#undef SHN_LOPROC +#undef SHN_HIPROC +#undef SHN_LOOS +#undef SHN_HIOS +#undef SHN_ABS +#undef SHN_COMMON +#undef SHN_XINDEX +#undef SHN_HIRESERVE +#define SHN_UNDEF 0 /* Undefined section reference */ +#define SHN_LORESERVE (-0x100u) /* Begin range of reserved indices */ +#define SHN_LOPROC (-0x100u) /* Begin range of appl-specific */ +#define SHN_HIPROC (-0xE1u) /* End range of appl-specific */ +#define SHN_LOOS (-0xE0u) /* OS specific semantics, lo */ +#define SHN_HIOS (-0xC1u) /* OS specific semantics, hi */ +#define SHN_ABS (-0xFu) /* Associated symbol is absolute */ +#define SHN_COMMON (-0xEu) /* Associated symbol is in common */ +#define SHN_XINDEX (-0x1u) /* Section index is held elsewhere */ +#define SHN_HIRESERVE (-0x1u) /* End range of reserved indices */ +#define SHN_BAD (-0x101u) /* Used internally by bfd */ + /* ELF Header */ #define EI_NIDENT 16 /* Size of e_ident[] */ diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 329d6fb..dcd73b4 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-03-12 Alan Modra + + PR 5900 + * ld-elf/sec64k.exp: Update. + 2008-03-08 Paul Brook * ld-arm/arm-elf.exp (armeabitests): Add thumb2-b-interwork. diff --git a/ld/testsuite/ld-elf/sec64k.exp b/ld/testsuite/ld-elf/sec64k.exp index 8b7cade..349477f 100644 --- a/ld/testsuite/ld-elf/sec64k.exp +++ b/ld/testsuite/ld-elf/sec64k.exp @@ -1,5 +1,5 @@ # Expect script for tests for >64k sections -# Copyright 2002, 2003, 2006, 2007 Free Software Foundation, Inc. +# Copyright 2002, 2003, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is part of the GNU Binutils. # @@ -106,12 +106,12 @@ if {![istarget "m32r-*-*"]} then { puts $ofd "#readelf: -W -Ss" puts $ofd "There are 680.. section headers.*:" puts $ofd "#..." - puts $ofd " \\\[ 0\\\] .* 682\[0-9\]\[0-9\]\[ \]+0\[ \]+0" + puts $ofd " \\\[ 0\\\] .* 680\[0-9\]\[0-9\]\[ \]+0\[ \]+0" puts $ofd "#..." puts $ofd " \\\[ \[0-9\]\\\] \.foo\.1\[ \]+PROGBITS\[ \]+.*" puts $ofd "#..." puts $ofd " \\\[65279\\\] (.rel\[a\]?)?\\.foo\\.\[0-9\]+ .*" - puts $ofd " \\\[65536\\\] (.rel\[a\]?)?\\.foo\\.\[0-9\]+ .*" + puts $ofd " \\\[65280\\\] (.rel\[a\]?)?\\.foo\\.\[0-9\]+ .*" puts $ofd "#..." puts $ofd " 340..: 0+\[ \]+0\[ \]+SECTION\[ \]+LOCAL\[ \]+DEFAULT\[ \]+68... " puts $ofd "#..." @@ -144,12 +144,12 @@ if { [istarget spu*-*-*] } { puts $ofd "#readelf: -W -Ss" puts $ofd "There are 660.. section headers.*:" puts $ofd "#..." -puts $ofd " \\\[ 0\\\] .* 662..\[ \]+0\[ \]+0" +puts $ofd " \\\[ 0\\\] .* 660..\[ \]+0\[ \]+0" puts $ofd "#..." puts $ofd " \\\[65279\\\] \\.foo\\.\[0-9\]+ .*" -puts $ofd " \\\[65536\\\] \\.foo\\.\[0-9\]+ .*" +puts $ofd " \\\[65280\\\] \\.foo\\.\[0-9\]+ .*" puts $ofd "#..." -puts $ofd " 660..: \[0-9a-f\]+\[ \]+0\[ \]+SECTION\[ \]+LOCAL\[ \]+DEFAULT\[ \]+662.. " +puts $ofd " 660..: \[0-9a-f\]+\[ \]+0\[ \]+SECTION\[ \]+LOCAL\[ \]+DEFAULT\[ \]+660.. " puts $ofd "#..." puts $ofd " 660..: \[0-9a-f\]+\[ \]+0\[ \]+NOTYPE\[ \]+LOCAL\[ \]+DEFAULT\[ \]+\[0-9\] bar_1$" puts $ofd "#..." -- 2.7.4