-static const struct mips_mach_extension mips_mach_extensions[] =
-{
- /* MIPS64r2 extensions. */
- { bfd_mach_mips_octeon2, bfd_mach_mips_octeonp },
- { bfd_mach_mips_octeonp, bfd_mach_mips_octeon },
- { bfd_mach_mips_octeon, bfd_mach_mipsisa64r2 },
-
- /* MIPS64 extensions. */
- { bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 },
- { bfd_mach_mips_sb1, bfd_mach_mipsisa64 },
- { bfd_mach_mips_xlr, bfd_mach_mipsisa64 },
- { bfd_mach_mips_loongson_3a, bfd_mach_mipsisa64 },
-
- /* MIPS V extensions. */
- { bfd_mach_mipsisa64, bfd_mach_mips5 },
-
- /* R10000 extensions. */
- { bfd_mach_mips12000, bfd_mach_mips10000 },
- { bfd_mach_mips14000, bfd_mach_mips10000 },
- { bfd_mach_mips16000, bfd_mach_mips10000 },
-
- /* R5000 extensions. Note: the vr5500 ISA is an extension of the core
- vr5400 ISA, but doesn't include the multimedia stuff. It seems
- better to allow vr5400 and vr5500 code to be merged anyway, since
- many libraries will just use the core ISA. Perhaps we could add
- some sort of ASE flag if this ever proves a problem. */
- { bfd_mach_mips5500, bfd_mach_mips5400 },
- { bfd_mach_mips5400, bfd_mach_mips5000 },
-
- /* MIPS IV extensions. */
- { bfd_mach_mips5, bfd_mach_mips8000 },
- { bfd_mach_mips10000, bfd_mach_mips8000 },
- { bfd_mach_mips5000, bfd_mach_mips8000 },
- { bfd_mach_mips7000, bfd_mach_mips8000 },
- { bfd_mach_mips9000, bfd_mach_mips8000 },
-
- /* VR4100 extensions. */
- { bfd_mach_mips4120, bfd_mach_mips4100 },
- { bfd_mach_mips4111, bfd_mach_mips4100 },
-
- /* MIPS III extensions. */
- { bfd_mach_mips_loongson_2e, bfd_mach_mips4000 },
- { bfd_mach_mips_loongson_2f, bfd_mach_mips4000 },
- { bfd_mach_mips8000, bfd_mach_mips4000 },
- { bfd_mach_mips4650, bfd_mach_mips4000 },
- { bfd_mach_mips4600, bfd_mach_mips4000 },
- { bfd_mach_mips4400, bfd_mach_mips4000 },
- { bfd_mach_mips4300, bfd_mach_mips4000 },
- { bfd_mach_mips4100, bfd_mach_mips4000 },
- { bfd_mach_mips4010, bfd_mach_mips4000 },
- { bfd_mach_mips5900, bfd_mach_mips4000 },
-
- /* MIPS32 extensions. */
- { bfd_mach_mipsisa32r2, bfd_mach_mipsisa32 },
-
- /* MIPS II extensions. */
- { bfd_mach_mips4000, bfd_mach_mips6000 },
- { bfd_mach_mipsisa32, bfd_mach_mips6000 },
-
- /* MIPS I extensions. */
- { bfd_mach_mips6000, bfd_mach_mips3000 },
- { bfd_mach_mips3900, bfd_mach_mips3000 }
-};
-
-
-/* Return true if bfd machine EXTENSION is an extension of machine BASE. */
-
-static bfd_boolean
-mips_mach_extends_p (unsigned long base, unsigned long extension)
-{
- size_t i;
-
- if (extension == base)
- return TRUE;
-
- if (base == bfd_mach_mipsisa32
- && mips_mach_extends_p (bfd_mach_mipsisa64, extension))
- return TRUE;
-
- if (base == bfd_mach_mipsisa32r2
- && mips_mach_extends_p (bfd_mach_mipsisa64r2, extension))
- return TRUE;
-
- for (i = 0; i < ARRAY_SIZE (mips_mach_extensions); i++)
- if (extension == mips_mach_extensions[i].extension)
- {
- extension = mips_mach_extensions[i].base;
- if (extension == base)
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/* Return true if the given ELF header flags describe a 32-bit binary. */
-
-static bfd_boolean
-mips_32bit_flags_p (flagword flags)
-{
- return ((flags & EF_MIPS_32BITMODE) != 0
- || (flags & EF_MIPS_ABI) == E_MIPS_ABI_O32
- || (flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI32
- || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1
- || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2
- || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32
- || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R2);
-}
-
-
-/* Merge object attributes from IBFD into OBFD. Raise an error if
- there are conflicting attributes. */
-static bfd_boolean
-mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
-{
- obj_attribute *in_attr;
- obj_attribute *out_attr;
- bfd *abi_fp_bfd;
-
- abi_fp_bfd = mips_elf_tdata (obfd)->abi_fp_bfd;
- in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
- if (!abi_fp_bfd && in_attr[Tag_GNU_MIPS_ABI_FP].i != 0)
- mips_elf_tdata (obfd)->abi_fp_bfd = ibfd;
-
- if (!elf_known_obj_attributes_proc (obfd)[0].i)
- {
- /* This is the first object. Copy the attributes. */
- _bfd_elf_copy_obj_attributes (ibfd, obfd);
-
- /* Use the Tag_null value to indicate the attributes have been
- initialized. */
- elf_known_obj_attributes_proc (obfd)[0].i = 1;
-
- return TRUE;
- }
-
- /* Check for conflicting Tag_GNU_MIPS_ABI_FP attributes and merge
- non-conflicting ones. */
- out_attr = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
- if (in_attr[Tag_GNU_MIPS_ABI_FP].i != out_attr[Tag_GNU_MIPS_ABI_FP].i)
- {
- out_attr[Tag_GNU_MIPS_ABI_FP].type = 1;
- if (out_attr[Tag_GNU_MIPS_ABI_FP].i == 0)
- out_attr[Tag_GNU_MIPS_ABI_FP].i = in_attr[Tag_GNU_MIPS_ABI_FP].i;
- else if (in_attr[Tag_GNU_MIPS_ABI_FP].i != 0)
- switch (out_attr[Tag_GNU_MIPS_ABI_FP].i)
- {
- case 1:
- switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
- {
- case 2:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd, "-mdouble-float", "-msingle-float");
- break;
-
- case 3:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd, "-mhard-float", "-msoft-float");
- break;
-
- case 4:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd,
- "-mdouble-float", "-mips32r2 -mfp64");
- break;
-
- default:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), "
- "%B uses unknown floating point ABI %d"),
- obfd, abi_fp_bfd, ibfd,
- "-mdouble-float", in_attr[Tag_GNU_MIPS_ABI_FP].i);
- break;
- }
- break;
-
- case 2:
- switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
- {
- case 1:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd, "-msingle-float", "-mdouble-float");
- break;
-
- case 3:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd, "-mhard-float", "-msoft-float");
- break;
-
- case 4:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd,
- "-msingle-float", "-mips32r2 -mfp64");
- break;
-
- default:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), "
- "%B uses unknown floating point ABI %d"),
- obfd, abi_fp_bfd, ibfd,
- "-msingle-float", in_attr[Tag_GNU_MIPS_ABI_FP].i);
- break;
- }
- break;
-
- case 3:
- switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
- {
- case 1:
- case 2:
- case 4:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd, "-msoft-float", "-mhard-float");
- break;
-
- default:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), "
- "%B uses unknown floating point ABI %d"),
- obfd, abi_fp_bfd, ibfd,
- "-msoft-float", in_attr[Tag_GNU_MIPS_ABI_FP].i);
- break;
- }
- break;
-
- case 4:
- switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
- {
- case 1:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd,
- "-mips32r2 -mfp64", "-mdouble-float");
- break;
-
- case 2:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd,
- "-mips32r2 -mfp64", "-msingle-float");
- break;
-
- case 3:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd, "-mhard-float", "-msoft-float");
- break;
-
- default:
- _bfd_error_handler
- (_("Warning: %B uses %s (set by %B), "
- "%B uses unknown floating point ABI %d"),
- obfd, abi_fp_bfd, ibfd,
- "-mips32r2 -mfp64", in_attr[Tag_GNU_MIPS_ABI_FP].i);
- break;
- }
- break;
-
- default:
- switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
- {
- case 1:
- _bfd_error_handler
- (_("Warning: %B uses unknown floating point ABI %d "
- "(set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd,
- out_attr[Tag_GNU_MIPS_ABI_FP].i, "-mdouble-float");
- break;
-
- case 2:
- _bfd_error_handler
- (_("Warning: %B uses unknown floating point ABI %d "
- "(set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd,
- out_attr[Tag_GNU_MIPS_ABI_FP].i, "-msingle-float");
- break;
-
- case 3:
- _bfd_error_handler
- (_("Warning: %B uses unknown floating point ABI %d "
- "(set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd,
- out_attr[Tag_GNU_MIPS_ABI_FP].i, "-msoft-float");
- break;
-
- case 4:
- _bfd_error_handler
- (_("Warning: %B uses unknown floating point ABI %d "
- "(set by %B), %B uses %s"),
- obfd, abi_fp_bfd, ibfd,
- out_attr[Tag_GNU_MIPS_ABI_FP].i, "-mips32r2 -mfp64");
- break;
-
- default:
- _bfd_error_handler
- (_("Warning: %B uses unknown floating point ABI %d "
- "(set by %B), %B uses unknown floating point ABI %d"),
- obfd, abi_fp_bfd, ibfd,
- out_attr[Tag_GNU_MIPS_ABI_FP].i,
- in_attr[Tag_GNU_MIPS_ABI_FP].i);
- break;
- }
- break;
- }
- }
-
- /* Merge Tag_compatibility attributes and any common GNU ones. */
- _bfd_elf_merge_object_attributes (ibfd, obfd);
-
- return TRUE;
-}
-
-/* Merge backend specific data from an object file to the output
- object file when linking. */
-
-bfd_boolean
-_bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
-{
- flagword old_flags;
- flagword new_flags;
- bfd_boolean ok;
- bfd_boolean null_input_bfd = TRUE;
- asection *sec;
-
- /* Check if we have the same endianness. */
- if (! _bfd_generic_verify_endian_match (ibfd, obfd))
- {
- (*_bfd_error_handler)
- (_("%B: endianness incompatible with that of the selected emulation"),
- ibfd);
- return FALSE;
- }
-
- if (!is_mips_elf (ibfd) || !is_mips_elf (obfd))
- return TRUE;
-
- if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
- {
- (*_bfd_error_handler)
- (_("%B: ABI is incompatible with that of the selected emulation"),
- ibfd);
- return FALSE;
- }
-
- if (!mips_elf_merge_obj_attributes (ibfd, obfd))
- return FALSE;
-
- new_flags = elf_elfheader (ibfd)->e_flags;
- elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER;
- old_flags = elf_elfheader (obfd)->e_flags;
-
- if (! elf_flags_init (obfd))
- {
- elf_flags_init (obfd) = TRUE;
- elf_elfheader (obfd)->e_flags = new_flags;
- elf_elfheader (obfd)->e_ident[EI_CLASS]
- = elf_elfheader (ibfd)->e_ident[EI_CLASS];
-
- if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
- && (bfd_get_arch_info (obfd)->the_default
- || mips_mach_extends_p (bfd_get_mach (obfd),
- bfd_get_mach (ibfd))))
- {
- if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
- bfd_get_mach (ibfd)))
- return FALSE;
- }
-
- return TRUE;
- }
-
- /* Check flag compatibility. */