Submitted By: Jim Gifford (jim at linuxfromscratch dot org) Date: 12-30-2008 Initial Package Version: 2.19 Origin: Upstream Upstream Status: Applied Description: This is a branch update for binutils-2.19, and should be rechecked periodically. diff -Naur binutils-2.19.orig/bfd/ChangeLog binutils-2.19/bfd/ChangeLog --- binutils-2.19.orig/bfd/ChangeLog 2008-10-16 06:20:48.000000000 -0700 +++ binutils-2.19/bfd/ChangeLog 2008-12-23 02:06:46.000000000 -0800 @@ -1,3 +1,31 @@ +2008-12-23 Nick Clifton + + * Import this patch from the mainline: + 2008-11-10 Andreas Schwab + + PR 7011 + * elf.c (assign_file_positions_for_non_load_sections): Handle + PT_GNU_RELRO specially. + +2008-11-20 Alan Modra + + * elf32-ppc.c (allocate_dynrelocs): Always use tlsld_got for + TLS_LD even when symbol is used with other TLS reloc types. + (ppc_elf_relocate_section): Bypass symbol checks when using tlsld_got. + Leave addend zero on LD DTPMOD dynamic reloc. + +2008-11-17 Eric B. Weddington + + PR 7022 + * elf32-avr.c (bfd_elf_avr_final_write_processing): + Add missing break statements. + +2008-10-28 Tristan Gingold + + * configure.in: Bump version to 2.19.0 + * Makefile.am (RELEASE): Unset. + * configure, Makefile.in: Regenerated. + 2008-10-16 Tristan Gingold * configure.in: Bump version to 2.19 diff -Naur binutils-2.19.orig/bfd/Makefile.in binutils-2.19/bfd/Makefile.in --- binutils-2.19.orig/bfd/Makefile.in 2008-10-16 06:20:48.000000000 -0700 +++ binutils-2.19/bfd/Makefile.in 2008-12-30 16:34:28.000000000 -0800 @@ -271,7 +271,7 @@ ACLOCAL_AMFLAGS = -I . -I .. -I ../config # Uncomment the following line when doing a release. -RELEASE = y +RELEASE=y INCDIR = $(srcdir)/../include CSEARCH = -I. -I$(srcdir) -I$(INCDIR) MKDEP = gcc -MM diff -Naur binutils-2.19.orig/bfd/configure binutils-2.19/bfd/configure --- binutils-2.19.orig/bfd/configure 2008-10-16 06:20:42.000000000 -0700 +++ binutils-2.19/bfd/configure 2008-10-28 03:42:15.000000000 -0700 @@ -3032,7 +3032,7 @@ # Define the identity of the package. PACKAGE=bfd - VERSION=2.19 + VERSION=2.19.0 cat >>confdefs.h <<_ACEOF diff -Naur binutils-2.19.orig/bfd/configure.in binutils-2.19/bfd/configure.in --- binutils-2.19.orig/bfd/configure.in 2008-10-16 06:20:34.000000000 -0700 +++ binutils-2.19/bfd/configure.in 2008-10-28 03:42:15.000000000 -0700 @@ -8,7 +8,7 @@ AC_CANONICAL_TARGET AC_ISC_POSIX -AM_INIT_AUTOMAKE(bfd, 2.19) +AM_INIT_AUTOMAKE(bfd, 2.19.0) dnl These must be called before LT_INIT, because it may want dnl to call AC_CHECK_PROG. diff -Naur binutils-2.19.orig/bfd/elf.c binutils-2.19/bfd/elf.c --- binutils-2.19.orig/bfd/elf.c 2008-10-09 05:18:23.000000000 -0700 +++ binutils-2.19/bfd/elf.c 2008-12-23 02:06:46.000000000 -0800 @@ -4606,7 +4606,61 @@ m != NULL; m = m->next, p++) { - if (m->count != 0) + if (p->p_type == PT_GNU_RELRO) + { + const Elf_Internal_Phdr *lp; + + BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs); + + if (link_info != NULL) + { + /* During linking the range of the RELRO segment is passed + in link_info. */ + for (lp = phdrs; lp < phdrs + count; ++lp) + { + if (lp->p_type == PT_LOAD + && lp->p_vaddr >= link_info->relro_start + && lp->p_vaddr < link_info->relro_end + && lp->p_vaddr + lp->p_filesz >= link_info->relro_end) + break; + } + } + else + { + /* Otherwise we are copying an executable or shared + library, but we need to use the same linker logic. */ + for (lp = phdrs; lp < phdrs + count; ++lp) + { + if (lp->p_type == PT_LOAD + && lp->p_paddr == p->p_paddr) + break; + } + } + + if (lp < phdrs + count) + { + p->p_vaddr = lp->p_vaddr; + p->p_paddr = lp->p_paddr; + p->p_offset = lp->p_offset; + if (link_info != NULL) + p->p_filesz = link_info->relro_end - lp->p_vaddr; + else if (m->p_size_valid) + p->p_filesz = m->p_size; + else + abort (); + p->p_memsz = p->p_filesz; + p->p_align = 1; + p->p_flags = (lp->p_flags & ~PF_W); + } + else if (link_info != NULL) + { + memset (p, 0, sizeof *p); + p->p_type = PT_NULL; + } + else + abort (); + } + else if (m->count != 0) { if (p->p_type != PT_LOAD && (p->p_type != PT_NOTE @@ -4622,87 +4676,20 @@ p->p_filesz = sect->filepos - m->sections[0]->filepos; if (hdr->sh_type != SHT_NOBITS) p->p_filesz += hdr->sh_size; - - if (p->p_type == PT_GNU_RELRO) - { - /* When we get here, we are copying executable - or shared library. But we need to use the same - linker logic. */ - Elf_Internal_Phdr *lp; - - for (lp = phdrs; lp < phdrs + count; ++lp) - { - if (lp->p_type == PT_LOAD - && lp->p_paddr == p->p_paddr) - break; - } - - if (lp < phdrs + count) - { - /* We should use p_size if it is valid since it - may contain the first few bytes of the next - SEC_ALLOC section. */ - if (m->p_size_valid) - p->p_filesz = m->p_size; - else - abort (); - p->p_vaddr = lp->p_vaddr; - p->p_offset = lp->p_offset; - p->p_memsz = p->p_filesz; - p->p_align = 1; - } - else - abort (); - } - else - p->p_offset = m->sections[0]->filepos; + p->p_offset = m->sections[0]->filepos; } } - else + else if (m->includes_filehdr) { - if (m->includes_filehdr) - { - p->p_vaddr = filehdr_vaddr; - if (! m->p_paddr_valid) - p->p_paddr = filehdr_paddr; - } - else if (m->includes_phdrs) - { - p->p_vaddr = phdrs_vaddr; - if (! m->p_paddr_valid) - p->p_paddr = phdrs_paddr; - } - else if (p->p_type == PT_GNU_RELRO) - { - Elf_Internal_Phdr *lp; - - for (lp = phdrs; lp < phdrs + count; ++lp) - { - if (lp->p_type == PT_LOAD - && lp->p_vaddr <= link_info->relro_end - && lp->p_vaddr >= link_info->relro_start - && (lp->p_vaddr + lp->p_filesz - >= link_info->relro_end)) - break; - } - - if (lp < phdrs + count - && link_info->relro_end > lp->p_vaddr) - { - p->p_vaddr = lp->p_vaddr; - p->p_paddr = lp->p_paddr; - p->p_offset = lp->p_offset; - p->p_filesz = link_info->relro_end - lp->p_vaddr; - p->p_memsz = p->p_filesz; - p->p_align = 1; - p->p_flags = (lp->p_flags & ~PF_W); - } - else - { - memset (p, 0, sizeof *p); - p->p_type = PT_NULL; - } - } + p->p_vaddr = filehdr_vaddr; + if (! m->p_paddr_valid) + p->p_paddr = filehdr_paddr; + } + else if (m->includes_phdrs) + { + p->p_vaddr = phdrs_vaddr; + if (! m->p_paddr_valid) + p->p_paddr = phdrs_paddr; } } diff -Naur binutils-2.19.orig/bfd/elf32-avr.c binutils-2.19/bfd/elf32-avr.c --- binutils-2.19.orig/bfd/elf32-avr.c 2008-08-08 22:35:12.000000000 -0700 +++ binutils-2.19/bfd/elf32-avr.c 2008-11-17 07:26:01.000000000 -0800 @@ -1298,6 +1298,7 @@ case bfd_mach_avr25: val = E_AVR_MACH_AVR25; + break; case bfd_mach_avr3: val = E_AVR_MACH_AVR3; @@ -1305,9 +1306,11 @@ case bfd_mach_avr31: val = E_AVR_MACH_AVR31; + break; case bfd_mach_avr35: val = E_AVR_MACH_AVR35; + break; case bfd_mach_avr4: val = E_AVR_MACH_AVR4; diff -Naur binutils-2.19.orig/bfd/elf32-ppc.c binutils-2.19/bfd/elf32-ppc.c --- binutils-2.19.orig/bfd/elf32-ppc.c 2008-10-02 01:07:16.000000000 -0700 +++ binutils-2.19/bfd/elf32-ppc.c 2008-11-20 03:50:22.000000000 -0800 @@ -4997,6 +4997,9 @@ eh = (struct ppc_elf_link_hash_entry *) h; if (eh->elf.got.refcount > 0) { + bfd_boolean dyn; + unsigned int need; + /* Make sure this symbol is output as a dynamic symbol. */ if (eh->elf.dynindx == -1 && !eh->elf.forced_local @@ -5006,30 +5009,32 @@ return FALSE; } - if (eh->tls_mask == (TLS_TLS | TLS_LD) - && !eh->elf.def_dynamic) - { - /* If just an LD reloc, we'll just use htab->tlsld_got.offset. */ - htab->tlsld_got.refcount += 1; - eh->elf.got.offset = (bfd_vma) -1; - } - else + need = 0; + if ((eh->tls_mask & TLS_TLS) != 0) { - bfd_boolean dyn; - unsigned int need = 0; - if ((eh->tls_mask & TLS_TLS) != 0) + if ((eh->tls_mask & TLS_LD) != 0) { - if ((eh->tls_mask & TLS_LD) != 0) - need += 8; - if ((eh->tls_mask & TLS_GD) != 0) + if (!eh->elf.def_dynamic) + /* We'll just use htab->tlsld_got.offset. This should + always be the case. It's a little odd if we have + a local dynamic reloc against a non-local symbol. */ + htab->tlsld_got.refcount += 1; + else need += 8; - if ((eh->tls_mask & (TLS_TPREL | TLS_TPRELGD)) != 0) - need += 4; - if ((eh->tls_mask & TLS_DTPREL) != 0) - need += 4; } - else + if ((eh->tls_mask & TLS_GD) != 0) + need += 8; + if ((eh->tls_mask & (TLS_TPREL | TLS_TPRELGD)) != 0) + need += 4; + if ((eh->tls_mask & TLS_DTPREL) != 0) need += 4; + } + else + need += 4; + if (need == 0) + eh->elf.got.offset = (bfd_vma) -1; + else + { eh->elf.got.offset = allocate_got (htab, need); dyn = htab->elf.dynamic_sections_created; if ((info->shared @@ -5039,7 +5044,8 @@ { /* All the entries we allocated need relocs. Except LD only needs one. */ - if ((eh->tls_mask & TLS_LD) != 0) + if ((eh->tls_mask & TLS_LD) != 0 + && eh->elf.def_dynamic) need -= 4; htab->relgot->size += need * (sizeof (Elf32_External_Rela) / 4); } @@ -5275,27 +5281,24 @@ for (; local_got < end_local_got; ++local_got, ++lgot_masks) if (*local_got > 0) { - if (*lgot_masks == (TLS_TLS | TLS_LD)) + unsigned int need = 0; + if ((*lgot_masks & TLS_TLS) != 0) { - /* If just an LD reloc, we'll just use - htab->tlsld_got.offset. */ - htab->tlsld_got.refcount += 1; - *local_got = (bfd_vma) -1; + if ((*lgot_masks & TLS_GD) != 0) + need += 8; + if ((*lgot_masks & TLS_LD) != 0) + htab->tlsld_got.refcount += 1; + if ((*lgot_masks & (TLS_TPREL | TLS_TPRELGD)) != 0) + need += 4; + if ((*lgot_masks & TLS_DTPREL) != 0) + need += 4; } else + need += 4; + if (need == 0) + *local_got = (bfd_vma) -1; + else { - unsigned int need = 0; - if ((*lgot_masks & TLS_TLS) != 0) - { - if ((*lgot_masks & TLS_GD) != 0) - need += 8; - if ((*lgot_masks & (TLS_TPREL | TLS_TPRELGD)) != 0) - need += 4; - if ((*lgot_masks & TLS_DTPREL) != 0) - need += 4; - } - else - need += 4; *local_got = allocate_got (htab, need); if (info->shared) htab->relgot->size += (need @@ -6560,7 +6563,8 @@ /* Generate relocs for the dynamic linker. */ if ((info->shared || indx != 0) - && (h == NULL + && (offp == &htab->tlsld_got.offset + || h == NULL || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT || h->root.type != bfd_link_hash_undefweak)) { @@ -6591,7 +6595,7 @@ outrel.r_info = ELF32_R_INFO (indx, R_PPC_RELATIVE); else outrel.r_info = ELF32_R_INFO (indx, R_PPC_GLOB_DAT); - if (indx == 0) + if (indx == 0 && tls_ty != (TLS_TLS | TLS_LD)) { outrel.r_addend += relocation; if (tls_ty & (TLS_GD | TLS_DTPREL | TLS_TPREL)) diff -Naur binutils-2.19.orig/bfd/version.h binutils-2.19/bfd/version.h --- binutils-2.19.orig/bfd/version.h 2008-10-16 05:51:57.000000000 -0700 +++ binutils-2.19/bfd/version.h 2008-12-30 16:00:14.000000000 -0800 @@ -1,4 +1,4 @@ -#define BFD_VERSION_DATE 20081016 +#define BFD_VERSION_DATE 20081231 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ diff -Naur binutils-2.19.orig/binutils/ChangeLog binutils-2.19/binutils/ChangeLog --- binutils-2.19.orig/binutils/ChangeLog 2008-10-02 01:07:16.000000000 -0700 +++ binutils-2.19/binutils/ChangeLog 2008-12-23 03:49:58.000000000 -0800 @@ -1,3 +1,16 @@ +2008-12-23 Nick Clifton + + * windmc.c (main): Use correct type for file length. + * dlltool.c (gen_exp_file): Likewise. + +2008-12-01 Nick Clifton + + PR 7044 + * dlltool.c (run): Use formatting string to avoid compile time + warning. + (gen_exp_file): Check return value from fread. + * windmc.c (main): Check return value from fread. + 2008-09-25 Richard Henderson * dwarf.c (size_of_encoded_value, get_encoded_value): Move up. diff -Naur binutils-2.19.orig/binutils/dlltool.c binutils-2.19/binutils/dlltool.c --- binutils-2.19.orig/binutils/dlltool.c 2008-07-29 21:34:56.000000000 -0700 +++ binutils-2.19/binutils/dlltool.c 2008-12-23 03:49:58.000000000 -0800 @@ -1206,7 +1206,7 @@ if (pid == -1) { - inform (strerror (errno)); + inform ("%s", strerror (errno)); fatal (errmsg_fmt, errmsg_arg); } @@ -1980,7 +1980,7 @@ int addr; long need[PAGE_SIZE]; long page_addr; - int numbytes; + bfd_size_type numbytes; int num_entries; long *copy; int j; @@ -1992,10 +1992,10 @@ numbytes = ftell (base_file); fseek (base_file, 0, SEEK_SET); copy = xmalloc (numbytes); - fread (copy, 1, numbytes, base_file); + if (fread (copy, 1, numbytes, base_file) < numbytes) + fatal (_("failed to read the number of entries from base file")); num_entries = numbytes / sizeof (long); - fprintf (f, "\t.section\t.reloc\n"); if (num_entries) { diff -Naur binutils-2.19.orig/binutils/windmc.c binutils-2.19/binutils/windmc.c --- binutils-2.19.orig/binutils/windmc.c 2008-07-29 21:34:56.000000000 -0700 +++ binutils-2.19/binutils/windmc.c 2008-12-23 03:49:58.000000000 -0800 @@ -1144,7 +1144,7 @@ unichar *u; rc_uint_type ul; char *buff; - long flen; + bfd_size_type flen; FILE *fp = fopen (input_filename, "rb"); if (!fp) @@ -1155,7 +1155,8 @@ fseek (fp, 0, SEEK_SET); buff = malloc (flen + 3); memset (buff, 0, flen + 3); - fread (buff, 1, flen, fp); + if (fread (buff, 1, flen, fp) < flen) + fatal (_("unable to read contents of %s"), input_filename); fclose (fp); if (mcset_text_in_is_unicode != 1) { diff -Naur binutils-2.19.orig/configure.ac binutils-2.19/configure.ac --- binutils-2.19.orig/configure.ac 2008-10-16 06:45:42.000000000 -0700 +++ binutils-2.19/configure.ac 2008-09-03 19:18:16.000000000 -0700 @@ -166,7 +166,7 @@ # binutils, gas and ld appear in that order because it makes sense to run # "make check" in that particular order. # If --enable-gold is used, "gold" will replace "ld". -host_tools="byacc flex bison binutils gas ld fixincludes gcc sid sim gdb make patch prms send-pr gprof etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool diff rcs fileutils shellutils time textutils wdiff find uudecode hello tar gzip indent recode release sed utils guile perl gawk findutils gettext zip fastjar gnattools" +host_tools="texinfo byacc flex bison binutils gas ld fixincludes gcc sid sim gdb make patch prms send-pr gprof etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool diff rcs fileutils shellutils time textutils wdiff find uudecode hello tar gzip indent recode release sed utils guile perl gawk findutils gettext zip fastjar gnattools" # libgcj represents the runtime libraries only used by gcj. libgcj="target-libffi \ diff -Naur binutils-2.19.orig/ld/ChangeLog binutils-2.19/ld/ChangeLog --- binutils-2.19.orig/ld/ChangeLog 2008-10-09 05:18:31.000000000 -0700 +++ binutils-2.19/ld/ChangeLog 2008-12-23 05:56:10.000000000 -0800 @@ -1,3 +1,13 @@ +2008-12-23 Tristan Gingold + + * Makefile.am (EXTRA_DIST): Add deffilep.c and deffilep.h + * Makefile.in: Regenerate. + +2008-11-14 Alan Modra + + * Makefile.am (spu_ovl.o_c): Add missing line continuations. + * Makefile.in: Regenerate. + 2008-10-05 Alan Modra PR 6943 diff -Naur binutils-2.19.orig/ld/Makefile.am binutils-2.19/ld/Makefile.am --- binutils-2.19.orig/ld/Makefile.am 2008-09-09 01:02:19.000000000 -0700 +++ binutils-2.19/ld/Makefile.am 2008-12-23 05:56:10.000000000 -0800 @@ -758,9 +758,9 @@ $(srcdir)/emultempl/spu_ovl.o_c: @MAINT@ $(srcdir)/emultempl/spu_ovl.S if ../gas/as-new --version \ | grep 'target.*spu' >/dev/null 2>/dev/null; then \ - cpp -DOVLY_IRQ_SAVE $(srcdir)/emultempl/spu_ovl.S spu_ovl.s + cpp -DOVLY_IRQ_SAVE $(srcdir)/emultempl/spu_ovl.S spu_ovl.s; \ ../gas/as-new -o spu_ovl.o spu_ovl.s; \ - ../binutils/bin2c $@ + ../binutils/bin2c $@; \ fi eelf32_i860.c: $(srcdir)/emulparams/elf32_i860.sh \ $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} @@ -1914,7 +1914,8 @@ # Stuff that should be included in a distribution. The diststuff # target is run by the taz target in ../Makefile.in. -EXTRA_DIST = ldgram.c ldgram.h ldlex.c emultempl/spu_ovl.o_c $(man_MANS) +EXTRA_DIST = ldgram.c ldgram.h ldlex.c emultempl/spu_ovl.o_c \ + deffilep.c deffilep.h $(man_MANS) diststuff: info $(EXTRA_DIST) all: info ld.1 diff -Naur binutils-2.19.orig/ld/Makefile.in binutils-2.19/ld/Makefile.in --- binutils-2.19.orig/ld/Makefile.in 2008-09-09 01:02:19.000000000 -0700 +++ binutils-2.19/ld/Makefile.in 2008-12-23 05:56:10.000000000 -0800 @@ -730,7 +730,9 @@ # Stuff that should be included in a distribution. The diststuff # target is run by the taz target in ../Makefile.in. -EXTRA_DIST = ldgram.c ldgram.h ldlex.c emultempl/spu_ovl.o_c $(man_MANS) +EXTRA_DIST = ldgram.c ldgram.h ldlex.c emultempl/spu_ovl.o_c \ + deffilep.c deffilep.h $(man_MANS) + DISTCLEANFILES = tdirs site.exp site.bak stringify.sed $(am__append_1) all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -1588,9 +1590,9 @@ $(srcdir)/emultempl/spu_ovl.o_c: @MAINT@ $(srcdir)/emultempl/spu_ovl.S if ../gas/as-new --version \ | grep 'target.*spu' >/dev/null 2>/dev/null; then \ - cpp -DOVLY_IRQ_SAVE $(srcdir)/emultempl/spu_ovl.S spu_ovl.s + cpp -DOVLY_IRQ_SAVE $(srcdir)/emultempl/spu_ovl.S spu_ovl.s; \ ../gas/as-new -o spu_ovl.o spu_ovl.s; \ - ../binutils/bin2c $@ + ../binutils/bin2c $@; \ fi eelf32_i860.c: $(srcdir)/emulparams/elf32_i860.sh \ $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} diff -Naur binutils-2.19.orig/opcodes/ChangeLog binutils-2.19/opcodes/ChangeLog --- binutils-2.19.orig/opcodes/ChangeLog 2008-10-02 01:07:19.000000000 -0700 +++ binutils-2.19/opcodes/ChangeLog 2008-11-27 02:51:53.000000000 -0800 @@ -1,3 +1,20 @@ +2008-11-27 Alan Modra + + * ppc-opc.c (extract_sprg): Correct operand range check. + +2008-11-26 Andreas Schwab + + * m68k-dis.c (NEXTBYTE, NEXTWORD, NEXTLONG, NEXTULONG, NEXTSINGLE) + (NEXTDOUBLE, NEXTEXTEND, NEXTPACKED): Fix error handling. + (save_printer, save_print_address): Remove. + (fetch_data): Don't use them. + (match_insn_m68k): Always restore printing functions. + (print_insn_m68k): Don't save/restore printing functions. + +2008-11-25 Nick Clifton + + * m68k-dis.c: Rewrite to remove use of setjmp/longjmp. + 2008-09-29 Nick Clifton * po/vi.po: Updated Vietnamese translation. diff -Naur binutils-2.19.orig/opcodes/m68k-dis.c binutils-2.19/opcodes/m68k-dis.c --- binutils-2.19.orig/opcodes/m68k-dis.c 2007-09-27 04:14:10.000000000 -0700 +++ binutils-2.19/opcodes/m68k-dis.c 2008-11-26 02:45:27.000000000 -0800 @@ -60,46 +60,103 @@ #endif /* Get a 1 byte signed integer. */ -#define NEXTBYTE(p) (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1])) +#define NEXTBYTE(p, val) \ + do \ + { \ + p += 2; \ + if (!FETCH_DATA (info, p)) \ + return -3; \ + val = COERCE_SIGNED_CHAR (p[-1]); \ + } \ + while (0) /* Get a 2 byte signed integer. */ #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000)) -#define NEXTWORD(p) \ - (p += 2, FETCH_DATA (info, p), \ - COERCE16 ((p[-2] << 8) + p[-1])) + +#define NEXTWORD(p, val, ret_val) \ + do \ + { \ + p += 2; \ + if (!FETCH_DATA (info, p)) \ + return ret_val; \ + val = COERCE16 ((p[-2] << 8) + p[-1]); \ + } \ + while (0) /* Get a 4 byte signed integer. */ #define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000) -#define NEXTLONG(p) \ - (p += 4, FETCH_DATA (info, p), \ - (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]))) + +#define NEXTLONG(p, val, ret_val) \ + do \ + { \ + p += 4; \ + if (!FETCH_DATA (info, p)) \ + return ret_val; \ + val = COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]); \ + } \ + while (0) /* Get a 4 byte unsigned integer. */ -#define NEXTULONG(p) \ - (p += 4, FETCH_DATA (info, p), \ - (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])) +#define NEXTULONG(p, val) \ + do \ + { \ + p += 4; \ + if (!FETCH_DATA (info, p)) \ + return -3; \ + val = (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]); \ + } \ + while (0) /* Get a single precision float. */ -#define NEXTSINGLE(val, p) \ - (p += 4, FETCH_DATA (info, p), \ - floatformat_to_double (&floatformat_ieee_single_big, (char *) p - 4, &val)) +#define NEXTSINGLE(val, p) \ + do \ + { \ + p += 4; \ + if (!FETCH_DATA (info, p)) \ + return -3; \ + floatformat_to_double (& floatformat_ieee_single_big, \ + (char *) p - 4, & val); \ + } \ + while (0) /* Get a double precision float. */ -#define NEXTDOUBLE(val, p) \ - (p += 8, FETCH_DATA (info, p), \ - floatformat_to_double (&floatformat_ieee_double_big, (char *) p - 8, &val)) +#define NEXTDOUBLE(val, p) \ + do \ + { \ + p += 8; \ + if (!FETCH_DATA (info, p)) \ + return -3; \ + floatformat_to_double (& floatformat_ieee_double_big, \ + (char *) p - 8, & val); \ + } \ + while (0) /* Get an extended precision float. */ -#define NEXTEXTEND(val, p) \ - (p += 12, FETCH_DATA (info, p), \ - floatformat_to_double (&floatformat_m68881_ext, (char *) p - 12, &val)) +#define NEXTEXTEND(val, p) \ + do \ + { \ + p += 12; \ + if (!FETCH_DATA (info, p)) \ + return -3; \ + floatformat_to_double (& floatformat_m68881_ext, \ + (char *) p - 12, & val); \ + } \ + while (0) /* Need a function to convert from packed to double precision. Actually, it's easier to print a packed number than a double anyway, so maybe there should be a special case to handle this... */ -#define NEXTPACKED(p) \ - (p += 12, FETCH_DATA (info, p), 0.0) +#define NEXTPACKED(p, val) \ + do \ + { \ + p += 12; \ + if (!FETCH_DATA (info, p)) \ + return -3; \ + val = 0.0; \ + } \ + while (0) + /* Maximum length of an instruction. */ #define MAXLEN 22 @@ -112,12 +169,10 @@ bfd_byte *max_fetched; bfd_byte the_buffer[MAXLEN]; bfd_vma insn_start; - jmp_buf bailout; }; /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) - to ADDR (exclusive) are valid. Returns 1 for success, longjmps - on error. */ + to ADDR (exclusive) are valid. Returns 1 for success, 0 on error. */ #define FETCH_DATA(info, addr) \ ((addr) <= ((struct private *) (info->private_data))->max_fetched \ ? 1 : fetch_data ((info), (addr))) @@ -136,7 +191,7 @@ if (status != 0) { (*info->memory_error_func) (status, start, info); - longjmp (priv->bailout, 1); + return 0; } else priv->max_fetched = addr; @@ -161,7 +216,8 @@ /* Fetch BITS bits from a position in the instruction specified by CODE. CODE is a "place to put an argument", or 'x' for a destination that is a general address (mode and register). - BUFFER contains the instruction. */ + BUFFER contains the instruction. + Returns -1 on failure. */ static int fetch_arg (unsigned char *buffer, @@ -216,64 +272,75 @@ break; case 'k': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[3] >> 4); break; case 'C': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = buffer[3]; break; case '1': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; val >>= 12; break; case '2': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; val >>= 6; break; case '3': case 'j': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; break; case '4': - FETCH_DATA (info, buffer + 5); + if (! FETCH_DATA (info, buffer + 5)) + return -1; val = (buffer[4] << 8) + buffer[5]; val >>= 12; break; case '5': - FETCH_DATA (info, buffer + 5); + if (! FETCH_DATA (info, buffer + 5)) + return -1; val = (buffer[4] << 8) + buffer[5]; val >>= 6; break; case '6': - FETCH_DATA (info, buffer + 5); + if (! FETCH_DATA (info, buffer + 5)) + return -1; val = (buffer[4] << 8) + buffer[5]; break; case '7': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; val >>= 7; break; case '8': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; val >>= 10; break; case '9': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; val >>= 5; break; @@ -283,7 +350,8 @@ break; case 'E': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] >> 1); break; @@ -450,7 +518,8 @@ /* Print an indexed argument. The base register is BASEREG (-1 for pc). P points to extension word, in buffer. - ADDR is the nominal core address of that extension word. */ + ADDR is the nominal core address of that extension word. + Returns NULL upon error. */ static unsigned char * print_indexed (int basereg, @@ -465,7 +534,7 @@ char buf[40]; char vmabuf[50]; - word = NEXTWORD (p); + NEXTWORD (p, word, NULL); /* Generate the text for the index register. Where this will be output is not yet determined. */ @@ -503,10 +572,10 @@ switch ((word >> 4) & 3) { case 2: - base_disp = NEXTWORD (p); + NEXTWORD (p, base_disp, NULL); break; case 3: - base_disp = NEXTLONG (p); + NEXTLONG (p, base_disp, NULL); } if (basereg == -1) base_disp += addr; @@ -526,10 +595,10 @@ switch (word & 3) { case 2: - outer_disp = NEXTWORD (p); + NEXTWORD (p, outer_disp, NULL); break; case 3: - outer_disp = NEXTLONG (p); + NEXTLONG (p, outer_disp, NULL); } print_base (basereg, base_disp, info); @@ -547,9 +616,18 @@ return p; } +#define FETCH_ARG(size, val) \ + do \ + { \ + val = fetch_arg (buffer, place, size, info); \ + if (val < 0) \ + return -3; \ + } \ + while (0) + /* Returns number of bytes "eaten" by the operand, or return -1 if an invalid operand was found, or -2 if - an opcode tabe error was found. + an opcode tabe error was found or -3 to simply abort. ADDR is the pc for this arg to be relative to. */ static int @@ -575,23 +653,21 @@ case 'c': /* Cache identifier. */ { static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" }; - val = fetch_arg (buffer, place, 2, info); - (*info->fprintf_func) (info->stream, cacheFieldName[val]); + FETCH_ARG (2, val); + (*info->fprintf_func) (info->stream, cacheFieldName[val]); break; } case 'a': /* Address register indirect only. Cf. case '+'. */ { - (*info->fprintf_func) - (info->stream, - "%s@", - reg_names[fetch_arg (buffer, place, 3, info) + 8]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s@", reg_names[val + 8]); break; } case '_': /* 32-bit absolute address for move16. */ { - uval = NEXTULONG (p); + NEXTULONG (p, uval); (*info->print_address_func) (uval, info); break; } @@ -643,7 +719,7 @@ /* Fido added these. */ {"%cac", 0xffe}, {"%mbo", 0xfff}}; - val = fetch_arg (buffer, place, 12, info); + FETCH_ARG (12, val); for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--) if (names[regno].value == val) { @@ -656,7 +732,7 @@ break; case 'Q': - val = fetch_arg (buffer, place, 3, info); + FETCH_ARG (3, val); /* 0 means 8, except for the bkpt instruction... */ if (val == 0 && d[1] != 's') val = 8; @@ -664,7 +740,7 @@ break; case 'x': - val = fetch_arg (buffer, place, 3, info); + FETCH_ARG (3, val); /* 0 means -1. */ if (val == 0) val = -1; @@ -672,12 +748,12 @@ break; case 'j': - val = fetch_arg (buffer, place, 3, info); + FETCH_ARG (3, val); (*info->fprintf_func) (info->stream, "#%d", val+1); break; case 'K': - val = fetch_arg (buffer, place, 9, info); + FETCH_ARG (9, val); (*info->fprintf_func) (info->stream, "#%d", val); break; @@ -685,12 +761,13 @@ if (place == 'h') { static char *const scalefactor_name[] = { "<<", ">>" }; - val = fetch_arg (buffer, place, 1, info); + + FETCH_ARG (1, val); (*info->fprintf_func) (info->stream, scalefactor_name[val]); } else { - val = fetch_arg (buffer, place, 8, info); + FETCH_ARG (8, val); if (val & 0x80) val = val - 0x100; (*info->fprintf_func) (info->stream, "#%d", val); @@ -698,29 +775,27 @@ break; case 'T': - val = fetch_arg (buffer, place, 4, info); + FETCH_ARG (4, val); (*info->fprintf_func) (info->stream, "#%d", val); break; case 'D': - (*info->fprintf_func) (info->stream, "%s", - reg_names[fetch_arg (buffer, place, 3, info)]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s", reg_names[val]); break; case 'A': - (*info->fprintf_func) - (info->stream, "%s", - reg_names[fetch_arg (buffer, place, 3, info) + 010]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s", reg_names[val + 010]); break; case 'R': - (*info->fprintf_func) - (info->stream, "%s", - reg_names[fetch_arg (buffer, place, 4, info)]); + FETCH_ARG (4, val); + (*info->fprintf_func) (info->stream, "%s", reg_names[val]); break; case 'r': - regno = fetch_arg (buffer, place, 4, info); + FETCH_ARG (4, regno); if (regno > 7) (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]); else @@ -728,13 +803,12 @@ break; case 'F': - (*info->fprintf_func) - (info->stream, "%%fp%d", - fetch_arg (buffer, place, 3, info)); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%%fp%d", val); break; case 'O': - val = fetch_arg (buffer, place, 6, info); + FETCH_ARG (6, val); if (val & 0x20) (*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]); else @@ -742,78 +816,78 @@ break; case '+': - (*info->fprintf_func) - (info->stream, "%s@+", - reg_names[fetch_arg (buffer, place, 3, info) + 8]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s@+", reg_names[val + 8]); break; case '-': - (*info->fprintf_func) - (info->stream, "%s@-", - reg_names[fetch_arg (buffer, place, 3, info) + 8]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s@-", reg_names[val + 8]); break; case 'k': if (place == 'k') - (*info->fprintf_func) - (info->stream, "{%s}", - reg_names[fetch_arg (buffer, place, 3, info)]); + { + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "{%s}", reg_names[val]); + } else if (place == 'C') { - val = fetch_arg (buffer, place, 7, info); + FETCH_ARG (7, val); if (val > 63) /* This is a signed constant. */ val -= 128; (*info->fprintf_func) (info->stream, "{#%d}", val); } else - return -2; + return -1; break; case '#': case '^': p1 = buffer + (*d == '#' ? 2 : 4); if (place == 's') - val = fetch_arg (buffer, place, 4, info); + FETCH_ARG (4, val); else if (place == 'C') - val = fetch_arg (buffer, place, 7, info); + FETCH_ARG (7, val); else if (place == '8') - val = fetch_arg (buffer, place, 3, info); + FETCH_ARG (3, val); else if (place == '3') - val = fetch_arg (buffer, place, 8, info); + FETCH_ARG (8, val); else if (place == 'b') - val = NEXTBYTE (p1); + NEXTBYTE (p1, val); else if (place == 'w' || place == 'W') - val = NEXTWORD (p1); + NEXTWORD (p1, val, -3); else if (place == 'l') - val = NEXTLONG (p1); + NEXTLONG (p1, val, -3); else return -2; + (*info->fprintf_func) (info->stream, "#%d", val); break; case 'B': if (place == 'b') - disp = NEXTBYTE (p); + NEXTBYTE (p, disp); else if (place == 'B') disp = COERCE_SIGNED_CHAR (buffer[1]); else if (place == 'w' || place == 'W') - disp = NEXTWORD (p); + NEXTWORD (p, disp, -3); else if (place == 'l' || place == 'L' || place == 'C') - disp = NEXTLONG (p); + NEXTLONG (p, disp, -3); else if (place == 'g') { - disp = NEXTBYTE (buffer); + NEXTBYTE (buffer, disp); if (disp == 0) - disp = NEXTWORD (p); + NEXTWORD (p, disp, -3); else if (disp == -1) - disp = NEXTLONG (p); + NEXTLONG (p, disp, -3); } else if (place == 'c') { if (buffer[1] & 0x40) /* If bit six is one, long offset. */ - disp = NEXTLONG (p); + NEXTLONG (p, disp, -3); else - disp = NEXTWORD (p); + NEXTWORD (p, disp, -3); } else return -2; @@ -822,29 +896,32 @@ break; case 'd': - val = NEXTWORD (p); - (*info->fprintf_func) - (info->stream, "%s@(%d)", - reg_names[fetch_arg (buffer, place, 3, info) + 8], val); - break; + { + int val1; + + NEXTWORD (p, val, -3); + FETCH_ARG (3, val1); + (*info->fprintf_func) (info->stream, "%s@(%d)", reg_names[val1 + 8], val); + break; + } case 's': - (*info->fprintf_func) (info->stream, "%s", - fpcr_names[fetch_arg (buffer, place, 3, info)]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]); break; case 'e': - val = fetch_arg(buffer, place, 2, info); + FETCH_ARG (2, val); (*info->fprintf_func) (info->stream, "%%acc%d", val); break; case 'g': - val = fetch_arg(buffer, place, 1, info); - (*info->fprintf_func) (info->stream, "%%accext%s", val==0 ? "01" : "23"); + FETCH_ARG (1, val); + (*info->fprintf_func) (info->stream, "%%accext%s", val == 0 ? "01" : "23"); break; case 'i': - val = fetch_arg(buffer, place, 2, info); + FETCH_ARG (2, val); if (val == 1) (*info->fprintf_func) (info->stream, "<<"); else if (val == 3) @@ -856,7 +933,8 @@ case 'I': /* Get coprocessor ID... */ val = fetch_arg (buffer, 'd', 3, info); - + if (val < 0) + return -3; if (val != 1) /* Unusual coprocessor ID? */ (*info->fprintf_func) (info->stream, "(cpid=%d) ", val); break; @@ -888,10 +966,16 @@ if (place == 'd') { val = fetch_arg (buffer, 'x', 6, info); + if (val < 0) + return -3; val = ((val & 7) << 3) + ((val >> 3) & 7); } else - val = fetch_arg (buffer, 's', 6, info); + { + val = fetch_arg (buffer, 's', 6, info); + if (val < 0) + return -3; + } /* If the is invalid for *d, then reject this match. */ if (!m68k_valid_ea (*d, val)) @@ -923,29 +1007,31 @@ break; case 5: - val = NEXTWORD (p); + NEXTWORD (p, val, -3); (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val); break; case 6: p = print_indexed (regno, p, addr, info); + if (p == NULL) + return -3; break; case 7: switch (val & 7) { case 0: - val = NEXTWORD (p); + NEXTWORD (p, val, -3); (*info->print_address_func) (val, info); break; case 1: - uval = NEXTULONG (p); + NEXTULONG (p, uval); (*info->print_address_func) (uval, info); break; case 2: - val = NEXTWORD (p); + NEXTWORD (p, val, -3); (*info->fprintf_func) (info->stream, "%%pc@("); (*info->print_address_func) (addr + val, info); (*info->fprintf_func) (info->stream, ")"); @@ -953,6 +1039,8 @@ case 3: p = print_indexed (-1, p, addr, info); + if (p == NULL) + return -3; break; case 4: @@ -960,17 +1048,17 @@ switch (place) { case 'b': - val = NEXTBYTE (p); + NEXTBYTE (p, val); flt_p = 0; break; case 'w': - val = NEXTWORD (p); + NEXTWORD (p, val, -3); flt_p = 0; break; case 'l': - val = NEXTLONG (p); + NEXTLONG (p, val, -3); flt_p = 0; break; @@ -987,7 +1075,7 @@ break; case 'p': - flval = NEXTPACKED (p); + NEXTPACKED (p, flval); break; default: @@ -1009,7 +1097,7 @@ mask bit and if set, add a '&' to the arg. */ if (place == '/') { - val = fetch_arg (buffer, place, 1, info); + FETCH_ARG (1, val); if (val) info->fprintf_func (info->stream, "&"); } @@ -1021,7 +1109,7 @@ { char doneany; p1 = buffer + 2; - val = NEXTWORD (p1); + NEXTWORD (p1, val, -3); /* Move the pointer ahead if this point is farther ahead than the last. */ p = p1 > p ? p1 : p; @@ -1062,7 +1150,8 @@ { /* `fmovem' insn. */ char doneany; - val = fetch_arg (buffer, place, 8, info); + + FETCH_ARG (8, val); if (val == 0) { (*info->fprintf_func) (info->stream, "#0"); @@ -1096,10 +1185,9 @@ } else if (place == '8') { + FETCH_ARG (3, val); /* fmoveml for FP status registers. */ - (*info->fprintf_func) (info->stream, "%s", - fpcr_names[fetch_arg (buffer, place, 3, - info)]); + (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]); } else return -2; @@ -1115,9 +1203,10 @@ case '2': case '3': { - int val = fetch_arg (buffer, place, 5, info); + int val; char *name = 0; + FETCH_ARG (5, val); switch (val) { case 2: name = "%tt0"; break; @@ -1152,8 +1241,9 @@ case 'f': { - int fc = fetch_arg (buffer, place, 5, info); + int fc; + FETCH_ARG (5, fc); if (fc == 1) (*info->fprintf_func) (info->stream, "%%dfc"); else if (fc == 0) @@ -1170,8 +1260,9 @@ case 't': { - int level = fetch_arg (buffer, place, 3, info); + int level; + FETCH_ARG (3, level); (*info->fprintf_func) (info->stream, "%d", level); } break; @@ -1179,8 +1270,9 @@ case 'u': { short is_upper = 0; - int reg = fetch_arg (buffer, place, 5, info); + int reg; + FETCH_ARG (5, reg); if (reg & 0x10) { is_upper = 1; @@ -1303,7 +1395,7 @@ if (eaten >= 0) p += eaten; - else if (eaten == -1) + else if (eaten == -1 || eaten == -3) { info->fprintf_func = save_printer; info->print_address_func = save_print_address; @@ -1318,7 +1410,7 @@ info->fprintf_func (info->stream, /* xgettext:c-format */ _("\n"), - best->name, best->args); + best->name, best->args); return 2; } } @@ -1439,6 +1531,8 @@ if (d[0] == 's' && d[1] == '8') { val = fetch_arg (buffer, d[1], 3, info); + if (val < 0) + return 0; if ((val & (val - 1)) != 0) break; } @@ -1479,13 +1573,7 @@ bfd_byte *buffer = priv.the_buffer; - /* Save these printing functions in case we need to restore them - later. */ - fprintf_ftype save_printer = info->fprintf_func; - void (* save_print_address) (bfd_vma, struct disassemble_info *) - = info->print_address_func; - - info->private_data = (PTR) &priv; + info->private_data = & priv; /* Tell objdump to use two bytes per chunk and six bytes per line for displaying raw data. */ info->bytes_per_chunk = 2; @@ -1494,49 +1582,23 @@ priv.max_fetched = priv.the_buffer; priv.insn_start = memaddr; - if (setjmp (priv.bailout) != 0) - { - /* longjmp may be called while these printing functions are - temporarily replaced with dummy functions. Restore them - before we leave. - - Admittedly, this save-and-restore operation is somewhat ugly - in that we are exposing the fact that match_insn_m68k - temporarily replaces insn->fprintf_func and - insn->print_address_func. Perhaps, a real fix is to report a - FETCH_DATA failure with a return value of some sort, without - using setjmp/longjmp. A better fix may be to teach the m68k - disassembler do its job without temporarily replacing - insn->fprintf_func and insn->print_address_func, but that's a - task for another day. */ - info->fprintf_func = save_printer; - info->print_address_func = save_print_address; - - /* Error return. */ - return -1; - } - arch_mask = bfd_m68k_mach_to_features (info->mach); if (!arch_mask) { /* First try printing an m680x0 instruction. Try printing a Coldfire one if that fails. */ val = m68k_scan_mask (memaddr, info, m68k_mask); - if (val) - return val; - - val = m68k_scan_mask (memaddr, info, mcf_mask); - if (val) - return val; + if (val == 0) + val = m68k_scan_mask (memaddr, info, mcf_mask); } else { val = m68k_scan_mask (memaddr, info, arch_mask); - if (val) - return val; } - /* Handle undefined instructions. */ - info->fprintf_func (info->stream, "0%o", (buffer[0] << 8) + buffer[1]); - return 2; + if (val == 0) + /* Handle undefined instructions. */ + info->fprintf_func (info->stream, "0%o", (buffer[0] << 8) + buffer[1]); + + return val ? val : 2; } diff -Naur binutils-2.19.orig/opcodes/ppc-opc.c binutils-2.19/opcodes/ppc-opc.c --- binutils-2.19.orig/opcodes/ppc-opc.c 2008-08-14 06:56:00.000000000 -0700 +++ binutils-2.19/opcodes/ppc-opc.c 2008-11-27 02:51:53.000000000 -0800 @@ -1281,10 +1281,10 @@ /* mfsprg can use 260..263 and 272..279. mtsprg only uses spr 272..279 If not BOOKE or 405, then both use only 272..275. */ - if (val <= 3 - || (val < 0x10 && (insn & 0x100) != 0) - || (val - 0x10 > 3 - && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0)) + if ((val - 0x10 > 3 && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_405)) == 0) + || (val - 0x10 > 7 && (insn & 0x100) != 0) + || val <= 3 + || (val & 8) != 0) *invalid = 1; return val & 7; }