197403Sobrien/* NDS32-specific support for 32-bit ELF.
297403Sobrien   Copyright (C) 2012-2020 Free Software Foundation, Inc.
3169691Skan   Contributed by Andes Technology Corporation.
497403Sobrien
597403Sobrien   This file is part of BFD, the Binary File Descriptor library.
697403Sobrien
797403Sobrien   This program is free software; you can redistribute it and/or modify
897403Sobrien   it under the terms of the GNU General Public License as published by
997403Sobrien   the Free Software Foundation; either version 3 of the License, or
1097403Sobrien   (at your option) any later version.
1197403Sobrien
1297403Sobrien   This program is distributed in the hope that it will be useful,
1397403Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien   GNU General Public License for more details.
1697403Sobrien
1797403Sobrien   You should have received a copy of the GNU General Public License
18169691Skan   along with this program; if not, write to the Free Software
1997403Sobrien   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
2097403Sobrien   02110-1301, USA.*/
2197403Sobrien
2297403Sobrien#ifndef ELF32_NDS32_H
2397403Sobrien#define ELF32_NDS32_H
2497403Sobrien
2597403Sobrien#ifdef __cplusplus
2697403Sobrienextern "C" {
2797403Sobrien#endif
2897403Sobrien
2997403Sobrien/* Relocation flags encoded in r_addend.  */
3097403Sobrien
3197403Sobrien/* Relocation flags for R_NDS32_ERLAX_ENTRY.  */
3297403Sobrien
3397403Sobrien/* Set if relax on this section is done or disabled.  */
3497403Sobrien#define R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG			(1u << 31)
3597403Sobrien/* Optimize for performance.  */
3697403Sobrien#define R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG			(1u << 30)
3797403Sobrien/* Optimize for size.  Branch destination 4-byte adjustment
3897403Sobrien   may be disabled.  */
3997403Sobrien#define R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG		(1u << 29)
4097403Sobrien/* To distinguish the assembly code generated by compiler
4197403Sobrien   or written manually.  */
4297403Sobrien#define R_NDS32_RELAX_ENTRY_VERBATIM_FLAG			(1u << 28)
4397403Sobrien/* Two bits for ICT to comply with files without directive.  */
4497403Sobrien/* ICT small model.  */
4597403Sobrien#define R_NDS32_RELAX_ENTRY_ICT_SMALL                           (0x2u << 4)
4697403Sobrien/* ICT large model.  */
4797403Sobrien#define R_NDS32_RELAX_ENTRY_ICT_LARGE                           (0x3u << 4)
4897403Sobrien/* Mask for get ict bits.  */
4997403Sobrien#define R_NDS32_RELAX_ENTRY_ICT_MASK                            (0x3u << 4)
5097403Sobrien
5197403Sobrien
5297403Sobrien/* Relocation flags for R_NDS32_INSN16.  */
5397403Sobrien
5497403Sobrien/* Tag the nop16 can be removed.  */
5597403Sobrien#define R_NDS32_INSN16_CONVERT_FLAG				(1u << 0)
5697403Sobrien/* Convert a gp-relative access (e.g., lwi.gp)
5797403Sobrien   to fp-as-gp access (lwi37.fp).
58169691Skan   This value is used by linker internally only.
5997403Sobrien   It's fine to change the vlaue.  */
6097403Sobrien#define R_NDS32_INSN16_FP7U2_FLAG				(1u << 1)
6197403Sobrien
62132720Skan/* Relocation flags for R_NDS32_RELAX_REGION_OMIT_FP_START/END.  */
6397403Sobrien
6497403Sobrien/* OMIT_FP_FLAG marks the region for applying fp-as-gp
65132720Skan   optimization.  */
6697403Sobrien#define R_NDS32_RELAX_REGION_OMIT_FP_FLAG			(1u << 0)
6797403Sobrien/* NOT_OMIT_FP_FLAG is set if this region is not worth
6897403Sobrien   for fp-as-gp.  */
6997403Sobrien#define R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG			(1u << 1)
7097403Sobrien/* A Innermost loop region.  Some optimizations is suppressed
71169691Skan   in this region due to performance drop.  */
72169691Skan#define R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG		(1u << 4)
7397403Sobrien
7497403Sobrien/* Tag range for LOADSTORE relocation.  */
7597403Sobrienenum
7697403Sobrien{
7797403Sobrien  NDS32_LOADSTORE_NONE = 0x0,
7897403Sobrien  NDS32_LOADSTORE_BYTE = 0x1,
7997403Sobrien  NDS32_LOADSTORE_HALF = 0x2,
8097403Sobrien  NDS32_LOADSTORE_WORD = 0x4,
81169691Skan  NDS32_LOADSTORE_FLOAT_S = 0x8,
82169691Skan  NDS32_LOADSTORE_FLOAT_D = 0x10,
83169691Skan  NDS32_LOADSTORE_IMM = 0x20
84169691Skan};
85169691Skan
86169691Skanstruct section_id_list_t
87169691Skan{
8897403Sobrien  int id;
89169691Skan  struct section_id_list_t *next;
9097403Sobrien};
91169691Skan
92169691Skanextern struct section_id_list_t *elf32_nds32_lookup_section_id
93169691Skan  (int, struct section_id_list_t **);
94169691Skanextern int elf32_nds32_check_relax_group (bfd *, asection *);
95169691Skanextern int elf32_nds32_unify_relax_group (bfd *, asection *);
96169691Skanextern int nds32_elf_unify_tls_model (bfd *, asection *, bfd_byte *,
97169691Skan				      struct bfd_link_info *);
98169691Skanextern void nds32_insertion_sort
9997403Sobrien(void *, size_t, size_t, int (*) (const void *, const void *));
10097403Sobrien
10197403Sobrienextern int	   nds32_convert_32_to_16 (bfd *, uint32_t, uint16_t *, int *);
10297403Sobrienextern int	   nds32_convert_16_to_32 (bfd *, uint16_t, uint32_t *);
10397403Sobrienextern void	   bfd_elf32_nds32_set_target_option (struct bfd_link_info *,
10497403Sobrien						      int, int, FILE *,
10597403Sobrien						      int, int, int);
10697403Sobrien
107102782Skan#define nds32_elf_hash_table(p) \
108102782Skan  ((is_elf_hash_table ((p)->hash)					\
109102782Skan    && elf_hash_table_id (elf_hash_table (p)) == NDS32_ELF_DATA)	\
110102782Skan   ? (struct elf_nds32_link_hash_table *) (p)->hash : NULL)
111102782Skan
112132720Skan#define elf32_nds32_compute_jump_table_size(htab) \
113132720Skan  ((htab)->next_tls_desc_index * 4)
11497403Sobrien
11597403Sobrien#define elf32_nds32_local_tlsdesc_gotent(bfd) \
11697403Sobrien  (elf_nds32_tdata (bfd)->local_tlsdesc_gotent)
11797403Sobrien
11897403Sobrien/* Hash table structure for target nds32.  There are some members to
119102782Skan   save target options passed from nds32elf.em to bfd.  */
120102782Skan
121102782Skanstruct elf_nds32_link_hash_table
122102782Skan{
123102782Skan  struct elf_link_hash_table root;
12497403Sobrien
12597403Sobrien  /* Target dependent options.  */
12697403Sobrien  int relax_fp_as_gp;		/* --mrelax-omit-fp.  */
12797403Sobrien  int eliminate_gc_relocs;	/* --meliminate-gc-relocs.  */
12897403Sobrien  FILE *sym_ld_script;		/* --mgen-symbol-ld-script=<file>.  */
129102782Skan  bfd_boolean hyper_relax;	/* Relax for symbol not in RW sections.  */
130102782Skan  int tls_desc_trampoline;	/* --m[no-]tlsdesc-trampoline.  */
131102782Skan  /* Disable if linking a dynamically linked executable.  */
132102782Skan  int load_store_relax;
133102782Skan
134132720Skan  /* Offset in .plt section of tls_nds32_trampoline.  */
13597403Sobrien  bfd_vma tls_trampoline;
136132720Skan
13797403Sobrien  /* The index of the next unused R_NDS32_TLS_DESC slot in .rel.plt.  */
13897403Sobrien  bfd_vma next_tls_desc_index;
13997403Sobrien
140132720Skan  /* How many R_NDS32_TLS_DESC relocations were generated so far.  */
141132720Skan  bfd_vma num_tls_desc;
14297403Sobrien
14397403Sobrien  /* The amount of space used by the reserved portion of the sgotplt
14497403Sobrien     section, plus whatever space is used by the jump slots.  */
14597403Sobrien  bfd_vma sgotplt_jump_table_size;
14697403Sobrien
14797403Sobrien  /* True if the target uses REL relocations.  */
148169691Skan  int use_rel;
149169691Skan};
150132720Skan
15197403Sobrien#ifdef __cplusplus
152}
153#endif
154
155#endif /* ELF32_NDS32_H */
156