diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/ppc-tdep.h | 11 | ||||
-rw-r--r-- | gdb/rs6000-tdep.c | 35 |
3 files changed, 54 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1d2e30ccccd..ba7ddd9d796 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 2014-02-04 Ulrich Weigand <uweigand@de.ibm.com> + * ppc-tdep.h (enum powerpc_elf_abi): New data type. + (struct gdbarch_tdep): New member elf_abi. + + * rs6000-tdep.c: Include "elf/ppc64.h". + (rs6000_gdbarch_init): Detect ELF ABI version. + +2014-02-04 Ulrich Weigand <uweigand@de.ibm.com> + * ppc-sysv-tdep.c (ppc64_sysv_abi_push_freg): Use correct order within a register pair holding a DFP 128-bit value on little-endian. (ppc64_sysv_abi_return_value_base): Likewise. diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h index e6a19b2e0be..08554ff1d24 100644 --- a/gdb/ppc-tdep.h +++ b/gdb/ppc-tdep.h @@ -182,6 +182,15 @@ extern void ppc_collect_vsxregset (const struct regset *regset, /* 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; diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index b407bd60a66..58afc530ba0 100644 --- a/gdb/rs6000-tdep.c +++ b/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" @@ -3554,6 +3555,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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; @@ -3860,6 +3862,21 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } #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, @@ -3896,6 +3913,21 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } #endif + /* At this point, the only supported ELF-based 64-bit little-endian + operating system is GNU/Linux, and this uses the ELFv2 ABI by + default. All other supported ELF-based operating systems use the + ELFv1 ABI by default. Therefore, if the ABI marker is missing, + e.g. because we run a legacy binary, or have attached to a process + and have not found any associated binary file, set the default + according to this heuristic. */ + 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) @@ -3938,6 +3970,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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) @@ -3960,6 +3994,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep = XCNEW (struct gdbarch_tdep); tdep->wordsize = wordsize; + tdep->elf_abi = elf_abi; tdep->soft_float = soft_float; tdep->vector_abi = vector_abi; |