From: Sandra Loosemore Date: Wed, 1 Jul 2015 22:55:28 +0000 (-0700) Subject: Add Nios II arch flags and compatibility tests X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=965b1d80832fde9ba17a8b5f11b578a8f9e10581;hp=dfc87947b5ac6d6382c225449d4fdce411c7ee66;p=deliverable%2Fbinutils-gdb.git Add Nios II arch flags and compatibility tests 2015-07-01 Sandra Loosemore Cesar Philippidis bfd/ * archures.c (bfd_mach_nios2r1, bfd_mach_nios2r2): New. * bfd-in2.h: Regenerated. * cpu-nios2.c (nios2_compatible): New. (N): Use nios2_compatible instead of bfd_default_compatible. (NIOS2R1_NEXT, NIOS2R2_NEXT): Define. (arch_info_struct): New. (bfd_nios2_arch): Chain to NIOS2R1_NEXT. * elf32-nios2.c (is_nios2_elf): New. (nios2_elf32_merge_private_bfd_data): New. (nios2_elf32_object_p): New. (bfd_elf32_bfd_merge_private_bfd_data): Define. (elf_backend_object_p): Define. gas/ * config/tc-nios2.c: Adjust includes. (OPTION_MARCH): Define. (md_longopts): Add -march option. (nios2_architecture): New. (nios2_use_arch): New. (md_parse_option): Handle OPTION_MARCH. (md_show_usage): Document -march. (md_begin): Set arch in BFD. (nios2_elf_final_processing): New. * config/tc-nios2.h (elf_tc_final_processing): Define. (nios2_elf_final_processing): New. * doc/c-nios2.texi (-march): Add documentation. include/elf/ * nios2.h (EF_NIOS2_ARCH_R1, EF_NIOS2_ARCH_R2): Define. ld/testsuite/ * ld-nios2/mixed1a.d: New. * ld-nios2/mixed1a.s: New. * ld-nios2/mixed1b.d: New. * ld-nios2/mixed1b.s: New. * ld-nios2/nios2.exp: Build the new compatibility tests. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5c1e94ce96..701f17737e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2015-07-01 Sandra Loosemore + Cesar Philippidis + + * archures.c (bfd_mach_nios2r1, bfd_mach_nios2r2): New. + * bfd-in2.h: Regenerated. + * cpu-nios2.c (nios2_compatible): New. + (N): Use nios2_compatible instead of bfd_default_compatible. + (NIOS2R1_NEXT, NIOS2R2_NEXT): Define. + (arch_info_struct): New. + (bfd_nios2_arch): Chain to NIOS2R1_NEXT. + * elf32-nios2.c (is_nios2_elf): New. + (nios2_elf32_merge_private_bfd_data): New. + (nios2_elf32_object_p): New. + (bfd_elf32_bfd_merge_private_bfd_data): Define. + (elf_backend_object_p): Define. + 2015-07-01 H.J. Lu * elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): Refactor. diff --git a/bfd/archures.c b/bfd/archures.c index 677c4708e9..95433f85ad 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -501,8 +501,10 @@ DESCRIPTION . bfd_arch_aarch64, {* AArch64 *} .#define bfd_mach_aarch64 0 .#define bfd_mach_aarch64_ilp32 32 -. bfd_arch_nios2, -.#define bfd_mach_nios2 0 +. bfd_arch_nios2, {* Nios II *} +.#define bfd_mach_nios2 0 +.#define bfd_mach_nios2r1 1 +.#define bfd_mach_nios2r2 2 . bfd_arch_visium, {* Visium *} .#define bfd_mach_visium 1 . bfd_arch_last diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index ce964bb355..83d729eec1 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2294,8 +2294,10 @@ enum bfd_architecture bfd_arch_aarch64, /* AArch64 */ #define bfd_mach_aarch64 0 #define bfd_mach_aarch64_ilp32 32 - bfd_arch_nios2, -#define bfd_mach_nios2 0 + bfd_arch_nios2, /* Nios II */ +#define bfd_mach_nios2 0 +#define bfd_mach_nios2r1 1 +#define bfd_mach_nios2r2 2 bfd_arch_visium, /* Visium */ #define bfd_mach_visium 1 bfd_arch_last diff --git a/bfd/cpu-nios2.c b/bfd/cpu-nios2.c index 57539db14d..1e8f521bee 100644 --- a/bfd/cpu-nios2.c +++ b/bfd/cpu-nios2.c @@ -24,6 +24,26 @@ #include "bfd.h" #include "libbfd.h" +static const bfd_arch_info_type * +nios2_compatible (const bfd_arch_info_type *a, + const bfd_arch_info_type *b) +{ + if (a->arch != b->arch) + return NULL; + + if (a->bits_per_word != b->bits_per_word) + return NULL; + + if (a->mach == bfd_mach_nios2) + return a; + else if (b->mach == bfd_mach_nios2) + return b; + else if (a->mach != b->mach) + return NULL; + + return a; +} + #define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \ { \ BITS_WORD, /* bits in a word */ \ @@ -35,10 +55,20 @@ PRINT, \ 3, \ DEFAULT, \ - bfd_default_compatible, \ + nios2_compatible, \ bfd_default_scan, \ bfd_arch_default_fill, \ NEXT \ } -const bfd_arch_info_type bfd_nios2_arch = N (32, 32, 0, "nios2", TRUE, NULL); +#define NIOS2R1_NEXT &arch_info_struct[0] +#define NIOS2R2_NEXT &arch_info_struct[1] + +static const bfd_arch_info_type arch_info_struct[] = +{ + N (32, 32, bfd_mach_nios2r1, "nios2:r1", FALSE, NIOS2R2_NEXT), + N (32, 32, bfd_mach_nios2r2, "nios2:r2", FALSE, NULL), +}; + +const bfd_arch_info_type bfd_nios2_arch = + N (32, 32, 0, "nios2", TRUE, NIOS2R1_NEXT); diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c index 4f992bfce7..6a1372b71a 100644 --- a/bfd/elf32-nios2.c +++ b/bfd/elf32-nios2.c @@ -2038,6 +2038,72 @@ nios2_elf32_build_stubs (struct bfd_link_info *info) } +#define is_nios2_elf(bfd) \ + (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ + && elf_object_id (bfd) == NIOS2_ELF_DATA) + +/* Merge backend specific data from an object file to the output + object file when linking. */ + +static bfd_boolean +nios2_elf32_merge_private_bfd_data (bfd *ibfd, bfd *obfd) +{ + flagword old_flags; + flagword new_flags; + + if (!is_nios2_elf (ibfd) || !is_nios2_elf (obfd)) + return TRUE; + + /* Check if we have the same endianness. */ + if (! _bfd_generic_verify_endian_match (ibfd, obfd)) + return FALSE; + + new_flags = elf_elfheader (ibfd)->e_flags; + old_flags = elf_elfheader (obfd)->e_flags; + if (!elf_flags_init (obfd)) + { + /* First call, no flags set. */ + elf_flags_init (obfd) = TRUE; + elf_elfheader (obfd)->e_flags = new_flags; + + switch (new_flags) + { + default: + case EF_NIOS2_ARCH_R1: + bfd_default_set_arch_mach (obfd, bfd_arch_nios2, bfd_mach_nios2r1); + break; + case EF_NIOS2_ARCH_R2: + if (bfd_big_endian (ibfd)) + { + (*_bfd_error_handler) + (_("error: %B: Big-endian R2 is not supported."), ibfd); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + bfd_default_set_arch_mach (obfd, bfd_arch_nios2, bfd_mach_nios2r2); + break; + } + } + + /* Incompatible flags. */ + else if (new_flags != old_flags) + { + /* So far, the only incompatible flags denote incompatible + architectures. */ + (*_bfd_error_handler) + (_("error: %B: Conflicting CPU architectures %d/%d"), + ibfd, new_flags, old_flags); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + /* Merge Tag_compatibility attributes and any common GNU ones. */ + _bfd_elf_merge_object_attributes (ibfd, obfd); + + return TRUE; +} + + /* Implement bfd_elf32_bfd_reloc_type_lookup: Given a BFD reloc type, return a howto structure. */ static reloc_howto_type * @@ -3707,6 +3773,29 @@ nios2_elf32_copy_indirect_symbol (struct bfd_link_info *info, _bfd_elf_link_hash_copy_indirect (info, dir, ind); } +/* Set the right machine number for a NIOS2 ELF file. */ + +static bfd_boolean +nios2_elf32_object_p (bfd *abfd) +{ + unsigned long mach; + + mach = elf_elfheader (abfd)->e_flags; + + switch (mach) + { + default: + case EF_NIOS2_ARCH_R1: + bfd_default_set_arch_mach (abfd, bfd_arch_nios2, bfd_mach_nios2r1); + break; + case EF_NIOS2_ARCH_R2: + bfd_default_set_arch_mach (abfd, bfd_arch_nios2, bfd_mach_nios2r2); + break; + } + + return TRUE; +} + /* Implement elf_backend_check_relocs: Look through the relocs for a section during the first phase. */ static bfd_boolean @@ -5256,6 +5345,9 @@ const struct bfd_elf_special_section elf32_nios2_special_sections[] = #define bfd_elf32_bfd_link_hash_table_create \ nios2_elf32_link_hash_table_create +#define bfd_elf32_bfd_merge_private_bfd_data \ + nios2_elf32_merge_private_bfd_data + /* Relocation table lookup macros. */ #define bfd_elf32_bfd_reloc_type_lookup nios2_elf32_bfd_reloc_type_lookup @@ -5292,6 +5384,7 @@ const struct bfd_elf_special_section elf32_nios2_special_sections[] = #define elf_backend_size_dynamic_sections nios2_elf32_size_dynamic_sections #define elf_backend_add_symbol_hook nios2_elf_add_symbol_hook #define elf_backend_copy_indirect_symbol nios2_elf32_copy_indirect_symbol +#define elf_backend_object_p nios2_elf32_object_p #define elf_backend_grok_prstatus nios2_grok_prstatus #define elf_backend_grok_psinfo nios2_grok_psinfo diff --git a/gas/ChangeLog b/gas/ChangeLog index 77965773c5..470cd9f7c1 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,19 @@ +2015-07-01 Sandra Loosemore + Cesar Philippidis + + * config/tc-nios2.c: Adjust includes. + (OPTION_MARCH): Define. + (md_longopts): Add -march option. + (nios2_architecture): New. + (nios2_use_arch): New. + (md_parse_option): Handle OPTION_MARCH. + (md_show_usage): Document -march. + (md_begin): Set arch in BFD. + (nios2_elf_final_processing): New. + * config/tc-nios2.h (elf_tc_final_processing): Define. + (nios2_elf_final_processing): New. + * doc/c-nios2.texi (-march): Add documentation. + 2015-06-30 Amit Pawar * config/tc-i386.c (cpu_arch): Add .mwaitx. diff --git a/gas/config/tc-nios2.c b/gas/config/tc-nios2.c index 2fb26b82c4..549ca98f5f 100644 --- a/gas/config/tc-nios2.c +++ b/gas/config/tc-nios2.c @@ -25,6 +25,7 @@ #include "elf/nios2.h" #include "tc-nios2.h" #include "bfd.h" +#include "libbfd.h" #include "dwarf2dbg.h" #include "subsegs.h" #include "safe-ctype.h" @@ -80,7 +81,9 @@ struct option md_longopts[] = { #define OPTION_EB (OPTION_MD_BASE + 3) {"EB", no_argument, NULL, OPTION_EB}, #define OPTION_EL (OPTION_MD_BASE + 4) - {"EL", no_argument, NULL, OPTION_EL} + {"EL", no_argument, NULL, OPTION_EL}, +#define OPTION_MARCH (OPTION_MD_BASE + 5) + {"march", required_argument, NULL, OPTION_MARCH} }; size_t md_longopts_size = sizeof (md_longopts); @@ -212,6 +215,9 @@ static symbolS *nios2_last_label; symbolS *GOT_symbol; #endif +/* The processor architecture value, EF_NIOS2_ARCH_R1 by default. */ +static int nios2_architecture = EF_NIOS2_ARCH_R1; + /** Utility routines. */ /* Function md_chars_to_number takes the sequence of @@ -2209,6 +2215,34 @@ output_movia (nios2_insn_infoS *insn) /** External interfaces. */ +/* Update the selected architecture based on ARCH, giving an error if + ARCH is an invalid value. */ + +static void +nios2_use_arch (const char *arch) +{ + if (strcmp (arch, "nios2") == 0 || strcmp (arch, "r1") == 0) + { + nios2_architecture |= EF_NIOS2_ARCH_R1; + nios2_opcodes = (struct nios2_opcode *) nios2_r1_opcodes; + nios2_num_opcodes = nios2_num_r1_opcodes; + nop32 = nop_r1; + nop16 = NULL; + return; + } + else if (strcmp (arch, "r2") == 0) + { + nios2_architecture |= EF_NIOS2_ARCH_R2; + nios2_opcodes = (struct nios2_opcode *) nios2_r2_opcodes; + nios2_num_opcodes = nios2_num_r2_opcodes; + nop32 = nop_r2; + nop16 = nop_r2_cdx; + return; + } + + as_bad (_("unknown architecture '%s'"), arch); +} + /* The following functions are called by machine-independent parts of the assembler. */ int @@ -2235,6 +2269,9 @@ md_parse_option (int c, char *arg ATTRIBUTE_UNUSED) case OPTION_EL: target_big_endian = 0; break; + case OPTION_MARCH: + nios2_use_arch (arg); + break; default: return 0; break; @@ -2262,9 +2299,11 @@ md_show_usage (FILE *stream) "branches with jmp sequences (default)\n" " -no-relax do not replace any branches or calls\n" " -EB force big-endian byte ordering\n" - " -EL force little-endian byte ordering\n"); + " -EL force little-endian byte ordering\n" + " -march=ARCH enable instructions from architecture ARCH\n"); } + /* This function is called once, at assembler startup time. It should set up all the tables, etc. that the MD part of the assembler will need. */ @@ -2274,6 +2313,19 @@ md_begin (void) int i; const char *inserted; + switch (nios2_architecture) + { + default: + case EF_NIOS2_ARCH_R1: + bfd_default_set_arch_mach (stdoutput, bfd_arch_nios2, bfd_mach_nios2r1); + break; + case EF_NIOS2_ARCH_R2: + if (target_big_endian) + as_fatal (_("Big-endian R2 is not supported.")); + bfd_default_set_arch_mach (stdoutput, bfd_arch_nios2, bfd_mach_nios2r2); + break; + } + /* Create and fill a hashtable for the Nios II opcodes, registers and arguments. */ nios2_opcode_hash = hash_new (); @@ -2747,3 +2799,13 @@ nios2_frame_initial_instructions (void) { cfi_add_CFA_def_cfa (27, 0); } + +#ifdef OBJ_ELF +/* Some special processing for a Nios II ELF file. */ + +void +nios2_elf_final_processing (void) +{ + elf_elfheader (stdoutput)->e_flags = nios2_architecture; +} +#endif diff --git a/gas/config/tc-nios2.h b/gas/config/tc-nios2.h index 2e69caff43..8b9a7d816f 100644 --- a/gas/config/tc-nios2.h +++ b/gas/config/tc-nios2.h @@ -118,4 +118,7 @@ extern int nios2_regname_to_dw2regnum (char *regname); #define tc_cfi_frame_initial_instructions nios2_frame_initial_instructions extern void nios2_frame_initial_instructions (void); +#define elf_tc_final_processing nios2_elf_final_processing +extern void nios2_elf_final_processing (void); + #endif /* TC_NIOS2 */ diff --git a/gas/doc/c-nios2.texi b/gas/doc/c-nios2.texi index 1fb29f2268..880346dadb 100644 --- a/gas/doc/c-nios2.texi +++ b/gas/doc/c-nios2.texi @@ -58,6 +58,16 @@ Generate big-endian output. @item -EL Generate little-endian output. This is the default. +@cindex @code{march} command line option, Nios II +@item -march=@var{architecture} +This option specifies the target architecture. The assembler issues +an error message if an attempt is made to assemble an instruction which +will not execute on the target architecture. The following architecture +names are recognized: +@code{r1}, +@code{r2}. +The default is @code{r1}. + @end table @c man end diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 3e7671c5b6..0c03d8e0d3 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,8 @@ +2015-07-01 Sandra Loosemore + Cesar Philippidis + + * nios2.h (EF_NIOS2_ARCH_R1, EF_NIOS2_ARCH_R2): Define. + 2015-05-29 Roland McGrath * common.h (GNU_ABI_TAG_SYLLABLE): New macro. diff --git a/include/elf/nios2.h b/include/elf/nios2.h index 429b8ba245..07f937f8df 100644 --- a/include/elf/nios2.h +++ b/include/elf/nios2.h @@ -93,4 +93,9 @@ END_RELOC_NUMBERS (R_NIOS2_maxext) /* Address of _gp. */ #define DT_NIOS2_GP 0x70000002 +/* Processor specific flags for the Elf header e_flags field. */ + +#define EF_NIOS2_ARCH_R1 0x00000000 +#define EF_NIOS2_ARCH_R2 0x00000001 + #endif /* _ELF_NIOS2_H */ diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index e4f913f0cd..0e611b99c1 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2015-07-01 Sandra Loosemore + Cesar Philippidis + + * ld-nios2/mixed1a.d: New. + * ld-nios2/mixed1a.s: New. + * ld-nios2/mixed1b.d: New. + * ld-nios2/mixed1b.s: New. + * ld-nios2/nios2.exp: Build the new compatibility tests. + 2015-06-27 H.J. Lu * ld-xtensa/tlsbin.rd: Updated. diff --git a/ld/testsuite/ld-nios2/mixed1a.d b/ld/testsuite/ld-nios2/mixed1a.d new file mode 100644 index 0000000000..0c7d66689d --- /dev/null +++ b/ld/testsuite/ld-nios2/mixed1a.d @@ -0,0 +1,9 @@ +#name: NIOS2 mixed1a +#source: mixed1a.s +#as: -march=r2 +#readelf: -h + +ELF Header: +#... + Flags: 0x1 +#... diff --git a/ld/testsuite/ld-nios2/mixed1a.s b/ld/testsuite/ld-nios2/mixed1a.s new file mode 100644 index 0000000000..8742f1cef1 --- /dev/null +++ b/ld/testsuite/ld-nios2/mixed1a.s @@ -0,0 +1,9 @@ +# Test linking incompatible object file types. + +.text +.global _start +_start: + movhi r2, %hiadj(foo) + addi r2, r2, %lo(foo) + ldw r2, 0(r2) + cmpeq r2, r2, zero diff --git a/ld/testsuite/ld-nios2/mixed1b.d b/ld/testsuite/ld-nios2/mixed1b.d new file mode 100644 index 0000000000..a702c5adb5 --- /dev/null +++ b/ld/testsuite/ld-nios2/mixed1b.d @@ -0,0 +1,9 @@ +#name: NIOS2 mixed1b +#source: mixed1b.s +#as: -march=r1 +#readelf: -h + +ELF Header: +#... + Flags: 0x0 +#... diff --git a/ld/testsuite/ld-nios2/mixed1b.s b/ld/testsuite/ld-nios2/mixed1b.s new file mode 100644 index 0000000000..0d075905a3 --- /dev/null +++ b/ld/testsuite/ld-nios2/mixed1b.s @@ -0,0 +1,3 @@ +# Test linking incompatible object file types. + +.comm foo,4,4 diff --git a/ld/testsuite/ld-nios2/nios2.exp b/ld/testsuite/ld-nios2/nios2.exp index 22080b49d7..b8ffd49ef0 100644 --- a/ld/testsuite/ld-nios2/nios2.exp +++ b/ld/testsuite/ld-nios2/nios2.exp @@ -1,7 +1,31 @@ if { ! [istarget nios2-*-*] } { - return + return } foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.d]] { run_dump_test [file rootname $test] } + +global link_output +global ld + +set test_name "NIOS2 Mixed R1 and R2 objects" +set test mixed1 + +if ![ld_assemble $as "-march=r1 $srcdir/$subdir/${test}a.s" tmpdir/${test}a.o] { + unresolved "Build mixed1a.o" + return +} + +if ![ld_assemble $as "-march=r2 $srcdir/$subdir/${test}b.s" tmpdir/${test}b.o] { + unresolved "Build mixed1b.o" + return +} + +if { ![ld_simple_link $ld tmpdir/$test "tmpdir/${test}a.o tmpdir/${test}b.o"] } { + if [string match "*architecture * is incompatible*" $link_output] { + pass "$test_name" + } { + fail "$test_name" + } +}