160 lines
5.4 KiB
Diff
160 lines
5.4 KiB
Diff
|
commit cd453cd072004d26ede355b850b3831acffaeddd
|
|||
|
Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
|
|||
|
Date: Tue Feb 4 18:38:56 2014 +0100
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
### 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.
|
|||
|
Index: gdb-7.7.1/gdb/ppc-tdep.h
|
|||
|
===================================================================
|
|||
|
--- gdb-7.7.1.orig/gdb/ppc-tdep.h 2014-05-09 19:23:40.892248064 +0200
|
|||
|
+++ gdb-7.7.1/gdb/ppc-tdep.h 2014-05-09 19:23:42.346248246 +0200
|
|||
|
@@ -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.1/gdb/rs6000-tdep.c
|
|||
|
===================================================================
|
|||
|
--- gdb-7.7.1.orig/gdb/rs6000-tdep.c 2014-05-09 19:23:40.894248064 +0200
|
|||
|
+++ gdb-7.7.1/gdb/rs6000-tdep.c 2014-05-09 19:23:57.974250197 +0200
|
|||
|
@@ -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
|
|||
|
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
|
|||
|
}
|
|||
|
|
|||
|
#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
|
|||
|
}
|
|||
|
#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
|
|||
|
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
|
|||
|
|
|||
|
tdep = XCALLOC (1, struct gdbarch_tdep);
|
|||
|
tdep->wordsize = wordsize;
|
|||
|
+ tdep->elf_abi = elf_abi;
|
|||
|
tdep->soft_float = soft_float;
|
|||
|
tdep->vector_abi = vector_abi;
|
|||
|
|