diff -uprN binutils-2.15.94.0.2/bfd/ChangeLog.linux binutils-2.15.94.0.2.2/bfd/ChangeLog.linux --- binutils-2.15.94.0.2/bfd/ChangeLog.linux 2003-05-05 14:46:46.000000000 -0700 +++ binutils-2.15.94.0.2.2/bfd/ChangeLog.linux 2005-02-17 22:14:30.309206517 -0800 @@ -1,3 +1,43 @@ +2005-02-14 H.J. Lu + + * elfxx-ia64.c (elfNN_ia64_relax_section): Allow relax + backward branch in the same section. + (elfNN_ia64_relocate_section): Inform users that the input + section is too big to relax br instruction when overflow + happens to R_IA64_PCREL21B, R_IA64_PCREL21BI, R_IA64_PCREL21M + and R_IA64_PCREL21F. + +2005-02-07 Alan Modra + + * elf-bfd.h (elf_string_from_elf_strtab): Delete macro. + * elf.c (bfd_elf_string_from_elf_section): Expand occurrence of + elf_string_from_elf_strtab. + (_bfd_elf_setup_group_pointers, bfd_section_from_shdr): Likewise. + (bfd_section_from_shdr): For SHT_SYMTAB, load SHT_SYMTAB_SHNDX too + if it exists. Don't do the reverse for SHT_SYMTAB_SHNDX. For + SHT_STRTAB, check whether the strtab is for symtab or dynsymtab by + looking at cached symtab info first, before iterating over headers. + For SHT_REL and SHT_RELA, load dynsymtab if needed. + * elfcode.h (elf_object_p): Don't load section header stringtab + specially. + +2005-01-24 H.J. Lu + + * elf32-i386.c (elf_i386_relocate_section): Disallow R_386_GOTOFF + against protected function when building shared library. + + PR 584 + * elf64-x86-64.c (is_32bit_relative_branch): New. + (elf64_x86_64_relocate_section): Alllow R_X86_64_PC32 on a + protected function symbol when building shared library for + 32bit relative branch instruction. + +2005-01-18 H.J. Lu + + PR 679 + * elflink.c (_bfd_elf_symbol_refs_local_p): Return TRUE for + protected non-function symbols. + 2003-05-05 H.J. Lu * elf32-ppc.c (ppc_elf_relocate_section): Updated. diff -uprN binutils-2.15.94.0.2/bfd/configure binutils-2.15.94.0.2.2/bfd/configure --- binutils-2.15.94.0.2/bfd/configure 2004-12-20 11:16:48.000000000 -0800 +++ binutils-2.15.94.0.2.2/bfd/configure 2005-02-17 22:14:30.359200059 -0800 @@ -2834,7 +2834,7 @@ fi # Define the identity of the package. PACKAGE=bfd - VERSION=2.15.94.0.2 + VERSION=2.15.94.0.2.2 cat >>confdefs.h <<_ACEOF diff -uprN binutils-2.15.94.0.2/bfd/configure.in binutils-2.15.94.0.2.2/bfd/configure.in --- binutils-2.15.94.0.2/bfd/configure.in 2004-12-20 11:16:48.000000000 -0800 +++ binutils-2.15.94.0.2.2/bfd/configure.in 2005-02-17 22:14:30.361199800 -0800 @@ -8,7 +8,7 @@ AC_CONFIG_SRCDIR([libbfd.c]) AC_CANONICAL_TARGET AC_ISC_POSIX -AM_INIT_AUTOMAKE(bfd, 2.15.94.0.2) +AM_INIT_AUTOMAKE(bfd, 2.15.94.0.2.2) dnl These must be called before AM_PROG_LIBTOOL, because it may want dnl to call AC_CHECK_PROG. diff -uprN binutils-2.15.94.0.2/bfd/elf32-i386.c binutils-2.15.94.0.2.2/bfd/elf32-i386.c --- binutils-2.15.94.0.2/bfd/elf32-i386.c 2004-11-22 12:33:30.000000000 -0800 +++ binutils-2.15.94.0.2.2/bfd/elf32-i386.c 2005-02-07 11:42:44.000000000 -0800 @@ -2271,6 +2271,22 @@ elf_i386_relocate_section (bfd *output_b /* Relocation is relative to the start of the global offset table. */ + /* Check to make sure it isn't a protected function symbol + for shared library since it may not be local when used + as function address. */ + if (info->shared + && h + && h->def_regular + && h->type == STT_FUNC + && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) + { + (*_bfd_error_handler) + (_("%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"), + input_bfd, h->root.root.string); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + /* Note that sgot is not involved in this calculation. We always want the start of .got.plt. If we defined _GLOBAL_OFFSET_TABLE_ in a different way, as is diff -uprN binutils-2.15.94.0.2/bfd/elf64-x86-64.c binutils-2.15.94.0.2.2/bfd/elf64-x86-64.c --- binutils-2.15.94.0.2/bfd/elf64-x86-64.c 2004-11-22 12:33:31.000000000 -0800 +++ binutils-2.15.94.0.2.2/bfd/elf64-x86-64.c 2005-02-07 11:42:44.000000000 -0800 @@ -1741,6 +1741,24 @@ tpoff (struct bfd_link_info *info, bfd_v return address - htab->tls_size - htab->tls_sec->vma; } +/* Is the instruction before OFFSET in CONTENTS a 32bit relative + branch? */ + +static bfd_boolean +is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset) +{ + /* Opcode Instruction + 0xe8 call + 0xe9 jump + 0x0f 0x8x conditional jump */ + return ((offset > 0 + && (contents [offset - 1] == 0xe8 + || contents [offset - 1] == 0xe9)) + || (offset > 1 + && contents [offset - 2] == 0x0f + && (contents [offset - 1] & 0xf0) == 0x80)); +} + /* Relocate an x86_64 ELF section. */ static bfd_boolean @@ -1946,13 +1964,26 @@ elf64_x86_64_relocate_section (bfd *outp if (info->shared && !SYMBOL_REFERENCES_LOCAL (info, h) && (input_section->flags & SEC_ALLOC) != 0 - && (input_section->flags & SEC_READONLY) != 0) + && (input_section->flags & SEC_READONLY) != 0 + && (!h->def_regular + || r_type != R_X86_64_PC32 + || h->type != STT_FUNC + || ELF_ST_VISIBILITY (h->other) != STV_PROTECTED + || !is_32bit_relative_branch (contents, + rel->r_offset))) { - (*_bfd_error_handler) - (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"), - input_bfd, - x86_64_elf_howto_table[r_type].name, - (h) ? h->root.root.string : "a local symbol"); + if (h->def_regular + && r_type == R_X86_64_PC32 + && h->type == STT_FUNC + && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) + (*_bfd_error_handler) + (_("%B: relocation R_X86_64_PC32 against protected function `%s' can not be used when making a shared object"), + input_bfd, h->root.root.string); + else + (*_bfd_error_handler) + (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"), + input_bfd, x86_64_elf_howto_table[r_type].name, + h->root.root.string); bfd_set_error (bfd_error_bad_value); return FALSE; } diff -uprN binutils-2.15.94.0.2/bfd/elf-bfd.h binutils-2.15.94.0.2.2/bfd/elf-bfd.h --- binutils-2.15.94.0.2/bfd/elf-bfd.h 2004-12-20 11:16:48.000000000 -0800 +++ binutils-2.15.94.0.2.2/bfd/elf-bfd.h 2005-02-07 11:42:44.000000000 -0800 @@ -1367,10 +1367,6 @@ extern bfd_boolean _bfd_elf_print_privat extern void bfd_elf_print_symbol (bfd *, void *, asymbol *, bfd_print_symbol_type); -#define elf_string_from_elf_strtab(abfd, strindex) \ - bfd_elf_string_from_elf_section (abfd, elf_elfheader(abfd)->e_shstrndx, \ - strindex) - extern void _bfd_elf_sprintf_vma (bfd *, char *, bfd_vma); extern void _bfd_elf_fprintf_vma diff -uprN binutils-2.15.94.0.2/bfd/elf.c binutils-2.15.94.0.2.2/bfd/elf.c --- binutils-2.15.94.0.2/bfd/elf.c 2004-12-20 11:16:48.000000000 -0800 +++ binutils-2.15.94.0.2.2/bfd/elf.c 2005-02-07 11:42:44.000000000 -0800 @@ -291,13 +291,13 @@ bfd_elf_string_from_elf_section (bfd *ab if (strindex >= hdr->sh_size) { + unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx; (*_bfd_error_handler) (_("%B: invalid string offset %u >= %lu for section `%s'"), abfd, strindex, (unsigned long) hdr->sh_size, - ((shindex == elf_elfheader(abfd)->e_shstrndx - && strindex == hdr->sh_name) + (shindex == shstrndx && strindex == hdr->sh_name ? ".shstrtab" - : elf_string_from_elf_strtab (abfd, hdr->sh_name))); + : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name))); return ""; } @@ -650,7 +650,10 @@ _bfd_elf_setup_group_pointers (bfd *abfd (_("%B: unknown [%d] section `%s' in group [%s]"), abfd, (unsigned int) idx->shdr->sh_type, - elf_string_from_elf_strtab (abfd, idx->shdr->sh_name), + bfd_elf_string_from_elf_section (abfd, + (elf_elfheader (abfd) + ->e_shstrndx), + idx->shdr->sh_name), shdr->bfd_section->name); result = FALSE; } @@ -1729,7 +1732,9 @@ bfd_section_from_shdr (bfd *abfd, unsign const struct elf_backend_data *bed = get_elf_backend_data (abfd); const char *name; - name = elf_string_from_elf_strtab (abfd, hdr->sh_name); + name = bfd_elf_string_from_elf_section (abfd, + elf_elfheader (abfd)->e_shstrndx, + hdr->sh_name); switch (hdr->sh_type) { @@ -1802,6 +1807,32 @@ bfd_section_from_shdr (bfd *abfd, unsign && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) return FALSE; + /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we + can't read symbols without that section loaded as well. It + is most likely specified by the next section header. */ + if (elf_elfsections (abfd)[elf_symtab_shndx (abfd)]->sh_link != shindex) + { + unsigned int i, num_sec; + + num_sec = elf_numsections (abfd); + for (i = shindex + 1; i < num_sec; i++) + { + Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; + if (hdr2->sh_type == SHT_SYMTAB_SHNDX + && hdr2->sh_link == shindex) + break; + } + if (i == num_sec) + for (i = 1; i < shindex; i++) + { + Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; + if (hdr2->sh_type == SHT_SYMTAB_SHNDX + && hdr2->sh_link == shindex) + break; + } + if (i != shindex) + return bfd_section_from_shdr (abfd, i); + } return TRUE; case SHT_DYNSYM: /* A dynamic symbol table */ @@ -1823,11 +1854,7 @@ bfd_section_from_shdr (bfd *abfd, unsign if (elf_symtab_shndx (abfd) == shindex) return TRUE; - /* Get the associated symbol table. */ - if (! bfd_section_from_shdr (abfd, hdr->sh_link) - || hdr->sh_link != elf_onesymtab (abfd)) - return FALSE; - + BFD_ASSERT (elf_symtab_shndx (abfd) == 0); elf_symtab_shndx (abfd) = shindex; elf_tdata (abfd)->symtab_shndx_hdr = *hdr; elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr; @@ -1842,48 +1869,46 @@ bfd_section_from_shdr (bfd *abfd, unsign elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr; return TRUE; } - { - unsigned int i, num_sec; + if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex) + { + symtab_strtab: + elf_tdata (abfd)->strtab_hdr = *hdr; + elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr; + return TRUE; + } + if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex) + { + dynsymtab_strtab: + elf_tdata (abfd)->dynstrtab_hdr = *hdr; + hdr = &elf_tdata (abfd)->dynstrtab_hdr; + elf_elfsections (abfd)[shindex] = hdr; + /* We also treat this as a regular section, so that objcopy + can handle it. */ + return _bfd_elf_make_section_from_shdr (abfd, hdr, name); + } - num_sec = elf_numsections (abfd); - for (i = 1; i < num_sec; i++) - { - Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; - if (hdr2->sh_link == shindex) - { - if (! bfd_section_from_shdr (abfd, i)) - return FALSE; - if (elf_onesymtab (abfd) == i) - { - elf_tdata (abfd)->strtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = - &elf_tdata (abfd)->strtab_hdr; - return TRUE; - } - if (elf_dynsymtab (abfd) == i) - { - elf_tdata (abfd)->dynstrtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = hdr = - &elf_tdata (abfd)->dynstrtab_hdr; - /* We also treat this as a regular section, so - that objcopy can handle it. */ - break; - } -#if 0 /* Not handling other string tables specially right now. */ - hdr2 = elf_elfsections (abfd)[i]; /* in case it moved */ - /* We have a strtab for some random other section. */ - newsect = (asection *) hdr2->bfd_section; - if (!newsect) - break; - hdr->bfd_section = newsect; - hdr2 = &elf_section_data (newsect)->str_hdr; - *hdr2 = *hdr; - elf_elfsections (abfd)[shindex] = hdr2; -#endif - } - } - } + /* If the string table isn't one of the above, then treat it as a + regular section. We need to scan all the headers to be sure, + just in case this strtab section appeared before the above. */ + if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0) + { + unsigned int i, num_sec; + num_sec = elf_numsections (abfd); + for (i = 1; i < num_sec; i++) + { + Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; + if (hdr2->sh_link == shindex) + { + if (! bfd_section_from_shdr (abfd, i)) + return FALSE; + if (elf_onesymtab (abfd) == i) + goto symtab_strtab; + if (elf_dynsymtab (abfd) == i) + goto dynsymtab_strtab; + } + } + } return _bfd_elf_make_section_from_shdr (abfd, hdr, name); case SHT_REL: @@ -1936,7 +1961,8 @@ bfd_section_from_shdr (bfd *abfd, unsign } /* Get the symbol table. */ - if (elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB + if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB + || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM) && ! bfd_section_from_shdr (abfd, hdr->sh_link)) return FALSE; @@ -2035,10 +2061,8 @@ bfd_section_from_shdr (bfd *abfd, unsign default: /* Check for any processor-specific section types. */ - { - if (bed->elf_backend_section_from_shdr) - (*bed->elf_backend_section_from_shdr) (abfd, hdr, name); - } + if (bed->elf_backend_section_from_shdr) + (*bed->elf_backend_section_from_shdr) (abfd, hdr, name); break; } diff -uprN binutils-2.15.94.0.2/bfd/elfcode.h binutils-2.15.94.0.2.2/bfd/elfcode.h --- binutils-2.15.94.0.2/bfd/elfcode.h 2004-12-20 11:16:48.000000000 -0800 +++ binutils-2.15.94.0.2.2/bfd/elfcode.h 2005-02-07 11:42:44.000000000 -0800 @@ -475,7 +475,6 @@ elf_object_p (bfd *abfd) Elf_Internal_Shdr i_shdr; Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ unsigned int shindex; - char *shstrtab; /* Internal copy of section header stringtab */ const struct elf_backend_data *ebd; struct bfd_preserve preserve; asection *s; @@ -686,12 +685,6 @@ elf_object_p (bfd *abfd) } } - if (i_ehdrp->e_shstrndx && i_ehdrp->e_shoff) - { - if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx)) - goto got_no_match; - } - /* Read in the program headers. */ if (i_ehdrp->e_phnum == 0) elf_tdata (abfd)->phdr = NULL; @@ -717,20 +710,10 @@ elf_object_p (bfd *abfd) } } - /* Read in the string table containing the names of the sections. We - will need the base pointer to this table later. */ - /* We read this inline now, so that we don't have to go through - bfd_section_from_shdr with it (since this particular strtab is - used to find all of the ELF section names.) */ - - if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff) + if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff != 0) { unsigned int num_sec; - shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx); - if (!shstrtab) - goto got_no_match; - /* Once all of the section headers have been read and converted, we can start processing them. Note that the first section header is a dummy placeholder entry, so we ignore it. */ diff -uprN binutils-2.15.94.0.2/bfd/elflink.c binutils-2.15.94.0.2.2/bfd/elflink.c --- binutils-2.15.94.0.2/bfd/elflink.c 2004-12-20 11:16:48.000000000 -0800 +++ binutils-2.15.94.0.2.2/bfd/elflink.c 2005-02-07 11:42:44.000000000 -0800 @@ -2533,6 +2533,10 @@ _bfd_elf_symbol_refs_local_p (struct elf if (ELF_ST_VISIBILITY (h->other) != STV_PROTECTED) return TRUE; + /* STV_PROTECTED non-function symbols are local. */ + if (h->type != STT_FUNC) + return TRUE; + /* Function pointer equality tests may require that STV_PROTECTED symbols be treated as dynamic symbols, even when we know that the dynamic linker will resolve them locally. */ diff -uprN binutils-2.15.94.0.2/bfd/elfxx-ia64.c binutils-2.15.94.0.2.2/bfd/elfxx-ia64.c --- binutils-2.15.94.0.2/bfd/elfxx-ia64.c 2004-11-22 12:33:31.000000000 -0800 +++ binutils-2.15.94.0.2.2/bfd/elfxx-ia64.c 2005-02-17 22:14:30.393195667 -0800 @@ -984,9 +984,10 @@ elfNN_ia64_relax_section (abfd, sec, lin } /* If the branch and target are in the same section, you've - got one honking big section and we can't help you. You'll - get an error message later. */ - if (tsec == sec) + got one honking big section and we can't help you unless + you are branching backwards. You'll get an error message + later. */ + if (tsec == sec && toff > roff) continue; /* Look for an existing fixup to this address. */ @@ -4507,13 +4508,37 @@ elfNN_ia64_relocate_section (output_bfd, if (*name == '\0') name = bfd_section_name (input_bfd, sym_sec); } - if (!(*info->callbacks->reloc_overflow) (info, &h->root, - name, howto->name, - (bfd_vma) 0, - input_bfd, - input_section, - rel->r_offset)) - return FALSE; + + switch (r_type) + { + case R_IA64_PCREL21B: + case R_IA64_PCREL21BI: + case R_IA64_PCREL21M: + case R_IA64_PCREL21F: + if (is_elf_hash_table (info->hash)) + { + /* Relaxtion is always performed for ELF output. + Overflow failures for those relocations mean + that the section is too big to relax. */ + (*_bfd_error_handler) + (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."), + input_bfd, input_section, howto->name, name, + rel->r_offset, input_section->size); + break; + } + default: + if (!(*info->callbacks->reloc_overflow) (info, + &h->root, + name, + howto->name, + (bfd_vma) 0, + input_bfd, + input_section, + rel->r_offset)) + return FALSE; + break; + } + ret_val = FALSE; } break; diff -uprN binutils-2.15.94.0.2/binutils/ChangeLog.linux binutils-2.15.94.0.2.2/binutils/ChangeLog.linux --- binutils-2.15.94.0.2/binutils/ChangeLog.linux 2004-01-14 13:07:44.000000000 -0800 +++ binutils-2.15.94.0.2.2/binutils/ChangeLog.linux 2005-02-17 22:14:30.409193600 -0800 @@ -1,3 +1,18 @@ +2005-02-11 H.J. Lu + + * readelf.c (group_count): Don't initialize it. + (process_section_groups): Reurn 1 if we won't do unwind nor + section groups. Set group_count to 0 before counting group + sections and return 1 if there are no group sections. Reread + SHT_SYMTAB/SHT_STRTAB sections only when needed. Don't skip + section 0. + (process_object): Only set do_unwind to 0 if + process_section_groups return 0. + +2004-12-27 H.J. Lu + + * readelf.c (read_leb128): Support 64bit host. + 2003-11-24 H.J. Lu * cxxfilt.c (main): Updated. diff -uprN binutils-2.15.94.0.2/binutils/readelf.c binutils-2.15.94.0.2.2/binutils/readelf.c --- binutils-2.15.94.0.2/binutils/readelf.c 2004-12-20 11:16:49.000000000 -0800 +++ binutils-2.15.94.0.2.2/binutils/readelf.c 2005-02-17 22:14:30.432190629 -0800 @@ -182,7 +182,7 @@ struct group }; struct group *section_groups; -size_t group_count = 0; +size_t group_count; struct group **section_headers_groups; @@ -3925,11 +3925,18 @@ process_section_groups (FILE *file) Elf_Internal_Shdr *section; unsigned int i; struct group *group; + Elf_Internal_Shdr *symtab_sec, *strtab_sec; + Elf_Internal_Sym *symtab; + char *strtab; + + /* Don't process section groups unless needed. */ + if (!do_unwind && !do_section_groups) + return 1; if (elf_header.e_shnum == 0) { if (do_section_groups) - printf (_("\nThere are no section groups in this file.\n")); + printf (_("\nThere are no sections in this file.\n")); return 1; } @@ -3950,12 +3957,21 @@ process_section_groups (FILE *file) } /* Scan the sections for the group section. */ + group_count = 0; for (i = 0, section = section_headers; i < elf_header.e_shnum; i++, section++) if (section->sh_type == SHT_GROUP) group_count++; + if (group_count == 0) + { + if (do_section_groups) + printf (_("\nThere are no section groups in this file.\n")); + + return 1; + } + section_groups = calloc (group_count, sizeof (struct group)); if (section_groups == NULL) @@ -3964,6 +3980,10 @@ process_section_groups (FILE *file) return 0; } + symtab_sec = NULL; + strtab_sec = NULL; + symtab = NULL; + strtab = NULL; for (i = 0, section = section_headers, group = section_groups; i < elf_header.e_shnum; i++, section++) @@ -3971,20 +3991,26 @@ process_section_groups (FILE *file) if (section->sh_type == SHT_GROUP) { char *name = SECTION_NAME (section); - char *group_name, *strtab, *start, *indices; + char *group_name, *start, *indices; unsigned int entry, j, size; + Elf_Internal_Shdr *sec; Elf_Internal_Sym *sym; - Elf_Internal_Shdr *symtab_sec, *strtab_sec, *sec; - Elf_Internal_Sym *symtab; /* Get the symbol table. */ - symtab_sec = SECTION_HEADER (section->sh_link); - if (symtab_sec->sh_type != SHT_SYMTAB) + sec = SECTION_HEADER (section->sh_link); + if (sec->sh_type != SHT_SYMTAB) { error (_("Bad sh_link in group section `%s'\n"), name); continue; } - symtab = GET_ELF_SYMBOLS (file, symtab_sec); + + if (symtab_sec != sec) + { + symtab_sec = sec; + if (symtab) + free (symtab); + symtab = GET_ELF_SYMBOLS (file, symtab_sec); + } sym = symtab + section->sh_info; @@ -4003,11 +4029,16 @@ process_section_groups (FILE *file) else { /* Get the string table. */ - strtab_sec = SECTION_HEADER (symtab_sec->sh_link); - strtab = get_data (NULL, file, strtab_sec->sh_offset, - strtab_sec->sh_size, - _("string table")); - + sec = SECTION_HEADER (symtab_sec->sh_link); + if (strtab_sec != sec) + { + strtab_sec = sec; + if (strtab) + free (strtab); + strtab = get_data (NULL, file, strtab_sec->sh_offset, + strtab_sec->sh_size, + _("string table")); + } group_name = strtab + sym->st_name; } @@ -4039,9 +4070,26 @@ process_section_groups (FILE *file) if (section_headers_groups [SECTION_HEADER_INDEX (entry)] != NULL) { - error (_("section [%5u] already in group section [%5u]\n"), - entry, section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index); - continue; + if (entry) + { + error (_("section [%5u] already in group section [%5u]\n"), + entry, + section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index); + continue; + } + else + { + /* Intel C/C++ compiler may put section 0 in a + section group. We just warn it the first time + and ignore it afterwards. */ + static int warned = 0; + if (!warned) + { + error (_("section 0 in group section [%5u]\n"), + section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index); + warned++; + } + } } section_headers_groups [SECTION_HEADER_INDEX (entry)] @@ -4060,10 +4108,6 @@ process_section_groups (FILE *file) group->root = g; } - if (symtab) - free (symtab); - if (strtab) - free (strtab); if (start) free (start); @@ -4071,6 +4115,10 @@ process_section_groups (FILE *file) } } + if (symtab) + free (symtab); + if (strtab) + free (strtab); return 1; } @@ -6933,7 +6981,7 @@ read_leb128 (unsigned char *data, int *l { unsigned long int result = 0; unsigned int num_read = 0; - int shift = 0; + unsigned int shift = 0; unsigned char byte; do @@ -6941,7 +6989,7 @@ read_leb128 (unsigned char *data, int *l byte = *data++; num_read++; - result |= (byte & 0x7f) << shift; + result |= ((unsigned long int) (byte & 0x7f)) << shift; shift += 7; @@ -6951,8 +6999,8 @@ read_leb128 (unsigned char *data, int *l if (length_return != NULL) *length_return = num_read; - if (sign && (shift < 32) && (byte & 0x40)) - result |= -1 << shift; + if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40)) + result |= -1L << shift; return result; } @@ -11444,17 +11492,22 @@ process_object (char *file_name, FILE *f if (! process_file_header ()) return 1; - if (! process_section_headers (file) - || ! process_section_groups (file)) + if (! process_section_headers (file)) { - /* Without loaded section headers and section groups we - cannot process lots of things. */ + /* Without loaded section headers we cannot process lots of + things. */ do_unwind = do_version = do_dump = do_arch = 0; if (! do_using_dynamic) do_syms = do_reloc = 0; } + if (! process_section_groups (file)) + { + /* Without loaded section groups we cannot process unwind. */ + do_unwind = 0; + } + if (process_program_headers (file)) process_dynamic_section (file); diff -uprN binutils-2.15.94.0.2/binutils.spec binutils-2.15.94.0.2.2/binutils.spec --- binutils-2.15.94.0.2/binutils.spec 2004-12-20 09:10:19.000000000 -0800 +++ binutils-2.15.94.0.2.2/binutils.spec 2005-02-11 11:22:44.000000000 -0800 @@ -12,7 +12,7 @@ Summary: A GNU collection of binary utilities. Name: binutils -Version: 2.15.94.0.2 +Version: 2.15.94.0.2.2 Release: 1 Copyright: GPL Group: Development/Tools diff -uprN binutils-2.15.94.0.2/gas/ChangeLog.linux binutils-2.15.94.0.2.2/gas/ChangeLog.linux --- binutils-2.15.94.0.2/gas/ChangeLog.linux 2004-04-12 12:56:34.000000000 -0700 +++ binutils-2.15.94.0.2.2/gas/ChangeLog.linux 2005-02-17 22:14:30.482184170 -0800 @@ -1,3 +1,31 @@ +2005-02-17 H.J. Lu + + * NEWS: Mention "-mhint.b=[ok|warning|error]". + + * config/tc-ia64.c (md): Add hint_b. + (emit_one_bundle): Handle md.hint_b for "hint". + (md_parse_option): Accepted "-mhint.b=[ok|warning|error]". + (md_show_usage): Add "-mhint.b=[ok|warning|error]". + (ia64_init): Set md.hint_b to error. + (md_assemble): Handle md.hint_b for "hint.b". + + * doc/as.texinfo: Add "-mhint.b=[ok|warning|error]". + * doc/c-ia64.texi: Likewise. + +2005-02-17 James E Wilson + + * config/tc-ia64.c (emit_one_bundle): Stop filling a bundle if we + see an instruction that specifies a template. + (remove_marked_resource): Set CURR_SLOT.user_template to -1 + when inserting srlz.i/srlz.d. + +2005-02-10 H.J. Lu + + * doc/all.texi: Add IA64. + * doc/as.texinfo: Likewise. + + * doc/c-ia64.texi: Fix typoes. + 2001-10-21 H.J. Lu * configure: Rebuid for ../libtool.m4 change. diff -uprN binutils-2.15.94.0.2/gas/config/tc-ia64.c binutils-2.15.94.0.2.2/gas/config/tc-ia64.c --- binutils-2.15.94.0.2/gas/config/tc-ia64.c 2004-11-22 12:33:32.000000000 -0800 +++ binutils-2.15.94.0.2.2/gas/config/tc-ia64.c 2005-02-17 22:14:30.541176548 -0800 @@ -1,5 +1,5 @@ /* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture. - Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by David Mosberger-Tang @@ -221,6 +221,14 @@ static struct that are predicatable. */ expressionS qp; + /* What to do when hint.b is used. */ + enum + { + hint_b_error, + hint_b_warning, + hint_b_ok + } hint_b; + unsigned int manual_bundling : 1, debug_dv: 1, @@ -6228,6 +6236,11 @@ emit_one_bundle () } } + /* If this instruction specifies a template, then it must be the first + instruction of a bundle. */ + if (curr != first && md.slot[curr].user_template >= 0) + break; + if (idesc->flags & IA64_OPCODE_SLOT2) { if (manual_bundling && i != 2) @@ -6358,9 +6371,34 @@ emit_one_bundle () if (idesc->type == IA64_TYPE_DYN) { if ((strcmp (idesc->name, "nop") == 0) - || (strcmp (idesc->name, "hint") == 0) || (strcmp (idesc->name, "break") == 0)) insn_unit = required_unit; + else if (strcmp (idesc->name, "hint") == 0) + { + insn_unit = required_unit; + if (required_unit == IA64_UNIT_B) + { + switch (md.hint_b) + { + case hint_b_ok: + break; + case hint_b_warning: + as_warn ("hint in B unit may be treated as nop"); + break; + case hint_b_error: + /* When manual bundling is off and there is no + user template, we choose a different unit so + that hint won't go into the current slot. We + will fill the current bundle with nops and + try to put hint into the next bundle. */ + if (!manual_bundling && user_template < 0) + insn_unit = IA64_UNIT_I; + else + as_bad ("hint in B unit can't be used"); + break; + } + } + } else if (strcmp (idesc->name, "chk.s") == 0) { insn_unit = IA64_UNIT_M; @@ -6557,6 +6595,18 @@ md_parse_option (c, arg) md.flags |= EF_IA_64_BE; default_big_endian = 1; } + else if (strncmp (arg, "hint.b=", 7) == 0) + { + arg += 7; + if (strcmp (arg, "ok") == 0) + md.hint_b = hint_b_ok; + else if (strcmp (arg, "warning") == 0) + md.hint_b = hint_b_warning; + else if (strcmp (arg, "error") == 0) + md.hint_b = hint_b_error; + else + return 0; + } else return 0; break; @@ -6660,6 +6710,8 @@ IA-64 options:\n\ EF_IA_64_NOFUNCDESC_CONS_GP)\n\ -milp32|-milp64|-mlp64|-mp64 select data model (default -mlp64)\n\ -mle | -mbe select little- or big-endian byte order (default -mle)\n\ + -mhint.b=[ok|warning|error]\n\ + hint.b check (default -mhint.b=error)\n\ -x | -xexplicit turn on dependency violation checking (default)\n\ -xauto automagically remove dependency violations\n\ -xdebug debug dependency violation checker\n"), @@ -6994,10 +7046,9 @@ md_begin () md.entry_labels = NULL; } -/* Set the elf type to 64 bit ABI by default. Cannot do this in md_begin - because that is called after md_parse_option which is where we do the - dynamic changing of md.flags based on -mlp64 or -milp32. Also, set the - default endianness. */ +/* Set the default options in md. Cannot do this in md_begin because + that is called after md_parse_option which is where we set the + options in md based on command line options. */ void ia64_init (argc, argv) @@ -7005,6 +7056,7 @@ ia64_init (argc, argv) char **argv ATTRIBUTE_UNUSED; { md.flags = MD_FLAGS_DEFAULT; + md.hint_b = hint_b_error; } /* Return a string for the target object file format. */ @@ -9596,6 +9648,7 @@ remove_marked_resource (rs) struct slot oldslot = CURR_SLOT; /* Manually jam a srlz.i insn into the stream */ memset (&CURR_SLOT, 0, sizeof (CURR_SLOT)); + CURR_SLOT.user_template = -1; CURR_SLOT.idesc = ia64_find_opcode ("srlz.i"); instruction_serialization (); md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS; @@ -9617,6 +9670,7 @@ remove_marked_resource (rs) struct slot oldslot = CURR_SLOT; /* Manually jam a srlz.d insn into the stream */ memset (&CURR_SLOT, 0, sizeof (CURR_SLOT)); + CURR_SLOT.user_template = -1; CURR_SLOT.idesc = ia64_find_opcode ("srlz.d"); data_serialization (); md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS; @@ -10097,6 +10151,20 @@ md_assemble (str) TOUPPER (unit)); } } + else if (strcmp (idesc->name, "hint.b") == 0) + { + switch (md.hint_b) + { + case hint_b_ok: + break; + case hint_b_warning: + as_warn ("hint.b may be treated as nop"); + break; + case hint_b_error: + as_bad ("hint.b shouldn't be used"); + break; + } + } qp_regno = 0; if (md.qp.X_op == O_register) diff -uprN binutils-2.15.94.0.2/gas/doc/all.texi binutils-2.15.94.0.2.2/gas/doc/all.texi --- binutils-2.15.94.0.2/gas/doc/all.texi 2003-05-05 14:46:48.000000000 -0700 +++ binutils-2.15.94.0.2.2/gas/doc/all.texi 2005-02-17 22:14:30.559174223 -0800 @@ -40,6 +40,7 @@ @set I80386 @set I860 @set I960 +@set IA64 @set IP2K @set M32R @set M68HC11 diff -uprN binutils-2.15.94.0.2/gas/doc/as.texinfo binutils-2.15.94.0.2.2/gas/doc/as.texinfo --- binutils-2.15.94.0.2/gas/doc/as.texinfo 2004-12-20 11:16:50.000000000 -0800 +++ binutils-2.15.94.0.2.2/gas/doc/as.texinfo 2005-02-17 22:14:30.591170090 -0800 @@ -315,6 +315,7 @@ gcc(1), ld(1), and the Info entries for [@b{-mconstant-gp}|@b{-mauto-pic}] [@b{-milp32}|@b{-milp64}|@b{-mlp64}|@b{-mp64}] [@b{-mle}|@b{mbe}] + [@b{-mhint.b=ok}|@b{-mhint.b=warning}|@b{-mhint.b=error}] [@b{-x}|@b{-xexplicit}] [@b{-xauto}] [@b{-xdebug}] @end ifset @ifset IP2K @@ -6039,6 +6040,9 @@ subject, see the hardware manufacturer's @ifset I960 * i960-Dependent:: Intel 80960 Dependent Features @end ifset +@ifset IA64 +* IA-64-Dependent:: Intel IA-64 Dependent Features +@end ifset @ifset IP2K * IP2K-Dependent:: IP2K Dependent Features @end ifset diff -uprN binutils-2.15.94.0.2/gas/doc/c-ia64.texi binutils-2.15.94.0.2.2/gas/doc/c-ia64.texi --- binutils-2.15.94.0.2/gas/doc/c-ia64.texi 2004-01-14 13:07:46.000000000 -0800 +++ binutils-2.15.94.0.2.2/gas/doc/c-ia64.texi 2005-02-17 22:14:30.616166860 -0800 @@ -65,6 +65,15 @@ These options select the byte order. Th byte order (default) and @code{-mbe} selects big-endian byte order. Note that IA-64 machine code always uses little-endian byte order. +@item -mhint.b=ok +@item -mhint.b=warning +@item -mhint.b=error +These options control what the assembler will do when the @samp{hint.b} +instruction is used. @code{-mhint.b=ok} will make the assembler accept +@samp{hint.b}. @code{-mint.b=warning} will make the assembler issue a +warning when @samp{hint.b} is used. @code{-mhint.b=error} will make +the assembler treat @samp{hint.b} as an error, which is the default. + @item -x @item -xexplicit These options turn on dependency violation checking. This checking is turned on by @@ -90,7 +99,7 @@ Reference Guide. * IA-64-Chars:: Special Characters * IA-64-Regs:: Register Names * IA-64-Bits:: Bit Names -* IA-64-Relocs:: Relocations +@c * IA-64-Relocs:: Relocations // to be written @end menu @node IA-64-Chars @@ -136,7 +145,7 @@ the end-of-interrupt register (@samp{cr6 The assembler defines bit masks for each of the bits in the IA-64 processor status register. For example, @samp{psr.ic} corresponds to a value of 0x2000. These masks are primarily intended for use with -the @sample{ssm}/@sample{sum} and @sample{rsm}/@sample{rum} +the @samp{ssm}/@samp{sum} and @samp{rsm}/@samp{rum} instructions, but they can be used anywhere else where an integer constant is expected. diff -uprN binutils-2.15.94.0.2/gas/NEWS binutils-2.15.94.0.2.2/gas/NEWS --- binutils-2.15.94.0.2/gas/NEWS 2004-12-20 11:16:49.000000000 -0800 +++ binutils-2.15.94.0.2.2/gas/NEWS 2005-02-17 22:14:30.496182361 -0800 @@ -1,5 +1,7 @@ -*- text -*- +* New command line option -mhint.b=[ok|warning|error] for IA64 targets. + * Port to MAXQ processor contributed by HCL Tech. * Added support for generating unwind tables for ARM ELF targets. diff -uprN binutils-2.15.94.0.2/gas/testsuite/ChangeLog.linux binutils-2.15.94.0.2.2/gas/testsuite/ChangeLog.linux --- binutils-2.15.94.0.2/gas/testsuite/ChangeLog.linux 2002-10-02 10:17:19.000000000 -0700 +++ binutils-2.15.94.0.2.2/gas/testsuite/ChangeLog.linux 2005-02-17 22:14:30.627165439 -0800 @@ -1,3 +1,10 @@ -2002-09-29 H.J. Lu +2005-02-17 H.J. Lu - * gas/mips/branch-misc-2.d: Updated. + * gas/ia64/hint.b-err.l: New file. + * gas/ia64/hint.b-err.s: Likewise. + * gas/ia64/hint.b-warn.l: Likewise. + * gas/ia64/hint.b-warn.s: Likewise. + + * gas/ia64/ia64.exp: Run hint.b-err and hint.b-warn. + + * gas/ia64/opc-b.d: Pass -mhint.b=ok to as. diff -uprN binutils-2.15.94.0.2/gas/testsuite/gas/ia64/hint.b-err.l binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/hint.b-err.l --- binutils-2.15.94.0.2/gas/testsuite/gas/ia64/hint.b-err.l 1969-12-31 16:00:00.000000000 -0800 +++ binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/hint.b-err.l 2005-02-17 22:14:30.627165439 -0800 @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*:1: Error: hint.b shouldn't be used +.*:2: Error: hint.b shouldn't be used diff -uprN binutils-2.15.94.0.2/gas/testsuite/gas/ia64/hint.b-err.s binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/hint.b-err.s --- binutils-2.15.94.0.2/gas/testsuite/gas/ia64/hint.b-err.s 1969-12-31 16:00:00.000000000 -0800 +++ binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/hint.b-err.s 2005-02-17 22:14:30.627165439 -0800 @@ -0,0 +1,2 @@ + hint.b @pause + hint.b 0x1ffff diff -uprN binutils-2.15.94.0.2/gas/testsuite/gas/ia64/hint.b-warn.l binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/hint.b-warn.l --- binutils-2.15.94.0.2/gas/testsuite/gas/ia64/hint.b-warn.l 1969-12-31 16:00:00.000000000 -0800 +++ binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/hint.b-warn.l 2005-02-17 22:14:30.628165310 -0800 @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*:1: Warning: hint.b may be treated as nop +.*:2: Warning: hint.b may be treated as nop diff -uprN binutils-2.15.94.0.2/gas/testsuite/gas/ia64/hint.b-warn.s binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/hint.b-warn.s --- binutils-2.15.94.0.2/gas/testsuite/gas/ia64/hint.b-warn.s 1969-12-31 16:00:00.000000000 -0800 +++ binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/hint.b-warn.s 2005-02-17 22:14:30.628165310 -0800 @@ -0,0 +1,2 @@ + hint.b @pause + hint.b 0x1ffff diff -uprN binutils-2.15.94.0.2/gas/testsuite/gas/ia64/ia64.exp binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/ia64.exp --- binutils-2.15.94.0.2/gas/testsuite/gas/ia64/ia64.exp 2004-07-27 21:36:10.000000000 -0700 +++ binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/ia64.exp 2005-02-17 22:14:30.634164535 -0800 @@ -58,4 +58,7 @@ if [istarget "ia64-*"] then { run_dump_test "alias" run_dump_test "group-1" } + + run_list_test "hint.b-err" "" + run_list_test "hint.b-warn" "-mhint.b=warning" } diff -uprN binutils-2.15.94.0.2/gas/testsuite/gas/ia64/opc-b.d binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/opc-b.d --- binutils-2.15.94.0.2/gas/testsuite/gas/ia64/opc-b.d 2004-01-14 13:07:47.000000000 -0800 +++ binutils-2.15.94.0.2.2/gas/testsuite/gas/ia64/opc-b.d 2005-02-17 22:14:30.639163889 -0800 @@ -1,5 +1,6 @@ #objdump: -d #name: ia64 opc-b +#as: -mhint.b=ok .*: +file format .* diff -uprN binutils-2.15.94.0.2/opcodes/ChangeLog.linux binutils-2.15.94.0.2.2/opcodes/ChangeLog.linux --- binutils-2.15.94.0.2/opcodes/ChangeLog.linux 2001-11-16 14:05:55.000000000 -0800 +++ binutils-2.15.94.0.2.2/opcodes/ChangeLog.linux 2005-02-17 22:14:30.674159368 -0800 @@ -1,3 +1,8 @@ +2005-02-14 H.J. Lu + + * dis-buf.c (perror_memory): Use sprintf_vma to print out + address. + 2001-10-21 H.J. Lu * configure: Rebuid for ../libtool.m4 change. diff -uprN binutils-2.15.94.0.2/opcodes/dis-buf.c binutils-2.15.94.0.2.2/opcodes/dis-buf.c --- binutils-2.15.94.0.2/opcodes/dis-buf.c 2004-01-14 13:07:54.000000000 -0800 +++ binutils-2.15.94.0.2.2/opcodes/dis-buf.c 2005-02-17 22:14:30.691157172 -0800 @@ -56,10 +56,15 @@ perror_memory (status, memaddr, info) /* Can't happen. */ info->fprintf_func (info->stream, _("Unknown error %d\n"), status); else - /* Actually, address between memaddr and memaddr + len was - out of bounds. */ - info->fprintf_func (info->stream, - _("Address 0x%x is out of bounds.\n"), memaddr); + { + char buf[30]; + + /* Actually, address between memaddr and memaddr + len was + out of bounds. */ + sprintf_vma (buf, memaddr); + info->fprintf_func (info->stream, + _("Address 0x%s is out of bounds.\n"), buf); + } } /* This could be in a separate file, to save miniscule amounts of space