diff options
author | Alan Modra <amodra@gmail.com> | 2013-10-29 15:06:09 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2013-10-30 13:37:47 +1030 |
commit | ee67d69a3ff0eed25d98c5e97ed6c3ede8069edc (patch) | |
tree | fe01ce8627a4436bea7d77485a61c01462a6d557 /gas/config | |
parent | 71a39c98f8bedad54818c62ab2d567b0e2de546b (diff) | |
download | gdb-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.c | 39 | ||||
-rw-r--r-- | gas/config/tc-ppc.h | 3 |
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) |