| /* NFP-specific support for 64-bit ELF | 
 |    Copyright (C) 2017-2022 Free Software Foundation, Inc. | 
 |    Contributed by Francois H. Theron <francois.theron@netronome.com> | 
 |  | 
 |    This file is part of BFD, the Binary File Descriptor library. | 
 |  | 
 |    This program is free software; you can redistribute it and/or modify | 
 |    it under the terms of the GNU General Public License as published by | 
 |    the Free Software Foundation; either version 3 of the License, or | 
 |    (at your option) any later version. | 
 |  | 
 |    This program is distributed in the hope that it will be useful, | 
 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |    GNU General Public License for more details. | 
 |  | 
 |    You should have received a copy of the GNU General Public License | 
 |    along with this program; if not, write to the Free Software | 
 |    Foundation, Inc., 51 Franklin Street - Fifth Floor, | 
 |    Boston, MA 02110-1301, USA.  */ | 
 |  | 
 | #include "sysdep.h" | 
 | #include "bfd.h" | 
 | #include "libbfd.h" | 
 | #include "elf-bfd.h" | 
 | #include "elf/nfp.h" | 
 |  | 
 |  | 
 | static bfd_reloc_status_type | 
 | elf64_nfp_reloc (bfd * abfd ATTRIBUTE_UNUSED, | 
 | 		 arelent * reloc_entry, | 
 | 		 asymbol * symbol, | 
 | 		 void *data ATTRIBUTE_UNUSED, | 
 | 		 asection * input_section, | 
 | 		 bfd * output_bfd, | 
 | 		 char **error_message ATTRIBUTE_UNUSED); | 
 |  | 
 | /* We don't actually apply any relocations in this toolset | 
 |    so we make them all do nothing, but at least display useful | 
 |    names. | 
 |    Most of these are mainly used by the NFP toolchain to resolve things | 
 |    before the final ELF file is created.  */ | 
 | #define NFP_HOWTO(type) \ | 
 |   HOWTO (type, 0, 0, 0, false, 0, complain_overflow_dont, elf64_nfp_reloc, \ | 
 | 	 #type, false, 0, 0, false) | 
 | static reloc_howto_type elf_nfp_howto_table[] = | 
 | { | 
 |   NFP_HOWTO (R_NFP_NOTYPE), | 
 |   NFP_HOWTO (R_NFP_W32LE), | 
 |   NFP_HOWTO (R_NFP_SRC8_A), | 
 |   NFP_HOWTO (R_NFP_SRC8_B), | 
 |   NFP_HOWTO (R_NFP_IMMED8_I), | 
 |   NFP_HOWTO (R_NFP_SC), | 
 |   NFP_HOWTO (R_NFP_IMMED_LO16_I_A), | 
 |   NFP_HOWTO (R_NFP_IMMED_LO16_I_B), | 
 |   NFP_HOWTO (R_NFP_SRC7_B), | 
 |   NFP_HOWTO (R_NFP_SRC7_A), | 
 |   NFP_HOWTO (R_NFP_SRC8_I_B), | 
 |   NFP_HOWTO (R_NFP_SRC8_I_A), | 
 |   NFP_HOWTO (R_NFP_IMMED_HI16_I_A), | 
 |   NFP_HOWTO (R_NFP_IMMED_HI16_I_B), | 
 |   NFP_HOWTO (R_NFP_W64LE), | 
 |   NFP_HOWTO (R_NFP_SH_INFO), | 
 |   NFP_HOWTO (R_NFP_W32BE), | 
 |   NFP_HOWTO (R_NFP_W64BE), | 
 |   NFP_HOWTO (R_NFP_W32_29_24), | 
 |   NFP_HOWTO (R_NFP_W32LE_AND), | 
 |   NFP_HOWTO (R_NFP_W32BE_AND), | 
 |   NFP_HOWTO (R_NFP_W32LE_OR), | 
 |   NFP_HOWTO (R_NFP_W32BE_OR), | 
 |   NFP_HOWTO (R_NFP_W64LE_AND), | 
 |   NFP_HOWTO (R_NFP_W64BE_AND), | 
 |   NFP_HOWTO (R_NFP_W64LE_OR), | 
 |   NFP_HOWTO (R_NFP_W64BE_OR) | 
 | }; | 
 |  | 
 | static bool | 
 | elf64_nfp_object_p (bfd * abfd) | 
 | { | 
 |   /* If the e_machine value is one of the unofficial ones, we convert | 
 |      it first and set e_flags accordingly for later consistency.  */ | 
 |   if (elf_elfheader (abfd)->e_machine == E_NFP_MACH_3200) | 
 |     { | 
 |       elf_elfheader (abfd)->e_machine = EM_NFP; | 
 |       elf_elfheader (abfd)->e_flags &= ~EF_NFP_SET_MACH (~0); | 
 |       elf_elfheader (abfd)->e_flags |= EF_NFP_SET_MACH (E_NFP_MACH_3200); | 
 |     } | 
 |   else if (elf_elfheader (abfd)->e_machine == E_NFP_MACH_6000) | 
 |     { | 
 |       elf_elfheader (abfd)->e_machine = EM_NFP; | 
 |       elf_elfheader (abfd)->e_flags &= ~EF_NFP_SET_MACH (~0); | 
 |       elf_elfheader (abfd)->e_flags |= EF_NFP_SET_MACH (E_NFP_MACH_6000); | 
 |     } | 
 |  | 
 |   if (elf_elfheader (abfd)->e_machine == EM_NFP) | 
 |     { | 
 |       int e_mach = EF_NFP_MACH (elf_elfheader (abfd)->e_flags); | 
 |  | 
 |       switch (e_mach) | 
 | 	{ | 
 | 	case E_NFP_MACH_3200: | 
 | 	case E_NFP_MACH_6000: | 
 | 	  if (!bfd_default_set_arch_mach (abfd, bfd_arch_nfp, e_mach)) | 
 | 	    return false; | 
 | 	default: | 
 | 	  break; | 
 | 	} | 
 |     } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | static bool | 
 | elf64_nfp_section_from_shdr (bfd * abfd, | 
 | 			     Elf_Internal_Shdr * hdr, | 
 | 			     const char *name, int shindex) | 
 | { | 
 |   switch (hdr->sh_type) | 
 |     { | 
 |     case SHT_NFP_INITREG: | 
 |     case SHT_NFP_MECONFIG: | 
 |     case SHT_NFP_UDEBUG: | 
 |       return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); | 
 |     default: | 
 |       return false; | 
 |     } | 
 | } | 
 |  | 
 | bfd_reloc_status_type | 
 | elf64_nfp_reloc (bfd * abfd ATTRIBUTE_UNUSED, | 
 | 		 arelent * reloc_entry ATTRIBUTE_UNUSED, | 
 | 		 asymbol * symbol ATTRIBUTE_UNUSED, | 
 | 		 void *data ATTRIBUTE_UNUSED, | 
 | 		 asection * input_section ATTRIBUTE_UNUSED, | 
 | 		 bfd * output_bfd ATTRIBUTE_UNUSED, | 
 | 		 char **error_message ATTRIBUTE_UNUSED) | 
 | { | 
 |   return bfd_reloc_ok; | 
 | } | 
 |  | 
 | static bool | 
 | elf64_nfp_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, | 
 | 			 arelent * cache_ptr, Elf_Internal_Rela * dst) | 
 | { | 
 |   unsigned int r_type; | 
 |  | 
 |   r_type = ELF64_R_TYPE (dst->r_info); | 
 |   if (r_type >= R_NFP_MAX) | 
 |     { | 
 |       /* xgettext:c-format */ | 
 |       _bfd_error_handler (_("%pB: unsupported relocation type %#x"), | 
 | 			  abfd, r_type); | 
 |       bfd_set_error (bfd_error_bad_value); | 
 |       return false; | 
 |     } | 
 |   cache_ptr->howto = &elf_nfp_howto_table[r_type]; | 
 |   return true; | 
 | } | 
 |  | 
 | static reloc_howto_type * | 
 | elf64_nfp_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, | 
 | 			     bfd_reloc_code_real_type code ATTRIBUTE_UNUSED) | 
 | { | 
 |   return NULL; | 
 | } | 
 |  | 
 | static reloc_howto_type * | 
 | elf64_nfp_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, | 
 | 			     const char *r_name ATTRIBUTE_UNUSED) | 
 | { | 
 |   return NULL; | 
 | } | 
 |  | 
 | #define ELF_ARCH		bfd_arch_nfp | 
 | #define ELF_MACHINE_CODE	EM_NFP | 
 | #define ELF_MACHINE_ALT1	E_NFP_MACH_6000 | 
 | #define ELF_MACHINE_ALT2	E_NFP_MACH_3200 | 
 | #define ELF_MAXPAGESIZE		1 | 
 | #define TARGET_LITTLE_NAME	"elf64-nfp" | 
 | #define TARGET_LITTLE_SYM       nfp_elf64_vec | 
 |  | 
 | #define elf_backend_object_p		elf64_nfp_object_p | 
 | #define elf_backend_section_from_shdr   elf64_nfp_section_from_shdr | 
 | #define elf_info_to_howto		elf64_nfp_info_to_howto | 
 | #define bfd_elf64_bfd_reloc_type_lookup	     elf64_nfp_reloc_type_lookup | 
 | #define bfd_elf64_bfd_reloc_name_lookup      elf64_nfp_reloc_name_lookup | 
 |  | 
 | #include "elf64-target.h" |