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;
|
||
|