summaryrefslogtreecommitdiff
blob: 58ce79135351beff9c19b849896f5d159a13dc0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* NDS32-specific support for 32-bit ELF.
   Copyright (C) 2012-2022 Free Software Foundation, Inc.
   Contributed by Andes Technology Corporation.

   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.*/

#ifndef ELF32_NDS32_H
#define ELF32_NDS32_H

#ifdef __cplusplus
extern "C" {
#endif

/* Relocation flags encoded in r_addend.  */

/* Relocation flags for R_NDS32_ERLAX_ENTRY.  */

/* Set if relax on this section is done or disabled.  */
#define R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG			(1u << 31)
/* Optimize for performance.  */
#define R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG			(1u << 30)
/* Optimize for size.  Branch destination 4-byte adjustment
   may be disabled.  */
#define R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG		(1u << 29)
/* To distinguish the assembly code generated by compiler
   or written manually.  */
#define R_NDS32_RELAX_ENTRY_VERBATIM_FLAG			(1u << 28)
/* Two bits for ICT to comply with files without directive.  */
/* ICT small model.  */
#define R_NDS32_RELAX_ENTRY_ICT_SMALL                           (0x2u << 4)
/* ICT large model.  */
#define R_NDS32_RELAX_ENTRY_ICT_LARGE                           (0x3u << 4)
/* Mask for get ict bits.  */
#define R_NDS32_RELAX_ENTRY_ICT_MASK                            (0x3u << 4)


/* Relocation flags for R_NDS32_INSN16.  */

/* Tag the nop16 can be removed.  */
#define R_NDS32_INSN16_CONVERT_FLAG				(1u << 0)
/* Convert a gp-relative access (e.g., lwi.gp)
   to fp-as-gp access (lwi37.fp).
   This value is used by linker internally only.
   It's fine to change the vlaue.  */
#define R_NDS32_INSN16_FP7U2_FLAG				(1u << 1)

/* Relocation flags for R_NDS32_RELAX_REGION_OMIT_FP_START/END.  */

/* OMIT_FP_FLAG marks the region for applying fp-as-gp
   optimization.  */
#define R_NDS32_RELAX_REGION_OMIT_FP_FLAG			(1u << 0)
/* NOT_OMIT_FP_FLAG is set if this region is not worth
   for fp-as-gp.  */
#define R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG			(1u << 1)
/* A Innermost loop region.  Some optimizations is suppressed
   in this region due to performance drop.  */
#define R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG		(1u << 4)

/* Tag range for LOADSTORE relocation.  */
enum
{
  NDS32_LOADSTORE_NONE = 0x0,
  NDS32_LOADSTORE_BYTE = 0x1,
  NDS32_LOADSTORE_HALF = 0x2,
  NDS32_LOADSTORE_WORD = 0x4,
  NDS32_LOADSTORE_FLOAT_S = 0x8,
  NDS32_LOADSTORE_FLOAT_D = 0x10,
  NDS32_LOADSTORE_IMM = 0x20
};

struct section_id_list_t
{
  int id;
  struct section_id_list_t *next;
};

extern struct section_id_list_t *elf32_nds32_lookup_section_id
  (int, struct section_id_list_t **);
extern int elf32_nds32_check_relax_group (bfd *, asection *);
extern int elf32_nds32_unify_relax_group (bfd *, asection *);
extern int nds32_elf_unify_tls_model (bfd *, asection *, bfd_byte *,
				      struct bfd_link_info *);

extern int	   nds32_convert_32_to_16 (bfd *, uint32_t, uint16_t *, int *);
extern int	   nds32_convert_16_to_32 (bfd *, uint16_t, uint32_t *);
extern void	   bfd_elf32_nds32_set_target_option (struct bfd_link_info *,
						      int, int, FILE *,
						      int, int, int);

#define nds32_elf_hash_table(p) \
  ((is_elf_hash_table ((p)->hash)					\
    && elf_hash_table_id (elf_hash_table (p)) == NDS32_ELF_DATA)	\
   ? (struct elf_nds32_link_hash_table *) (p)->hash : NULL)

#define elf32_nds32_compute_jump_table_size(htab) \
  ((htab)->next_tls_desc_index * 4)

#define elf32_nds32_local_tlsdesc_gotent(bfd) \
  (elf_nds32_tdata (bfd)->local_tlsdesc_gotent)

/* Hash table structure for target nds32.  There are some members to
   save target options passed from nds32elf.em to bfd.  */

struct elf_nds32_link_hash_table
{
  struct elf_link_hash_table root;

  /* Target dependent options.  */
  int relax_fp_as_gp;		/* --mrelax-omit-fp.  */
  int eliminate_gc_relocs;	/* --meliminate-gc-relocs.  */
  FILE *sym_ld_script;		/* --mgen-symbol-ld-script=<file>.  */
  int hyper_relax;		/* Relax for symbol not in RW sections.  */
  int tls_desc_trampoline;	/* --m[no-]tlsdesc-trampoline.  */
  /* Disable if linking a dynamically linked executable.  */
  int load_store_relax;

  /* Offset in .plt section of tls_nds32_trampoline.  */
  bfd_vma tls_trampoline;

  /* The index of the next unused R_NDS32_TLS_DESC slot in .rel.plt.  */
  bfd_vma next_tls_desc_index;

  /* How many R_NDS32_TLS_DESC relocations were generated so far.  */
  bfd_vma num_tls_desc;

  /* The amount of space used by the reserved portion of the sgotplt
     section, plus whatever space is used by the jump slots.  */
  bfd_vma sgotplt_jump_table_size;

  /* True if the target uses REL relocations.  */
  int use_rel;
};

#ifdef __cplusplus
}
#endif

#endif /* ELF32_NDS32_H */