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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
/* AArch64-specific backend routines.
Copyright (C) 2009-2024 Free Software Foundation, Inc.
Contributed by ARM Ltd.
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; see the file COPYING3. If not,
see <http://www.gnu.org/licenses/>. */
extern void bfd_elf64_aarch64_init_maps
(bfd *);
extern void bfd_elf32_aarch64_init_maps
(bfd *);
/* Types of PLTs based on the level of security. This would be a
bit-mask to denote which of the combinations of security features
are enabled:
- No security feature PLTs
- PLTs with BTI instruction
- PLTs with PAC instruction
*/
typedef enum
{
PLT_NORMAL = 0x0, /* Normal plts. */
PLT_BTI = 0x1, /* plts with bti. */
PLT_PAC = 0x2, /* plts with pointer authentication. */
PLT_BTI_PAC = PLT_BTI | PLT_PAC
} aarch64_plt_type;
/* To indicate if BTI is enabled with/without warning. */
typedef enum
{
BTI_NONE = 0, /* BTI is not enabled. */
BTI_WARN = 1, /* BTI is enabled with -z force-bti. */
} aarch64_enable_bti_type;
/* To indicate whether GNU_PROPERTY_AARCH64_FEATURE_1_GCS bit is
enabled/disabled on the output when -z gcs linker
command line option is passed. */
typedef enum
{
GCS_NEVER = 0, /* gcs is disabled on output. */
GCS_IMPLICIT = 1, /* gcs is deduced from input object. */
GCS_ALWAYS = 2, /* gsc is enabled on output. */
} aarch64_gcs_type;
/* To indicate whether to generate linker warning/errors for
-z gcs-report when -z gcs=always is passed. */
typedef enum
{
GCS_NONE = 0, /* Does not emit any warning/error messages. */
GCS_WARN = 1, /* Emit warning when the input objects are missing gcs
markings and output have gcs marking. */
GCS_ERROR = 2, /* Emit error when the input objects are missing gcs
markings and output have gcs marking. */
} aarch64_gcs_report;
/* A structure to encompass all information coming from BTI or PAC
related command line options. This involves the "PLT_TYPE" to determine
which version of PLTs to pick and "BTI_TYPE" to determine if
BTI should be turned on with any warnings. */
typedef struct
{
aarch64_plt_type plt_type;
aarch64_enable_bti_type bti_type;
aarch64_gcs_type gcs_type;
aarch64_gcs_report gcs_report;
} aarch64_gnu_prop_info;
/* An enum to define what kind of erratum fixes we should apply. This gives the
user a bit more control over the sequences we generate. */
typedef enum
{
ERRAT_NONE = (1 << 0), /* No erratum workarounds allowed. */
ERRAT_ADR = (1 << 1), /* Erratum workarounds using ADR allowed. */
ERRAT_ADRP = (1 << 2), /* Erratum workarounds using ADRP are allowed. */
} erratum_84319_opts;
extern void bfd_elf64_aarch64_set_options
(bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
aarch64_gnu_prop_info);
extern void bfd_elf32_aarch64_set_options
(bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
aarch64_gnu_prop_info);
/* AArch64 stub generation support for ELF64. Called from the linker. */
extern int elf64_aarch64_setup_section_lists
(bfd *, struct bfd_link_info *);
extern void elf64_aarch64_next_input_section
(struct bfd_link_info *, struct bfd_section *);
extern bool elf64_aarch64_size_stubs
(bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
struct bfd_section * (*) (const char *, struct bfd_section *),
void (*) (void));
extern bool elf64_aarch64_build_stubs
(struct bfd_link_info *);
/* AArch64 stub generation support for ELF32. Called from the linker. */
extern int elf32_aarch64_setup_section_lists
(bfd *, struct bfd_link_info *);
extern void elf32_aarch64_next_input_section
(struct bfd_link_info *, struct bfd_section *);
extern bool elf32_aarch64_size_stubs
(bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
struct bfd_section * (*) (const char *, struct bfd_section *),
void (*) (void));
extern bool elf32_aarch64_build_stubs
(struct bfd_link_info *);
/* AArch64 relative relocation packing support for ELF64. */
extern bool elf64_aarch64_size_relative_relocs
(struct bfd_link_info *, bool *);
extern bool elf64_aarch64_finish_relative_relocs
(struct bfd_link_info *);
/* AArch64 relative relocation packing support for ELF32. */
extern bool elf32_aarch64_size_relative_relocs
(struct bfd_link_info *, bool *);
extern bool elf32_aarch64_finish_relative_relocs
(struct bfd_link_info *);
/* Take the PAGE component of an address or offset. */
#define PG(x) ((x) & ~ (bfd_vma) 0xfff)
#define PG_OFFSET(x) ((x) & (bfd_vma) 0xfff)
#define AARCH64_ADR_OP 0x10000000
#define AARCH64_ADRP_OP 0x90000000
#define AARCH64_ADRP_OP_MASK 0x9F000000
extern bfd_signed_vma
_bfd_aarch64_sign_extend (bfd_vma, int);
extern uint32_t
_bfd_aarch64_decode_adrp_imm (uint32_t);
extern uint32_t
_bfd_aarch64_reencode_adr_imm (uint32_t, uint32_t);
extern bfd_reloc_status_type
_bfd_aarch64_elf_put_addend (bfd *, bfd_byte *, bfd_reloc_code_real_type,
reloc_howto_type *, bfd_signed_vma);
extern bfd_vma
_bfd_aarch64_elf_resolve_relocation (bfd *, bfd_reloc_code_real_type, bfd_vma,
bfd_vma, bfd_vma, bool);
extern bool
_bfd_aarch64_elf_grok_prstatus (bfd *, Elf_Internal_Note *);
extern bool
_bfd_aarch64_elf_grok_psinfo (bfd *, Elf_Internal_Note *);
extern char *
_bfd_aarch64_elf_write_core_note (bfd *, char *, int *, int, ...);
#define elf_backend_grok_prstatus _bfd_aarch64_elf_grok_prstatus
#define elf_backend_grok_psinfo _bfd_aarch64_elf_grok_psinfo
#define elf_backend_write_core_note _bfd_aarch64_elf_write_core_note
extern bfd *
_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *, uint32_t *,
aarch64_gcs_report,
aarch64_gcs_type);
extern enum elf_property_kind
_bfd_aarch64_elf_parse_gnu_properties (bfd *, unsigned int,
bfd_byte *, unsigned int);
extern bool
_bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *, bfd *,
elf_property *, elf_property *,
uint32_t);
extern void
_bfd_aarch64_elf_check_gcs_report (aarch64_gcs_report, bfd *);
extern void
_bfd_aarch64_elf_link_fixup_gnu_properties (struct bfd_link_info *,
elf_property_list **);
#define elf_backend_parse_gnu_properties \
_bfd_aarch64_elf_parse_gnu_properties
#define elf_backend_fixup_gnu_properties \
_bfd_aarch64_elf_link_fixup_gnu_properties
|