You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.8 KiB
144 lines
4.8 KiB
6 years ago
|
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.
|
||
|
|
||
|
Index: gdb-7.6.1/gdb/ppc-tdep.h
|
||
|
===================================================================
|
||
|
--- gdb-7.6.1.orig/gdb/ppc-tdep.h
|
||
|
+++ gdb-7.6.1/gdb/ppc-tdep.h
|
||
|
@@ -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.6.1/gdb/rs6000-tdep.c
|
||
|
===================================================================
|
||
|
--- gdb-7.6.1.orig/gdb/rs6000-tdep.c
|
||
|
+++ gdb-7.6.1/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"
|
||
|
@@ -3605,6 +3606,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;
|
||
|
@@ -3911,6 +3913,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,
|
||
|
@@ -3947,6 +3964,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)
|
||
|
@@ -3989,6 +4021,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)
|
||
|
@@ -4011,6 +4045,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;
|
||
|
|