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.
143 lines
4.8 KiB
143 lines
4.8 KiB
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; |
|
|
|
|