aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2014-02-04 18:38:56 +0100
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2014-02-04 18:38:56 +0100
commitcd453cd072004d26ede355b850b3831acffaeddd (patch)
tree04473bb2ed749e0e160232241e6a5a84d8d49bbf /gdb
parent0ff3e01fdc67a3842ee54224cf197e9a55f0a750 (diff)
downloadgdb-cd453cd072004d26ede355b850b3831acffaeddd.zip
gdb-cd453cd072004d26ede355b850b3831acffaeddd.tar.gz
gdb-cd453cd072004d26ede355b850b3831acffaeddd.tar.bz2
PowerPC64 ELFv2 ABI: base support
This is the first patch of a series to implement support for the PowerPC ELFv2 ABI. While powerpc64le-linux will use ELFv2, and the existing powerpc64-linux code will continue to use ELFv1, in theory ELFv2 is also defined for big-endian systems (and ELFv1 was also defined for little-endian systems). Therefore this patch adds a new tdep->elf_abi variable to decide which ABI version to use. This is detected from the ELF header e_flags value; if this is not present, we default to ELFv2 on little-endian and ELFv1 otherwise. This patch does not yet introduce any actual difference in GDB's handling of the two ABIs. Those will be added by the remainder of this patch series. For an overview of the changes in ELFv2, have a look at the comments in the patch series that added ELFv2 to GCC, starting at: http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01144.html gdb/ChangeLog: * 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.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/ppc-tdep.h11
-rw-r--r--gdb/rs6000-tdep.c35
3 files changed, 54 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1d2e30c..ba7ddd9 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 e6a19b2..08554ff 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 b407bd6..58afc53 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;