15ba6b03cSchristos /* NDS32-specific support for 32-bit ELF.
2*f22f0ef4Schristos    Copyright (C) 2012-2022 Free Software Foundation, Inc.
35ba6b03cSchristos    Contributed by Andes Technology Corporation.
45ba6b03cSchristos 
55ba6b03cSchristos    This file is part of BFD, the Binary File Descriptor library.
65ba6b03cSchristos 
75ba6b03cSchristos    This program is free software; you can redistribute it and/or modify
85ba6b03cSchristos    it under the terms of the GNU General Public License as published by
95ba6b03cSchristos    the Free Software Foundation; either version 3 of the License, or
105ba6b03cSchristos    (at your option) any later version.
115ba6b03cSchristos 
125ba6b03cSchristos    This program is distributed in the hope that it will be useful,
135ba6b03cSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
145ba6b03cSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155ba6b03cSchristos    GNU General Public License for more details.
165ba6b03cSchristos 
175ba6b03cSchristos    You should have received a copy of the GNU General Public License
185ba6b03cSchristos    along with this program; if not, write to the Free Software
195ba6b03cSchristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
205ba6b03cSchristos    02110-1301, USA.*/
215ba6b03cSchristos 
225ba6b03cSchristos #ifndef ELF32_NDS32_H
235ba6b03cSchristos #define ELF32_NDS32_H
245ba6b03cSchristos 
2575f9f1baSchristos #ifdef __cplusplus
2675f9f1baSchristos extern "C" {
2775f9f1baSchristos #endif
2875f9f1baSchristos 
295ba6b03cSchristos /* Relocation flags encoded in r_addend.  */
305ba6b03cSchristos 
315ba6b03cSchristos /* Relocation flags for R_NDS32_ERLAX_ENTRY.  */
325ba6b03cSchristos 
335ba6b03cSchristos /* Set if relax on this section is done or disabled.  */
34f7172901Schristos #define R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG			(1u << 31)
355ba6b03cSchristos /* Optimize for performance.  */
36f7172901Schristos #define R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG			(1u << 30)
375ba6b03cSchristos /* Optimize for size.  Branch destination 4-byte adjustment
385ba6b03cSchristos    may be disabled.  */
39f7172901Schristos #define R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG		(1u << 29)
405ba6b03cSchristos /* To distinguish the assembly code generated by compiler
415ba6b03cSchristos    or written manually.  */
42f7172901Schristos #define R_NDS32_RELAX_ENTRY_VERBATIM_FLAG			(1u << 28)
43fa2c2dd3Schristos /* Two bits for ICT to comply with files without directive.  */
44fa2c2dd3Schristos /* ICT small model.  */
45f7172901Schristos #define R_NDS32_RELAX_ENTRY_ICT_SMALL                           (0x2u << 4)
46fa2c2dd3Schristos /* ICT large model.  */
47f7172901Schristos #define R_NDS32_RELAX_ENTRY_ICT_LARGE                           (0x3u << 4)
48fa2c2dd3Schristos /* Mask for get ict bits.  */
49f7172901Schristos #define R_NDS32_RELAX_ENTRY_ICT_MASK                            (0x3u << 4)
505ba6b03cSchristos 
515ba6b03cSchristos 
525ba6b03cSchristos /* Relocation flags for R_NDS32_INSN16.  */
535ba6b03cSchristos 
545ba6b03cSchristos /* Tag the nop16 can be removed.  */
55f7172901Schristos #define R_NDS32_INSN16_CONVERT_FLAG				(1u << 0)
565ba6b03cSchristos /* Convert a gp-relative access (e.g., lwi.gp)
575ba6b03cSchristos    to fp-as-gp access (lwi37.fp).
585ba6b03cSchristos    This value is used by linker internally only.
595ba6b03cSchristos    It's fine to change the vlaue.  */
60f7172901Schristos #define R_NDS32_INSN16_FP7U2_FLAG				(1u << 1)
615ba6b03cSchristos 
625ba6b03cSchristos /* Relocation flags for R_NDS32_RELAX_REGION_OMIT_FP_START/END.  */
635ba6b03cSchristos 
645ba6b03cSchristos /* OMIT_FP_FLAG marks the region for applying fp-as-gp
655ba6b03cSchristos    optimization.  */
66f7172901Schristos #define R_NDS32_RELAX_REGION_OMIT_FP_FLAG			(1u << 0)
675ba6b03cSchristos /* NOT_OMIT_FP_FLAG is set if this region is not worth
685ba6b03cSchristos    for fp-as-gp.  */
69f7172901Schristos #define R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG			(1u << 1)
705ba6b03cSchristos /* A Innermost loop region.  Some optimizations is suppressed
715ba6b03cSchristos    in this region due to performance drop.  */
72f7172901Schristos #define R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG		(1u << 4)
735ba6b03cSchristos 
745ba6b03cSchristos /* Tag range for LOADSTORE relocation.  */
755ba6b03cSchristos enum
765ba6b03cSchristos {
775ba6b03cSchristos   NDS32_LOADSTORE_NONE = 0x0,
785ba6b03cSchristos   NDS32_LOADSTORE_BYTE = 0x1,
795ba6b03cSchristos   NDS32_LOADSTORE_HALF = 0x2,
805ba6b03cSchristos   NDS32_LOADSTORE_WORD = 0x4,
815ba6b03cSchristos   NDS32_LOADSTORE_FLOAT_S = 0x8,
825ba6b03cSchristos   NDS32_LOADSTORE_FLOAT_D = 0x10,
835ba6b03cSchristos   NDS32_LOADSTORE_IMM = 0x20
845ba6b03cSchristos };
855ba6b03cSchristos 
86f7172901Schristos struct section_id_list_t
875ba6b03cSchristos {
88f7172901Schristos   int id;
89f7172901Schristos   struct section_id_list_t *next;
905ba6b03cSchristos };
915ba6b03cSchristos 
92f7172901Schristos extern struct section_id_list_t *elf32_nds32_lookup_section_id
93f7172901Schristos   (int, struct section_id_list_t **);
94f7172901Schristos extern int elf32_nds32_check_relax_group (bfd *, asection *);
95f7172901Schristos extern int elf32_nds32_unify_relax_group (bfd *, asection *);
96f7172901Schristos extern int nds32_elf_unify_tls_model (bfd *, asection *, bfd_byte *,
97f7172901Schristos 				      struct bfd_link_info *);
985ba6b03cSchristos 
995ba6b03cSchristos extern int	   nds32_convert_32_to_16 (bfd *, uint32_t, uint16_t *, int *);
1005ba6b03cSchristos extern int	   nds32_convert_16_to_32 (bfd *, uint16_t, uint32_t *);
1015ba6b03cSchristos extern void	   bfd_elf32_nds32_set_target_option (struct bfd_link_info *,
102f7172901Schristos 						      int, int, FILE *,
103f7172901Schristos 						      int, int, int);
1045ba6b03cSchristos 
105*f22f0ef4Schristos #define nds32_elf_hash_table(p) \
106*f22f0ef4Schristos   ((is_elf_hash_table ((p)->hash)					\
107*f22f0ef4Schristos     && elf_hash_table_id (elf_hash_table (p)) == NDS32_ELF_DATA)	\
108*f22f0ef4Schristos    ? (struct elf_nds32_link_hash_table *) (p)->hash : NULL)
1095ba6b03cSchristos 
110f7172901Schristos #define elf32_nds32_compute_jump_table_size(htab) \
111f7172901Schristos   ((htab)->next_tls_desc_index * 4)
112f7172901Schristos 
113f7172901Schristos #define elf32_nds32_local_tlsdesc_gotent(bfd) \
114f7172901Schristos   (elf_nds32_tdata (bfd)->local_tlsdesc_gotent)
115f7172901Schristos 
1165ba6b03cSchristos /* Hash table structure for target nds32.  There are some members to
1175ba6b03cSchristos    save target options passed from nds32elf.em to bfd.  */
1185ba6b03cSchristos 
1195ba6b03cSchristos struct elf_nds32_link_hash_table
1205ba6b03cSchristos {
1215ba6b03cSchristos   struct elf_link_hash_table root;
1225ba6b03cSchristos 
1235ba6b03cSchristos   /* Target dependent options.  */
124f7172901Schristos   int relax_fp_as_gp;		/* --mrelax-omit-fp.  */
125f7172901Schristos   int eliminate_gc_relocs;	/* --meliminate-gc-relocs.  */
126f7172901Schristos   FILE *sym_ld_script;		/* --mgen-symbol-ld-script=<file>.  */
127*f22f0ef4Schristos   int hyper_relax;		/* Relax for symbol not in RW sections.  */
128f7172901Schristos   int tls_desc_trampoline;	/* --m[no-]tlsdesc-trampoline.  */
1295ba6b03cSchristos   /* Disable if linking a dynamically linked executable.  */
1305ba6b03cSchristos   int load_store_relax;
131f7172901Schristos 
132f7172901Schristos   /* Offset in .plt section of tls_nds32_trampoline.  */
133f7172901Schristos   bfd_vma tls_trampoline;
134f7172901Schristos 
135f7172901Schristos   /* The index of the next unused R_NDS32_TLS_DESC slot in .rel.plt.  */
136f7172901Schristos   bfd_vma next_tls_desc_index;
137f7172901Schristos 
138f7172901Schristos   /* How many R_NDS32_TLS_DESC relocations were generated so far.  */
139f7172901Schristos   bfd_vma num_tls_desc;
140f7172901Schristos 
141f7172901Schristos   /* The amount of space used by the reserved portion of the sgotplt
142f7172901Schristos      section, plus whatever space is used by the jump slots.  */
143f7172901Schristos   bfd_vma sgotplt_jump_table_size;
144f7172901Schristos 
145f7172901Schristos   /* True if the target uses REL relocations.  */
146f7172901Schristos   int use_rel;
1475ba6b03cSchristos };
14875f9f1baSchristos 
14975f9f1baSchristos #ifdef __cplusplus
15075f9f1baSchristos }
15175f9f1baSchristos #endif
15275f9f1baSchristos 
153f7172901Schristos #endif /* ELF32_NDS32_H */
154