diff -u crash-7.0.3/debian/changelog crash-7.0.3/debian/changelog --- crash-7.0.3/debian/changelog +++ crash-7.0.3/debian/changelog @@ -1,3 +1,11 @@ +crash (7.0.3-3ubuntu2.1+lp1318809.c3) UNRELEASED; urgency=medium + + * Non-maintainer upload. + * Add ppc64el support (debian/control, debian/rules (for patches), gdb-7.6-ppc64el.patch); + patch-set provided by Bharata Rao. + + -- Mauricio Faria de Oliveira Fri, 16 May 2014 08:52:26 -0300 + crash (7.0.3-3ubuntu2) trusty; urgency=low * debian/tests/live: Previous merge dropped the "allow-stderr" restriction. diff -u crash-7.0.3/debian/control crash-7.0.3/debian/control --- crash-7.0.3/debian/control +++ crash-7.0.3/debian/control @@ -9,7 +9,7 @@ XS-Testsuite: autopkgtest Package: crash -Architecture: i386 ia64 alpha powerpc amd64 armel armhf arm64 s390x +Architecture: i386 ia64 alpha powerpc ppc64el amd64 armel armhf arm64 s390x Depends: ${shlibs:Depends}, ${misc:Depends}, binutils Suggests: kexec-tools, makedumpfile Description: kernel debugging utility, allowing gdb like syntax diff -u crash-7.0.3/debian/rules crash-7.0.3/debian/rules --- crash-7.0.3/debian/rules +++ crash-7.0.3/debian/rules @@ -8,10 +8,16 @@ DPKG_EXPORT_BUILDFLAGS=1 include /usr/share/dpkg/buildflags.mk +DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH) + %: dh $@ --with quilt override_dh_auto_build: +ifeq ($(DEB_HOST_ARCH),ppc64el) + cp gdb-7.6.patch gdb-7.6.patch.orig + cat gdb-7.6-ppc64el.patch >> gdb-7.6.patch +endif dh_auto_build $(MAKE) extensions @@ -21,6 +27,11 @@ override_dh_clean: dh_clean +ifeq ($(DEB_HOST_ARCH),ppc64el) + if [ -f gdb-7.6.patch.orig ]; then \ + mv gdb-7.6.patch.orig gdb-7.6.patch; \ + fi +endif cp $(CURDIR)/debian/Makefile.ori $(CURDIR)/Makefile rm -Rf $(CURDIR)/configure rm -Rf $(CURDIR)/gdb-7.6 --- crash-7.0.3.orig/gdb-7.6-ppc64el.patch +++ crash-7.0.3/gdb-7.6-ppc64el.patch @@ -0,0 +1,4654 @@ +--- gdb-7.6/gdb/ChangeLog ++++ gdb-7.6/gdb/ChangeLog +@@ -148,6 +148,11 @@ + * dwarf2read.c (free_dwo_file): Add comment. + (dwarf2_per_objfile_free): Unref dwp bfd. + ++2013-03-31 Tiago Stürmer Daitx ++ ++ * ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function. ++ (ppc64_sysv_abi_push_dummy_call): Handle complex arguments. ++ + 2013-03-29 Doug Evans + + * dwarf2read.c (open_and_init_dwp_file): Remove incorrect, and +--- gdb-7.6/gdb/ppc-sysv-tdep.c ++++ gdb-7.6/gdb/ppc-sysv-tdep.c +@@ -1101,6 +1101,83 @@ convert_code_addr_to_desc_addr (CORE_ADD + return 1; + } + ++/* Push a float in either registers, or in the stack. Using the ppc 64 bit ++ SysV ABI. ++ ++ This implements a dumbed down version of the ABI. It always writes ++ values to memory, GPR and FPR, even when not necessary. Doing this ++ greatly simplifies the logic. */ ++ ++static void ++ppc64_sysv_abi_push_float (struct gdbarch *gdbarch, struct regcache *regcache, ++ struct gdbarch_tdep *tdep, struct type *type, ++ const bfd_byte *val, int freg, int greg, ++ CORE_ADDR gparam) ++{ ++ gdb_byte regval[MAX_REGISTER_SIZE]; ++ const gdb_byte *p; ++ ++ if (TYPE_LENGTH (type) <= 8) ++ { ++ /* Version 1.7 of the 64-bit PowerPC ELF ABI says: ++ ++ "Single precision floating point values are mapped to ++ the first word in a single doubleword." ++ ++ And version 1.9 says: ++ ++ "Single precision floating point values are mapped to ++ the second word in a single doubleword." ++ ++ GDB then writes single precision floating point values ++ at both words in a doubleword, to support both ABIs. */ ++ if (TYPE_LENGTH (type) == 4) ++ { ++ memcpy (regval, val, 4); ++ memcpy (regval + 4, val, 4); ++ p = regval; ++ } ++ else ++ p = val; ++ ++ /* Write value in the stack's parameter save area. */ ++ write_memory (gparam, p, 8); ++ ++ /* Floats and Doubles go in f1 .. f13. They also consume a left aligned ++ GREG, and can end up in memory. */ ++ if (freg <= 13) ++ { ++ struct type *regtype; ++ ++ regtype = register_type (gdbarch, tdep->ppc_fp0_regnum + freg); ++ convert_typed_floating (val, type, regval, regtype); ++ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval); ++ } ++ if (greg <= 10) ++ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval); ++ } ++ else ++ { ++ /* IBM long double stored in two doublewords of the ++ parameter save area and corresponding registers. */ ++ if (!tdep->soft_float && freg <= 13) ++ { ++ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, val); ++ if (freg <= 12) ++ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg + 1, ++ val + 8); ++ } ++ if (greg <= 10) ++ { ++ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, val); ++ if (greg <= 9) ++ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg + 1, ++ val + 8); ++ } ++ write_memory (gparam, val, TYPE_LENGTH (type)); ++ } ++} ++ + /* Pass the arguments in either registers, or in the stack. Using the + ppc 64 bit SysV ABI. + +@@ -1218,53 +1295,9 @@ ppc64_sysv_abi_push_dummy_call (struct g + + if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8) + { +- /* Floats and Doubles go in f1 .. f13. They also +- consume a left aligned GREG,, and can end up in +- memory. */ + if (write_pass) +- { +- gdb_byte regval[MAX_REGISTER_SIZE]; +- const gdb_byte *p; +- +- /* Version 1.7 of the 64-bit PowerPC ELF ABI says: +- +- "Single precision floating point values are mapped to +- the first word in a single doubleword." +- +- And version 1.9 says: +- +- "Single precision floating point values are mapped to +- the second word in a single doubleword." +- +- GDB then writes single precision floating point values +- at both words in a doubleword, to support both ABIs. */ +- if (TYPE_LENGTH (type) == 4) +- { +- memcpy (regval, val, 4); +- memcpy (regval + 4, val, 4); +- p = regval; +- } +- else +- p = val; +- +- /* Write value in the stack's parameter save area. */ +- write_memory (gparam, p, 8); +- +- if (freg <= 13) +- { +- struct type *regtype +- = register_type (gdbarch, tdep->ppc_fp0_regnum); +- +- convert_typed_floating (val, type, regval, regtype); +- regcache_cooked_write (regcache, +- tdep->ppc_fp0_regnum + freg, +- regval); +- } +- if (greg <= 10) +- regcache_cooked_write (regcache, +- tdep->ppc_gp0_regnum + greg, +- regval); +- } ++ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type, ++ val, freg, greg, gparam); + + freg++; + greg++; +@@ -1276,35 +1309,58 @@ ppc64_sysv_abi_push_dummy_call (struct g + && (gdbarch_long_double_format (gdbarch) + == floatformats_ibm_long_double)) + { +- /* IBM long double stored in two doublewords of the +- parameter save area and corresponding registers. */ + if (write_pass) ++ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type, ++ val, freg, greg, gparam); ++ freg += 2; ++ greg += 2; ++ gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); ++ } ++ else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX ++ && (TYPE_LENGTH (type) == 8 || TYPE_LENGTH (type) == 16)) ++ { ++ int i; ++ ++ for (i = 0; i < 2; i++) + { +- if (!tdep->soft_float && freg <= 13) +- { +- regcache_cooked_write (regcache, +- tdep->ppc_fp0_regnum + freg, +- val); +- if (freg <= 12) +- regcache_cooked_write (regcache, +- tdep->ppc_fp0_regnum + freg + 1, +- val + 8); +- } +- if (greg <= 10) ++ if (write_pass) + { +- regcache_cooked_write (regcache, +- tdep->ppc_gp0_regnum + greg, +- val); +- if (greg <= 9) +- regcache_cooked_write (regcache, +- tdep->ppc_gp0_regnum + greg + 1, +- val + 8); ++ struct type *target_type; ++ ++ target_type = check_typedef (TYPE_TARGET_TYPE (type)); ++ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, ++ target_type, val + i * ++ TYPE_LENGTH (target_type), ++ freg, greg, gparam); + } +- write_memory (gparam, val, TYPE_LENGTH (type)); ++ freg++; ++ greg++; ++ /* Always consume parameter stack space. */ ++ gparam = align_up (gparam + 8, tdep->wordsize); ++ } ++ } ++ else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX ++ && TYPE_LENGTH (type) == 32 ++ && (gdbarch_long_double_format (gdbarch) ++ == floatformats_ibm_long_double)) ++ { ++ int i; ++ ++ for (i = 0; i < 2; i++) ++ { ++ struct type *target_type; ++ ++ target_type = check_typedef (TYPE_TARGET_TYPE (type)); ++ if (write_pass) ++ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, ++ target_type, val + i * ++ TYPE_LENGTH (target_type), ++ freg, greg, gparam); ++ freg += 2; ++ greg += 2; ++ gparam = align_up (gparam + TYPE_LENGTH (target_type), ++ tdep->wordsize); + } +- freg += 2; +- greg += 2; +- gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); + } + else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT + && TYPE_LENGTH (type) <= 8) +--- gdb-7.6/gdb/ChangeLog ++++ gdb-7.6/gdb/ChangeLog +@@ -59,6 +59,30 @@ + + * NEWS: Mention new btrace RSP packets. + ++2013-04-08 Tom Tromey ++ ++ * minsyms.h (struct bound_minimal_symbol): New. ++ (lookup_minimal_symbol_and_objfile): Return bound_minimal_symbol. ++ Remove objfile argument. ++ (lookup_minimal_symbol_by_pc_section, lookup_minimal_symbol_by_pc): ++ Return bound_minimal_symbol. ++ * minsyms.c (lookup_minimal_symbol_by_pc_1) ++ (lookup_minimal_symbol_by_pc_section, lookup_minimal_symbol_by_pc): ++ Return bound_minimal_symbol. ++ (in_gnu_ifunc_stub): Update. ++ (lookup_minimal_symbol_and_objfile): Return bound_minimal_symbol. ++ Remove 'objfile_p' argument. ++ (lookup_solib_trampoline_symbol_by_pc): Update. ++ * ada-tasks.c, amd64-windows-tdep.c, arm-tdep.c, ++ arm-wince-tdep.c, block.c, blockframe.c, breakpoint.c, btrace.c, ++ c-valprint.c, dwarf2loc.c, elfread.c, frame.c, frv-tdep.c, ++ glibc-tdep.c, gnu-v2-abi.c, gnu-v3-abi.c, hppa-hpux-tdep.c, ++ i386-tdep.c, ia64-tdep.c, infcall.c, infcmd.c, jit.c, ++ linux-fork.c, m32c-tdep.c, m68hc11-tdep.c, maint.c, ++ mips-tdep.c, p-valprint.c, parse.c, ppc-linux-tdep.c, ++ ppc-sysv-tdep.c, printcmd.c, rs6000-tdep.c, sh64-tdep.c, ++ stack.c, symtab.c, tui/tui-disasm.c: Update. ++ + 2013-04-06 Eli Zaretskii + + * mingw-hdep.c (windows_get_absolute_argv0): New function. +--- gdb-7.6/gdb/ada-tasks.c ++++ gdb-7.6/gdb/ada-tasks.c +@@ -635,12 +635,12 @@ read_atcb (CORE_ADDR task_id, struct ada + sizeof (task_info->name) - 1); + else + { +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + + msym = lookup_minimal_symbol_by_pc (task_id); +- if (msym) ++ if (msym.minsym) + { +- const char *full_name = SYMBOL_LINKAGE_NAME (msym); ++ const char *full_name = SYMBOL_LINKAGE_NAME (msym.minsym); + const char *task_name = full_name; + const char *p; + +--- gdb-7.6/gdb/amd64-windows-tdep.c ++++ gdb-7.6/gdb/amd64-windows-tdep.c +@@ -140,14 +140,14 @@ amd64_skip_main_prologue (struct gdbarch + + if (target_read_memory (pc + 1, buf, sizeof buf) == 0) + { +- struct minimal_symbol *s; ++ struct bound_minimal_symbol s; + CORE_ADDR call_dest; + + call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order); + s = lookup_minimal_symbol_by_pc (call_dest); +- if (s != NULL +- && SYMBOL_LINKAGE_NAME (s) != NULL +- && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0) ++ if (s.minsym != NULL ++ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL ++ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0) + pc += 5; + } + } +@@ -175,7 +175,9 @@ amd64_windows_skip_trampoline_code (stru + CORE_ADDR indirect_addr = pc + offset + 6; + + struct minimal_symbol *indsym +- = indirect_addr ? lookup_minimal_symbol_by_pc (indirect_addr) : NULL; ++ = (indirect_addr ++ ? lookup_minimal_symbol_by_pc (indirect_addr).minsym ++ : NULL); + const char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : NULL; + + if (symname) +--- gdb-7.6/gdb/arm-tdep.c ++++ gdb-7.6/gdb/arm-tdep.c +@@ -381,7 +381,7 @@ arm_find_mapping_symbol (CORE_ADDR memad + int + arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr) + { +- struct minimal_symbol *sym; ++ struct bound_minimal_symbol sym; + char type; + struct displaced_step_closure* dsc + = get_displaced_step_closure_by_addr(memaddr); +@@ -423,8 +423,8 @@ arm_pc_is_thumb (struct gdbarch *gdbarch + + /* Thumb functions have a "special" bit set in minimal symbols. */ + sym = lookup_minimal_symbol_by_pc (memaddr); +- if (sym) +- return (MSYMBOL_IS_SPECIAL (sym)); ++ if (sym.minsym) ++ return (MSYMBOL_IS_SPECIAL (sym.minsym)); + + /* If the user wants to override the fallback mode, let them. */ + if (strcmp (arm_fallback_mode_string, "arm") == 0) +@@ -468,14 +468,14 @@ static int + skip_prologue_function (struct gdbarch *gdbarch, CORE_ADDR pc, int is_thumb) + { + enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + + msym = lookup_minimal_symbol_by_pc (pc); +- if (msym != NULL +- && SYMBOL_VALUE_ADDRESS (msym) == pc +- && SYMBOL_LINKAGE_NAME (msym) != NULL) ++ if (msym.minsym != NULL ++ && SYMBOL_VALUE_ADDRESS (msym.minsym) == pc ++ && SYMBOL_LINKAGE_NAME (msym.minsym) != NULL) + { +- const char *name = SYMBOL_LINKAGE_NAME (msym); ++ const char *name = SYMBOL_LINKAGE_NAME (msym.minsym); + + /* The GNU linker's Thumb call stub to foo is named + __foo_from_thumb. */ +@@ -1284,7 +1284,7 @@ arm_skip_stack_protector(CORE_ADDR pc, s + { + enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); + unsigned int basereg; +- struct minimal_symbol *stack_chk_guard; ++ struct bound_minimal_symbol stack_chk_guard; + int offset; + int is_thumb = arm_pc_is_thumb (gdbarch, pc); + CORE_ADDR addr; +@@ -1299,8 +1299,9 @@ arm_skip_stack_protector(CORE_ADDR pc, s + /* If name of symbol doesn't start with '__stack_chk_guard', this + instruction sequence is not for stack protector. If symbol is + removed, we conservatively think this sequence is for stack protector. */ +- if (stack_chk_guard +- && strncmp (SYMBOL_LINKAGE_NAME (stack_chk_guard), "__stack_chk_guard", ++ if (stack_chk_guard.minsym ++ && strncmp (SYMBOL_LINKAGE_NAME (stack_chk_guard.minsym), ++ "__stack_chk_guard", + strlen ("__stack_chk_guard")) != 0) + return pc; + +--- gdb-7.6/gdb/arm-wince-tdep.c ++++ gdb-7.6/gdb/arm-wince-tdep.c +@@ -43,7 +43,7 @@ arm_pe_skip_trampoline_code (struct fram + struct gdbarch *gdbarch = get_frame_arch (frame); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + ULONGEST indirect; +- struct minimal_symbol *indsym; ++ struct bound_minimal_symbol indsym; + const char *symname; + CORE_ADDR next_pc; + +@@ -62,10 +62,10 @@ arm_pe_skip_trampoline_code (struct fram + return 0; + + indsym = lookup_minimal_symbol_by_pc (indirect); +- if (indsym == NULL) ++ if (indsym.minsym == NULL) + return 0; + +- symname = SYMBOL_LINKAGE_NAME (indsym); ++ symname = SYMBOL_LINKAGE_NAME (indsym.minsym); + if (symname == NULL || strncmp (symname, "__imp_", 6) != 0) + return 0; + +@@ -100,11 +100,11 @@ arm_wince_skip_main_prologue (struct gdb + + long offset = sign_extend (this_instr & 0x000fffff, 23) << 2; + CORE_ADDR call_dest = (pc + 8 + offset) & 0xffffffffU; +- struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest); ++ struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); + +- if (s != NULL +- && SYMBOL_LINKAGE_NAME (s) != NULL +- && strcmp (SYMBOL_LINKAGE_NAME (s), "__gccmain") == 0) ++ if (s.minsym != NULL ++ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL ++ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__gccmain") == 0) + pc += 4; + } + +--- gdb-7.6/gdb/block.c ++++ gdb-7.6/gdb/block.c +@@ -208,7 +208,7 @@ call_site_for_pc (struct gdbarch *gdbarc + + if (slot == NULL) + { +- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (pc); ++ struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc); + + /* DW_TAG_gnu_call_site will be missing just if GCC could not determine + the call target. */ +@@ -216,7 +216,8 @@ call_site_for_pc (struct gdbarch *gdbarc + _("DW_OP_GNU_entry_value resolving cannot find " + "DW_TAG_GNU_call_site %s in %s"), + paddress (gdbarch, pc), +- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); ++ (msym.minsym == NULL ? "???" ++ : SYMBOL_PRINT_NAME (msym.minsym))); + } + + return *slot; +--- gdb-7.6/gdb/blockframe.c ++++ gdb-7.6/gdb/blockframe.c +@@ -88,7 +88,7 @@ CORE_ADDR + get_pc_function_start (CORE_ADDR pc) + { + struct block *bl; +- struct minimal_symbol *msymbol; ++ struct bound_minimal_symbol msymbol; + + bl = block_for_pc (pc); + if (bl) +@@ -103,9 +103,9 @@ get_pc_function_start (CORE_ADDR pc) + } + + msymbol = lookup_minimal_symbol_by_pc (pc); +- if (msymbol) ++ if (msymbol.minsym) + { +- CORE_ADDR fstart = SYMBOL_VALUE_ADDRESS (msymbol); ++ CORE_ADDR fstart = SYMBOL_VALUE_ADDRESS (msymbol.minsym); + + if (find_pc_section (fstart)) + return fstart; +@@ -218,7 +218,7 @@ find_pc_partial_function_gnu_ifunc (CORE + && section == cache_pc_function_section) + goto return_cached_value; + +- msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section); ++ msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section).minsym; + ALL_OBJFILES (objfile) + { + if (objfile->sf) +--- gdb-7.6/gdb/breakpoint.c ++++ gdb-7.6/gdb/breakpoint.c +@@ -9824,14 +9824,14 @@ resolve_sal_pc (struct symtab_and_line * + if we have line numbers but no functions (as can + happen in assembly source). */ + +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + struct cleanup *old_chain = save_current_space_and_thread (); + + switch_to_program_space_and_thread (sal->pspace); + + msym = lookup_minimal_symbol_by_pc (sal->pc); +- if (msym) +- sal->section = SYMBOL_OBJ_SECTION (msym); ++ if (msym.minsym) ++ sal->section = SYMBOL_OBJ_SECTION (msym.minsym); + + do_cleanups (old_chain); + } +--- gdb-7.6/gdb/btrace.c ++++ gdb-7.6/gdb/btrace.c +@@ -272,7 +272,7 @@ compute_ftrace (VEC (btrace_inst_s) *itr + for (idx = 0; VEC_iterate (btrace_inst_s, itrace, idx, binst); ++idx) + { + struct symtab_and_line sal; +- struct minimal_symbol *mfun; ++ struct bound_minimal_symbol mfun; + struct symbol *fun; + const char *filename; + CORE_ADDR pc; +@@ -285,7 +285,7 @@ compute_ftrace (VEC (btrace_inst_s) *itr + fun = find_pc_function (pc); + mfun = lookup_minimal_symbol_by_pc (pc); + +- if (fun == NULL && mfun == NULL) ++ if (fun == NULL && mfun.minsym == NULL) + { + DEBUG_FTRACE ("no symbol at %u, pc=%s", idx, + core_addr_to_string_nz (pc)); +@@ -293,11 +293,11 @@ compute_ftrace (VEC (btrace_inst_s) *itr + } + + /* If we're switching functions, we start over. */ +- if (ftrace_function_switched (bfun, mfun, fun)) ++ if (ftrace_function_switched (bfun, mfun.minsym, fun)) + { + bfun = VEC_safe_push (btrace_func_s, ftrace, NULL); + +- ftrace_init_func (bfun, mfun, fun, idx); ++ ftrace_init_func (bfun, mfun.minsym, fun, idx); + ftrace_debug (bfun, "init"); + } + +--- gdb-7.6/gdb/c-valprint.c ++++ gdb-7.6/gdb/c-valprint.c +@@ -310,18 +310,18 @@ c_val_print (struct type *type, const gd + CORE_ADDR vt_address = unpack_pointer (type, + valaddr + + embedded_offset); +- struct minimal_symbol *msymbol = +- lookup_minimal_symbol_by_pc (vt_address); ++ struct bound_minimal_symbol msymbol = ++ lookup_minimal_symbol_by_pc (vt_address); + + /* If 'symbol_print' is set, we did the work above. */ + if (!options->symbol_print +- && (msymbol != NULL) +- && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) ++ && (msymbol.minsym != NULL) ++ && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol.minsym))) + { + if (want_space) + fputs_filtered (" ", stream); + fputs_filtered (" <", stream); +- fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); ++ fputs_filtered (SYMBOL_PRINT_NAME (msymbol.minsym), stream); + fputs_filtered (">", stream); + want_space = 1; + } +@@ -337,8 +337,8 @@ c_val_print (struct type *type, const gd + if (want_space) + fputs_filtered (" ", stream); + +- if (msymbol != NULL) +- wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), ++ if (msymbol.minsym != NULL) ++ wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol.minsym), + block, VAR_DOMAIN, + &is_this_fld); + +--- gdb-7.6/gdb/coff-pe-read.c ++++ gdb-7.6/gdb/coff-pe-read.c +@@ -203,8 +203,7 @@ add_pe_forwarded_sym (const char *sym_na + const char *dll_name, struct objfile *objfile) + { + CORE_ADDR vma; +- struct objfile *forward_objfile; +- struct minimal_symbol *msymbol; ++ struct bound_minimal_symbol msymbol; + short section; + enum minimal_symbol_type msymtype; + int dll_name_len = strlen (dll_name); +@@ -218,20 +217,18 @@ add_pe_forwarded_sym (const char *sym_na + forward_func_name); + + +- msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name, +- &forward_objfile); ++ msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name); + +- if (!msymbol) ++ if (!msymbol.minsym) + { + int i; + + for (i = 0; i < forward_dll_name_len; i++) + forward_qualified_name[i] = tolower (forward_qualified_name[i]); +- msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name, +- &forward_objfile); ++ msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name); + } + +- if (!msymbol) ++ if (!msymbol.minsym) + { + if (debug_coff_pe_read) + fprintf_unfiltered (gdb_stdlog, _("Unable to find function \"%s\" in" +@@ -246,9 +243,9 @@ add_pe_forwarded_sym (const char *sym_na + " \"%s\" in dll \"%s\", pointing to \"%s\"\n"), + sym_name, dll_name, forward_qualified_name); + +- vma = SYMBOL_VALUE_ADDRESS (msymbol); +- section = SYMBOL_SECTION (msymbol); +- msymtype = MSYMBOL_TYPE (msymbol); ++ section = SYMBOL_SECTION (msymbol.minsym); ++ vma = SYMBOL_VALUE_ADDRESS (msymbol.minsym); ++ msymtype = MSYMBOL_TYPE (msymbol.minsym); + + /* Generate a (hopefully unique) qualified name using the first part + of the dll name, e.g. KERNEL32!AddAtomA. This matches the style +--- gdb-7.6/gdb/dwarf2loc.c ++++ gdb-7.6/gdb/dwarf2loc.c +@@ -500,19 +500,20 @@ call_site_to_target_addr (struct gdbarch + dwarf_block = FIELD_DWARF_BLOCK (call_site->target); + if (dwarf_block == NULL) + { +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + + msym = lookup_minimal_symbol_by_pc (call_site->pc - 1); + throw_error (NO_ENTRY_VALUE_ERROR, + _("DW_AT_GNU_call_site_target is not specified " + "at %s in %s"), + paddress (call_site_gdbarch, call_site->pc), +- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); ++ (msym.minsym == NULL ? "???" ++ : SYMBOL_PRINT_NAME (msym.minsym))); + + } + if (caller_frame == NULL) + { +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + + msym = lookup_minimal_symbol_by_pc (call_site->pc - 1); + throw_error (NO_ENTRY_VALUE_ERROR, +@@ -520,7 +521,8 @@ call_site_to_target_addr (struct gdbarch + "requires known frame which is currently not " + "available at %s in %s"), + paddress (call_site_gdbarch, call_site->pc), +- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); ++ (msym.minsym == NULL ? "???" ++ : SYMBOL_PRINT_NAME (msym.minsym))); + + } + caller_arch = get_frame_arch (caller_frame); +@@ -547,7 +549,7 @@ call_site_to_target_addr (struct gdbarch + msym = lookup_minimal_symbol (physname, NULL, NULL); + if (msym == NULL) + { +- msym = lookup_minimal_symbol_by_pc (call_site->pc - 1); ++ msym = lookup_minimal_symbol_by_pc (call_site->pc - 1).minsym; + throw_error (NO_ENTRY_VALUE_ERROR, + _("Cannot find function \"%s\" for a call site target " + "at %s in %s"), +@@ -643,14 +645,15 @@ func_verify_no_selftailcall (struct gdba + + if (target_addr == verify_addr) + { +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + + msym = lookup_minimal_symbol_by_pc (verify_addr); + throw_error (NO_ENTRY_VALUE_ERROR, + _("DW_OP_GNU_entry_value resolving has found " + "function \"%s\" at %s can call itself via tail " + "calls"), +- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym), ++ (msym.minsym == NULL ? "???" ++ : SYMBOL_PRINT_NAME (msym.minsym)), + paddress (gdbarch, verify_addr)); + } + +@@ -674,10 +677,11 @@ static void + tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site) + { + CORE_ADDR addr = call_site->pc; +- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (addr - 1); ++ struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1); + + fprintf_unfiltered (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr), +- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); ++ (msym.minsym == NULL ? "???" ++ : SYMBOL_PRINT_NAME (msym.minsym))); + + } + +@@ -907,7 +911,7 @@ call_site_find_chain_1 (struct gdbarch * + + if (retval == NULL) + { +- struct minimal_symbol *msym_caller, *msym_callee; ++ struct bound_minimal_symbol msym_caller, msym_callee; + + msym_caller = lookup_minimal_symbol_by_pc (caller_pc); + msym_callee = lookup_minimal_symbol_by_pc (callee_pc); +@@ -915,11 +919,11 @@ call_site_find_chain_1 (struct gdbarch * + _("There are no unambiguously determinable intermediate " + "callers or callees between caller function \"%s\" at %s " + "and callee function \"%s\" at %s"), +- (msym_caller == NULL +- ? "???" : SYMBOL_PRINT_NAME (msym_caller)), ++ (msym_caller.minsym == NULL ++ ? "???" : SYMBOL_PRINT_NAME (msym_caller.minsym)), + paddress (gdbarch, caller_pc), +- (msym_callee == NULL +- ? "???" : SYMBOL_PRINT_NAME (msym_callee)), ++ (msym_callee.minsym == NULL ++ ? "???" : SYMBOL_PRINT_NAME (msym_callee.minsym)), + paddress (gdbarch, callee_pc)); + } + +@@ -1011,7 +1015,8 @@ dwarf_expr_reg_to_entry_parameter (struc + caller_frame = get_prev_frame (frame); + if (gdbarch != frame_unwind_arch (frame)) + { +- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (func_addr); ++ struct bound_minimal_symbol msym ++ = lookup_minimal_symbol_by_pc (func_addr); + struct gdbarch *caller_gdbarch = frame_unwind_arch (frame); + + throw_error (NO_ENTRY_VALUE_ERROR, +@@ -1019,18 +1024,21 @@ dwarf_expr_reg_to_entry_parameter (struc + "(of %s (%s)) does not match caller gdbarch %s"), + gdbarch_bfd_arch_info (gdbarch)->printable_name, + paddress (gdbarch, func_addr), +- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym), ++ (msym.minsym == NULL ? "???" ++ : SYMBOL_PRINT_NAME (msym.minsym)), + gdbarch_bfd_arch_info (caller_gdbarch)->printable_name); + } + + if (caller_frame == NULL) + { +- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (func_addr); ++ struct bound_minimal_symbol msym ++ = lookup_minimal_symbol_by_pc (func_addr); + + throw_error (NO_ENTRY_VALUE_ERROR, _("DW_OP_GNU_entry_value resolving " + "requires caller of %s (%s)"), + paddress (gdbarch, func_addr), +- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); ++ (msym.minsym == NULL ? "???" ++ : SYMBOL_PRINT_NAME (msym.minsym))); + } + caller_pc = get_frame_pc (caller_frame); + call_site = call_site_for_pc (gdbarch, caller_pc); +@@ -1040,8 +1048,8 @@ dwarf_expr_reg_to_entry_parameter (struc + { + struct minimal_symbol *target_msym, *func_msym; + +- target_msym = lookup_minimal_symbol_by_pc (target_addr); +- func_msym = lookup_minimal_symbol_by_pc (func_addr); ++ target_msym = lookup_minimal_symbol_by_pc (target_addr).minsym; ++ func_msym = lookup_minimal_symbol_by_pc (func_addr).minsym; + throw_error (NO_ENTRY_VALUE_ERROR, + _("DW_OP_GNU_entry_value resolving expects callee %s at %s " + "but the called frame is for %s at %s"), +@@ -1064,7 +1072,8 @@ dwarf_expr_reg_to_entry_parameter (struc + } + if (iparams == call_site->parameter_count) + { +- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (caller_pc); ++ struct minimal_symbol *msym ++ = lookup_minimal_symbol_by_pc (caller_pc).minsym; + + /* DW_TAG_GNU_call_site_parameter will be missing just if GCC could not + determine its value. */ +--- gdb-7.6/gdb/elfread.c ++++ gdb-7.6/gdb/elfread.c +@@ -735,7 +735,7 @@ elf_gnu_ifunc_cache_eq (const void *a_vo + static int + elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr) + { +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + asection *sect; + struct objfile *objfile; + htab_t htab; +@@ -743,13 +743,13 @@ elf_gnu_ifunc_record_cache (const char * + void **slot; + + msym = lookup_minimal_symbol_by_pc (addr); +- if (msym == NULL) ++ if (msym.minsym == NULL) + return 0; +- if (SYMBOL_VALUE_ADDRESS (msym) != addr) ++ if (SYMBOL_VALUE_ADDRESS (msym.minsym) != addr) + return 0; + /* minimal symbols have always SYMBOL_OBJ_SECTION non-NULL. */ +- sect = SYMBOL_OBJ_SECTION (msym)->the_bfd_section; +- objfile = SYMBOL_OBJ_SECTION (msym)->objfile; ++ sect = SYMBOL_OBJ_SECTION (msym.minsym)->the_bfd_section; ++ objfile = SYMBOL_OBJ_SECTION (msym.minsym)->objfile; + + /* If .plt jumps back to .plt the symbol is still deferred for later + resolution and it has no use for GDB. Besides ".text" this symbol can +--- gdb-7.6/gdb/frame.c ++++ gdb-7.6/gdb/frame.c +@@ -1678,7 +1678,7 @@ get_prev_frame_1 (struct frame_info *thi + + /* gcc -fsplit-stack __morestack can continue the stack anywhere. */ + this_pc_in_block = get_frame_address_in_block (this_frame); +- morestack_msym = lookup_minimal_symbol_by_pc (this_pc_in_block); ++ morestack_msym = lookup_minimal_symbol_by_pc (this_pc_in_block).minsym; + if (morestack_msym) + morestack_name = SYMBOL_LINKAGE_NAME (morestack_msym); + if (!morestack_name || strcmp (morestack_name, "__morestack") != 0) +--- gdb-7.6/gdb/frv-tdep.c ++++ gdb-7.6/gdb/frv-tdep.c +@@ -1072,7 +1072,7 @@ frv_skip_main_prologue (struct gdbarch * + { + LONGEST displ; + CORE_ADDR call_dest; +- struct minimal_symbol *s; ++ struct bound_minimal_symbol s; + + displ = ((op & 0xfe000000) >> 7) | (op & 0x0003ffff); + if ((displ & 0x00800000) != 0) +@@ -1081,9 +1081,9 @@ frv_skip_main_prologue (struct gdbarch * + call_dest = pc + 4 * displ; + s = lookup_minimal_symbol_by_pc (call_dest); + +- if (s != NULL +- && SYMBOL_LINKAGE_NAME (s) != NULL +- && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0) ++ if (s.minsym != NULL ++ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL ++ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0) + { + pc += 4; + return pc; +--- gdb-7.6/gdb/glibc-tdep.c ++++ gdb-7.6/gdb/glibc-tdep.c +@@ -53,19 +53,18 @@ glibc_skip_solib_resolver (struct gdbarc + of GNU/Linux will provide a portable, efficient interface for + debugging programs that use shared libraries. */ + +- struct objfile *objfile; +- struct minimal_symbol *resolver +- = lookup_minimal_symbol_and_objfile ("_dl_runtime_resolve", &objfile); ++ struct bound_minimal_symbol resolver ++ = lookup_minimal_symbol_and_objfile ("_dl_runtime_resolve"); + +- if (resolver) ++ if (resolver.minsym) + { + /* The dynamic linker began using this name in early 2005. */ + struct minimal_symbol *fixup +- = lookup_minimal_symbol ("_dl_fixup", NULL, objfile); ++ = lookup_minimal_symbol ("_dl_fixup", NULL, resolver.objfile); + + /* This is the name used in older versions. */ + if (! fixup) +- fixup = lookup_minimal_symbol ("fixup", NULL, objfile); ++ fixup = lookup_minimal_symbol ("fixup", NULL, resolver.objfile); + + if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc) + return frame_unwind_caller_pc (get_current_frame ()); +--- gdb-7.6/gdb/gnu-v2-abi.c ++++ gdb-7.6/gdb/gnu-v2-abi.c +@@ -191,7 +191,7 @@ gnuv2_value_rtti_type (struct value *v, + struct type *known_type; + struct type *rtti_type; + CORE_ADDR vtbl; +- struct minimal_symbol *minsym; ++ struct bound_minimal_symbol minsym; + char *demangled_name, *p; + const char *linkage_name; + struct type *btype; +@@ -245,8 +245,8 @@ gnuv2_value_rtti_type (struct value *v, + + /* Try to find a symbol that is the vtable. */ + minsym=lookup_minimal_symbol_by_pc(vtbl); +- if (minsym==NULL +- || (linkage_name=SYMBOL_LINKAGE_NAME (minsym))==NULL ++ if (minsym.minsym==NULL ++ || (linkage_name=SYMBOL_LINKAGE_NAME (minsym.minsym))==NULL + || !is_vtable_name (linkage_name)) + return NULL; + +--- gdb-7.6/gdb/gnu-v3-abi.c ++++ gdb-7.6/gdb/gnu-v3-abi.c +@@ -306,7 +306,7 @@ gnuv3_rtti_type (struct value *value, + /* Find the linker symbol for this vtable. */ + vtable_symbol + = lookup_minimal_symbol_by_pc (value_address (vtable) +- + value_embedded_offset (vtable)); ++ + value_embedded_offset (vtable)).minsym; + if (! vtable_symbol) + return NULL; + +@@ -988,7 +988,7 @@ gnuv3_skip_trampoline (struct frame_info + real_stop_pc = stop_pc; + + /* Find the linker symbol for this potential thunk. */ +- thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc); ++ thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc).minsym; + section = find_pc_section (real_stop_pc); + if (thunk_sym == NULL || section == NULL) + return 0; +--- gdb-7.6/gdb/hppa-hpux-tdep.c ++++ gdb-7.6/gdb/hppa-hpux-tdep.c +@@ -89,7 +89,7 @@ hppa32_hpux_in_solib_call_trampoline (st + CORE_ADDR pc, char *name) + { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +- struct minimal_symbol *minsym; ++ struct bound_minimal_symbol minsym; + struct unwind_table_entry *u; + + /* First see if PC is in one of the two C-library trampolines. */ +@@ -98,7 +98,8 @@ hppa32_hpux_in_solib_call_trampoline (st + return 1; + + minsym = lookup_minimal_symbol_by_pc (pc); +- if (minsym && strcmp (SYMBOL_LINKAGE_NAME (minsym), ".stub") == 0) ++ if (minsym.minsym ++ && strcmp (SYMBOL_LINKAGE_NAME (minsym.minsym), ".stub") == 0) + return 1; + + /* Get the unwind descriptor corresponding to PC, return zero +@@ -174,16 +175,16 @@ hppa64_hpux_in_solib_call_trampoline (st + step. If it does, then assume we are not in a stub and return. + + Finally peek at the instructions to see if they look like a stub. */ +- struct minimal_symbol *minsym; ++ struct bound_minimal_symbol minsym; + asection *sec; + CORE_ADDR addr; + int insn; + + minsym = lookup_minimal_symbol_by_pc (pc); +- if (! minsym) ++ if (! minsym.minsym) + return 0; + +- sec = SYMBOL_OBJ_SECTION (minsym)->the_bfd_section; ++ sec = SYMBOL_OBJ_SECTION (minsym.minsym)->the_bfd_section; + + if (bfd_get_section_vma (sec->owner, sec) <= pc + && pc < (bfd_get_section_vma (sec->owner, sec) +@@ -311,7 +312,7 @@ hppa_hpux_skip_trampoline_code (struct f + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + long orig_pc = pc; + long prev_inst, curr_inst, loc; +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + struct unwind_table_entry *u; + + /* Addresses passed to dyncall may *NOT* be the actual address +@@ -366,10 +367,12 @@ hppa_hpux_skip_trampoline_code (struct f + /*--------------------------------------------------------------------------*/ + msym = lookup_minimal_symbol_by_pc (pc); + +- if (msym == NULL || MSYMBOL_TYPE (msym) != mst_solib_trampoline) ++ if (msym.minsym == NULL ++ || MSYMBOL_TYPE (msym.minsym) != mst_solib_trampoline) + return orig_pc == pc ? 0 : pc & ~0x3; + +- else if (msym != NULL && MSYMBOL_TYPE (msym) == mst_solib_trampoline) ++ else if (msym.minsym != NULL ++ && MSYMBOL_TYPE (msym.minsym) == mst_solib_trampoline) + { + struct objfile *objfile; + struct minimal_symbol *msymbol; +@@ -384,7 +387,7 @@ hppa_hpux_skip_trampoline_code (struct f + { + if (MSYMBOL_TYPE (msymbol) == mst_text + && strcmp (SYMBOL_LINKAGE_NAME (msymbol), +- SYMBOL_LINKAGE_NAME (msym)) == 0) ++ SYMBOL_LINKAGE_NAME (msym.minsym)) == 0) + { + function_found = 1; + break; +@@ -401,7 +404,7 @@ hppa_hpux_skip_trampoline_code (struct f + should be mst_text. So we need to fix the msym, and also + get out of this function. */ + { +- MSYMBOL_TYPE (msym) = mst_text; ++ MSYMBOL_TYPE (msym.minsym) = mst_text; + return orig_pc == pc ? 0 : pc & ~0x3; + } + } +@@ -472,21 +475,22 @@ hppa_hpux_skip_trampoline_code (struct f + (curr_inst == 0xeaa0d000) || + (curr_inst == 0xeaa0d002)) + { +- struct minimal_symbol *stubsym, *libsym; ++ struct bound_minimal_symbol stubsym; ++ struct minimal_symbol *libsym; + + stubsym = lookup_minimal_symbol_by_pc (loc); +- if (stubsym == NULL) ++ if (stubsym.minsym == NULL) + { + warning (_("Unable to find symbol for 0x%lx"), loc); + return orig_pc == pc ? 0 : pc & ~0x3; + } + +- libsym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (stubsym), ++ libsym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (stubsym.minsym), + NULL, NULL); + if (libsym == NULL) + { + warning (_("Unable to find library symbol for %s."), +- SYMBOL_PRINT_NAME (stubsym)); ++ SYMBOL_PRINT_NAME (stubsym.minsym)); + return orig_pc == pc ? 0 : pc & ~0x3; + } + +@@ -1025,7 +1029,8 @@ static CORE_ADDR + hppa_hpux_find_import_stub_for_addr (CORE_ADDR funcaddr) + { + struct objfile *objfile; +- struct minimal_symbol *funsym, *stubsym; ++ struct bound_minimal_symbol funsym; ++ struct minimal_symbol *stubsym; + CORE_ADDR stubaddr; + + funsym = lookup_minimal_symbol_by_pc (funcaddr); +@@ -1034,7 +1039,7 @@ hppa_hpux_find_import_stub_for_addr (COR + ALL_OBJFILES (objfile) + { + stubsym = lookup_minimal_symbol_solib_trampoline +- (SYMBOL_LINKAGE_NAME (funsym), objfile); ++ (SYMBOL_LINKAGE_NAME (funsym.minsym), objfile); + + if (stubsym) + { +--- gdb-7.6/gdb/i386-tdep.c ++++ gdb-7.6/gdb/i386-tdep.c +@@ -1687,15 +1687,15 @@ i386_skip_main_prologue (struct gdbarch + { + /* Make sure address is computed correctly as a 32bit + integer even if CORE_ADDR is 64 bit wide. */ +- struct minimal_symbol *s; ++ struct bound_minimal_symbol s; + CORE_ADDR call_dest; + + call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order); + call_dest = call_dest & 0xffffffffU; + s = lookup_minimal_symbol_by_pc (call_dest); +- if (s != NULL +- && SYMBOL_LINKAGE_NAME (s) != NULL +- && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0) ++ if (s.minsym != NULL ++ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL ++ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0) + pc += 5; + } + } +@@ -3352,7 +3352,7 @@ i386_pe_skip_trampoline_code (struct fra + unsigned long indirect = + read_memory_unsigned_integer (pc + 2, 4, byte_order); + struct minimal_symbol *indsym = +- indirect ? lookup_minimal_symbol_by_pc (indirect) : 0; ++ indirect ? lookup_minimal_symbol_by_pc (indirect).minsym : 0; + const char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : 0; + + if (symname) +--- gdb-7.6/gdb/ia64-tdep.c ++++ gdb-7.6/gdb/ia64-tdep.c +@@ -3651,11 +3651,11 @@ ia64_convert_from_func_ptr_addr (struct + /* There are also descriptors embedded in vtables. */ + if (s) + { +- struct minimal_symbol *minsym; ++ struct bound_minimal_symbol minsym; + + minsym = lookup_minimal_symbol_by_pc (addr); + +- if (minsym && is_vtable_name (SYMBOL_LINKAGE_NAME (minsym))) ++ if (minsym.minsym && is_vtable_name (SYMBOL_LINKAGE_NAME (minsym.minsym))) + return read_memory_unsigned_integer (addr, 8, byte_order); + } + +--- gdb-7.6/gdb/infcall.c ++++ gdb-7.6/gdb/infcall.c +@@ -355,10 +355,10 @@ get_function_name (CORE_ADDR funaddr, ch + + { + /* Try the minimal symbols. */ +- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr); ++ struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (funaddr); + +- if (msymbol) +- return SYMBOL_PRINT_NAME (msymbol); ++ if (msymbol.minsym) ++ return SYMBOL_PRINT_NAME (msymbol.minsym); + } + + { +--- gdb-7.6/gdb/infcmd.c ++++ gdb-7.6/gdb/infcmd.c +@@ -1332,12 +1332,12 @@ until_next_command (int from_tty) + + if (!func) + { +- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc); ++ struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); + +- if (msymbol == NULL) ++ if (msymbol.minsym == NULL) + error (_("Execution is not within a known function.")); + +- tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol); ++ tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol.minsym); + tp->control.step_range_end = pc; + } + else +--- gdb-7.6/gdb/jit.c ++++ gdb-7.6/gdb/jit.c +@@ -1016,8 +1016,8 @@ static int + jit_breakpoint_re_set_internal (struct gdbarch *gdbarch, + struct jit_program_space_data *ps_data) + { +- struct minimal_symbol *reg_symbol, *desc_symbol; +- struct objfile *objf; ++ struct bound_minimal_symbol reg_symbol; ++ struct minimal_symbol *desc_symbol; + struct jit_objfile_data *objf_data; + CORE_ADDR addr; + +@@ -1025,19 +1025,21 @@ jit_breakpoint_re_set_internal (struct g + { + /* Lookup the registration symbol. If it is missing, then we + assume we are not attached to a JIT. */ +- reg_symbol = lookup_minimal_symbol_and_objfile (jit_break_name, &objf); +- if (reg_symbol == NULL || SYMBOL_VALUE_ADDRESS (reg_symbol) == 0) ++ reg_symbol = lookup_minimal_symbol_and_objfile (jit_break_name); ++ if (reg_symbol.minsym == NULL ++ || SYMBOL_VALUE_ADDRESS (reg_symbol.minsym) == 0) + return 1; + +- desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, objf); ++ desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, ++ reg_symbol.objfile); + if (desc_symbol == NULL || SYMBOL_VALUE_ADDRESS (desc_symbol) == 0) + return 1; + +- objf_data = get_jit_objfile_data (objf); +- objf_data->register_code = reg_symbol; ++ objf_data = get_jit_objfile_data (reg_symbol.objfile); ++ objf_data->register_code = reg_symbol.minsym; + objf_data->descriptor = desc_symbol; + +- ps_data->objfile = objf; ++ ps_data->objfile = reg_symbol.objfile; + } + else + objf_data = get_jit_objfile_data (ps_data->objfile); +--- gdb-7.6/gdb/linux-fork.c ++++ gdb-7.6/gdb/linux-fork.c +@@ -592,11 +592,11 @@ info_checkpoints_command (char *arg, int + printf_filtered (_(", line %d"), sal.line); + if (!sal.symtab && !sal.line) + { +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + + msym = lookup_minimal_symbol_by_pc (pc); +- if (msym) +- printf_filtered (", <%s>", SYMBOL_LINKAGE_NAME (msym)); ++ if (msym.minsym) ++ printf_filtered (", <%s>", SYMBOL_LINKAGE_NAME (msym.minsym)); + } + + putchar_filtered ('\n'); +--- gdb-7.6/gdb/m32c-tdep.c ++++ gdb-7.6/gdb/m32c-tdep.c +@@ -2457,14 +2457,15 @@ m32c_m16c_address_to_pointer (struct gdb + struct minimal_symbol *tramp_msym; + + /* Try to find a linker symbol at this address. */ +- struct minimal_symbol *func_msym = lookup_minimal_symbol_by_pc (addr); ++ struct bound_minimal_symbol func_msym ++ = lookup_minimal_symbol_by_pc (addr); + +- if (! func_msym) ++ if (! func_msym.minsym) + error (_("Cannot convert code address %s to function pointer:\n" + "couldn't find a symbol at that address, to find trampoline."), + paddress (gdbarch, addr)); + +- func_name = SYMBOL_LINKAGE_NAME (func_msym); ++ func_name = SYMBOL_LINKAGE_NAME (func_msym.minsym); + tramp_name = xmalloc (strlen (func_name) + 5); + strcpy (tramp_name, func_name); + strcat (tramp_name, ".plt"); +@@ -2535,11 +2536,11 @@ m32c_m16c_pointer_to_address (struct gdb + { + /* See if there is a minimal symbol at that address whose name is + "NAME.plt". */ +- struct minimal_symbol *ptr_msym = lookup_minimal_symbol_by_pc (ptr); ++ struct bound_minimal_symbol ptr_msym = lookup_minimal_symbol_by_pc (ptr); + +- if (ptr_msym) ++ if (ptr_msym.minsym) + { +- const char *ptr_msym_name = SYMBOL_LINKAGE_NAME (ptr_msym); ++ const char *ptr_msym_name = SYMBOL_LINKAGE_NAME (ptr_msym.minsym); + int len = strlen (ptr_msym_name); + + if (len > 4 +@@ -2572,7 +2573,7 @@ m32c_m16c_pointer_to_address (struct gdb + { + ptr_msym = lookup_minimal_symbol_by_pc ((aspace << 16) | ptr); + +- if (ptr_msym) ++ if (ptr_msym.minsym) + ptr |= aspace << 16; + } + } +--- gdb-7.6/gdb/m68hc11-tdep.c ++++ gdb-7.6/gdb/m68hc11-tdep.c +@@ -587,18 +587,18 @@ m68hc11_analyze_instruction (struct gdba + static enum insn_return_kind + m68hc11_get_return_insn (CORE_ADDR pc) + { +- struct minimal_symbol *sym; ++ struct bound_minimal_symbol sym; + + /* A flag indicating that this is a STO_M68HC12_FAR or STO_M68HC12_INTERRUPT + function is stored by elfread.c in the high bit of the info field. + Use this to decide which instruction the function uses to return. */ + sym = lookup_minimal_symbol_by_pc (pc); +- if (sym == 0) ++ if (sym.minsym == 0) + return RETURN_RTS; + +- if (MSYMBOL_IS_RTC (sym)) ++ if (MSYMBOL_IS_RTC (sym.minsym)) + return RETURN_RTC; +- else if (MSYMBOL_IS_RTI (sym)) ++ else if (MSYMBOL_IS_RTI (sym.minsym)) + return RETURN_RTI; + else + return RETURN_RTS; +--- gdb-7.6/gdb/maint.c ++++ gdb-7.6/gdb/maint.c +@@ -445,7 +445,7 @@ maintenance_translate_address (char *arg + CORE_ADDR address; + struct obj_section *sect; + char *p; +- struct minimal_symbol *sym; ++ struct bound_minimal_symbol sym; + struct objfile *objfile; + + if (arg == NULL || *arg == 0) +@@ -480,13 +480,13 @@ maintenance_translate_address (char *arg + else + sym = lookup_minimal_symbol_by_pc (address); + +- if (sym) ++ if (sym.minsym) + { +- const char *symbol_name = SYMBOL_PRINT_NAME (sym); ++ const char *symbol_name = SYMBOL_PRINT_NAME (sym.minsym); + const char *symbol_offset +- = pulongest (address - SYMBOL_VALUE_ADDRESS (sym)); ++ = pulongest (address - SYMBOL_VALUE_ADDRESS (sym.minsym)); + +- sect = SYMBOL_OBJ_SECTION(sym); ++ sect = SYMBOL_OBJ_SECTION(sym.minsym); + if (sect != NULL) + { + const char *section_name; +--- gdb-7.6/gdb/minsyms.c ++++ gdb-7.6/gdb/minsyms.c +@@ -474,7 +474,7 @@ lookup_minimal_symbol_solib_trampoline ( + there are text and trampoline symbols at the same address. + Otherwise prefer mst_text symbols. */ + +-static struct minimal_symbol * ++static struct bound_minimal_symbol + lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, + struct obj_section *section, + int want_trampoline) +@@ -485,6 +485,8 @@ lookup_minimal_symbol_by_pc_section_1 (C + struct objfile *objfile; + struct minimal_symbol *msymbol; + struct minimal_symbol *best_symbol = NULL; ++ struct objfile *best_objfile = NULL; ++ struct bound_minimal_symbol result; + enum minimal_symbol_type want_type, other_type; + + want_type = want_trampoline ? mst_solib_trampoline : mst_text; +@@ -690,14 +692,18 @@ lookup_minimal_symbol_by_pc_section_1 (C + SYMBOL_VALUE_ADDRESS (&msymbol[hi])))) + { + best_symbol = &msymbol[hi]; ++ best_objfile = objfile; + } + } + } + } +- return (best_symbol); ++ ++ result.minsym = best_symbol; ++ result.objfile = best_objfile; ++ return result; + } + +-struct minimal_symbol * ++struct bound_minimal_symbol + lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, struct obj_section *section) + { + if (section == NULL) +@@ -707,17 +713,31 @@ lookup_minimal_symbol_by_pc_section (COR + debugging) always returns NULL making the call somewhat useless. */ + section = find_pc_section (pc); + if (section == NULL) +- return NULL; ++ { ++ struct bound_minimal_symbol result; ++ ++ memset (&result, 0, sizeof (result)); ++ return result; ++ } + } + return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0); + } + + /* See minsyms.h. */ + +-struct minimal_symbol * ++struct bound_minimal_symbol + lookup_minimal_symbol_by_pc (CORE_ADDR pc) + { +- return lookup_minimal_symbol_by_pc_section (pc, NULL); ++ struct obj_section *section = find_pc_section (pc); ++ ++ if (section == NULL) ++ { ++ struct bound_minimal_symbol result; ++ ++ memset (&result, 0, sizeof (result)); ++ return result; ++ } ++ return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0); + } + + /* Return non-zero iff PC is in an STT_GNU_IFUNC function resolver. */ +@@ -725,9 +745,9 @@ lookup_minimal_symbol_by_pc (CORE_ADDR p + int + in_gnu_ifunc_stub (CORE_ADDR pc) + { +- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc); ++ struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); + +- return msymbol && MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc; ++ return msymbol.minsym && MSYMBOL_TYPE (msymbol.minsym) == mst_text_gnu_ifunc; + } + + /* See elf_gnu_ifunc_resolve_addr for its real implementation. */ +@@ -785,10 +805,10 @@ const struct gnu_ifunc_fns *gnu_ifunc_fn + + /* See minsyms.h. */ + +-struct minimal_symbol * +-lookup_minimal_symbol_and_objfile (const char *name, +- struct objfile **objfile_p) ++struct bound_minimal_symbol ++lookup_minimal_symbol_and_objfile (const char *name) + { ++ struct bound_minimal_symbol result; + struct objfile *objfile; + unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; + +@@ -802,13 +822,15 @@ lookup_minimal_symbol_and_objfile (const + { + if (strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0) + { +- *objfile_p = objfile; +- return msym; ++ result.minsym = msym; ++ result.objfile = objfile; ++ return result; + } + } + } + +- return 0; ++ memset (&result, 0, sizeof (result)); ++ return result; + } + + +@@ -1287,14 +1309,15 @@ static struct minimal_symbol * + lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc) + { + struct obj_section *section = find_pc_section (pc); +- struct minimal_symbol *msymbol; ++ struct bound_minimal_symbol msymbol; + + if (section == NULL) + return NULL; + msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section, 1); + +- if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) +- return msymbol; ++ if (msymbol.minsym != NULL ++ && MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline) ++ return msymbol.minsym; + return NULL; + } + +--- gdb-7.6/gdb/minsyms.h ++++ gdb-7.6/gdb/minsyms.h +@@ -20,6 +20,23 @@ + #ifndef MINSYMS_H + #define MINSYMS_H + ++/* Several lookup functions return both a minimal symbol and the ++ objfile in which it is found. This structure is used in these ++ cases. */ ++ ++struct bound_minimal_symbol ++{ ++ /* The minimal symbol that was found, or NULL if no minimal symbol ++ was found. */ ++ ++ struct minimal_symbol *minsym; ++ ++ /* If MINSYM is not NULL, then this is the objfile in which the ++ symbol is defined. */ ++ ++ struct objfile *objfile; ++}; ++ + /* This header declares most of the API for dealing with minimal + symbols and minimal symbol tables. A few things are declared + elsewhere; see below. +@@ -169,12 +186,9 @@ struct minimal_symbol *lookup_minimal_sy + struct objfile *); + + /* Find the minimal symbol named NAME, and return both the minsym +- struct and its objfile. This only checks the linkage name. Sets +- *OBJFILE_P and returns the minimal symbol, if it is found. If it +- is not found, returns NULL. */ ++ struct and its objfile. This only checks the linkage name. */ + +-struct minimal_symbol *lookup_minimal_symbol_and_objfile (const char *, +- struct objfile **); ++struct bound_minimal_symbol lookup_minimal_symbol_and_objfile (const char *); + + /* Look through all the current minimal symbol tables and find the + first minimal symbol that matches NAME and has text type. If OBJF +@@ -213,10 +227,10 @@ struct minimal_symbol *lookup_minimal_sy + If SECTION is NULL, this uses the result of find_pc_section + instead. + +- Returns a pointer to the minimal symbol if such a symbol is found, +- or NULL if PC is not in a suitable range. */ ++ The result has a non-NULL 'minsym' member if such a symbol is ++ found, or NULL if PC is not in a suitable range. */ + +-struct minimal_symbol *lookup_minimal_symbol_by_pc_section ++struct bound_minimal_symbol lookup_minimal_symbol_by_pc_section + (CORE_ADDR, + struct obj_section *); + +@@ -226,7 +240,7 @@ struct minimal_symbol *lookup_minimal_sy + This is a wrapper that calls lookup_minimal_symbol_by_pc_section + with a NULL section argument. */ + +-struct minimal_symbol *lookup_minimal_symbol_by_pc (CORE_ADDR); ++struct bound_minimal_symbol lookup_minimal_symbol_by_pc (CORE_ADDR); + + /* Iterate over all the minimal symbols in the objfile OBJF which + match NAME. Both the ordinary and demangled names of each symbol +--- gdb-7.6/gdb/mips-tdep.c ++++ gdb-7.6/gdb/mips-tdep.c +@@ -1115,15 +1115,15 @@ show_mask_address (struct ui_file *file, + int + mips_pc_is_mips (CORE_ADDR memaddr) + { +- struct minimal_symbol *sym; ++ struct bound_minimal_symbol sym; + + /* Flags indicating that this is a MIPS16 or microMIPS function is + stored by elfread.c in the high bit of the info field. Use this + to decide if the function is standard MIPS. Otherwise if bit 0 + of the address is clear, then this is a standard MIPS function. */ + sym = lookup_minimal_symbol_by_pc (memaddr); +- if (sym) +- return msymbol_is_mips (sym); ++ if (sym.minsym) ++ return msymbol_is_mips (sym.minsym); + else + return is_mips_addr (memaddr); + } +@@ -1133,15 +1133,15 @@ mips_pc_is_mips (CORE_ADDR memaddr) + int + mips_pc_is_mips16 (struct gdbarch *gdbarch, CORE_ADDR memaddr) + { +- struct minimal_symbol *sym; ++ struct bound_minimal_symbol sym; + + /* A flag indicating that this is a MIPS16 function is stored by + elfread.c in the high bit of the info field. Use this to decide + if the function is MIPS16. Otherwise if bit 0 of the address is + set, then ELF file flags will tell if this is a MIPS16 function. */ + sym = lookup_minimal_symbol_by_pc (memaddr); +- if (sym) +- return msymbol_is_mips16 (sym); ++ if (sym.minsym) ++ return msymbol_is_mips16 (sym.minsym); + else + return is_mips16_addr (gdbarch, memaddr); + } +@@ -1151,7 +1151,7 @@ mips_pc_is_mips16 (struct gdbarch *gdbar + int + mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr) + { +- struct minimal_symbol *sym; ++ struct bound_minimal_symbol sym; + + /* A flag indicating that this is a microMIPS function is stored by + elfread.c in the high bit of the info field. Use this to decide +@@ -1159,8 +1159,8 @@ mips_pc_is_micromips (struct gdbarch *gd + is set, then ELF file flags will tell if this is a microMIPS + function. */ + sym = lookup_minimal_symbol_by_pc (memaddr); +- if (sym) +- return msymbol_is_micromips (sym); ++ if (sym.minsym) ++ return msymbol_is_micromips (sym.minsym); + else + return is_micromips_addr (gdbarch, memaddr); + } +@@ -1171,7 +1171,7 @@ mips_pc_is_micromips (struct gdbarch *gd + static enum mips_isa + mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr) + { +- struct minimal_symbol *sym; ++ struct bound_minimal_symbol sym; + + /* A flag indicating that this is a MIPS16 or a microMIPS function + is stored by elfread.c in the high bit of the info field. Use +@@ -1179,11 +1179,11 @@ mips_pc_isa (struct gdbarch *gdbarch, CO + MIPS. Otherwise if bit 0 of the address is set, then ELF file + flags will tell if this is a MIPS16 or a microMIPS function. */ + sym = lookup_minimal_symbol_by_pc (memaddr); +- if (sym) ++ if (sym.minsym) + { +- if (msymbol_is_micromips (sym)) ++ if (msymbol_is_micromips (sym.minsym)) + return ISA_MICROMIPS; +- else if (msymbol_is_mips16 (sym)) ++ else if (msymbol_is_mips16 (sym.minsym)) + return ISA_MIPS16; + else + return ISA_MIPS; +@@ -3582,7 +3582,7 @@ mips_stub_frame_sniffer (const struct fr + gdb_byte dummy[4]; + struct obj_section *s; + CORE_ADDR pc = get_frame_address_in_block (this_frame); +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + + /* Use the stub unwinder for unreadable code. */ + if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0) +@@ -3602,9 +3602,9 @@ mips_stub_frame_sniffer (const struct fr + /* Calling a PIC function from a non-PIC function passes through a + stub. The stub for foo is named ".pic.foo". */ + msym = lookup_minimal_symbol_by_pc (pc); +- if (msym != NULL +- && SYMBOL_LINKAGE_NAME (msym) != NULL +- && strncmp (SYMBOL_LINKAGE_NAME (msym), ".pic.", 5) == 0) ++ if (msym.minsym != NULL ++ && SYMBOL_LINKAGE_NAME (msym.minsym) != NULL ++ && strncmp (SYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) == 0) + return 1; + + return 0; +@@ -7626,7 +7626,7 @@ mips_skip_pic_trampoline_code (struct fr + { + struct gdbarch *gdbarch = get_frame_arch (frame); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +- struct minimal_symbol *msym; ++ struct bound_minimal_symbol msym; + int i; + gdb_byte stub_code[16]; + int32_t stub_words[4]; +@@ -7635,18 +7635,18 @@ mips_skip_pic_trampoline_code (struct fr + instructions inserted before foo or a three instruction sequence + which jumps to foo. */ + msym = lookup_minimal_symbol_by_pc (pc); +- if (msym == NULL +- || SYMBOL_VALUE_ADDRESS (msym) != pc +- || SYMBOL_LINKAGE_NAME (msym) == NULL +- || strncmp (SYMBOL_LINKAGE_NAME (msym), ".pic.", 5) != 0) ++ if (msym.minsym == NULL ++ || SYMBOL_VALUE_ADDRESS (msym.minsym) != pc ++ || SYMBOL_LINKAGE_NAME (msym.minsym) == NULL ++ || strncmp (SYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) != 0) + return 0; + + /* A two-instruction header. */ +- if (MSYMBOL_SIZE (msym) == 8) ++ if (MSYMBOL_SIZE (msym.minsym) == 8) + return pc + 8; + + /* A three-instruction (plus delay slot) trampoline. */ +- if (MSYMBOL_SIZE (msym) == 16) ++ if (MSYMBOL_SIZE (msym.minsym) == 16) + { + if (target_read_memory (pc, stub_code, 16) != 0) + return 0; +--- gdb-7.6/gdb/p-valprint.c ++++ gdb-7.6/gdb/p-valprint.c +@@ -221,18 +221,18 @@ pascal_val_print (struct type *type, con + /* Print vtbl's nicely. */ + CORE_ADDR vt_address = unpack_pointer (type, + valaddr + embedded_offset); +- struct minimal_symbol *msymbol = ++ struct bound_minimal_symbol msymbol = + lookup_minimal_symbol_by_pc (vt_address); + + /* If 'symbol_print' is set, we did the work above. */ + if (!options->symbol_print +- && (msymbol != NULL) +- && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) ++ && (msymbol.minsym != NULL) ++ && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol.minsym))) + { + if (want_space) + fputs_filtered (" ", stream); + fputs_filtered ("<", stream); +- fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); ++ fputs_filtered (SYMBOL_PRINT_NAME (msymbol.minsym), stream); + fputs_filtered (">", stream); + want_space = 1; + } +@@ -247,8 +247,9 @@ pascal_val_print (struct type *type, con + if (want_space) + fputs_filtered (" ", stream); + +- if (msymbol != NULL) +- wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), block, ++ if (msymbol.minsym != NULL) ++ wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol.minsym), ++ block, + VAR_DOMAIN, &is_this_fld); + + if (wsym) +--- gdb-7.6/gdb/parse.c ++++ gdb-7.6/gdb/parse.c +@@ -508,13 +508,14 @@ write_exp_msymbol (struct minimal_symbol + pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, ¤t_target); + if (pc != addr) + { +- struct minimal_symbol *ifunc_msym = lookup_minimal_symbol_by_pc (pc); ++ struct bound_minimal_symbol ifunc_msym = lookup_minimal_symbol_by_pc (pc); + + /* In this case, assume we have a code symbol instead of + a data symbol. */ + +- if (ifunc_msym != NULL && MSYMBOL_TYPE (ifunc_msym) == mst_text_gnu_ifunc +- && SYMBOL_VALUE_ADDRESS (ifunc_msym) == pc) ++ if (ifunc_msym.minsym != NULL ++ && MSYMBOL_TYPE (ifunc_msym.minsym) == mst_text_gnu_ifunc ++ && SYMBOL_VALUE_ADDRESS (ifunc_msym.minsym) == pc) + { + /* A function descriptor has been resolved but PC is still in the + STT_GNU_IFUNC resolver body (such as because inferior does not +--- gdb-7.6/gdb/ppc-linux-tdep.c ++++ gdb-7.6/gdb/ppc-linux-tdep.c +@@ -332,7 +332,7 @@ static struct ppc_insn_pattern powerpc32 + static int + powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc) + { +- struct minimal_symbol *sym; ++ struct bound_minimal_symbol sym; + + /* Check whether PC is in the dynamic linker. This also checks + whether it is in the .plt section, used by non-PIC executables. */ +@@ -341,9 +341,10 @@ powerpc_linux_in_dynsym_resolve_code (CO + + /* Check if we are in the resolver. */ + sym = lookup_minimal_symbol_by_pc (pc); +- if (sym != NULL +- && (strcmp (SYMBOL_LINKAGE_NAME (sym), "__glink") == 0 +- || strcmp (SYMBOL_LINKAGE_NAME (sym), "__glink_PLTresolve") == 0)) ++ if (sym.minsym != NULL ++ && (strcmp (SYMBOL_LINKAGE_NAME (sym.minsym), "__glink") == 0 ++ || strcmp (SYMBOL_LINKAGE_NAME (sym.minsym), ++ "__glink_PLTresolve") == 0)) + return 1; + + return 0; +--- gdb-7.6/gdb/ppc-sysv-tdep.c ++++ gdb-7.6/gdb/ppc-sysv-tdep.c +@@ -1076,12 +1076,13 @@ static int + convert_code_addr_to_desc_addr (CORE_ADDR code_addr, CORE_ADDR *desc_addr) + { + struct obj_section *dot_fn_section; +- struct minimal_symbol *dot_fn; ++ struct bound_minimal_symbol dot_fn; + struct minimal_symbol *fn; ++ + /* Find the minimal symbol that corresponds to CODE_ADDR (should + have a name of the form ".FN"). */ + dot_fn = lookup_minimal_symbol_by_pc (code_addr); +- if (dot_fn == NULL || SYMBOL_LINKAGE_NAME (dot_fn)[0] != '.') ++ if (dot_fn.minsym == NULL || SYMBOL_LINKAGE_NAME (dot_fn.minsym)[0] != '.') + return 0; + /* Get the section that contains CODE_ADDR. Need this for the + "objfile" that it contains. */ +@@ -1092,7 +1093,7 @@ convert_code_addr_to_desc_addr (CORE_ADD + address. Only look for the minimal symbol in ".FN"'s object file + - avoids problems when two object files (i.e., shared libraries) + contain a minimal symbol with the same name. */ +- fn = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn) + 1, NULL, ++ fn = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn.minsym) + 1, NULL, + dot_fn_section->objfile); + if (fn == NULL) + return 0; +--- gdb-7.6/gdb/printcmd.c ++++ gdb-7.6/gdb/printcmd.c +@@ -658,7 +658,7 @@ build_address_symbolic (struct gdbarch * + save some memory, but for many debug format--ELF/DWARF or + anything/stabs--it would be inconvenient to eliminate those minimal + symbols anyway). */ +- msymbol = lookup_minimal_symbol_by_pc_section (addr, section); ++ msymbol = lookup_minimal_symbol_by_pc_section (addr, section).minsym; + symbol = find_pc_sect_function (addr, section); + + if (symbol) +@@ -1105,7 +1105,8 @@ sym_info (char *arg, int from_tty) + + if (obj_section_addr (osect) <= sect_addr + && sect_addr < obj_section_endaddr (osect) +- && (msymbol = lookup_minimal_symbol_by_pc_section (sect_addr, osect))) ++ && (msymbol ++ = lookup_minimal_symbol_by_pc_section (sect_addr, osect).minsym)) + { + const char *obj_name, *mapped, *sec_name, *msym_name; + char *loc_string; +--- gdb-7.6/gdb/rs6000-tdep.c ++++ gdb-7.6/gdb/rs6000-tdep.c +@@ -2152,15 +2152,15 @@ rs6000_skip_main_prologue (struct gdbarc + { + CORE_ADDR displ = op & BL_DISPLACEMENT_MASK; + CORE_ADDR call_dest = pc + 4 + displ; +- struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest); ++ struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); + + /* We check for ___eabi (three leading underscores) in addition + to __eabi in case the GCC option "-fleading-underscore" was + used to compile the program. */ +- if (s != NULL +- && SYMBOL_LINKAGE_NAME (s) != NULL +- && (strcmp (SYMBOL_LINKAGE_NAME (s), "__eabi") == 0 +- || strcmp (SYMBOL_LINKAGE_NAME (s), "___eabi") == 0)) ++ if (s.minsym != NULL ++ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL ++ && (strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__eabi") == 0 ++ || strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "___eabi") == 0)) + pc += 4; + } + return pc; +@@ -2226,7 +2226,7 @@ rs6000_skip_trampoline_code (struct fram + unsigned int ii, op; + int rel; + CORE_ADDR solib_target_pc; +- struct minimal_symbol *msymbol; ++ struct bound_minimal_symbol msymbol; + + static unsigned trampoline_code[] = + { +@@ -2242,9 +2242,9 @@ rs6000_skip_trampoline_code (struct fram + + /* Check for bigtoc fixup code. */ + msymbol = lookup_minimal_symbol_by_pc (pc); +- if (msymbol ++ if (msymbol.minsym + && rs6000_in_solib_return_trampoline (gdbarch, pc, +- SYMBOL_LINKAGE_NAME (msymbol))) ++ SYMBOL_LINKAGE_NAME (msymbol.minsym))) + { + /* Double-check that the third instruction from PC is relative "b". */ + op = read_memory_integer (pc + 8, 4, byte_order); +--- gdb-7.6/gdb/sh64-tdep.c ++++ gdb-7.6/gdb/sh64-tdep.c +@@ -237,7 +237,7 @@ sh64_elf_make_msymbol_special (asymbol * + static int + pc_is_isa32 (bfd_vma memaddr) + { +- struct minimal_symbol *sym; ++ struct bound_minimal_symbol sym; + + /* If bit 0 of the address is set, assume this is a + ISA32 (shmedia) address. */ +@@ -248,8 +248,8 @@ pc_is_isa32 (bfd_vma memaddr) + the high bit of the info field. Use this to decide if the function is + ISA16 or ISA32. */ + sym = lookup_minimal_symbol_by_pc (memaddr); +- if (sym) +- return MSYMBOL_IS_SPECIAL (sym); ++ if (sym.minsym) ++ return MSYMBOL_IS_SPECIAL (sym.minsym); + else + return 0; + } +--- gdb-7.6/gdb/stack.c ++++ gdb-7.6/gdb/stack.c +@@ -1036,23 +1036,25 @@ find_frame_funname (struct frame_info *f + changed (and we'll create a find_pc_minimal_function or some + such). */ + +- struct minimal_symbol *msymbol = NULL; ++ struct bound_minimal_symbol msymbol; + + /* Don't attempt to do this for inlined functions, which do not + have a corresponding minimal symbol. */ + if (!block_inlined_p (SYMBOL_BLOCK_VALUE (func))) + msymbol + = lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame)); ++ else ++ memset (&msymbol, 0, sizeof (msymbol)); + +- if (msymbol != NULL +- && (SYMBOL_VALUE_ADDRESS (msymbol) ++ if (msymbol.minsym != NULL ++ && (SYMBOL_VALUE_ADDRESS (msymbol.minsym) + > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) + { + /* We also don't know anything about the function besides + its address and name. */ + func = 0; +- *funname = SYMBOL_PRINT_NAME (msymbol); +- *funlang = SYMBOL_LANGUAGE (msymbol); ++ *funname = SYMBOL_PRINT_NAME (msymbol.minsym); ++ *funlang = SYMBOL_LANGUAGE (msymbol.minsym); + } + else + { +@@ -1079,17 +1081,17 @@ find_frame_funname (struct frame_info *f + } + else + { +- struct minimal_symbol *msymbol; ++ struct bound_minimal_symbol msymbol; + CORE_ADDR pc; + + if (!get_frame_address_in_block_if_available (frame, &pc)) + return; + + msymbol = lookup_minimal_symbol_by_pc (pc); +- if (msymbol != NULL) ++ if (msymbol.minsym != NULL) + { +- *funname = SYMBOL_PRINT_NAME (msymbol); +- *funlang = SYMBOL_LANGUAGE (msymbol); ++ *funname = SYMBOL_PRINT_NAME (msymbol.minsym); ++ *funlang = SYMBOL_LANGUAGE (msymbol.minsym); + } + } + } +@@ -1423,13 +1425,13 @@ frame_info (char *addr_exp, int from_tty + } + else if (frame_pc_p) + { +- struct minimal_symbol *msymbol; ++ struct bound_minimal_symbol msymbol; + + msymbol = lookup_minimal_symbol_by_pc (frame_pc); +- if (msymbol != NULL) ++ if (msymbol.minsym != NULL) + { +- funname = SYMBOL_PRINT_NAME (msymbol); +- funlang = SYMBOL_LANGUAGE (msymbol); ++ funname = SYMBOL_PRINT_NAME (msymbol.minsym); ++ funlang = SYMBOL_LANGUAGE (msymbol.minsym); + } + } + calling_frame_info = get_prev_frame (fi); +--- gdb-7.6/gdb/symtab.c ++++ gdb-7.6/gdb/symtab.c +@@ -956,7 +956,7 @@ find_pc_sect_symtab_via_partial (CORE_AD + /* If we know that this is not a text address, return failure. This is + necessary because we loop based on texthigh and textlow, which do + not include the data ranges. */ +- msymbol = lookup_minimal_symbol_by_pc_section (pc, section); ++ msymbol = lookup_minimal_symbol_by_pc_section (pc, section).minsym; + if (msymbol + && (MSYMBOL_TYPE (msymbol) == mst_data + || MSYMBOL_TYPE (msymbol) == mst_bss +@@ -2073,7 +2073,7 @@ find_pc_sect_symtab (CORE_ADDR pc, struc + addresses, which do not include the data ranges, and because + we call find_pc_sect_psymtab which has a similar restriction based + on the partial_symtab's texthigh and textlow. */ +- msymbol = lookup_minimal_symbol_by_pc_section (pc, section); ++ msymbol = lookup_minimal_symbol_by_pc_section (pc, section).minsym; + if (msymbol + && (MSYMBOL_TYPE (msymbol) == mst_data + || MSYMBOL_TYPE (msymbol) == mst_bss +@@ -2204,7 +2204,7 @@ find_pc_sect_line (CORE_ADDR pc, struct + struct linetable_entry *item; + struct symtab_and_line val; + struct blockvector *bv; +- struct minimal_symbol *msymbol; ++ struct bound_minimal_symbol msymbol; + struct minimal_symbol *mfunsym; + struct objfile *objfile; + +@@ -2290,11 +2290,12 @@ find_pc_sect_line (CORE_ADDR pc, struct + * infinite recursion. + */ + msymbol = lookup_minimal_symbol_by_pc (pc); +- if (msymbol != NULL) +- if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) ++ if (msymbol.minsym != NULL) ++ if (MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline) + { +- mfunsym = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol), +- NULL); ++ mfunsym ++ = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol.minsym), ++ NULL); + if (mfunsym == NULL) + /* I eliminated this warning since it is coming out + * in the following situation: +@@ -2310,7 +2311,7 @@ find_pc_sect_line (CORE_ADDR pc, struct + ; + /* fall through */ + else if (SYMBOL_VALUE_ADDRESS (mfunsym) +- == SYMBOL_VALUE_ADDRESS (msymbol)) ++ == SYMBOL_VALUE_ADDRESS (msymbol.minsym)) + /* Avoid infinite recursion */ + /* See above comment about why warning is commented out. */ + /* warning ("In stub for %s; unable to find real function/line info", +@@ -2823,7 +2824,7 @@ skip_prologue_sal (struct symtab_and_lin + else + { + struct minimal_symbol *msymbol +- = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section); ++ = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section).minsym; + + if (msymbol == NULL) + { +@@ -2879,8 +2880,8 @@ skip_prologue_sal (struct symtab_and_lin + if (skip && start_sal.pc != pc + && (sym ? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end + && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) +- : (lookup_minimal_symbol_by_pc_section (start_sal.end, section) +- == lookup_minimal_symbol_by_pc_section (pc, section)))) ++ : (lookup_minimal_symbol_by_pc_section (start_sal.end, section).minsym ++ == lookup_minimal_symbol_by_pc_section (pc, section).minsym))) + { + /* First pc of next line */ + pc = start_sal.end; +--- gdb-7.6/gdb/tui/tui-disasm.c ++++ gdb-7.6/gdb/tui/tui-disasm.c +@@ -121,7 +121,7 @@ tui_find_disassembly_address (struct gdb + pos = max_lines - 1; + do { + new_low -= 1 * max_lines; +- msymbol = lookup_minimal_symbol_by_pc_section (new_low, 0); ++ msymbol = lookup_minimal_symbol_by_pc_section (new_low, 0).minsym; + + if (msymbol) + new_low = SYMBOL_VALUE_ADDRESS (msymbol); +--- gdb-7.6/bfd/ChangeLog ++++ gdb-7.6/bfd/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-25 Alan Modra ++ ++ * config.bfd: Add powerpc64le-linux. ++ + 2013-03-08 Venkataramanan Kumar + + * elf64-aarch64.c (elf_backend_can_gc_sections): Enable gc-section +--- gdb-7.6/bfd/config.bfd ++++ gdb-7.6/bfd/config.bfd +@@ -1242,7 +1242,8 @@ case "${targ}" in + targ_selvecs="bfd_elf64_powerpcle_vec bfd_elf32_powerpc_vec bfd_elf32_powerpcle_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec" + want64=true + ;; +- powerpc64le-*-elf* | powerpcle-*-elf64*) ++ powerpc64le-*-elf* | powerpcle-*-elf64* | powerpc64le-*-linux* | \ ++ powerpc64le-*-*bsd*) + targ_defvec=bfd_elf64_powerpcle_vec + targ_selvecs="bfd_elf64_powerpc_vec bfd_elf32_powerpcle_vec bfd_elf32_powerpc_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec" + want64=true +--- gdb-7.6/ChangeLog ++++ gdb-7.6/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-29 Jan-Benedict Glaw ++ ++ * config.guess: Update from config repo. ++ * config.sub: Ditto. ++ + 2013-02-15 Yufeng Zhang + + * configure.ac: Sync with GCC repo. +--- gdb-7.6/config.guess ++++ gdb-7.6/config.guess +@@ -1,10 +1,8 @@ + #! /bin/sh + # Attempt to guess a canonical system name. +-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +-# 2011, 2012, 2013 Free Software Foundation, Inc. ++# Copyright 1992-2013 Free Software Foundation, Inc. + +-timestamp='2012-12-30' ++timestamp='2013-04-24' + + # This file is free software; you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by +@@ -52,9 +50,7 @@ version="\ + GNU config.guess ($timestamp) + + Originally written by Per Bothner. +-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, +-2012, 2013 Free Software Foundation, Inc. ++Copyright 1992-2013 Free Software Foundation, Inc. + + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." +@@ -887,6 +883,9 @@ EOF + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; ++ arc:Linux:*:* | arceb:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-gnu ++ exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ +@@ -925,6 +924,11 @@ EOF + #ifdef __dietlibc__ + LIBC=dietlibc + #endif ++ #else ++ #include ++ #ifdef __UCLIBC__ ++ LIBC=uclibc ++ #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" +@@ -957,6 +961,9 @@ EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; ++ or1k:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-gnu ++ exit ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; +@@ -999,7 +1006,9 @@ EOF + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ LIBC=gnu ++ test -r /lib/libc.so && od -An -S13 /lib/libc.so | grep -q __uClibc_main && LIBC=uclibc ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu +--- gdb-7.6/config.sub ++++ gdb-7.6/config.sub +@@ -1,10 +1,8 @@ + #! /bin/sh + # Configuration validation subroutine script. +-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +-# 2011, 2012, 2013 Free Software Foundation, Inc. ++# Copyright 1992-2013 Free Software Foundation, Inc. + +-timestamp='2013-01-11' ++timestamp='2013-04-24' + + # This file is free software; you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by +@@ -70,9 +68,7 @@ Report bugs and patches to ++ ++ * ppc-tdep.h (ppc_insns_match_pattern): Update prototype. ++ * rs6000-tdep.c (read_insn): Add frame param, don't assume big-endian. ++ (ppc_insns_match_pattern): Add frame param. Avoid multiple ++ target mem reads on optional insns. ++ * ppc-linux-tdep.c (ppc_skip_trampoline_code): Update ++ ppc_insns_match_pattern calls. ++ * ppc64-tdep.c (ppc64_standard_linkage2, ppc64_standard_linkage3): ++ Add match for power7 thread safety insns, and new order of ++ std 2,40(1) insn. Correct code shown for _dl_runtime_resolve ++ invocation in comment, and update rest of comment. ++ (PPC64_STANDARD_LINKAGE1_LEN, PPC64_STANDARD_LINKAGE2_LEN, ++ PPC64_STANDARD_LINKAGE3_LEN): Delete. ++ (ppc64_standard_linkage2_target): Update insn offsets. ++ (ppc64_skip_trampoline_code): Use a single insn buffer. Match newer ++ stubs first. Update calls. ++ + 2013-04-26 Joel Brobecker + + * NEWS: Change "since GDB 7.5" into "in GDB 7.6". +--- gdb-7.6/gdb/ppc-linux-tdep.c ++++ gdb-7.6/gdb/ppc-linux-tdep.c +@@ -361,7 +361,7 @@ ppc_skip_trampoline_code (struct frame_i + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + CORE_ADDR target = 0; + +- if (ppc_insns_match_pattern (pc, powerpc32_plt_stub, insnbuf)) ++ if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf)) + { + /* Insn pattern is + lis r11, xxxx +@@ -373,7 +373,7 @@ ppc_skip_trampoline_code (struct frame_i + target = read_memory_unsigned_integer (target, 4, byte_order); + } + +- if (ppc_insns_match_pattern (pc, powerpc32_plt_stub_so, insnbuf)) ++ if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf)) + { + /* Insn pattern is + lwz r11, xxxx(r30) +--- gdb-7.6/gdb/ppc-tdep.h ++++ gdb-7.6/gdb/ppc-tdep.h +@@ -300,9 +300,9 @@ struct ppc_insn_pattern + int optional; /* If non-zero, this insn may be absent. */ + }; + +-extern int ppc_insns_match_pattern (CORE_ADDR pc, ++extern int ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc, + struct ppc_insn_pattern *pattern, +- unsigned int *insn); ++ unsigned int *insns); + extern CORE_ADDR ppc_insn_d_field (unsigned int insn); + + extern CORE_ADDR ppc_insn_ds_field (unsigned int insn); +--- gdb-7.6/gdb/ppc64-tdep.c ++++ gdb-7.6/gdb/ppc64-tdep.c +@@ -59,9 +59,10 @@ ppc64_desc_entry_point (struct gdbarch * + return (CORE_ADDR) read_memory_unsigned_integer (desc, 8, byte_order); + } + +-/* Pattern for the standard linkage function. These are built by +- build_plt_stub in elf64-ppc.c, whose GLINK argument is always +- zero. */ ++/* Patterns for the standard linkage functions. These are built by ++ build_plt_stub in bfd/elf64-ppc.c. */ ++ ++/* Old PLT call stub. */ + + static struct ppc_insn_pattern ppc64_standard_linkage1[] = + { +@@ -95,15 +96,23 @@ static struct ppc_insn_pattern ppc64_sta + { 0, 0, 0 } + }; + +-#define PPC64_STANDARD_LINKAGE1_LEN ARRAY_SIZE (ppc64_standard_linkage1) ++/* Current PLT call stub to access PLT entries more than +/- 32k from r2. ++ Also supports older stub with different placement of std 2,40(1), ++ a stub that omits the std 2,40(1), and both versions of power7 ++ thread safety read barriers. Note that there are actually two more ++ instructions following "cmpldi r2, 0", "bnectr+" and "b ", ++ but there isn't any need to match them. */ + + static struct ppc_insn_pattern ppc64_standard_linkage2[] = + { ++ /* std r2, 40(r1) */ ++ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, ++ + /* addis r12, r2, */ + { insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 }, + +- /* std r2, 40(r1) */ +- { -1, insn_ds (62, 2, 1, 40, 0), 0 }, ++ /* std r2, 40(r1) */ ++ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, + + /* ld r11, (r12) */ + { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 }, +@@ -114,24 +123,33 @@ static struct ppc_insn_pattern ppc64_sta + /* mtctr r11 */ + { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 }, + ++ /* xor r11, r11, r11 */ ++ { -1, 0x7d6b5a78, 1 }, ++ ++ /* add r12, r12, r11 */ ++ { -1, 0x7d8c5a14, 1 }, ++ + /* ld r2, (r12) */ + { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 }, + + /* ld r11, (r12) */ + { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 1 }, + +- /* bctr */ +- { -1, 0x4e800420, 0 }, ++ /* bctr */ ++ { -1, 0x4e800420, 1 }, ++ ++ /* cmpldi r2, 0 */ ++ { -1, 0x28220000, 1 }, + + { 0, 0, 0 } + }; + +-#define PPC64_STANDARD_LINKAGE2_LEN ARRAY_SIZE (ppc64_standard_linkage2) ++/* Current PLT call stub to access PLT entries within +/- 32k of r2. */ + + static struct ppc_insn_pattern ppc64_standard_linkage3[] = + { +- /* std r2, 40(r1) */ +- { -1, insn_ds (62, 2, 1, 40, 0), 0 }, ++ /* std r2, 40(r1) */ ++ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, + + /* ld r11, (r2) */ + { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 0 }, +@@ -142,56 +160,71 @@ static struct ppc_insn_pattern ppc64_sta + /* mtctr r11 */ + { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 }, + ++ /* xor r11, r11, r11 */ ++ { -1, 0x7d6b5a78, 1 }, ++ ++ /* add r2, r2, r11 */ ++ { -1, 0x7c425a14, 1 }, ++ + /* ld r11, (r2) */ + { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 1 }, + + /* ld r2, (r2) */ + { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 2, 0, 0), 0 }, + +- /* bctr */ +- { -1, 0x4e800420, 0 }, ++ /* bctr */ ++ { -1, 0x4e800420, 1 }, ++ ++ /* cmpldi r2, 0 */ ++ { -1, 0x28220000, 1 }, + + { 0, 0, 0 } + }; + +-#define PPC64_STANDARD_LINKAGE3_LEN ARRAY_SIZE (ppc64_standard_linkage3) +- + /* When the dynamic linker is doing lazy symbol resolution, the first + call to a function in another object will go like this: + + - The user's function calls the linkage function: + +- 100007c4: 4b ff fc d5 bl 10000498 +- 100007c8: e8 41 00 28 ld r2,40(r1) ++ 100003d4: 4b ff ff ad bl 10000380 ++ 100003d8: e8 41 00 28 ld r2,40(r1) + +- - The linkage function loads the entry point (and other stuff) from +- the function descriptor in the PLT, and jumps to it: ++ - The linkage function loads the entry point and toc pointer from ++ the function descriptor in the PLT, and jumps to it: + +- 10000498: 3d 82 00 00 addis r12,r2,0 +- 1000049c: f8 41 00 28 std r2,40(r1) +- 100004a0: e9 6c 80 98 ld r11,-32616(r12) +- 100004a4: e8 4c 80 a0 ld r2,-32608(r12) +- 100004a8: 7d 69 03 a6 mtctr r11 +- 100004ac: e9 6c 80 a8 ld r11,-32600(r12) +- 100004b0: 4e 80 04 20 bctr ++ : ++ 10000380: f8 41 00 28 std r2,40(r1) ++ 10000384: e9 62 80 78 ld r11,-32648(r2) ++ 10000388: 7d 69 03 a6 mtctr r11 ++ 1000038c: e8 42 80 80 ld r2,-32640(r2) ++ 10000390: 28 22 00 00 cmpldi r2,0 ++ 10000394: 4c e2 04 20 bnectr+ ++ 10000398: 48 00 03 a0 b 10000738 + + - But since this is the first time that PLT entry has been used, it +- sends control to its glink entry. That loads the number of the +- PLT entry and jumps to the common glink0 code: ++ sends control to its glink entry. That loads the number of the ++ PLT entry and jumps to the common glink0 code: + +- 10000c98: 38 00 00 00 li r0,0 +- 10000c9c: 4b ff ff dc b 10000c78 ++ : ++ 10000738: 38 00 00 01 li r0,1 ++ 1000073c: 4b ff ff bc b 100006f8 <__glink_PLTresolve> + + - The common glink0 code then transfers control to the dynamic +- linker's fixup code: ++ linker's fixup code: + +- 10000c78: e8 41 00 28 ld r2,40(r1) +- 10000c7c: 3d 82 00 00 addis r12,r2,0 +- 10000c80: e9 6c 80 80 ld r11,-32640(r12) +- 10000c84: e8 4c 80 88 ld r2,-32632(r12) +- 10000c88: 7d 69 03 a6 mtctr r11 +- 10000c8c: e9 6c 80 90 ld r11,-32624(r12) +- 10000c90: 4e 80 04 20 bctr ++ 100006f0: 0000000000010440 .quad plt0 - (. + 16) ++ <__glink_PLTresolve>: ++ 100006f8: 7d 88 02 a6 mflr r12 ++ 100006fc: 42 9f 00 05 bcl 20,4*cr7+so,10000700 ++ 10000700: 7d 68 02 a6 mflr r11 ++ 10000704: e8 4b ff f0 ld r2,-16(r11) ++ 10000708: 7d 88 03 a6 mtlr r12 ++ 1000070c: 7d 82 5a 14 add r12,r2,r11 ++ 10000710: e9 6c 00 00 ld r11,0(r12) ++ 10000714: e8 4c 00 08 ld r2,8(r12) ++ 10000718: 7d 69 03 a6 mtctr r11 ++ 1000071c: e9 6c 00 10 ld r11,16(r12) ++ 10000720: 4e 80 04 20 bctr + + Eventually, this code will figure out how to skip all of this, + including the dynamic linker. At the moment, we just get through +@@ -234,8 +267,8 @@ ppc64_standard_linkage2_target (struct f + CORE_ADDR desc + = ((CORE_ADDR) get_frame_register_unsigned (frame, + tdep->ppc_gp0_regnum + 2) +- + (ppc_insn_d_field (insn[0]) << 16) +- + ppc_insn_ds_field (insn[2])); ++ + (ppc_insn_d_field (insn[1]) << 16) ++ + ppc_insn_ds_field (insn[3])); + + /* The first word of the descriptor is the entry point. Return that. */ + return ppc64_desc_entry_point (gdbarch, desc); +@@ -266,23 +299,20 @@ ppc64_standard_linkage3_target (struct f + CORE_ADDR + ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) + { +- unsigned int ppc64_standard_linkage1_insn[PPC64_STANDARD_LINKAGE1_LEN]; +- unsigned int ppc64_standard_linkage2_insn[PPC64_STANDARD_LINKAGE2_LEN]; +- unsigned int ppc64_standard_linkage3_insn[PPC64_STANDARD_LINKAGE3_LEN]; ++#define MAX(a,b) ((a) > (b) ? (a) : (b)) ++ unsigned int insns[MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1), ++ ARRAY_SIZE (ppc64_standard_linkage2)), ++ ARRAY_SIZE (ppc64_standard_linkage3)) - 1]; + CORE_ADDR target; + +- if (ppc_insns_match_pattern (pc, ppc64_standard_linkage1, +- ppc64_standard_linkage1_insn)) +- pc = ppc64_standard_linkage1_target (frame, pc, +- ppc64_standard_linkage1_insn); +- else if (ppc_insns_match_pattern (pc, ppc64_standard_linkage2, +- ppc64_standard_linkage2_insn)) +- pc = ppc64_standard_linkage2_target (frame, pc, +- ppc64_standard_linkage2_insn); +- else if (ppc_insns_match_pattern (pc, ppc64_standard_linkage3, +- ppc64_standard_linkage3_insn)) +- pc = ppc64_standard_linkage3_target (frame, pc, +- ppc64_standard_linkage3_insn); ++ if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns) ++ && (insns[8] != 0 || insns[9] != 0)) ++ pc = ppc64_standard_linkage3_target (frame, pc, insns); ++ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns) ++ && (insns[10] != 0 || insns[11] != 0)) ++ pc = ppc64_standard_linkage2_target (frame, pc, insns); ++ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns)) ++ pc = ppc64_standard_linkage1_target (frame, pc, insns); + else + return 0; + +--- gdb-7.6/gdb/rs6000-tdep.c ++++ gdb-7.6/gdb/rs6000-tdep.c +@@ -4238,14 +4238,15 @@ show_powerpc_exact_watchpoints (struct u + fprintf_filtered (file, _("Use of exact watchpoints is %s.\n"), value); + } + +-/* Read a PPC instruction from memory. PPC instructions are always +- big-endian, no matter what endianness the program is running in, so +- we can hardcode BFD_ENDIAN_BIG for read_memory_unsigned_integer. */ ++/* Read a PPC instruction from memory. */ + + static unsigned int +-read_insn (CORE_ADDR pc) ++read_insn (struct frame_info *frame, CORE_ADDR pc) + { +- return read_memory_unsigned_integer (pc, 4, BFD_ENDIAN_BIG); ++ struct gdbarch *gdbarch = get_frame_arch (frame); ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ ++ return read_memory_unsigned_integer (pc, 4, byte_order); + } + + /* Return non-zero if the instructions at PC match the series +@@ -4262,19 +4263,25 @@ read_insn (CORE_ADDR pc) + i'th instruction in memory. */ + + int +-ppc_insns_match_pattern (CORE_ADDR pc, struct ppc_insn_pattern *pattern, +- unsigned int *insn) ++ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc, ++ struct ppc_insn_pattern *pattern, ++ unsigned int *insns) + { + int i; ++ unsigned int insn; + +- for (i = 0; pattern[i].mask; i++) ++ for (i = 0, insn = 0; pattern[i].mask; i++) + { +- insn[i] = read_insn (pc); +- if ((insn[i] & pattern[i].mask) == pattern[i].data) +- pc += 4; +- else if (pattern[i].optional) +- insn[i] = 0; +- else ++ if (insn == 0) ++ insn = read_insn (frame, pc); ++ insns[i] = 0; ++ if ((insn & pattern[i].mask) == pattern[i].data) ++ { ++ insns[i] = insn; ++ pc += 4; ++ insn = 0; ++ } ++ else if (!pattern[i].optional) + return 0; + } + +--- gdb-7.6/include/ChangeLog ++++ gdb-7.6/include/ChangeLog +@@ -1,3 +1,13 @@ ++2013-08-20 Alan Modra ++ ++ * floatformat.h (floatformat_ibm_long_double): Delete. ++ (floatformat_ibm_long_double_big): Declare. ++ (floatformat_ibm_long_double_little): Declare. ++ ++2013-08-19 Dehao Chen ++ ++ * dwarf2.def (DW_AT_GNU_discriminator): New attribute. ++ + 2013-03-12 Sebastian Huber + + * opcode/nios2.h: Edit comment. +--- gdb-7.6/include/dwarf2.def ++++ gdb-7.6/include/dwarf2.def +@@ -390,6 +390,9 @@ DW_AT (DW_AT_GNU_ranges_base, 0x2132) + DW_AT (DW_AT_GNU_addr_base, 0x2133) + DW_AT (DW_AT_GNU_pubnames, 0x2134) + DW_AT (DW_AT_GNU_pubtypes, 0x2135) ++/* Attribute for discriminator. ++ See http://gcc.gnu.org/wiki/Discriminator */ ++DW_AT (DW_AT_GNU_discriminator, 0x2136) + /* VMS extensions. */ + DW_AT (DW_AT_VMS_rtnbeg_pd_address, 0x2201) + /* GNAT extensions. */ +--- gdb-7.6/include/floatformat.h ++++ gdb-7.6/include/floatformat.h +@@ -128,7 +128,8 @@ extern const struct floatformat floatfor + extern const struct floatformat floatformat_ia64_quad_big; + extern const struct floatformat floatformat_ia64_quad_little; + /* IBM long double (double+double). */ +-extern const struct floatformat floatformat_ibm_long_double; ++extern const struct floatformat floatformat_ibm_long_double_big; ++extern const struct floatformat floatformat_ibm_long_double_little; + + /* Convert from FMT to a double. + FROM is the address of the extended float. +--- gdb-7.6/libiberty/ChangeLog ++++ gdb-7.6/libiberty/ChangeLog +@@ -1,3 +1,9 @@ ++2013-08-20 Alan Modra ++ ++ * floatformat.c (floatformat_ibm_long_double): Rename to.. ++ (floatformat_ibm_long_double_big): ..this. ++ (floatformat_ibm_long_double_little): New. ++ + 2013-03-01 Andreas Schwab + + * obstacks.texi (Obstacks): Trim @node to only contain the +--- gdb-7.6/libiberty/floatformat.c ++++ gdb-7.6/libiberty/floatformat.c +@@ -371,14 +371,23 @@ floatformat_ibm_long_double_is_valid (co + } + } + +-const struct floatformat floatformat_ibm_long_double = ++const struct floatformat floatformat_ibm_long_double_big = + { + floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52, + floatformat_intbit_no, +- "floatformat_ibm_long_double", ++ "floatformat_ibm_long_double_big", + floatformat_ibm_long_double_is_valid, + &floatformat_ieee_double_big + }; ++ ++const struct floatformat floatformat_ibm_long_double_little = ++{ ++ floatformat_little, 128, 0, 1, 11, 1023, 2047, 12, 52, ++ floatformat_intbit_no, ++ "floatformat_ibm_long_double_little", ++ floatformat_ibm_long_double_is_valid, ++ &floatformat_ieee_double_little ++}; + + + #ifndef min +--- gdb-7.6/gdb/ChangeLog ++++ gdb-7.6/gdb/ChangeLog +@@ -1,3 +1,18 @@ ++2013-11-15 Alan Modra ++ ++ * ppc64-tdep.c (ppc64_plt_entry_point): Renamed from.. ++ (ppc64_desc_entry_point): ..this. Update comments here and at ++ call points. ++ (ppc64_standard_linkage1, ppc64_standard_linkage2, ++ ppc64_standard_linkage3): Update comments. ++ (ppc64_standard_linkage4, ppc64_standard_linkage5, ++ (ppc64_standard_linkage6, ppc64_standard_linkage7): New insn ++ patterns. ++ (ppc64_standard_linkage4_target): New function. ++ (ppc64_skip_trampoline_code): Skip ELFv2 patterns too. ++ * rs6000-tdep.c (skip_prologue): Skip ELFv2 r2 setup. Correct ++ nop match. Fix comment wrap. ++ + 2013-06-04 Alan Modra + + * ppc-tdep.h (ppc_insns_match_pattern): Update prototype. +--- gdb-7.6/gdb/ppc64-tdep.c ++++ gdb-7.6/gdb/ppc64-tdep.c +@@ -48,21 +48,21 @@ + | (((spr) & 0x3e0) << 6) \ + | (((xo) & 0x3ff) << 1)) + +-/* If DESC is the address of a 64-bit PowerPC FreeBSD function +- descriptor, return the descriptor's entry point. */ ++/* If PLT is the address of a 64-bit PowerPC PLT entry, ++ return the function's entry point. */ + + static CORE_ADDR +-ppc64_desc_entry_point (struct gdbarch *gdbarch, CORE_ADDR desc) ++ppc64_plt_entry_point (struct gdbarch *gdbarch, CORE_ADDR plt) + { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +- /* The first word of the descriptor is the entry point. */ +- return (CORE_ADDR) read_memory_unsigned_integer (desc, 8, byte_order); ++ /* The first word of the PLT entry is the function entry point. */ ++ return (CORE_ADDR) read_memory_unsigned_integer (plt, 8, byte_order); + } + + /* Patterns for the standard linkage functions. These are built by + build_plt_stub in bfd/elf64-ppc.c. */ + +-/* Old PLT call stub. */ ++/* Old ELFv1 PLT call stub. */ + + static struct ppc_insn_pattern ppc64_standard_linkage1[] = + { +@@ -96,7 +96,7 @@ static struct ppc_insn_pattern ppc64_sta + { 0, 0, 0 } + }; + +-/* Current PLT call stub to access PLT entries more than +/- 32k from r2. ++/* ELFv1 PLT call stub to access PLT entries more than +/- 32k from r2. + Also supports older stub with different placement of std 2,40(1), + a stub that omits the std 2,40(1), and both versions of power7 + thread safety read barriers. Note that there are actually two more +@@ -144,7 +144,7 @@ static struct ppc_insn_pattern ppc64_sta + { 0, 0, 0 } + }; + +-/* Current PLT call stub to access PLT entries within +/- 32k of r2. */ ++/* ELFv1 PLT call stub to access PLT entries within +/- 32k of r2. */ + + static struct ppc_insn_pattern ppc64_standard_linkage3[] = + { +@@ -181,6 +181,128 @@ static struct ppc_insn_pattern ppc64_sta + { 0, 0, 0 } + }; + ++/* ELFv1 PLT call stub to access PLT entries more than +/- 32k from r2. ++ A more modern variant of ppc64_standard_linkage2 differing in ++ register usage. */ ++ ++static struct ppc_insn_pattern ppc64_standard_linkage4[] = ++ { ++ /* std r2, 40(r1) */ ++ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, ++ ++ /* addis r11, r2, */ ++ { insn_d (-1, -1, -1, 0), insn_d (15, 11, 2, 0), 0 }, ++ ++ /* ld r12, (r11) */ ++ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 11, 0, 0), 0 }, ++ ++ /* addi r11, r11, */ ++ { insn_d (-1, -1, -1, 0), insn_d (14, 11, 11, 0), 1 }, ++ ++ /* mtctr r12 */ ++ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, ++ ++ /* xor r2, r12, r12 */ ++ { -1, 0x7d826278, 1 }, ++ ++ /* add r11, r11, r2 */ ++ { -1, 0x7d6b1214, 1 }, ++ ++ /* ld r2, (r11) */ ++ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 11, 0, 0), 0 }, ++ ++ /* ld r11, (r11) */ ++ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 11, 0, 0), 1 }, ++ ++ /* bctr */ ++ { -1, 0x4e800420, 1 }, ++ ++ /* cmpldi r2, 0 */ ++ { -1, 0x28220000, 1 }, ++ ++ { 0, 0, 0 } ++ }; ++ ++/* ELFv1 PLT call stub to access PLT entries within +/- 32k of r2. ++ A more modern variant of ppc64_standard_linkage3 differing in ++ register usage. */ ++ ++static struct ppc_insn_pattern ppc64_standard_linkage5[] = ++ { ++ /* std r2, 40(r1) */ ++ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, ++ ++ /* ld r12, (r2) */ ++ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 }, ++ ++ /* addi r2, r2, */ ++ { insn_d (-1, -1, -1, 0), insn_d (14, 2, 2, 0), 1 }, ++ ++ /* mtctr r12 */ ++ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, ++ ++ /* xor r11, r12, r12 */ ++ { -1, 0x7d8b6278, 1 }, ++ ++ /* add r2, r2, r11 */ ++ { -1, 0x7c425a14, 1 }, ++ ++ /* ld r11, (r2) */ ++ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 1 }, ++ ++ /* ld r2, (r2) */ ++ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 2, 0, 0), 0 }, ++ ++ /* bctr */ ++ { -1, 0x4e800420, 1 }, ++ ++ /* cmpldi r2, 0 */ ++ { -1, 0x28220000, 1 }, ++ ++ { 0, 0, 0 } ++ }; ++ ++/* ELFv2 PLT call stub to access PLT entries more than +/- 32k from r2. */ ++ ++static struct ppc_insn_pattern ppc64_standard_linkage6[] = ++ { ++ /* std r2, 24(r1) */ ++ { -1, insn_ds (62, 2, 1, 24, 0), 1 }, ++ ++ /* addis r11, r2, */ ++ { insn_d (-1, -1, -1, 0), insn_d (15, 11, 2, 0), 0 }, ++ ++ /* ld r12, (r11) */ ++ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 11, 0, 0), 0 }, ++ ++ /* mtctr r12 */ ++ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, ++ ++ /* bctr */ ++ { -1, 0x4e800420, 0 }, ++ ++ { 0, 0, 0 } ++ }; ++ ++/* ELFv2 PLT call stub to access PLT entries within +/- 32k of r2. */ ++ ++static struct ppc_insn_pattern ppc64_standard_linkage7[] = ++ { ++ /* std r2, 24(r1) */ ++ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, ++ ++ /* ld r12, (r2) */ ++ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 }, ++ ++ /* mtctr r12 */ ++ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, ++ ++ /* bctr */ ++ { -1, 0x4e800420, 0 }, ++ ++ { 0, 0, 0 } ++ }; ++ + /* When the dynamic linker is doing lazy symbol resolution, the first + call to a function in another object will go like this: + +@@ -243,16 +365,14 @@ ppc64_standard_linkage1_target (struct f + struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + +- /* The address of the function descriptor this linkage function +- references. */ +- CORE_ADDR desc ++ /* The address of the PLT entry this linkage function references. */ ++ CORE_ADDR plt + = ((CORE_ADDR) get_frame_register_unsigned (frame, + tdep->ppc_gp0_regnum + 2) + + (ppc_insn_d_field (insn[0]) << 16) + + ppc_insn_ds_field (insn[2])); + +- /* The first word of the descriptor is the entry point. Return that. */ +- return ppc64_desc_entry_point (gdbarch, desc); ++ return ppc64_plt_entry_point (gdbarch, plt); + } + + static CORE_ADDR +@@ -262,16 +382,14 @@ ppc64_standard_linkage2_target (struct f + struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + +- /* The address of the function descriptor this linkage function +- references. */ +- CORE_ADDR desc ++ /* The address of the PLT entry this linkage function references. */ ++ CORE_ADDR plt + = ((CORE_ADDR) get_frame_register_unsigned (frame, + tdep->ppc_gp0_regnum + 2) + + (ppc_insn_d_field (insn[1]) << 16) + + ppc_insn_ds_field (insn[3])); + +- /* The first word of the descriptor is the entry point. Return that. */ +- return ppc64_desc_entry_point (gdbarch, desc); ++ return ppc64_plt_entry_point (gdbarch, plt); + } + + static CORE_ADDR +@@ -281,15 +399,28 @@ ppc64_standard_linkage3_target (struct f + struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + +- /* The address of the function descriptor this linkage function +- references. */ +- CORE_ADDR desc ++ /* The address of the PLT entry this linkage function references. */ ++ CORE_ADDR plt + = ((CORE_ADDR) get_frame_register_unsigned (frame, + tdep->ppc_gp0_regnum + 2) + + ppc_insn_ds_field (insn[1])); + +- /* The first word of the descriptor is the entry point. Return that. */ +- return ppc64_desc_entry_point (gdbarch, desc); ++ return ppc64_plt_entry_point (gdbarch, plt); ++} ++ ++static CORE_ADDR ++ppc64_standard_linkage4_target (struct frame_info *frame, ++ CORE_ADDR pc, unsigned int *insn) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (frame); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++ CORE_ADDR plt ++ = ((CORE_ADDR) get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 2) ++ + (ppc_insn_d_field (insn[1]) << 16) ++ + ppc_insn_ds_field (insn[2])); ++ ++ return ppc64_plt_entry_point (gdbarch, plt); + } + + +@@ -300,13 +431,27 @@ CORE_ADDR + ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) + { + #define MAX(a,b) ((a) > (b) ? (a) : (b)) +- unsigned int insns[MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1), +- ARRAY_SIZE (ppc64_standard_linkage2)), +- ARRAY_SIZE (ppc64_standard_linkage3)) - 1]; ++ unsigned int insns[MAX (MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1), ++ ARRAY_SIZE (ppc64_standard_linkage2)), ++ MAX (ARRAY_SIZE (ppc64_standard_linkage3), ++ ARRAY_SIZE (ppc64_standard_linkage4))), ++ MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage5), ++ ARRAY_SIZE (ppc64_standard_linkage6)), ++ ARRAY_SIZE (ppc64_standard_linkage7))) - 1]; + CORE_ADDR target; + +- if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns) +- && (insns[8] != 0 || insns[9] != 0)) ++ if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns)) ++ pc = ppc64_standard_linkage3_target (frame, pc, insns); ++ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, insns)) ++ pc = ppc64_standard_linkage4_target (frame, pc, insns); ++ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5, insns) ++ && (insns[8] != 0 || insns[9] != 0)) ++ pc = ppc64_standard_linkage3_target (frame, pc, insns); ++ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4, insns) ++ && (insns[9] != 0 || insns[10] != 0)) ++ pc = ppc64_standard_linkage4_target (frame, pc, insns); ++ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns) ++ && (insns[8] != 0 || insns[9] != 0)) + pc = ppc64_standard_linkage3_target (frame, pc, insns); + else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns) + && (insns[10] != 0 || insns[11] != 0)) +--- gdb-7.6/gdb/rs6000-tdep.c ++++ gdb-7.6/gdb/rs6000-tdep.c +@@ -1616,7 +1616,19 @@ skip_prologue (struct gdbarch *gdbarch, + continue; + + } +- else if ((op & 0xffff0000) == 0x60000000) ++ else if ((op & 0xffff0000) == 0x3c4c0000 ++ || (op & 0xffff0000) == 0x3c400000 ++ || (op & 0xffff0000) == 0x38420000) ++ { ++ /* . 0: addis 2,12,.TOC.-0b@ha ++ . addi 2,2,.TOC.-0b@l ++ or ++ . lis 2,.TOC.@ha ++ . addi 2,2,.TOC.@l ++ used by ELFv2 global entry points to set up r2. */ ++ continue; ++ } ++ else if (op == 0x60000000) + { + /* nop */ + /* Allow nops in the prologue, but do not consider them to +@@ -1627,8 +1639,7 @@ skip_prologue (struct gdbarch *gdbarch, + + } + else if ((op & 0xffff0000) == 0x3c000000) +- { /* addis 0,0,NUM, used +- for >= 32k frames */ ++ { /* addis 0,0,NUM, used for >= 32k frames */ + fdata->offset = (op & 0x0000ffff) << 16; + fdata->frameless = 0; + r0_contains_arg = 0; +@@ -1636,8 +1647,7 @@ skip_prologue (struct gdbarch *gdbarch, + + } + else if ((op & 0xffff0000) == 0x60000000) +- { /* ori 0,0,NUM, 2nd ha +- lf of >= 32k frames */ ++ { /* ori 0,0,NUM, 2nd half of >= 32k frames */ + fdata->offset |= (op & 0x0000ffff); + fdata->frameless = 0; + r0_contains_arg = 0; +--- gdb-7.6/ChangeLog ++++ gdb-7.6/ChangeLog +@@ -1,3 +1,7 @@ ++2013-11-23 Alan Modra ++ ++ * config.sub, config.guess: Import from upstream. ++ + 2013-04-29 Jan-Benedict Glaw + + * config.guess: Update from config repo. +--- gdb-7.6/config.guess ++++ gdb-7.6/config.guess +@@ -2,7 +2,7 @@ + # Attempt to guess a canonical system name. + # Copyright 1992-2013 Free Software Foundation, Inc. + +-timestamp='2013-04-24' ++timestamp='2013-06-10' + + # This file is free software; you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by +@@ -132,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` | + UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown + UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + ++case "${UNAME_SYSTEM}" in ++Linux|GNU|GNU/*) ++ # If the system lacks a compiler, then just pick glibc. ++ # We could probably try harder. ++ LIBC=gnu ++ ++ eval $set_cc_for_build ++ cat <<-EOF > $dummy.c ++ #include ++ #if defined(__UCLIBC__) ++ LIBC=uclibc ++ #elif defined(__dietlibc__) ++ LIBC=dietlibc ++ #else ++ LIBC=gnu ++ #endif ++ EOF ++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` ++ ;; ++esac ++ + # Note: order is significant - the case branches are not exclusive. + + case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +@@ -853,21 +874,21 @@ EOF + exit ;; + *:GNU:*:*) + # the GNU system +- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` ++ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland +- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu ++ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in +@@ -880,67 +901,54 @@ EOF + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 +- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi +- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ++ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then +- echo ${UNAME_MACHINE}-unknown-linux-gnueabi ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else +- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) +- echo ${UNAME_MACHINE}-axis-linux-gnu ++ echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) +- echo ${UNAME_MACHINE}-axis-linux-gnu ++ echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) +- LIBC=gnu +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +- #ifdef __dietlibc__ +- LIBC=dietlibc +- #endif +- #else +- #include +- #ifdef __UCLIBC__ +- LIBC=uclibc +- #endif +-EOF +- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` +- echo "${UNAME_MACHINE}-pc-linux-${LIBC}" ++ echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build +@@ -959,59 +967,63 @@ EOF + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` +- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ++ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + or1k:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) +- echo sparc-unknown-linux-gnu ++ echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) +- echo hppa64-unknown-linux-gnu ++ echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in +- PA7*) echo hppa1.1-unknown-linux-gnu ;; +- PA8*) echo hppa2.0-unknown-linux-gnu ;; +- *) echo hppa-unknown-linux-gnu ;; ++ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; ++ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; ++ *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) +- echo powerpc64-unknown-linux-gnu ++ echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) +- echo powerpc-unknown-linux-gnu ++ echo powerpc-unknown-linux-${LIBC} ++ exit ;; ++ ppc64le:Linux:*:*) ++ echo powerpc64le-unknown-linux-${LIBC} ++ exit ;; ++ ppcle:Linux:*:*) ++ echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) +- echo ${UNAME_MACHINE}-ibm-linux ++ echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) +- echo ${UNAME_MACHINE}-dec-linux-gnu ++ echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) +- LIBC=gnu +- test -r /lib/libc.so && od -An -S13 /lib/libc.so | grep -q __uClibc_main && LIBC=uclibc + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. +@@ -1244,19 +1256,21 @@ EOF + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown +- case $UNAME_PROCESSOR in +- i386) +- eval $set_cc_for_build +- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then +- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ +- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ +- grep IS_64BIT_ARCH >/dev/null +- then +- UNAME_PROCESSOR="x86_64" +- fi +- fi ;; +- unknown) UNAME_PROCESSOR=powerpc ;; +- esac ++ eval $set_cc_for_build ++ if test "$UNAME_PROCESSOR" = unknown ; then ++ UNAME_PROCESSOR=powerpc ++ fi ++ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then ++ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ ++ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ ++ grep IS_64BIT_ARCH >/dev/null ++ then ++ case $UNAME_PROCESSOR in ++ i386) UNAME_PROCESSOR=x86_64 ;; ++ powerpc) UNAME_PROCESSOR=powerpc64 ;; ++ esac ++ fi ++ fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) +--- gdb-7.6/config.sub ++++ gdb-7.6/config.sub +@@ -2,7 +2,7 @@ + # Configuration validation subroutine script. + # Copyright 1992-2013 Free Software Foundation, Inc. + +-timestamp='2013-04-24' ++timestamp='2013-10-01' + + # This file is free software; you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by +@@ -257,7 +257,7 @@ case $basic_machine in + | avr | avr32 \ + | be32 | be64 \ + | bfin \ +- | c4x | clipper \ ++ | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ +@@ -265,6 +265,7 @@ case $basic_machine in + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ ++ | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ +@@ -324,7 +325,7 @@ case $basic_machine in + c6x) + basic_machine=tic6x-unknown + ;; +- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) ++ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; +@@ -372,7 +373,7 @@ case $basic_machine in + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ +- | clipper-* | craynv-* | cydra-* \ ++ | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ +@@ -381,6 +382,7 @@ case $basic_machine in + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ ++ | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ +@@ -794,7 +796,7 @@ case $basic_machine in + os=-mingw64 + ;; + mingw32) +- basic_machine=i386-pc ++ basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) +@@ -830,7 +832,7 @@ case $basic_machine in + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) +- basic_machine=i386-pc ++ basic_machine=i686-pc + os=-msys + ;; + mvs) +@@ -1546,6 +1548,9 @@ case $basic_machine in + c4x-* | tic4x-*) + os=-coff + ;; ++ c8051-*) ++ os=-elf ++ ;; + hexagon-*) + os=-elf + ;; +--- gdb-7.6/gdb/auxv.c ++++ gdb-7.6/gdb/auxv.c +@@ -441,6 +441,7 @@ fprint_target_auxv (struct ui_file *file + TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec); + TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str); + TAG (AT_RANDOM, _("Address of 16 random bytes"), hex); ++ TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), hex); + TAG (AT_EXECFN, _("File name of executable"), str); + TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec); + TAG (AT_SYSINFO, _("Special system info/entry points"), hex); +--- gdb-7.6/gdb/configure.host ++++ gdb-7.6/gdb/configure.host +@@ -129,18 +129,18 @@ mips64*-*-openbsd*) gdb_host=obsd64 ;; + powerpc-*-aix* | rs6000-*-*) + gdb_host=aix ;; + powerpc*-*-freebsd*) gdb_host=fbsd ;; +-powerpc-*-linux*) gdb_host=linux ;; + powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu) + gdb_host=nbsd ;; + powerpc-*-openbsd*) gdb_host=obsd ;; + +-powerpc64-*-linux*) gdb_host=ppc64-linux ++powerpc64*-*-linux*) gdb_host=ppc64-linux + # Support 'pseudo-native' debugging on the Cell BE + if test "${target_cpu}" = "spu"; then + gdb_host=spu-linux + gdb_native=yes + fi + ;; ++powerpc*-*-linux*) gdb_host=linux ;; + + s390*-*-*) gdb_host=s390 ;; + +--- gdb-7.6/gdb/configure.tgt ++++ gdb-7.6/gdb/configure.tgt +@@ -421,7 +421,7 @@ powerpc-*-aix* | rs6000-*-*) + ppc-sysv-tdep.o solib-svr4.o \ + ravenscar-thread.o ppc-ravenscar-thread.o" + ;; +-powerpc-*-linux* | powerpc64-*-linux*) ++powerpc*-*-linux*) + # Target: PowerPC running Linux + gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \ + ppc64-tdep.o solib-svr4.o solib-spu.o \ +--- gdb-7.6/gdb/doublest.c ++++ gdb-7.6/gdb/doublest.c +@@ -190,7 +190,8 @@ convert_floatformat_to_doublest (const s + { + double dto; + +- floatformat_to_double (fmt, from, &dto); ++ floatformat_to_double (fmt->split_half ? fmt->split_half : fmt, ++ from, &dto); + *to = (DOUBLEST) dto; + return; + } +@@ -561,6 +562,11 @@ floatformat_is_negative (const struct fl + gdb_assert (fmt->totalsize + <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT); + ++ /* An IBM long double (a two element array of double) always takes the ++ sign of the first double. */ ++ if (fmt->split_half) ++ fmt = fmt->split_half; ++ + order = floatformat_normalize_byteorder (fmt, uval, newfrom); + + if (order != fmt->byteorder) +@@ -587,6 +593,13 @@ floatformat_classify (const struct float + gdb_assert (fmt->totalsize + <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT); + ++ /* An IBM long double (a two element array of double) can be classified ++ by looking at the first double. inf and nan are specified as ++ ignoring the second double. zero and subnormal will always have ++ the second double 0.0 if the long double is correctly rounded. */ ++ if (fmt->split_half) ++ fmt = fmt->split_half; ++ + order = floatformat_normalize_byteorder (fmt, uval, newfrom); + + if (order != fmt->byteorder) +@@ -669,6 +682,16 @@ floatformat_mantissa (const struct float + gdb_assert (fmt->totalsize + <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT); + ++ /* For IBM long double (a two element array of double), return the ++ mantissa of the first double. The problem with returning the ++ actual mantissa from both doubles is that there can be an ++ arbitrary number of implied 0's or 1's between the mantissas ++ of the first and second double. In any case, this function ++ is only used for dumping out nans, and a nan is specified to ++ ignore the value in the second double. */ ++ if (fmt->split_half) ++ fmt = fmt->split_half; ++ + order = floatformat_normalize_byteorder (fmt, uval, newfrom); + + if (order != fmt->byteorder) +@@ -926,27 +949,3 @@ convert_typed_floating (const void *from + floatformat_from_doublest (to_fmt, &d, to); + } + } +- +-const struct floatformat *floatformat_ieee_single[BFD_ENDIAN_UNKNOWN]; +-const struct floatformat *floatformat_ieee_double[BFD_ENDIAN_UNKNOWN]; +-const struct floatformat *floatformat_ieee_quad[BFD_ENDIAN_UNKNOWN]; +-const struct floatformat *floatformat_arm_ext[BFD_ENDIAN_UNKNOWN]; +-const struct floatformat *floatformat_ia64_spill[BFD_ENDIAN_UNKNOWN]; +- +-extern void _initialize_doublest (void); +- +-extern void +-_initialize_doublest (void) +-{ +- floatformat_ieee_single[BFD_ENDIAN_LITTLE] = &floatformat_ieee_single_little; +- floatformat_ieee_single[BFD_ENDIAN_BIG] = &floatformat_ieee_single_big; +- floatformat_ieee_double[BFD_ENDIAN_LITTLE] = &floatformat_ieee_double_little; +- floatformat_ieee_double[BFD_ENDIAN_BIG] = &floatformat_ieee_double_big; +- floatformat_arm_ext[BFD_ENDIAN_LITTLE] +- = &floatformat_arm_ext_littlebyte_bigword; +- floatformat_arm_ext[BFD_ENDIAN_BIG] = &floatformat_arm_ext_big; +- floatformat_ia64_spill[BFD_ENDIAN_LITTLE] = &floatformat_ia64_spill_little; +- floatformat_ia64_spill[BFD_ENDIAN_BIG] = &floatformat_ia64_spill_big; +- floatformat_ieee_quad[BFD_ENDIAN_LITTLE] = &floatformat_ia64_quad_little; +- floatformat_ieee_quad[BFD_ENDIAN_BIG] = &floatformat_ia64_quad_big; +-} +--- gdb-7.6/gdb/gdbarch.c ++++ gdb-7.6/gdb/gdbarch.c +@@ -200,6 +200,7 @@ struct gdbarch + gdbarch_return_in_first_hidden_param_p_ftype *return_in_first_hidden_param_p; + gdbarch_skip_prologue_ftype *skip_prologue; + gdbarch_skip_main_prologue_ftype *skip_main_prologue; ++ gdbarch_skip_entrypoint_ftype *skip_entrypoint; + gdbarch_inner_than_ftype *inner_than; + gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc; + gdbarch_remote_breakpoint_from_pc_ftype *remote_breakpoint_from_pc; +@@ -371,6 +372,7 @@ struct gdbarch startup_gdbarch = + default_return_in_first_hidden_param_p, /* return_in_first_hidden_param_p */ + 0, /* skip_prologue */ + 0, /* skip_main_prologue */ ++ 0, /* skip_entrypoint */ + 0, /* inner_than */ + 0, /* breakpoint_from_pc */ + default_remote_breakpoint_from_pc, /* remote_breakpoint_from_pc */ +@@ -672,6 +674,7 @@ verify_gdbarch (struct gdbarch *gdbarch) + if (gdbarch->skip_prologue == 0) + fprintf_unfiltered (log, "\n\tskip_prologue"); + /* Skip verify of skip_main_prologue, has predicate. */ ++ /* Skip verify of skip_entrypoint, has predicate. */ + if (gdbarch->inner_than == 0) + fprintf_unfiltered (log, "\n\tinner_than"); + if (gdbarch->breakpoint_from_pc == 0) +@@ -1285,6 +1288,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s + "gdbarch_dump: single_step_through_delay = <%s>\n", + host_address_to_string (gdbarch->single_step_through_delay)); + fprintf_unfiltered (file, ++ "gdbarch_dump: gdbarch_skip_entrypoint_p() = %d\n", ++ gdbarch_skip_entrypoint_p (gdbarch)); ++ fprintf_unfiltered (file, ++ "gdbarch_dump: skip_entrypoint = <%s>\n", ++ host_address_to_string (gdbarch->skip_entrypoint)); ++ fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_skip_main_prologue_p() = %d\n", + gdbarch_skip_main_prologue_p (gdbarch)); + fprintf_unfiltered (file, +@@ -2635,6 +2644,30 @@ set_gdbarch_skip_main_prologue (struct g + } + + int ++gdbarch_skip_entrypoint_p (struct gdbarch *gdbarch) ++{ ++ gdb_assert (gdbarch != NULL); ++ return gdbarch->skip_entrypoint != NULL; ++} ++ ++CORE_ADDR ++gdbarch_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR ip) ++{ ++ gdb_assert (gdbarch != NULL); ++ gdb_assert (gdbarch->skip_entrypoint != NULL); ++ if (gdbarch_debug >= 2) ++ fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_entrypoint called\n"); ++ return gdbarch->skip_entrypoint (gdbarch, ip); ++} ++ ++void ++set_gdbarch_skip_entrypoint (struct gdbarch *gdbarch, ++ gdbarch_skip_entrypoint_ftype skip_entrypoint) ++{ ++ gdbarch->skip_entrypoint = skip_entrypoint; ++} ++ ++int + gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs) + { + gdb_assert (gdbarch != NULL); +--- gdb-7.6/gdb/gdbarch.h ++++ gdb-7.6/gdb/gdbarch.h +@@ -487,6 +487,12 @@ typedef CORE_ADDR (gdbarch_skip_main_pro + extern CORE_ADDR gdbarch_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR ip); + extern void set_gdbarch_skip_main_prologue (struct gdbarch *gdbarch, gdbarch_skip_main_prologue_ftype *skip_main_prologue); + ++extern int gdbarch_skip_entrypoint_p (struct gdbarch *gdbarch); ++ ++typedef CORE_ADDR (gdbarch_skip_entrypoint_ftype) (struct gdbarch *gdbarch, CORE_ADDR ip); ++extern CORE_ADDR gdbarch_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR ip); ++extern void set_gdbarch_skip_entrypoint (struct gdbarch *gdbarch, gdbarch_skip_entrypoint_ftype *skip_entrypoint); ++ + typedef int (gdbarch_inner_than_ftype) (CORE_ADDR lhs, CORE_ADDR rhs); + extern int gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs); + extern void set_gdbarch_inner_than (struct gdbarch *gdbarch, gdbarch_inner_than_ftype *inner_than); +--- gdb-7.6/gdb/gdbarch.sh ++++ gdb-7.6/gdb/gdbarch.sh +@@ -527,6 +527,7 @@ m:int:return_in_first_hidden_param_p:str + + m:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0 + M:CORE_ADDR:skip_main_prologue:CORE_ADDR ip:ip ++M:CORE_ADDR:skip_entrypoint:CORE_ADDR ip:ip + f:int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs:0:0 + m:const gdb_byte *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr::0: + # Return the adjusted address and kind to use for Z0/Z1 packets. +--- gdb-7.6/gdb/gdbtypes.c ++++ gdb-7.6/gdb/gdbtypes.c +@@ -107,8 +107,8 @@ const struct floatformat *floatformats_v + &floatformat_vax_d + }; + const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN] = { +- &floatformat_ibm_long_double, +- &floatformat_ibm_long_double ++ &floatformat_ibm_long_double_big, ++ &floatformat_ibm_long_double_little + }; + + /* Should opaque types be resolved? */ +--- gdb-7.6/gdb/infrun.c ++++ gdb-7.6/gdb/infrun.c +@@ -3139,6 +3139,10 @@ fill_in_stop_func (struct gdbarch *gdbar + ecs->stop_func_start + += gdbarch_deprecated_function_start_offset (gdbarch); + ++ if (gdbarch_skip_entrypoint_p (gdbarch)) ++ ecs->stop_func_start = gdbarch_skip_entrypoint (gdbarch, ++ ecs->stop_func_start); ++ + ecs->stop_func_filled_in = 1; + } + } +--- gdb-7.6/gdb/ppc-linux-tdep.c ++++ gdb-7.6/gdb/ppc-linux-tdep.c +@@ -44,6 +44,7 @@ + #include "observer.h" + #include "auxv.h" + #include "elf/common.h" ++#include "elf/ppc64.h" + #include "exceptions.h" + #include "arch-utils.h" + #include "spu-tdep.h" +@@ -876,6 +877,43 @@ ppc_linux_core_read_description (struct + } + } + ++/* If the ELF symbol has a local entry point, use it as SYMBOL_VALUE_ADDRESS ++ for the msymbol. This matches the DWARF function start if present. */ ++ ++static void ++ppc_elfv2_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym) ++{ ++ elf_symbol_type *elf_sym = (elf_symbol_type *)sym; ++ switch (PPC64_LOCAL_ENTRY_OFFSET (elf_sym->internal_elf_sym.st_other)) ++ { ++ default: ++ break; ++ case 8: ++ MSYMBOL_TARGET_FLAG_1 (msym) = 1; ++ break; ++ } ++} ++ ++static CORE_ADDR ++ppc_elfv2_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR pc) ++{ ++ struct bound_minimal_symbol fun; ++ int local_entry_offset = 0; ++ ++ fun = lookup_minimal_symbol_by_pc (pc); ++ if (fun.minsym == NULL) ++ return pc; ++ ++ if (MSYMBOL_TARGET_FLAG_1 (fun.minsym)) ++ local_entry_offset = 8; ++ ++ if (SYMBOL_VALUE_ADDRESS (fun.minsym) <= pc ++ && pc < SYMBOL_VALUE_ADDRESS (fun.minsym) + local_entry_offset) ++ return SYMBOL_VALUE_ADDRESS (fun.minsym) + local_entry_offset; ++ ++ return pc; ++} ++ + /* Implementation of `gdbarch_stap_is_single_operand', as defined in + gdbarch.h. */ + +@@ -1332,13 +1370,23 @@ ppc_linux_init_abi (struct gdbarch_info + + if (tdep->wordsize == 8) + { +- /* Handle PPC GNU/Linux 64-bit function pointers (which are really +- function descriptors). */ +- set_gdbarch_convert_from_func_ptr_addr +- (gdbarch, ppc64_convert_from_func_ptr_addr); ++ if (tdep->elf_abi == POWERPC_ELF_V1) ++ { ++ /* Handle PPC GNU/Linux 64-bit function pointers (which are really ++ function descriptors). */ ++ set_gdbarch_convert_from_func_ptr_addr ++ (gdbarch, ppc64_convert_from_func_ptr_addr); + +- set_gdbarch_elf_make_msymbol_special (gdbarch, +- ppc64_elf_make_msymbol_special); ++ set_gdbarch_elf_make_msymbol_special ++ (gdbarch, ppc64_elf_make_msymbol_special); ++ } ++ else ++ { ++ set_gdbarch_elf_make_msymbol_special ++ (gdbarch, ppc_elfv2_elf_make_msymbol_special); ++ ++ set_gdbarch_skip_entrypoint (gdbarch, ppc_elfv2_skip_entrypoint); ++ } + + /* Shared library handling. */ + set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code); +--- gdb-7.6/gdb/ppc-sysv-tdep.c ++++ gdb-7.6/gdb/ppc-sysv-tdep.c +@@ -610,42 +610,48 @@ ppc_sysv_abi_push_dummy_call (struct gdb + } + + /* Handle the return-value conventions for Decimal Floating Point values +- in both ppc32 and ppc64, which are the same. */ +-static int ++ in both ppc32 and ppc64, which are the same. INDEX specifies which ++ part of a multi-part return value is to be handled. */ ++static void + get_decimal_float_return_value (struct gdbarch *gdbarch, struct type *valtype, + struct regcache *regcache, gdb_byte *readbuf, +- const gdb_byte *writebuf) ++ const gdb_byte *writebuf, int index) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ int offset = index * TYPE_LENGTH (valtype); + + gdb_assert (TYPE_CODE (valtype) == TYPE_CODE_DECFLOAT); + + /* 32-bit and 64-bit decimal floats in f1. */ + if (TYPE_LENGTH (valtype) <= 8) + { ++ int regnum = tdep->ppc_fp0_regnum + 1 + index; ++ + if (writebuf != NULL) + { + gdb_byte regval[MAX_REGISTER_SIZE]; + const gdb_byte *p; + + /* 32-bit decimal float is right aligned in the doubleword. */ +- if (TYPE_LENGTH (valtype) == 4) ++ if (TYPE_LENGTH (valtype) == 4 ++ && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { +- memcpy (regval + 4, writebuf, 4); ++ memcpy (regval + 4, writebuf + offset, 4); + p = regval; + } + else +- p = writebuf; ++ p = writebuf + offset; + +- regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, p); ++ regcache_cooked_write (regcache, regnum, p); + } + if (readbuf != NULL) + { +- regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, readbuf); ++ regcache_cooked_read (regcache, regnum, readbuf); + + /* Left align 32-bit decimal float. */ +- if (TYPE_LENGTH (valtype) == 4) +- memcpy (readbuf, readbuf + 4, 4); ++ if (TYPE_LENGTH (valtype) == 4 ++ && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) ++ memcpy (readbuf + offset, readbuf + offset + 4, 4); + } + } + /* 128-bit decimal floats in f2,f3. */ +@@ -653,24 +659,27 @@ get_decimal_float_return_value (struct g + { + if (writebuf != NULL || readbuf != NULL) + { +- int i; ++ int i, regnum; + + for (i = 0; i < 2; i++) + { ++ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) ++ regnum = tdep->ppc_fp0_regnum + 2 + i + 2 * index; ++ else ++ regnum = tdep->ppc_fp0_regnum + 3 - i + 2 * index; ++ + if (writebuf != NULL) +- regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 2 + i, +- writebuf + i * 8); ++ regcache_cooked_write (regcache, regnum, ++ writebuf + offset + i * 8); + if (readbuf != NULL) +- regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 2 + i, +- readbuf + i * 8); ++ regcache_cooked_read (regcache, regnum, ++ readbuf + offset + i * 8); + } + } + } + else + /* Can't happen. */ + internal_error (__FILE__, __LINE__, _("Unknown decimal float size.")); +- +- return RETURN_VALUE_REGISTER_CONVENTION; + } + + /* Handle the return-value conventions specified by the SysV 32-bit +@@ -802,8 +811,11 @@ do_ppc_sysv_return_value (struct gdbarch + return RETURN_VALUE_REGISTER_CONVENTION; + } + if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && !tdep->soft_float) +- return get_decimal_float_return_value (gdbarch, type, regcache, readbuf, +- writebuf); ++ { ++ get_decimal_float_return_value (gdbarch, type, regcache, ++ readbuf, writebuf, 0); ++ return RETURN_VALUE_REGISTER_CONVENTION; ++ } + else if ((TYPE_CODE (type) == TYPE_CODE_INT + || TYPE_CODE (type) == TYPE_CODE_CHAR + || TYPE_CODE (type) == TYPE_CODE_BOOL +@@ -1102,6 +1114,156 @@ convert_code_addr_to_desc_addr (CORE_ADD + return 1; + } + ++/* Walk down the type tree of TYPE counting consecutive base elements. ++ If *FIELD_TYPE is NULL, then set it to the first valid floating point ++ or vector type. If a non-floating point or vector type is found, or ++ if a floating point or vector type that doesn't match a non-NULL ++ *FIELD_TYPE is found, then return -1, otherwise return the count in the ++ sub-tree. */ ++ ++static LONGEST ++ppc64_aggregate_candidate (struct type *type, ++ struct type **field_type) ++{ ++ type = check_typedef (type); ++ ++ switch (TYPE_CODE (type)) ++ { ++ case TYPE_CODE_FLT: ++ case TYPE_CODE_DECFLOAT: ++ if (!*field_type) ++ *field_type = type; ++ if (TYPE_CODE (*field_type) == TYPE_CODE (type) ++ && TYPE_LENGTH (*field_type) == TYPE_LENGTH (type)) ++ return 1; ++ break; ++ ++ case TYPE_CODE_COMPLEX: ++ type = TYPE_TARGET_TYPE (type); ++ if (TYPE_CODE (type) == TYPE_CODE_FLT ++ || TYPE_CODE (type) == TYPE_CODE_DECFLOAT) ++ { ++ if (!*field_type) ++ *field_type = type; ++ if (TYPE_CODE (*field_type) == TYPE_CODE (type) ++ && TYPE_LENGTH (*field_type) == TYPE_LENGTH (type)) ++ return 2; ++ } ++ break; ++ ++ case TYPE_CODE_ARRAY: ++ if (TYPE_VECTOR (type)) ++ { ++ if (!*field_type) ++ *field_type = type; ++ if (TYPE_CODE (*field_type) == TYPE_CODE (type) ++ && TYPE_LENGTH (*field_type) == TYPE_LENGTH (type)) ++ return 1; ++ } ++ else ++ { ++ LONGEST count, low_bound, high_bound; ++ ++ count = ppc64_aggregate_candidate ++ (TYPE_TARGET_TYPE (type), field_type); ++ if (count == -1) ++ return -1; ++ ++ if (!get_array_bounds (type, &low_bound, &high_bound)) ++ return -1; ++ count *= high_bound - low_bound; ++ ++ /* There must be no padding. */ ++ if (count == 0) ++ return TYPE_LENGTH (type) == 0 ? 0 : -1; ++ else if (TYPE_LENGTH (type) != count * TYPE_LENGTH (*field_type)) ++ return -1; ++ ++ return count; ++ } ++ break; ++ ++ case TYPE_CODE_STRUCT: ++ case TYPE_CODE_UNION: ++ { ++ LONGEST count = 0; ++ int i; ++ ++ for (i = 0; i < TYPE_NFIELDS (type); i++) ++ { ++ LONGEST sub_count; ++ ++ if (field_is_static (&TYPE_FIELD (type, i))) ++ continue; ++ ++ sub_count = ppc64_aggregate_candidate ++ (TYPE_FIELD_TYPE (type, i), field_type); ++ if (sub_count == -1) ++ return -1; ++ ++ if (TYPE_CODE (type) == TYPE_CODE_STRUCT) ++ count += sub_count; ++ else ++ count = max (count, sub_count); ++ } ++ ++ /* There must be no padding. */ ++ if (count == 0) ++ return TYPE_LENGTH (type) == 0 ? 0 : -1; ++ else if (TYPE_LENGTH (type) != count * TYPE_LENGTH (*field_type)) ++ return -1; ++ ++ return count; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ return -1; ++} ++ ++/* If an argument of type TYPE is a homogeneous float or vector aggregate ++ that shall be passed in FP/vector registers according to the ELFv2 ABI, ++ return the homogeneous element type in *ELT_TYPE and the number of ++ elements in *N_ELTS, and return non-zero. Otherwise, return zero. */ ++ ++static int ++ppc64_elfv2_abi_homogeneous_aggregate (struct type *type, ++ struct type **elt_type, int *n_elts) ++{ ++ /* Complex types at the top level are treated separately. However, ++ complex types can be elements of homogeneous aggregates. */ ++ if (TYPE_CODE (type) == TYPE_CODE_STRUCT ++ || TYPE_CODE (type) == TYPE_CODE_UNION ++ || (TYPE_CODE (type) == TYPE_CODE_ARRAY && !TYPE_VECTOR (type))) ++ { ++ struct type *field_type = NULL; ++ LONGEST field_count = ppc64_aggregate_candidate (type, &field_type); ++ ++ if (field_count > 0) ++ { ++ int n_regs = ((TYPE_CODE (field_type) == TYPE_CODE_FLT ++ || TYPE_CODE (field_type) == TYPE_CODE_DECFLOAT)? ++ (TYPE_LENGTH (field_type) + 7) >> 3 : 1); ++ ++ /* The ELFv2 ABI allows homogeneous aggregates to occupy ++ up to 8 registers. */ ++ if (field_count * n_regs <= 8) ++ { ++ if (elt_type) ++ *elt_type = field_type; ++ if (n_elts) ++ *n_elts = (int) field_count; ++ return 1; ++ } ++ } ++ } ++ ++ return 0; ++} ++ + /* Push a float in either registers, or in the stack. Using the ppc 64 bit + SysV ABI. + +@@ -1143,6 +1305,8 @@ ppc64_sysv_abi_push_float (struct gdbarc + + /* Write value in the stack's parameter save area. */ + write_memory (gparam, p, 8); ++ if (greg <= 10) ++ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, p); + + /* Floats and Doubles go in f1 .. f13. They also consume a left aligned + GREG, and can end up in memory. */ +@@ -1154,8 +1318,6 @@ ppc64_sysv_abi_push_float (struct gdbarc + convert_typed_floating (val, type, regval, regtype); + regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval); + } +- if (greg <= 10) +- regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval); + } + else + { +@@ -1268,9 +1430,13 @@ ppc64_sysv_abi_push_dummy_call (struct g + to their corresponding regions. */ + refparam = align_down (sp - refparam_size, 16); + gparam = align_down (refparam - gparam_size, 16); +- /* Add in space for the TOC, link editor double word, +- compiler double word, LR save area, CR save area. */ +- sp = align_down (gparam - 48, 16); ++ /* Add in space for the TOC, link editor double word (v1 only), ++ compiler double word (v1 only), LR save area, CR save area, ++ and backchain. */ ++ if (tdep->elf_abi == POWERPC_ELF_V1) ++ sp = align_down (gparam - 48, 16); ++ else ++ sp = align_down (gparam - 32, 16); + } + + /* If the function is returning a `struct', then there is an +@@ -1375,7 +1541,8 @@ ppc64_sysv_abi_push_dummy_call (struct g + + /* 32-bit decimal floats are right aligned in the + doubleword. */ +- if (TYPE_LENGTH (type) == 4) ++ if (TYPE_LENGTH (type) == 4 ++ && byte_order == BFD_ENDIAN_BIG) + { + memcpy (regval + 4, val, 4); + p = regval; +@@ -1407,10 +1574,21 @@ ppc64_sysv_abi_push_dummy_call (struct g + { + /* Make sure freg is even. */ + freg += freg & 1; +- regcache_cooked_write (regcache, +- tdep->ppc_fp0_regnum + freg, val); +- regcache_cooked_write (regcache, +- tdep->ppc_fp0_regnum + freg + 1, val + 8); ++ ++ if (byte_order == BFD_ENDIAN_BIG) ++ { ++ regcache_cooked_write (regcache, ++ tdep->ppc_fp0_regnum + freg, val); ++ regcache_cooked_write (regcache, ++ tdep->ppc_fp0_regnum + freg + 1, val + 8); ++ } ++ else ++ { ++ regcache_cooked_write (regcache, ++ tdep->ppc_fp0_regnum + freg + 1, val); ++ regcache_cooked_write (regcache, ++ tdep->ppc_fp0_regnum + freg, val + 8); ++ } + } + + write_memory (gparam, val, TYPE_LENGTH (type)); +@@ -1587,8 +1765,9 @@ ppc64_sysv_abi_push_dummy_call (struct g + ULONGEST word = unpack_long (type, val); + /* Convert any function code addresses into + descriptors. */ +- if (TYPE_CODE (type) == TYPE_CODE_PTR +- || TYPE_CODE (type) == TYPE_CODE_REF) ++ if (tdep->elf_abi == POWERPC_ELF_V1 ++ && (TYPE_CODE (type) == TYPE_CODE_PTR ++ || TYPE_CODE (type) == TYPE_CODE_REF)) + { + struct type *target_type; + target_type = check_typedef (TYPE_TARGET_TYPE (type)); +@@ -1613,6 +1792,9 @@ ppc64_sysv_abi_push_dummy_call (struct g + } + else + { ++ struct type *elt_type; ++ int n_elts; ++ + int byte; + for (byte = 0; byte < TYPE_LENGTH (type); + byte += tdep->wordsize) +@@ -1630,7 +1812,7 @@ ppc64_sysv_abi_push_dummy_call (struct g + versions before 3.4 implemented this + incorrectly; see + . */ +- if (byte == 0) ++ if (byte_order == BFD_ENDIAN_BIG && byte == 0) + memcpy (regval + tdep->wordsize - len, + val + byte, len); + else +@@ -1649,7 +1831,7 @@ ppc64_sysv_abi_push_dummy_call (struct g + value to memory. Fortunately, doing this + simplifies the code. */ + int len = TYPE_LENGTH (type); +- if (len < tdep->wordsize) ++ if (byte_order == BFD_ENDIAN_BIG && len < tdep->wordsize) + write_memory (gparam + tdep->wordsize - len, val, len); + else + write_memory (gparam, val, len); +@@ -1705,6 +1887,132 @@ ppc64_sysv_abi_push_dummy_call (struct g + } + } + } ++ /* In the ELFv2 ABI, homogeneous floating-point or vector ++ aggregates are passed in registers. */ ++ if (tdep->elf_abi == POWERPC_ELF_V2 ++ && ppc64_elfv2_abi_homogeneous_aggregate (type, ++ &elt_type, &n_elts)) ++ { ++ int i; ++ for (i = 0; i < n_elts; i++) ++ { ++ const gdb_byte *elt_val ++ = val + i * TYPE_LENGTH (elt_type); ++ ++ switch (TYPE_CODE (elt_type)) ++ { ++ case TYPE_CODE_FLT: ++ if (TYPE_LENGTH (elt_type) <= 8) ++ { ++ if (write_pass && freg <= 13) ++ { ++ int fregnum = tdep->ppc_fp0_regnum + freg; ++ gdb_byte regval[MAX_REGISTER_SIZE]; ++ struct type *regtype ++ = register_type (gdbarch, fregnum); ++ convert_typed_floating (elt_val, elt_type, ++ regval, regtype); ++ regcache_cooked_write (regcache, ++ fregnum, regval); ++ } ++ freg++; ++ } ++ else if (TYPE_LENGTH (elt_type) == 16 ++ && (gdbarch_long_double_format (gdbarch) ++ == floatformats_ibm_long_double)) ++ { ++ if (write_pass && freg <= 13) ++ { ++ int fregnum = tdep->ppc_fp0_regnum + freg; ++ regcache_cooked_write (regcache, ++ fregnum, elt_val); ++ if (freg <= 12) ++ regcache_cooked_write (regcache, ++ fregnum + 1, ++ elt_val + 8); ++ } ++ freg += 2; ++ } ++ break; ++ ++ case TYPE_CODE_DECFLOAT: ++ if (TYPE_LENGTH (elt_type) <= 8) ++ { ++ if (write_pass && freg <= 13) ++ { ++ int fregnum = tdep->ppc_fp0_regnum + freg; ++ gdb_byte regval[MAX_REGISTER_SIZE]; ++ const gdb_byte *p; ++ ++ /* 32-bit decimal floats are right aligned ++ in the doubleword. */ ++ if (TYPE_LENGTH (elt_type) == 4 ++ && byte_order == BFD_ENDIAN_BIG) ++ { ++ memcpy (regval + 4, elt_val, 4); ++ p = regval; ++ } ++ else ++ p = elt_val; ++ ++ regcache_cooked_write (regcache, fregnum, p); ++ } ++ freg++; ++ } ++ else if (TYPE_LENGTH (elt_type) == 16) ++ { ++ /* Make sure freg is even. */ ++ freg += freg & 1; ++ ++ if (write_pass && freg <= 12) ++ { ++ int fregnum = tdep->ppc_fp0_regnum + freg; ++ if (byte_order == BFD_ENDIAN_BIG) ++ { ++ regcache_cooked_write (regcache, ++ fregnum, ++ elt_val); ++ regcache_cooked_write (regcache, ++ fregnum + 1, ++ elt_val + 8); ++ } ++ else ++ { ++ regcache_cooked_write (regcache, ++ fregnum + 1, ++ elt_val); ++ regcache_cooked_write (regcache, ++ fregnum, ++ elt_val + 8); ++ } ++ } ++ freg += 2; ++ } ++ break; ++ ++ case TYPE_CODE_ARRAY: ++ gdb_assert (TYPE_VECTOR (type)); ++ ++ if (tdep->vector_abi == POWERPC_VEC_ALTIVEC ++ && TYPE_LENGTH (elt_type) == 16) ++ { ++ if (write_pass && vreg <= 13) ++ { ++ int vregnum = tdep->ppc_vr0_regnum + vreg; ++ regcache_cooked_write (regcache, ++ vregnum, elt_val); ++ } ++ vreg++; ++ } ++ break; ++ ++ default: ++ internal_error (__FILE__, __LINE__, ++ _("Unknown element type.")); ++ break; ++ } ++ } ++ } + /* Always consume parameter stack space. */ + gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); + } +@@ -1733,24 +2041,31 @@ ppc64_sysv_abi_push_dummy_call (struct g + breakpoint. */ + regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); + +- /* Use the func_addr to find the descriptor, and use that to find +- the TOC. If we're calling via a function pointer, the pointer +- itself identifies the descriptor. */ +- { +- struct type *ftype = check_typedef (value_type (function)); +- CORE_ADDR desc_addr = value_as_address (function); +- +- if (TYPE_CODE (ftype) == TYPE_CODE_PTR +- || convert_code_addr_to_desc_addr (func_addr, &desc_addr)) +- { +- /* The TOC is the second double word in the descriptor. */ +- CORE_ADDR toc = +- read_memory_unsigned_integer (desc_addr + tdep->wordsize, +- tdep->wordsize, byte_order); +- regcache_cooked_write_unsigned (regcache, +- tdep->ppc_gp0_regnum + 2, toc); +- } +- } ++ /* In the ELFv1 ABI, use the func_addr to find the descriptor, and use ++ that to find the TOC. If we're calling via a function pointer, ++ the pointer itself identifies the descriptor. */ ++ if (tdep->elf_abi == POWERPC_ELF_V1) ++ { ++ struct type *ftype = check_typedef (value_type (function)); ++ CORE_ADDR desc_addr = value_as_address (function); ++ ++ if (TYPE_CODE (ftype) == TYPE_CODE_PTR ++ || convert_code_addr_to_desc_addr (func_addr, &desc_addr)) ++ { ++ /* The TOC is the second double word in the descriptor. */ ++ CORE_ADDR toc = ++ read_memory_unsigned_integer (desc_addr + tdep->wordsize, ++ tdep->wordsize, byte_order); ++ regcache_cooked_write_unsigned (regcache, ++ tdep->ppc_gp0_regnum + 2, toc); ++ } ++ } ++ ++ /* In the ELFv2 ABI, we need to pass the target address in r12 since ++ we may be calling a global entry point. */ ++ if (tdep->elf_abi == POWERPC_ELF_V2) ++ regcache_cooked_write_unsigned (regcache, ++ tdep->ppc_gp0_regnum + 12, func_addr); + + return sp; + } +@@ -1775,6 +2090,8 @@ ppc64_sysv_abi_return_value (struct gdba + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + struct type *func_type = function ? value_type (function) : NULL; + int opencl_abi = func_type? ppc_sysv_use_opencl_abi (func_type) : 0; ++ struct type *elt_type; ++ int n_elts; + + /* This function exists to support a calling convention that + requires floating-point registers. It shouldn't be used on +@@ -1799,8 +2116,11 @@ ppc64_sysv_abi_return_value (struct gdba + return RETURN_VALUE_REGISTER_CONVENTION; + } + if (TYPE_CODE (valtype) == TYPE_CODE_DECFLOAT) +- return get_decimal_float_return_value (gdbarch, valtype, regcache, readbuf, +- writebuf); ++ { ++ get_decimal_float_return_value (gdbarch, valtype, regcache, ++ readbuf, writebuf, 0); ++ return RETURN_VALUE_REGISTER_CONVENTION; ++ } + /* Integers in r3. */ + if ((TYPE_CODE (valtype) == TYPE_CODE_INT + || TYPE_CODE (valtype) == TYPE_CODE_ENUM +@@ -2019,6 +2339,114 @@ ppc64_sysv_abi_return_value (struct gdba + } + } + return RETURN_VALUE_REGISTER_CONVENTION; ++ } ++ /* In the ELFv2 ABI, homogeneous floating-point or vector ++ aggregates are returned in registers. */ ++ if (tdep->elf_abi == POWERPC_ELF_V2 ++ && ppc64_elfv2_abi_homogeneous_aggregate (valtype, &elt_type, &n_elts)) ++ { ++ int i; ++ for (i = 0; i < n_elts; i++) ++ { ++ int offset = i * TYPE_LENGTH (elt_type); ++ ++ switch (TYPE_CODE (elt_type)) ++ { ++ case TYPE_CODE_FLT: ++ if (TYPE_LENGTH (elt_type) <= 8) ++ { ++ int regnum = tdep->ppc_fp0_regnum + 1 + i; ++ gdb_byte regval[MAX_REGISTER_SIZE]; ++ struct type *regtype = register_type (gdbarch, regnum); ++ if (writebuf != NULL) ++ { ++ convert_typed_floating (writebuf + offset, elt_type, ++ regval, regtype); ++ regcache_cooked_write (regcache, regnum, regval); ++ } ++ if (readbuf != NULL) ++ { ++ regcache_cooked_read (regcache, regnum, regval); ++ convert_typed_floating (regval, regtype, ++ readbuf + offset, elt_type); ++ } ++ } ++ else ++ { ++ int j, nregs = (TYPE_LENGTH (elt_type) + 7) / 8; ++ for (j = 0; j < nregs; j++) ++ { ++ int regnum = tdep->ppc_fp0_regnum + 1 + nregs * i + j; ++ ++ if (writebuf != NULL) ++ regcache_cooked_write (regcache, regnum, ++ writebuf + offset + j * 8); ++ if (readbuf != NULL) ++ regcache_cooked_read (regcache, regnum, ++ readbuf + offset + j * 8); ++ } ++ } ++ break; ++ ++ case TYPE_CODE_DECFLOAT: ++ get_decimal_float_return_value (gdbarch, elt_type, regcache, ++ readbuf, writebuf, i); ++ break; ++ ++ case TYPE_CODE_ARRAY: ++ { ++ int regnum = tdep->ppc_vr0_regnum + 2 + i; ++ gdb_assert (TYPE_VECTOR (elt_type)); ++ ++ if (writebuf != NULL) ++ regcache_cooked_write (regcache, regnum, writebuf + offset); ++ if (readbuf != NULL) ++ regcache_cooked_read (regcache, regnum, readbuf + offset); ++ } ++ break; ++ } ++ } ++ return RETURN_VALUE_REGISTER_CONVENTION; ++ } ++ /* In the ELFv2 ABI, aggregate types of up to 16 bytes are ++ returned in registers r3:r4. */ ++ if (tdep->elf_abi == POWERPC_ELF_V2 ++ && TYPE_LENGTH (valtype) <= 16 ++ && (TYPE_CODE (valtype) == TYPE_CODE_STRUCT ++ || TYPE_CODE (valtype) == TYPE_CODE_UNION ++ || (TYPE_CODE (valtype) == TYPE_CODE_ARRAY && !TYPE_VECTOR (valtype)))) ++ { ++ int n_regs = (TYPE_LENGTH (valtype) + tdep->wordsize - 1) / tdep->wordsize; ++ int i; ++ ++ for (i = 0; i < n_regs; i++) ++ { ++ gdb_byte regval[MAX_REGISTER_SIZE]; ++ int regnum = tdep->ppc_gp0_regnum + 3 + i; ++ int offset = i * tdep->wordsize; ++ int len = TYPE_LENGTH (valtype) - offset; ++ if (len > tdep->wordsize) ++ len = tdep->wordsize; ++ ++ if (writebuf != NULL) ++ { ++ memset (regval, 0, sizeof regval); ++ if (byte_order == BFD_ENDIAN_BIG && offset == 0) ++ memcpy (regval + tdep->wordsize - len, writebuf, len); ++ else ++ memcpy (regval, writebuf + offset, len); ++ regcache_cooked_write (regcache, regnum, regval); ++ } ++ if (readbuf != NULL) ++ { ++ regcache_cooked_read (regcache, regnum, regval); ++ if (byte_order == BFD_ENDIAN_BIG && offset == 0) ++ memcpy (readbuf, regval + tdep->wordsize - len, len); ++ else ++ memcpy (readbuf + offset, regval, len); ++ } ++ } ++ return RETURN_VALUE_REGISTER_CONVENTION; + } + return RETURN_VALUE_STRUCT_CONVENTION; + } +--- gdb-7.6/gdb/ppc-tdep.h ++++ gdb-7.6/gdb/ppc-tdep.h +@@ -182,6 +182,15 @@ extern void ppc_collect_vsxregset (const + + /* Private data that this module attaches to struct gdbarch. */ + ++/* ELF ABI version used by the inferior. */ ++enum powerpc_elf_abi ++{ ++ POWERPC_ELF_AUTO, ++ POWERPC_ELF_V1, ++ POWERPC_ELF_V2, ++ POWERPC_ELF_LAST ++}; ++ + /* Vector ABI used by the inferior. */ + enum powerpc_vector_abi + { +@@ -197,6 +206,8 @@ struct gdbarch_tdep + int wordsize; /* Size in bytes of fixed-point word. */ + int soft_float; /* Avoid FP registers for arguments? */ + ++ enum powerpc_elf_abi elf_abi; /* ELF ABI version. */ ++ + /* How to pass vector arguments. Never set to AUTO or LAST. */ + enum powerpc_vector_abi vector_abi; + +--- gdb-7.6/gdb/ppc64-tdep.c ++++ gdb-7.6/gdb/ppc64-tdep.c +@@ -289,7 +289,7 @@ static struct ppc_insn_pattern ppc64_sta + static struct ppc_insn_pattern ppc64_standard_linkage7[] = + { + /* std r2, 24(r1) */ +- { -1, insn_ds (62, 2, 1, 40, 0), 1 }, ++ { -1, insn_ds (62, 2, 1, 24, 0), 1 }, + + /* ld r12, (r2) */ + { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 }, +--- gdb-7.6/gdb/rs6000-tdep.c ++++ gdb-7.6/gdb/rs6000-tdep.c +@@ -48,6 +48,7 @@ + + #include "elf-bfd.h" + #include "elf/ppc.h" ++#include "elf/ppc64.h" + + #include "solib-svr4.h" + #include "ppc-tdep.h" +@@ -2672,10 +2673,10 @@ dfp_pseudo_register_read (struct gdbarch + else + { + status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum + +- 2 * reg_index + 1, buffer + 8); ++ 2 * reg_index + 1, buffer); + if (status == REG_VALID) + status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum + +- 2 * reg_index, buffer); ++ 2 * reg_index, buffer + 8); + } + + return status; +@@ -2701,9 +2702,9 @@ dfp_pseudo_register_write (struct gdbarc + else + { + regcache_raw_write (regcache, tdep->ppc_fp0_regnum + +- 2 * reg_index + 1, buffer + 8); ++ 2 * reg_index + 1, buffer); + regcache_raw_write (regcache, tdep->ppc_fp0_regnum + +- 2 * reg_index, buffer); ++ 2 * reg_index, buffer + 8); + } + } + +@@ -2781,7 +2782,8 @@ efpr_pseudo_register_read (struct gdbarc + int reg_index = reg_nr - tdep->ppc_efpr0_regnum; + + /* Read the portion that overlaps the VMX register. */ +- return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0, ++ int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8; ++ return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, offset, + register_size (gdbarch, reg_nr), buffer); + } + +@@ -2794,7 +2796,8 @@ efpr_pseudo_register_write (struct gdbar + int reg_index = reg_nr - tdep->ppc_efpr0_regnum; + + /* Write the portion that overlaps the VMX register. */ +- regcache_raw_write_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0, ++ int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8; ++ regcache_raw_write_part (regcache, tdep->ppc_vr0_regnum + reg_index, offset, + register_size (gdbarch, reg_nr), buffer); + } + +@@ -3550,6 +3553,7 @@ rs6000_gdbarch_init (struct gdbarch_info + enum auto_boolean soft_float_flag = powerpc_soft_float_global; + int soft_float; + enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global; ++ enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO; + int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0, + have_vsx = 0; + int tdesc_wordsize = -1; +@@ -3856,6 +3860,21 @@ rs6000_gdbarch_init (struct gdbarch_info + } + + #ifdef HAVE_ELF ++ if (from_elf_exec) ++ { ++ switch (elf_elfheader (info.abfd)->e_flags & EF_PPC64_ABI) ++ { ++ case 1: ++ elf_abi = POWERPC_ELF_V1; ++ break; ++ case 2: ++ elf_abi = POWERPC_ELF_V2; ++ break; ++ default: ++ break; ++ } ++ } ++ + if (soft_float_flag == AUTO_BOOLEAN_AUTO && from_elf_exec) + { + switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU, +@@ -3892,6 +3911,15 @@ rs6000_gdbarch_init (struct gdbarch_info + } + #endif + ++ /* Default to ELFv2 ABI on 64-bit little-endian, and ELFv1 otherwise. */ ++ if (elf_abi == POWERPC_ELF_AUTO) ++ { ++ if (wordsize == 8 && info.byte_order == BFD_ENDIAN_LITTLE) ++ elf_abi = POWERPC_ELF_V2; ++ else ++ elf_abi = POWERPC_ELF_V1; ++ } ++ + if (soft_float_flag == AUTO_BOOLEAN_TRUE) + soft_float = 1; + else if (soft_float_flag == AUTO_BOOLEAN_FALSE) +@@ -3934,6 +3962,8 @@ rs6000_gdbarch_init (struct gdbarch_info + meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform + separate word size check. */ + tdep = gdbarch_tdep (arches->gdbarch); ++ if (tdep && tdep->elf_abi != elf_abi) ++ continue; + if (tdep && tdep->soft_float != soft_float) + continue; + if (tdep && tdep->vector_abi != vector_abi) +@@ -3956,6 +3986,7 @@ rs6000_gdbarch_init (struct gdbarch_info + + tdep = XCALLOC (1, struct gdbarch_tdep); + tdep->wordsize = wordsize; ++ tdep->elf_abi = elf_abi; + tdep->soft_float = soft_float; + tdep->vector_abi = vector_abi; + +--- gdb-7.6/gdb/symtab.c ++++ gdb-7.6/gdb/symtab.c +@@ -2866,6 +2866,8 @@ skip_prologue_sal (struct symtab_and_lin + + /* Skip "first line" of function (which is actually its prologue). */ + pc += gdbarch_deprecated_function_start_offset (gdbarch); ++ if (gdbarch_skip_entrypoint_p (gdbarch)) ++ pc = gdbarch_skip_entrypoint (gdbarch, pc); + if (skip) + pc = gdbarch_skip_prologue (gdbarch, pc); + +--- gdb-7.6/gdb/testsuite/gdb.arch/altivec-regs.exp ++++ gdb-7.6/gdb/testsuite/gdb.arch/altivec-regs.exp +@@ -118,7 +118,7 @@ gdb_test "info reg vscr" "vscr.*0x1\t1" + if {$endianness == "big"} { + set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .0, 1, 0, 1, 0, 1, 0, 1., v16_int8 = .0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1.." + } else { +- set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = .1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.." ++ set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = .1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.." + } + + for {set i 0} {$i < 32} {incr i 1} { +--- gdb-7.6/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp ++++ gdb-7.6/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp +@@ -20,7 +20,7 @@ + + # Testcase for ppc decimal128 pseudo-registers. + +-if ![istarget "powerpc64-*"] then { ++if ![istarget "powerpc64*-*"] then { + verbose "Skipping powerpc Decimal128 pseudo-registers testcase." + return + } +--- gdb-7.6/gdb/testsuite/gdb.arch/vsx-regs.exp ++++ gdb-7.6/gdb/testsuite/gdb.arch/vsx-regs.exp +@@ -58,19 +58,46 @@ if ![runto_main] then { + gdb_suppress_tests + } + ++send_gdb "show endian\n" ++set endianness "" ++gdb_expect { ++ -re "(The target endianness is set automatically .currently )(big|little)( endian.*)$gdb_prompt $" { ++ pass "endianness" ++ set endianness $expect_out(2,string) ++ } ++ -re ".*$gdb_prompt $" { ++ fail "couldn't get endianness" ++ } ++ timeout { fail "(timeout) endianness" } ++} ++ + # Data sets used throughout the test + +-set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x1, 0x0., v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x0, 0x0., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x0, 0x0, 0x0., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0.." ++if {$endianness == "big"} { ++ set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x1, 0x0., v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x0, 0x0., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x0, 0x0, 0x0., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0.." ++ ++ set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x1, 0x1., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." ++ ++ set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.." + +-set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x1, 0x1., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." ++ set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.." + +-set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.." ++ set vector_register3 ".uint128 = 0x00000001000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." + +-set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.." ++ set vector_register3_vr ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." ++} else { ++ set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x0, 0x1., v4_float = .0x0, 0x0, 0xf99999a0, 0x1., v4_int32 = .0x0, 0x0, 0xcccccccc, 0x3ff4cccc., v8_int16 = .0x0, 0x0, 0x0, 0x0, 0xcccc, 0xcccc, 0xcccc, 0x3ff4., v16_int8 = .0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x3f.." + +-set vector_register3 ".uint128 = 0x00000001000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." ++ set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x0, 0x0, 0xf99999a0, 0x1., v4_int32 = .0x1, 0x1, 0xcccccccc, 0x3ff4cccc., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0xcccc, 0xcccc, 0xcccc, 0x3ff4., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x3f.." + +-set vector_register3_vr ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." ++ set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead., v16_int8 = .0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde.." ++ ++ set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead., v16_int8 = .0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde.." ++ ++ set vector_register3 ".uint128 = 0x00000001000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.." ++ ++ set vector_register3_vr ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.." ++} + + set float_register ".raw 0xdeadbeefdeadbeef." + +--- gdb-7.6/gdb/testsuite/gdb.base/sigbpt.exp ++++ gdb-7.6/gdb/testsuite/gdb.base/sigbpt.exp +@@ -82,7 +82,7 @@ gdb_test "break keeper" + set bowler_addrs bowler + set segv_addr none + gdb_test {display/i $pc} +-gdb_test "advance *bowler" "bowler.*" "advance to the bowler" ++gdb_test "advance bowler" "bowler.*" "advance to the bowler" + set test "stepping to fault" + set signame "SIGSEGV" + gdb_test_multiple "stepi" "$test" { +--- gdb-7.6/gdb/testsuite/gdb.base/step-bt.exp ++++ gdb-7.6/gdb/testsuite/gdb.base/step-bt.exp +@@ -32,7 +32,7 @@ gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + +-gdb_test "break *hello" \ ++gdb_test "break hello" \ + "Breakpoint.*at.* file .*$srcfile, line .*" \ + "breakpoint at first instruction of hello()" + +--- gdb-7.6/include/elf/common.h ++++ gdb-7.6/include/elf/common.h +@@ -954,6 +954,7 @@ + #define AT_BASE_PLATFORM 24 /* String identifying real platform, + may differ from AT_PLATFORM. */ + #define AT_RANDOM 25 /* Address of 16 random bytes. */ ++#define AT_HWCAP2 26 /* Extension of AT_HWCAP. */ + #define AT_EXECFN 31 /* Filename of executable. */ + /* Pointer to the global system page used for system calls and other + nice things. */ +--- gdb-7.6/include/elf/ppc64.h ++++ gdb-7.6/include/elf/ppc64.h +@@ -164,6 +164,60 @@ END_RELOC_NUMBERS (R_PPC64_max) + #define IS_PPC64_TLS_RELOC(R) \ + ((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA) + ++ ++/* e_flags bits specifying ABI. ++ 1 for original function descriptor using ABI, ++ 2 for revised ABI without function descriptors, ++ 0 for unspecified or not using any features affected by the differences. */ ++#define EF_PPC64_ABI 3 ++ ++/* The ELFv2 ABI uses three bits in the symbol st_other field of a ++ function definition to specify the number of instructions between a ++ function's global entry point and local entry point. ++ The global entry point is used when it is necessary to set up the ++ toc pointer (r2) for the function. Callers must enter the global ++ entry point with r12 set to the global entry point address. On ++ return from the function, r2 may have a different value to that ++ which it had on entry. ++ The local entry point is used when r2 is known to already be valid ++ for the function. There is no requirement on r12 when using the ++ local entry point, and on return r2 will contain the same value as ++ at entry. ++ A value of zero in these bits means that the function has a single ++ entry point with no requirement on r12 or r2, and that on return r2 ++ will contain the same value as at entry. ++ Values of one and seven are reserved. */ ++#define STO_PPC64_LOCAL_BIT 5 ++#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT) ++ ++// 3 bit other field to bytes. ++static inline unsigned int ++ppc64_decode_local_entry(unsigned int other) ++{ ++ return ((1 << other) >> 2) << 2; ++} ++ ++// bytes to field value. ++static inline unsigned int ++ppc64_encode_local_entry(unsigned int val) ++{ ++ return (val >= 4 * 4 ++ ? (val >= 8 * 4 ++ ? (val >= 16 * 4 ? 6 : 5) ++ : 4) ++ : (val >= 2 * 4 ++ ? 3 ++ : (val >= 1 * 4 ? 2 : 0))); ++} ++ ++/* st_other to number of bytes. */ ++#define PPC64_LOCAL_ENTRY_OFFSET(other) \ ++ ppc64_decode_local_entry (((other) & STO_PPC64_LOCAL_MASK) \ ++ >> STO_PPC64_LOCAL_BIT) ++/* number of bytes to st_other. */ ++#define PPC64_SET_LOCAL_ENTRY_OFFSET(val) \ ++ ppc64_encode_local_entry (val) << STO_PPC64_LOCAL_BIT ++ + /* Specify the start of the .glink section. */ + #define DT_PPC64_GLINK DT_LOPROC +