Index: gdb-7.7/gdb/auxv.c =================================================================== --- gdb-7.7.orig/gdb/auxv.c 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/gdb/auxv.c 2014-02-10 18:07:42.000000000 +0100 @@ -442,6 +442,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); Index: gdb-7.7/gdb/gdbarch.c =================================================================== --- gdb-7.7.orig/gdb/gdbarch.c 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/gdb/gdbarch.c 2014-02-10 18:07:42.000000000 +0100 @@ -229,6 +229,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; @@ -402,6 +403,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 */ @@ -705,6 +707,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) @@ -1332,6 +1335,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, @@ -2682,6 +2691,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); Index: gdb-7.7/gdb/gdbarch.h =================================================================== --- gdb-7.7.orig/gdb/gdbarch.h 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/gdb/gdbarch.h 2014-02-10 18:07:42.000000000 +0100 @@ -486,6 +486,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); Index: gdb-7.7/gdb/gdbarch.sh =================================================================== --- gdb-7.7.orig/gdb/gdbarch.sh 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/gdb/gdbarch.sh 2014-02-10 18:07:42.000000000 +0100 @@ -530,6 +530,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. Index: gdb-7.7/gdb/infrun.c =================================================================== --- gdb-7.7.orig/gdb/infrun.c 2014-02-10 18:07:40.000000000 +0100 +++ gdb-7.7/gdb/infrun.c 2014-02-10 18:07:42.000000000 +0100 @@ -3170,6 +3170,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; } } Index: gdb-7.7/gdb/ppc-linux-tdep.c =================================================================== --- gdb-7.7.orig/gdb/ppc-linux-tdep.c 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/gdb/ppc-linux-tdep.c 2014-02-10 18:07:42.000000000 +0100 @@ -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. */ @@ -1339,13 +1377,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); Index: gdb-7.7/gdb/ppc-sysv-tdep.c =================================================================== --- gdb-7.7.orig/gdb/ppc-sysv-tdep.c 2014-02-10 18:07:42.000000000 +0100 +++ gdb-7.7/gdb/ppc-sysv-tdep.c 2014-02-10 18:07:42.000000000 +0100 @@ -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; + ssize_t 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. */ ssize_t 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; } Index: gdb-7.7/gdb/ppc-tdep.h =================================================================== --- gdb-7.7.orig/gdb/ppc-tdep.h 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/gdb/ppc-tdep.h 2014-02-10 18:07:42.000000000 +0100 @@ -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; Index: gdb-7.7/gdb/rs6000-tdep.c =================================================================== --- gdb-7.7.orig/gdb/rs6000-tdep.c 2014-02-10 18:07:39.000000000 +0100 +++ gdb-7.7/gdb/rs6000-tdep.c 2014-02-10 18:07:42.000000000 +0100 @@ -48,6 +48,7 @@ #include "elf-bfd.h" #include "elf/ppc.h" +#include "elf/ppc64.h" #include "solib-svr4.h" #include "ppc-tdep.h" @@ -2723,10 +2724,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; @@ -2752,9 +2753,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); } } @@ -2832,7 +2833,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); } @@ -2845,7 +2847,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); } @@ -3601,6 +3604,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; @@ -3907,6 +3911,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, @@ -3943,6 +3962,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) @@ -3985,6 +4013,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) @@ -4007,6 +4037,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; Index: gdb-7.7/gdb/symtab.c =================================================================== --- gdb-7.7.orig/gdb/symtab.c 2014-02-10 18:07:39.000000000 +0100 +++ gdb-7.7/gdb/symtab.c 2014-02-10 18:07:42.000000000 +0100 @@ -2941,6 +2941,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); Index: gdb-7.7/gdb/testsuite/gdb.arch/altivec-regs.exp =================================================================== --- gdb-7.7.orig/gdb/testsuite/gdb.arch/altivec-regs.exp 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/gdb/testsuite/gdb.arch/altivec-regs.exp 2014-02-10 18:07:42.000000000 +0100 @@ -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} { Index: gdb-7.7/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp =================================================================== --- gdb-7.7.orig/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp 2014-02-10 18:07:42.000000000 +0100 @@ -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 } Index: gdb-7.7/gdb/testsuite/gdb.arch/vsx-regs.exp =================================================================== --- gdb-7.7.orig/gdb/testsuite/gdb.arch/vsx-regs.exp 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/gdb/testsuite/gdb.arch/vsx-regs.exp 2014-02-10 18:07:42.000000000 +0100 @@ -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." Index: gdb-7.7/gdb/testsuite/gdb.base/sigbpt.exp =================================================================== --- gdb-7.7.orig/gdb/testsuite/gdb.base/sigbpt.exp 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/gdb/testsuite/gdb.base/sigbpt.exp 2014-02-10 18:07:42.000000000 +0100 @@ -76,7 +76,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" { Index: gdb-7.7/gdb/testsuite/gdb.base/step-bt.exp =================================================================== --- gdb-7.7.orig/gdb/testsuite/gdb.base/step-bt.exp 2014-01-08 10:23:36.000000000 +0100 +++ gdb-7.7/gdb/testsuite/gdb.base/step-bt.exp 2014-02-10 18:07:42.000000000 +0100 @@ -24,7 +24,7 @@ if {[prepare_for_testing $testfile.exp $ return -1 } -gdb_test "break *hello" \ +gdb_test "break hello" \ "Breakpoint.*at.* file .*$srcfile, line .*" \ "breakpoint at first instruction of hello()" Index: gdb-7.7/include/elf/common.h =================================================================== --- gdb-7.7.orig/include/elf/common.h 2014-02-06 03:21:29.000000000 +0100 +++ gdb-7.7/include/elf/common.h 2014-02-10 18:07:42.000000000 +0100 @@ -959,6 +959,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. */