diff options
author | Claudiu Zissulescu <claziss@synopsys.com> | 2017-05-10 14:42:22 +0200 |
---|---|---|
committer | claziss <claziss@synopsys.com> | 2017-05-10 14:42:22 +0200 |
commit | 53a346d8236aec06f1d3c767716d3340fb0aa013 (patch) | |
tree | 4de962aabfa44a9640583f64e8af3e032be12947 /bfd/elf32-arc.c | |
parent | 21d1fbeed4b7c4d006e399437445519e6505088f (diff) | |
download | gdb-53a346d8236aec06f1d3c767716d3340fb0aa013.zip gdb-53a346d8236aec06f1d3c767716d3340fb0aa013.tar.gz gdb-53a346d8236aec06f1d3c767716d3340fb0aa013.tar.bz2 |
[ARC] Object attributes.
gas/
2017-05-10 Claudiu Zissulescu <claziss@synopsys.com>
* testsuite/gas/arc/attr-arc600.d: New file.
* testsuite/gas/arc/attr-arc600_mul32x16.d: Likewise.
* testsuite/gas/arc/attr-arc600_norm.d: Likewise.
* testsuite/gas/arc/attr-arc601.d: Likewise.
* testsuite/gas/arc/attr-arc601_mul32x16.d: Likewise.
* testsuite/gas/arc/attr-arc601_mul64.d: Likewise.
* testsuite/gas/arc/attr-arc601_norm.d: Likewise.
* testsuite/gas/arc/attr-arc700.d: Likewise.
* testsuite/gas/arc/attr-arcem.d: Likewise.
* testsuite/gas/arc/attr-archs.d: Likewise.
* testsuite/gas/arc/attr-autodetect-1.d: Likewise.
* testsuite/gas/arc/attr-autodetect-1.s: Likewise.
* testsuite/gas/arc/attr-cpu-a601.d: Likewise.
* testsuite/gas/arc/attr-cpu-a601.s: Likewise.
* testsuite/gas/arc/attr-cpu-a700.d: Likewise.
* testsuite/gas/arc/attr-cpu-a700.s: Likewise.
* testsuite/gas/arc/attr-cpu-em.d: Likewise.
* testsuite/gas/arc/attr-cpu-em.s: Likewise.
* testsuite/gas/arc/attr-cpu-hs.d: Likewise.
* testsuite/gas/arc/attr-cpu-hs.s: Likewise.
* testsuite/gas/arc/attr-em.d: Likewise.
* testsuite/gas/arc/attr-em4.d: Likewise.
* testsuite/gas/arc/attr-em4_dmips.d: Likewise.
* testsuite/gas/arc/attr-em4_fpuda.d: Likewise.
* testsuite/gas/arc/attr-em4_fpus.d: Likewise.
* testsuite/gas/arc/attr-hs.d: Likewise.
* testsuite/gas/arc/attr-hs34.d: Likewise.
* testsuite/gas/arc/attr-hs38.d: Likewise.
* testsuite/gas/arc/attr-hs38_linux.d: Likewise.
* testsuite/gas/arc/attr-mul64.d: Likewise.
* testsuite/gas/arc/attr-name.d: Likewise.
* testsuite/gas/arc/attr-name.s: Likewise.
* testsuite/gas/arc/attr-nps400.d: Likewise.
* testsuite/gas/arc/attr-override-mcpu.d: Likewise.
* testsuite/gas/arc/attr-override-mcpu.s
* testsuite/gas/arc/attr-quarkse_em.d: Likewise.
* testsuite/gas/arc/blank.s: Likewise.
* testsuite/gas/elf/section2.e-arc: Likewise.
* testsuite/gas/arc/cpu-pseudop-1.d: Update test.
* testsuite/gas/arc/cpu-pseudop-2.d: Likewise.
* testsuite/gas/arc/nps400-0.d: Likewise.
* testsuite/gas/elf/elf.exp: Set target_machine for ARC.
* config/tc-arc.c (opcode/arc-attrs.h): Include.
(ARC_GET_FLAG, ARC_SET_FLAG, streq): Define.
(arc_attribute): Declare new function.
(md_pseudo_table): Add arc_attribute.
(cpu_types): Rename default cpu features.
(selected_cpu): Set the default OSABI flag.
(mpy_option): New variable.
(pic_option): Likewise.
(sda_option): Likewise.
(tls_option): Likewise.
(feature_type, feature_list): Remove.
(arc_initial_eflag): Likewise.
(attributes_set_explicitly): New variable.
(arc_check_feature): Check also for the conflicting features.
(arc_select_cpu): Refactor assignment of selected_cpu.eflags.
(arc_option): Remove setting of private flags and architecture.
(check_cpu_feature): Refactor feature names.
(autodetect_attributes): New function.
(assemble_tokens): Use above function.
(md_parse_option): Refactor feature names.
(arc_attribute): New function.
(arc_set_attribute_int): Likewise.
(arc_set_attribute_string): Likewise.
(arc_stralloc): Likewise.
(arc_set_public_attributes): Likewise.
(arc_md_end): Likewise.
(arc_copy_symbol_attributes): Likewise.
(rc_convert_symbolic_attribute): Likewise.
* config/tc-arc.h (md_end): Define.
(CONVERT_SYMBOLIC_ATTRIBUTE): Likewise.
(TC_COPY_SYMBOL_ATTRIBUTES): Likewise.
* doc/c-arc.texi: Document ARC object attributes.
binutils/
2017-05-10 Claudiu Zissulescu <claziss@synopsys.com>
* readelf.c (decode_ARC_machine_flags): Recognize OSABI v4.
(get_arc_section_type_name): New function.
(get_section_type_name): Use the above function.
(display_arc_attribute): New function.
(process_arc_specific): Likewise.
(process_arch_specific): Handle ARC specific information.
* testsuite/binutils-all/strip-3.d: Consider ARC.attributes
section.
include/
2017-05-10 Claudiu Zissulescu <claziss@synopsys.com>
* elf/arc.h (SHT_ARC_ATTRIBUTES): Define.
(Tag_ARC_*): Define.
(E_ARC_OSABI_V4): Define.
(E_ARC_OSABI_CURRENT): Reassign it.
(TAG_CPU_*): Define.
* opcode/arc-attrs.h: New file.
* opcode/arc.h (insn_subclass_t): Assign enum values.
(insn_subclass_t): Update enum with QUARKSE1, QUARKSE2, and LL64.
(ARC_EA, ARC_CD, ARC_LLOCK, ARC_ATOMIC, ARC_MPY, ARC_MULT)
(ARC_NPS400, ARC_DPFP, ARC_SPFP, ARC_FPU, ARC_FPUDA, ARC_SWAP)
(ARC_NORM, ARC_BSCAN, ARC_UIX, ARC_TSTAMP, ARC_VBFDW)
(ARC_BARREL, ARC_DSPA, ARC_SHIFT, ARC_INTR, ARC_DIV, ARC_XMAC)
(ARC_CRC): Delete.
bfd/
2017-05-10 Claudiu Zissulescu <claziss@synopsys.com>
* elf32-arc.c (FEATURE_LIST_NAME): Define.
(CONFLICT_LIST): Likewise.
(opcode/arc-attrs.h): Include.
(arc_elf_print_private_bfd_data): Print OSABI v4 flag.
(arc_extract_features): New file.
(arc_stralloc): Likewise.
(arc_elf_merge_attributes): Likewise.
(arc_elf_merge_private_bfd_data): Use object attributes.
(bfd_arc_get_mach_from_attributes): New function.
(arc_elf_object_p): Use object attributes.
(arc_elf_final_write_processing): Likewise.
(elf32_arc_obj_attrs_arg_type): New function.
(elf32_arc_obj_attrs_handle_unknown): Likewise.
(elf32_arc_section_from_shdr): Likewise.
(elf_backend_obj_attrs_vendor): Define.
(elf_backend_obj_attrs_section): Likewise.
(elf_backend_obj_attrs_arg_type): Likewise.
(elf_backend_obj_attrs_section_type): Likewise.
(elf_backend_obj_attrs_handle_unknown): Likewise.
(elf_backend_section_from_shdr): Likewise.
ld/
2017-05-10 Claudiu Zissulescu <claziss@synopsys.com>
* testsuite/ld-arc/attr-merge-0.d: New file.
* testsuite/ld-arc/attr-merge-0.s: Likewise.
* testsuite/ld-arc/attr-merge-0e.s: Likewise.
* testsuite/ld-arc/attr-merge-1.d: Likewise.
* testsuite/ld-arc/attr-merge-1.s: Likewise.
* testsuite/ld-arc/attr-merge-1e.s: Likewise.
* testsuite/ld-arc/attr-merge-2.d: Likewise.
* testsuite/ld-arc/attr-merge-2.s: Likewise.
* testsuite/ld-arc/attr-merge-3.d: Likewise.
* testsuite/ld-arc/attr-merge-3.s: Likewise.
* testsuite/ld-arc/attr-merge-3e.s: Likewise.
* testsuite/ld-arc/attr-merge-4.s: Likewise.
* testsuite/ld-arc/attr-merge-5.d: Likewise.
* testsuite/ld-arc/attr-merge-5a.s: Likewise.
* testsuite/ld-arc/attr-merge-5b.s: Likewise.
* testsuite/ld-arc/attr-merge-conflict-isa.d: Likewise.
* testsuite/ld-arc/attr-merge-err-isa.d: Likewise.
* testsuite/ld-arc/attr-merge-incompatible-cpu.d: Likewise.
* testsuite/ld-arc/got-01.d: Update test.
* testsuite/ld-arc/attr-merge-err-quarkse.d: New file.
* testsuite/ld-arc/attr-quarkse.s: Likewise.
* testsuite/ld-arc/attr-quarkse2.s: Likewise.
opcodes/
2017-05-10 Claudiu Zissulescu <claziss@synopsys.com>
* arc-dis.c (parse_option): Update quarkse_em option..
* arc-ext-tbl.h (dsp_fp_flt2i, dsp_fp_i2flt): Change subclass to
QUARKSE1.
(dsp_fp_div, dsp_fp_cmp): Change subclass to QUARKSE2.
Diffstat (limited to 'bfd/elf32-arc.c')
-rw-r--r-- | bfd/elf32-arc.c | 439 |
1 files changed, 427 insertions, 12 deletions
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index 5f1505e..b00207e 100644 --- a/bfd/elf32-arc.c +++ b/bfd/elf32-arc.c @@ -29,6 +29,10 @@ #include "opcode/arc.h" #include "arc-plt.h" +#define FEATURE_LIST_NAME bfd_feature_list +#define CONFLICT_LIST bfd_conflict_list +#include "opcode/arc-attrs.h" + /* #define ARC_ENABLE_DEBUG 1 */ #ifdef ARC_ENABLE_DEBUG static const char * @@ -442,8 +446,9 @@ arc_elf_print_private_bfd_data (bfd *abfd, void * ptr) case E_ARC_OSABI_ORIG : fprintf (file, " (ABI:legacy)"); break; case E_ARC_OSABI_V2 : fprintf (file, " (ABI:v2)"); break; case E_ARC_OSABI_V3 : fprintf (file, " (ABI:v3)"); break; + case E_ARC_OSABI_V4 : fprintf (file, " (ABI:v4)"); break; default: - fprintf (file, "(ABI:unknown)"); + fprintf (file, " (ABI:unknown)"); break; } @@ -500,6 +505,301 @@ arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED, cache_ptr->howto = arc_elf_howto (r_type); } +/* Extract CPU features from an NTBS. */ + +static unsigned +arc_extract_features (const char *p) +{ + unsigned i, r = 0; + + if (!p) + return 0; + + for (i = 0; i < ARRAY_SIZE (bfd_feature_list); i++) + { + char *t = strstr (p, bfd_feature_list[i].attr); + unsigned l = strlen (bfd_feature_list[i].attr); + if ((t != NULL) + && (t[l] == ',' + || t[l] == '\0')) + r |= bfd_feature_list[i].feature; + } + + return r; +} + +/* Concatenate two strings. s1 can be NULL but not + s2. */ + +static char * +arc_stralloc (char * s1, const char * s2) +{ + char *p; + + /* Only s1 can be null. */ + BFD_ASSERT (s2); + + p = s1 ? concat (s1, ",", s2, NULL) : (char *)s2; + + return p; +} + +/* Merge ARC object attributes from IBFD into OBFD. Raise an error if + there are conflicting attributes. */ + +static bfd_boolean +arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_info *info) +{ + bfd *obfd = info->output_bfd; + obj_attribute *in_attr; + obj_attribute *out_attr; + int i; + bfd_boolean result = TRUE; + const char *sec_name = get_elf_backend_data (ibfd)->obj_attrs_section; + char *tagname = NULL; + + /* Skip the linker stubs file. This preserves previous behavior + of accepting unknown attributes in the first input file - but + is that a bug? */ + if (ibfd->flags & BFD_LINKER_CREATED) + return TRUE; + + /* Skip any input that hasn't attribute section. + This enables to link object files without attribute section with + any others. */ + if (bfd_get_section_by_name (ibfd, sec_name) == NULL) + return TRUE; + + if (!elf_known_obj_attributes_proc (obfd)[0].i) + { + /* This is the first object. Copy the attributes. */ + _bfd_elf_copy_obj_attributes (ibfd, obfd); + + out_attr = elf_known_obj_attributes_proc (obfd); + + /* Use the Tag_null value to indicate the attributes have been + initialized. */ + out_attr[0].i = 1; + + return TRUE; + } + + in_attr = elf_known_obj_attributes_proc (ibfd); + out_attr = elf_known_obj_attributes_proc (obfd); + + for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) + { + /* Merge this attribute with existing attributes. */ + switch (i) + { + case Tag_ARC_PCS_config: + if (out_attr[i].i == 0) + out_attr[i].i = in_attr[i].i; + else if (in_attr[i].i != 0 && out_attr[i].i != in_attr[i].i) + { + const char *tagval[] = { "Absent", "Bare-metal/mwdt", + "Bare-metal/newlib", "Linux/uclibc", + "Linux/glibc" }; + BFD_ASSERT (in_attr[i].i < 5); + BFD_ASSERT (out_attr[i].i < 5); + /* It's sometimes ok to mix different configs, so this is only + a warning. */ + _bfd_error_handler + (_("Warning: %B: Conflicting platform configuration " + "%s with %s.\n"), ibfd, + tagval[in_attr[i].i], + tagval[out_attr[i].i]); + } + break; + + case Tag_ARC_CPU_base: + if (out_attr[i].i == 0) + out_attr[i].i = in_attr[i].i; + else if (in_attr[i].i != 0 && out_attr[i].i != in_attr[i].i + && ((out_attr[i].i + in_attr[i].i) < 6)) + { + const char *tagval[] = { "Absent", "ARC6xx", "ARC7xx", + "ARCEM", "ARCHS" }; + BFD_ASSERT (in_attr[i].i < 5); + BFD_ASSERT (out_attr[i].i < 5); + /* We cannot mix code for different CPUs. */ + _bfd_error_handler + (_("error: %B: unable to merge CPU base attributes " + "%s with %s.\n"), + obfd, + tagval[in_attr[i].i], + tagval[out_attr[i].i]); + result = FALSE; + break; + } + else + { + /* The CPUs may be different, check if we can still mix + the objects against the output choosen CPU. */ + unsigned in_feature = 0; + unsigned out_feature = 0; + char *p1 = in_attr[Tag_ARC_ISA_config].s; + char *p2 = out_attr[Tag_ARC_ISA_config].s; + unsigned j; + unsigned cpu_out; + unsigned opcode_map[] = {0, ARC_OPCODE_ARC600, ARC_OPCODE_ARC700, + ARC_OPCODE_ARCv2EM, ARC_OPCODE_ARCv2HS}; + + BFD_ASSERT (in_attr[i].i < (sizeof (opcode_map) + / sizeof (unsigned))); + BFD_ASSERT (out_attr[i].i < (sizeof (opcode_map) + / sizeof (unsigned))); + cpu_out = opcode_map[out_attr[i].i]; + + in_feature = arc_extract_features (p1); + out_feature = arc_extract_features (p2); + + /* First, check if a feature is compatible with the + output object chosen CPU. */ + for (j = 0; j < ARRAY_SIZE (bfd_feature_list); j++) + if (((in_feature | out_feature) & bfd_feature_list[j].feature) + && (!(cpu_out & bfd_feature_list[j].cpus))) + { + _bfd_error_handler + (_("error: %B: unable to merge ISA extension attributes " + "%s.\n"), + obfd, bfd_feature_list[j].name); + result = FALSE; + break; + } + /* Second, if we have compatible features with the + chosen CPU, check if they are compatible among + them. */ + for (j = 0; j < ARRAY_SIZE (bfd_conflict_list); j++) + if (((in_feature | out_feature) & bfd_conflict_list[j]) + == bfd_conflict_list[j]) + { + unsigned k; + for (k = 0; k < ARRAY_SIZE (bfd_feature_list); k++) + { + if (in_feature & bfd_feature_list[k].feature + & bfd_conflict_list[j]) + p1 = (char *) bfd_feature_list[k].name; + if (out_feature & bfd_feature_list[k].feature + & bfd_conflict_list[j]) + p2 = (char *) bfd_feature_list[k].name; + } + _bfd_error_handler + (_("error: %B: conflicting ISA extension attributes " + "%s with %s.\n"), + obfd, p1, p2); + result = FALSE; + break; + } + /* Everithing is alright. */ + out_feature |= in_feature; + p1 = NULL; + for (j = 0; j < ARRAY_SIZE (bfd_feature_list); j++) + if (out_feature & bfd_feature_list[j].feature) + p1 = arc_stralloc (p1, bfd_feature_list[j].attr); + if (p1) + out_attr[Tag_ARC_ISA_config].s = + _bfd_elf_attr_strdup (obfd, p1); + } + /* Fall through. */ + case Tag_ARC_CPU_variation: + case Tag_ARC_ISA_mpy_option: + case Tag_ARC_ABI_osver: + /* Use the largest value specified. */ + if (in_attr[i].i > out_attr[i].i) + out_attr[i].i = in_attr[i].i; + break; + + case Tag_ARC_CPU_name: + break; + + case Tag_ARC_ABI_rf16: + if (out_attr[i].i == 0) + out_attr[i].i = in_attr[i].i; + else if (out_attr[i].i != in_attr[i].i) + { + /* We cannot mix code with rf16 and without. */ + _bfd_error_handler + (_("error: %B: cannot mix rf16 with full register set %B.\n"), + obfd, ibfd); + result = FALSE; + } + break; + + case Tag_ARC_ABI_pic: + tagname = "PIC"; + case Tag_ARC_ABI_sda: + if (!tagname) + tagname = "SDA"; + case Tag_ARC_ABI_tls: + { + const char *tagval[] = { "Absent", "MWDT", "GNU" }; + + if (!tagname) + tagname = "TLS"; + + BFD_ASSERT (in_attr[i].i < 3); + BFD_ASSERT (out_attr[i].i < 3); + if (out_attr[i].i != 0 && in_attr[i].i != 0 + && out_attr[i].i != in_attr[i].i) + { + _bfd_error_handler + (_("error: %B: conflicting attributes %s: %s with %s.\n"), + obfd, tagname, + tagval[in_attr[i].i], + tagval[out_attr[i].i]); + result = FALSE; + } + tagname = NULL; + break; + } + + case Tag_ARC_ABI_double_size: + tagname = "Double size"; + case Tag_ARC_ABI_enumsize: + if (!tagname) + tagname = "Enum size"; + case Tag_ARC_ABI_exceptions: + if (!tagname) + tagname = "ABI exceptions"; + + if (out_attr[i].i != 0 && in_attr[i].i != 0 + && out_attr[i].i != in_attr[i].i) + { + _bfd_error_handler + (_("error: %B: conflicting attributes %s.\n"), + obfd, tagname); + result = FALSE; + } + break; + + case Tag_ARC_ISA_apex: + break; /* Do nothing for APEX attributes. */ + + case Tag_ARC_ISA_config: + /* It is handled in Tag_ARC_CPU_base. */ + break; + + default: + result + = result && _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i); + } + + /* If out_attr was copied from in_attr then it won't have a type yet. */ + if (in_attr[i].type && !out_attr[i].type) + out_attr[i].type = in_attr[i].type; + } + + /* Merge Tag_compatibility attributes and any common GNU ones. */ + if (!_bfd_elf_merge_object_attributes (ibfd, info)) + return FALSE; + + /* Check for any attributes not known on ARC. */ + result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd); + + return result; +} + /* Merge backend specific data from an object file to the output object file when linking. */ @@ -517,6 +817,10 @@ arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) if (! _bfd_generic_verify_endian_match (ibfd, info)) return FALSE; + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour + || bfd_get_flavour (obfd) != bfd_target_elf_flavour) + return TRUE; + /* Collect ELF flags. */ in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK; out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK; @@ -527,9 +831,8 @@ arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) out_flags = in_flags; } - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour - || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return TRUE; + if (!arc_elf_merge_attributes (ibfd, info)) + return FALSE; /* Check to see if the input BFD actually contains any sections. Do not short-circuit dynamic objects; their section list may be @@ -569,7 +872,11 @@ arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) ibfd, obfd); return FALSE; } - else if (in_flags != out_flags) + else if ((in_flags != out_flags) + /* If we have object attributes, then we already + checked the objects compatibility, skip it. */ + && !bfd_elf_get_obj_attr_int (ibfd, OBJ_ATTR_PROC, + Tag_ARC_CPU_base)) { /* Warn if different flags. */ _bfd_error_handler @@ -583,6 +890,11 @@ arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) eflags set by gcc. */ in_flags = in_flags > out_flags ? in_flags : out_flags; } + else + { + /* Everything is correct; don't change the output flags. */ + in_flags = out_flags; + } } /* Update the flags. */ @@ -596,6 +908,30 @@ arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) return TRUE; } +/* Return a best guess for the machine number based on the attributes. */ + +static unsigned int +bfd_arc_get_mach_from_attributes (bfd * abfd) +{ + int arch = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_ARC_CPU_base); + unsigned e_machine = elf_elfheader (abfd)->e_machine; + + switch (arch) + { + case TAG_CPU_ARC6xx: + return bfd_mach_arc_arc600; + case TAG_CPU_ARC7xx: + return bfd_mach_arc_arc700; + case TAG_CPU_ARCEM: + case TAG_CPU_ARCHS: + return bfd_mach_arc_arcv2; + default: + break; + } + return (e_machine == EM_ARC_COMPACT) + ? bfd_mach_arc_arc700 : bfd_mach_arc_arcv2; +} + /* Set the right machine number for an ARC ELF file. */ static bfd_boolean arc_elf_object_p (bfd * abfd) @@ -603,7 +939,7 @@ arc_elf_object_p (bfd * abfd) /* Make sure this is initialised, or you'll have the potential of passing garbage---or misleading values---into the call to bfd_default_set_arch_mach (). */ - int mach = bfd_mach_arc_arc700; + unsigned int mach = bfd_mach_arc_arc700; unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK; unsigned e_machine = elf_elfheader (abfd)->e_machine; @@ -625,8 +961,7 @@ arc_elf_object_p (bfd * abfd) mach = bfd_mach_arc_arcv2; break; default: - mach = (e_machine == EM_ARC_COMPACT) - ? bfd_mach_arc_arc700 : bfd_mach_arc_arcv2; + mach = bfd_arc_get_mach_from_attributes (abfd); break; } } @@ -657,6 +992,9 @@ arc_elf_final_write_processing (bfd * abfd, bfd_boolean linker ATTRIBUTE_UNUSED) { unsigned long emf; + int osver = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, + Tag_ARC_ABI_osver); + flagword e_flags = elf_elfheader (abfd)->e_flags & ~EF_ARC_OSABI_MSK; switch (bfd_get_mach (abfd)) { @@ -673,16 +1011,18 @@ arc_elf_final_write_processing (bfd * abfd, emf = EM_ARC_COMPACT2; break; default: - goto DO_NOTHING; + return; } elf_elfheader (abfd)->e_machine = emf; /* Record whatever is the current syscall ABI version. */ - elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT; + if (osver) + e_flags |= ((osver & 0x0f) << 8); + else + e_flags |= E_ARC_OSABI_V3; -DO_NOTHING: - return; + elf_elfheader (abfd)->e_flags |= e_flags; } #ifdef ARC_ENABLE_DEBUG @@ -2465,6 +2805,69 @@ elf32_arc_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) note->descpos + offset); } +/* Determine whether an object attribute tag takes an integer, a + string or both. */ + +static int +elf32_arc_obj_attrs_arg_type (int tag) +{ + if (tag == Tag_ARC_CPU_name + || tag == Tag_ARC_ISA_config + || tag == Tag_ARC_ISA_apex) + return ATTR_TYPE_FLAG_STR_VAL; + else if (tag < (Tag_ARC_ISA_mpy_option + 1)) + return ATTR_TYPE_FLAG_INT_VAL; + else + return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL; +} + +/* Attribute numbers >=14 can be safely ignored. */ + +static bfd_boolean +elf32_arc_obj_attrs_handle_unknown (bfd *abfd, int tag) +{ + if ((tag & 127) < (Tag_ARC_ISA_mpy_option + 1)) + { + _bfd_error_handler + (_("%B: Unknown mandatory ARC object attribute %d."), + abfd, tag); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + else + { + _bfd_error_handler + (_("Warning: %B: Unknown ARC object attribute %d."), + abfd, tag); + return TRUE; + } +} + +/* Handle an ARC specific section when reading an object file. This is + called when bfd_section_from_shdr finds a section with an unknown + type. */ + +static bfd_boolean +elf32_arc_section_from_shdr (bfd *abfd, + Elf_Internal_Shdr * hdr, + const char *name, + int shindex) +{ + switch (hdr->sh_type) + { + case SHT_ARC_ATTRIBUTES: + break; + + default: + return FALSE; + } + + if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) + return FALSE; + + return TRUE; +} + #define TARGET_LITTLE_SYM arc_elf32_le_vec #define TARGET_LITTLE_NAME "elf32-littlearc" #define TARGET_BIG_SYM arc_elf32_be_vec @@ -2516,4 +2919,16 @@ elf32_arc_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) #define elf_backend_default_execstack 0 +#undef elf_backend_obj_attrs_vendor +#define elf_backend_obj_attrs_vendor "ARC" +#undef elf_backend_obj_attrs_section +#define elf_backend_obj_attrs_section ".ARC.attributes" +#undef elf_backend_obj_attrs_arg_type +#define elf_backend_obj_attrs_arg_type elf32_arc_obj_attrs_arg_type +#undef elf_backend_obj_attrs_section_type +#define elf_backend_obj_attrs_section_type SHT_ARC_ATTRIBUTES +#define elf_backend_obj_attrs_handle_unknown elf32_arc_obj_attrs_handle_unknown + +#define elf_backend_section_from_shdr elf32_arc_section_from_shdr + #include "elf32-target.h" |