1 /* AArch64-specific backend routines.
2    Copyright (C) 2009-2021 Free Software Foundation, Inc.
3    Contributed by ARM Ltd.
4 
5    This file is part of BFD, the Binary File Descriptor library.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; see the file COPYING3. If not,
19    see <http://www.gnu.org/licenses/>.  */
20 
21 extern void bfd_elf64_aarch64_init_maps
22   (bfd *);
23 
24 extern void bfd_elf32_aarch64_init_maps
25   (bfd *);
26 
27 /* Types of PLTs based on the level of security.  This would be a
28    bit-mask to denote which of the combinations of security features
29    are enabled:
30    - No security feature PLTs
31    - PLTs with BTI instruction
32    - PLTs with PAC instruction
33 */
34 typedef enum
35 {
36   PLT_NORMAL	= 0x0,  /* Normal plts.  */
37   PLT_BTI	= 0x1,  /* plts with bti.  */
38   PLT_PAC	= 0x2,  /* plts with pointer authentication.  */
39   PLT_BTI_PAC	= PLT_BTI | PLT_PAC
40 } aarch64_plt_type;
41 
42 /* To indicate if BTI is enabled with/without warning.  */
43 typedef enum
44 {
45   BTI_NONE	= 0,  /* BTI is not enabled.  */
46   BTI_WARN	= 1,  /* BTI is enabled with -z force-bti.  */
47 } aarch64_enable_bti_type;
48 
49 /* A structure to encompass all information coming from BTI or PAC
50    related command line options.  This involves the "PLT_TYPE" to determine
51    which version of PLTs to pick and "BTI_TYPE" to determine if
52    BTI should be turned on with any warnings.   */
53 typedef struct
54 {
55   aarch64_plt_type plt_type;
56   aarch64_enable_bti_type bti_type;
57 } aarch64_bti_pac_info;
58 
59 /* An enum to define what kind of erratum fixes we should apply.  This gives the
60    user a bit more control over the sequences we generate.  */
61 typedef enum
62 {
63   ERRAT_NONE  = (1 << 0),  /* No erratum workarounds allowed.  */
64   ERRAT_ADR   = (1 << 1),  /* Erratum workarounds using ADR allowed.  */
65   ERRAT_ADRP  = (1 << 2),  /* Erratum workarounds using ADRP are allowed.  */
66 } erratum_84319_opts;
67 
68 extern void bfd_elf64_aarch64_set_options
69   (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
70    aarch64_bti_pac_info);
71 
72 extern void bfd_elf32_aarch64_set_options
73   (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
74    aarch64_bti_pac_info);
75 
76 /* AArch64 stub generation support for ELF64.  Called from the linker.  */
77 extern int elf64_aarch64_setup_section_lists
78   (bfd *, struct bfd_link_info *);
79 extern void elf64_aarch64_next_input_section
80   (struct bfd_link_info *, struct bfd_section *);
81 extern bool elf64_aarch64_size_stubs
82   (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
83    struct bfd_section * (*) (const char *, struct bfd_section *),
84    void (*) (void));
85 extern bool elf64_aarch64_build_stubs
86   (struct bfd_link_info *);
87 /* AArch64 stub generation support for ELF32.  Called from the linker.  */
88 extern int elf32_aarch64_setup_section_lists
89   (bfd *, struct bfd_link_info *);
90 extern void elf32_aarch64_next_input_section
91   (struct bfd_link_info *, struct bfd_section *);
92 extern bool elf32_aarch64_size_stubs
93   (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
94    struct bfd_section * (*) (const char *, struct bfd_section *),
95    void (*) (void));
96 extern bool elf32_aarch64_build_stubs
97   (struct bfd_link_info *);
98 
99 /* Take the PAGE component of an address or offset.  */
100 #define PG(x)	     ((x) & ~ (bfd_vma) 0xfff)
101 #define PG_OFFSET(x) ((x) &   (bfd_vma) 0xfff)
102 
103 #define AARCH64_ADR_OP		0x10000000
104 #define AARCH64_ADRP_OP		0x90000000
105 #define AARCH64_ADRP_OP_MASK	0x9F000000
106 
107 extern bfd_signed_vma
108 _bfd_aarch64_sign_extend (bfd_vma, int);
109 
110 extern uint32_t
111 _bfd_aarch64_decode_adrp_imm (uint32_t);
112 
113 extern uint32_t
114 _bfd_aarch64_reencode_adr_imm (uint32_t, uint32_t);
115 
116 extern bfd_reloc_status_type
117 _bfd_aarch64_elf_put_addend (bfd *, bfd_byte *, bfd_reloc_code_real_type,
118 			     reloc_howto_type *, bfd_signed_vma);
119 
120 extern bfd_vma
121 _bfd_aarch64_elf_resolve_relocation (bfd *, bfd_reloc_code_real_type, bfd_vma,
122 				     bfd_vma, bfd_vma, bool);
123 
124 extern bool
125 _bfd_aarch64_elf_grok_prstatus (bfd *, Elf_Internal_Note *);
126 
127 extern bool
128 _bfd_aarch64_elf_grok_psinfo (bfd *, Elf_Internal_Note *);
129 
130 extern char *
131 _bfd_aarch64_elf_write_core_note (bfd *, char *, int *, int, ...);
132 
133 #define elf_backend_grok_prstatus	_bfd_aarch64_elf_grok_prstatus
134 #define elf_backend_grok_psinfo		_bfd_aarch64_elf_grok_psinfo
135 #define elf_backend_write_core_note	_bfd_aarch64_elf_write_core_note
136 
137 extern bfd *
138 _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *,
139 					    uint32_t *);
140 
141 extern enum elf_property_kind
142 _bfd_aarch64_elf_parse_gnu_properties (bfd *, unsigned int,
143 				       bfd_byte *, unsigned int);
144 
145 extern bool
146 _bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *, bfd *,
147 				       elf_property *, elf_property *,
148 				       uint32_t);
149 
150 extern void
151 _bfd_aarch64_elf_link_fixup_gnu_properties (struct bfd_link_info *,
152 					    elf_property_list **);
153 
154 #define elf_backend_parse_gnu_properties	\
155   _bfd_aarch64_elf_parse_gnu_properties
156 
157 #define elf_backend_fixup_gnu_properties	\
158   _bfd_aarch64_elf_link_fixup_gnu_properties
159