aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2013-10-29 15:06:09 +1030
committerAlan Modra <amodra@gmail.com>2013-10-30 13:37:47 +1030
commitee67d69a3ff0eed25d98c5e97ed6c3ede8069edc (patch)
treefe01ce8627a4436bea7d77485a61c01462a6d557 /gas/config
parent71a39c98f8bedad54818c62ab2d567b0e2de546b (diff)
downloadgdb-ee67d69a3ff0eed25d98c5e97ed6c3ede8069edc.zip
gdb-ee67d69a3ff0eed25d98c5e97ed6c3ede8069edc.tar.gz
gdb-ee67d69a3ff0eed25d98c5e97ed6c3ede8069edc.tar.bz2
Add .abiversion related support for ELFv2
Defines bits in ELF e_flags to differentiate ELFv2 objects from ELFv2, adds .abiversion directive to explicitly choose the ABI, and code to check and automatically select ABI. include/elf/ * ppc64.h (EF_PPC64_ABI): Define. bfd/ * elf64-ppc.c (abiversion, set_abiversion): New functions. (ppc64_elf_get_synthetic_symtab): Handle ELFv2 objects without .opd. (struct ppc_link_hash_table): Add opd_abi. (ppc64_elf_check_relocs): Check no .opd with ELFv2. (ppc64_elf_merge_private_bfd_data): New function. (ppc64_elf_print_private_bfd_data): New function. (ppc64_elf_tls_setup): Set htab->opd_abi. (ppc64_elf_size_dynamic_sections): Don't emit OPD related dynamic tags for ELFv2. (ppc_build_one_stub): Use R_PPC64_IRELATIVE for ELFv2 ifunc. (ppc64_elf_finish_dynamic_symbol): Likewise binutils/ * readelf.c (get_machine_flags): Display ABI version for EM_PPC64. gas/ * config/tc-ppc.c: Include elf/ppc64.h. (ppc_abiversion): New variable. (md_pseudo_table): Add .abiversion. (ppc_elf_abiversion, ppc_elf_end): New functions. * config/tc-ppc.h (md_end): Define.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-ppc.c39
-rw-r--r--gas/config/tc-ppc.h3
2 files changed, 42 insertions, 0 deletions
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 34afc91..c249cec 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -29,6 +29,7 @@
#ifdef OBJ_ELF
#include "elf/ppc.h"
+#include "elf/ppc64.h"
#include "dwarf2dbg.h"
#endif
@@ -133,6 +134,7 @@ static void ppc_vbyte (int);
static void ppc_elf_cons (int);
static void ppc_elf_rdata (int);
static void ppc_elf_lcomm (int);
+static void ppc_elf_abiversion (int);
#endif
#ifdef TE_PE
@@ -203,6 +205,9 @@ unsigned long nop_limit = 4;
ppc_cpu_t ppc_cpu = 0;
ppc_cpu_t sticky = 0;
+/* Value for ELF e_flags EF_PPC64_ABI. */
+unsigned int ppc_abiversion = 0;
+
/* Flags set on encountering toc relocs. */
enum {
has_large_toc_reloc = 1,
@@ -261,6 +266,7 @@ const pseudo_typeS md_pseudo_table[] =
{ "rdata", ppc_elf_rdata, 0 },
{ "rodata", ppc_elf_rdata, 0 },
{ "lcomm", ppc_elf_lcomm, 0 },
+ { "abiversion", ppc_elf_abiversion, 0 },
#endif
#ifdef TE_PE
@@ -2220,6 +2226,39 @@ ppc_elf_lcomm (int xxx ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
+/* Pseudo op to set ABI version. */
+static void
+ppc_elf_abiversion (int ignore ATTRIBUTE_UNUSED)
+{
+ expressionS exp;
+
+ expression (&exp);
+ if (exp.X_op == O_absent)
+ {
+ as_bad (_("missing expression in .abiversion directive"));
+ exp.X_op = O_constant;
+ exp.X_add_number = 0;
+ }
+
+ if (resolve_expression (&exp)
+ && exp.X_op == O_constant)
+ ppc_abiversion = exp.X_add_number;
+ else
+ as_bad (_(".abiversion expression does not evaluate to a constant"));
+ demand_empty_rest_of_line ();
+}
+
+/* Set ABI version in output file. */
+void
+ppc_elf_end (void)
+{
+ if (ppc_obj64 && ppc_abiversion != 0)
+ {
+ elf_elfheader (stdoutput)->e_flags &= ~EF_PPC64_ABI;
+ elf_elfheader (stdoutput)->e_flags |= ppc_abiversion & EF_PPC64_ABI;
+ }
+}
+
/* Validate any relocations emitted for -mrelocatable, possibly adding
fixups for word relocations in writable segments, so we can adjust
them at runtime. */
diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h
index 3dd3f81..6095416 100644
--- a/gas/config/tc-ppc.h
+++ b/gas/config/tc-ppc.h
@@ -238,6 +238,9 @@ extern void ppc_frob_file_before_adjust (void);
#define tc_adjust_symtab() ppc_elf_adjust_symtab ()
extern void ppc_elf_adjust_symtab (void);
+extern void ppc_elf_end (void);
+#define md_end ppc_elf_end
+
#endif /* OBJ_ELF */
#if defined (OBJ_ELF) || defined (OBJ_XCOFF)