/src/elfutils/libebl/eblopenbackend.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Generate ELF backend handle. |
2 | | Copyright (C) 2000-2017 Red Hat, Inc. |
3 | | This file is part of elfutils. |
4 | | |
5 | | This file is free software; you can redistribute it and/or modify |
6 | | it under the terms of either |
7 | | |
8 | | * the GNU Lesser General Public License as published by the Free |
9 | | Software Foundation; either version 3 of the License, or (at |
10 | | your option) any later version |
11 | | |
12 | | or |
13 | | |
14 | | * the GNU General Public License as published by the Free |
15 | | Software Foundation; either version 2 of the License, or (at |
16 | | your option) any later version |
17 | | |
18 | | or both in parallel, as here. |
19 | | |
20 | | elfutils is distributed in the hope that it will be useful, but |
21 | | WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
23 | | General Public License for more details. |
24 | | |
25 | | You should have received copies of the GNU General Public License and |
26 | | the GNU Lesser General Public License along with this program. If |
27 | | not, see <http://www.gnu.org/licenses/>. */ |
28 | | |
29 | | #ifdef HAVE_CONFIG_H |
30 | | # include <config.h> |
31 | | #endif |
32 | | |
33 | | #include <assert.h> |
34 | | #include <libelfP.h> |
35 | | #include <dwarf.h> |
36 | | #include <stdlib.h> |
37 | | #include <string.h> |
38 | | #include <stdio.h> |
39 | | |
40 | | #include <system.h> |
41 | | #include <libeblP.h> |
42 | | |
43 | | Ebl *i386_init (Elf *, GElf_Half, Ebl *); |
44 | | Ebl *sh_init (Elf *, GElf_Half, Ebl *); |
45 | | Ebl *x86_64_init (Elf *, GElf_Half, Ebl *); |
46 | | Ebl *ia64_init (Elf *, GElf_Half, Ebl *); |
47 | | Ebl *alpha_init (Elf *, GElf_Half, Ebl *); |
48 | | Ebl *arm_init (Elf *, GElf_Half, Ebl *); |
49 | | Ebl *aarch64_init (Elf *, GElf_Half, Ebl *); |
50 | | Ebl *sparc_init (Elf *, GElf_Half, Ebl *); |
51 | | Ebl *ppc_init (Elf *, GElf_Half, Ebl *); |
52 | | Ebl *ppc64_init (Elf *, GElf_Half, Ebl *); |
53 | | Ebl *s390_init (Elf *, GElf_Half, Ebl *); |
54 | | Ebl *m68k_init (Elf *, GElf_Half, Ebl *); |
55 | | Ebl *bpf_init (Elf *, GElf_Half, Ebl *); |
56 | | Ebl *riscv_init (Elf *, GElf_Half, Ebl *); |
57 | | Ebl *csky_init (Elf *, GElf_Half, Ebl *); |
58 | | Ebl *loongarch_init (Elf *, GElf_Half, Ebl *); |
59 | | Ebl *arc_init (Elf *, GElf_Half, Ebl *); |
60 | | Ebl *mips_init (Elf *, GElf_Half, Ebl *); |
61 | | Ebl *hexagon_init (Elf *, GElf_Half, Ebl *); |
62 | | |
63 | | /* This table should contain the complete list of architectures as far |
64 | | as the ELF specification is concerned. */ |
65 | | /* XXX When things are stable replace the string pointers with char |
66 | | arrays to avoid relocations. */ |
67 | | static const struct |
68 | | { |
69 | | ebl_bhinit_t init; |
70 | | const char *emulation; |
71 | | const char *prefix; |
72 | | int prefix_len; |
73 | | int em; |
74 | | int class; |
75 | | int data; |
76 | | } machines[] = |
77 | | { |
78 | | { i386_init, "elf_i386", "i386", 4, EM_386, ELFCLASS32, ELFDATA2LSB }, |
79 | | { ia64_init, "elf_ia64", "ia64", 4, EM_IA_64, ELFCLASS64, ELFDATA2LSB }, |
80 | | { alpha_init, "elf_alpha", "alpha", 5, EM_ALPHA, ELFCLASS64, ELFDATA2LSB }, |
81 | | { x86_64_init, "elf_x86_64", "x86_64", 6, EM_X86_64, ELFCLASS64, ELFDATA2LSB }, |
82 | | { ppc_init, "elf_ppc", "ppc", 3, EM_PPC, ELFCLASS32, ELFDATA2MSB }, |
83 | | { ppc64_init, "elf_ppc64", "ppc64", 5, EM_PPC64, ELFCLASS64, ELFDATA2MSB }, |
84 | | // XXX class and machine fields need to be filled in for all archs. |
85 | | { sh_init, "elf_sh", "sh", 2, EM_SH, 0, 0 }, |
86 | | { arm_init, "ebl_arm", "arm", 3, EM_ARM, 0, 0 }, |
87 | | { sparc_init, "elf_sparcv9", "sparc", 5, EM_SPARCV9, 0, 0 }, |
88 | | { sparc_init, "elf_sparc", "sparc", 5, EM_SPARC, 0, 0 }, |
89 | | { sparc_init, "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS, 0, 0 }, |
90 | | { s390_init, "ebl_s390", "s390", 4, EM_S390, 0, 0 }, |
91 | | |
92 | | { NULL, "elf_tilegx", "tilegx", 6, EM_TILEGX, ELFCLASS64, ELFDATA2LSB }, |
93 | | { NULL, "elf_m32", "m32", 3, EM_M32, 0, 0 }, |
94 | | { m68k_init, "elf_m68k", "m68k", 4, EM_68K, ELFCLASS32, ELFDATA2MSB }, |
95 | | { NULL, "elf_m88k", "m88k", 4, EM_88K, 0, 0 }, |
96 | | { NULL, "elf_i860", "i860", 4, EM_860, 0, 0 }, |
97 | | { NULL, "ebl_s370", "s370", 4, EM_S370, 0, 0 }, |
98 | | { NULL, "elf_parisc", "parisc", 6, EM_PARISC, 0, 0 }, |
99 | | { NULL, "elf_vpp500", "vpp500", 5, EM_VPP500, 0, 0 }, |
100 | | { sparc_init, "elf_v8plus", "v8plus", 6, EM_SPARC32PLUS, 0, 0 }, |
101 | | { NULL, "elf_i960", "i960", 4, EM_960, 0, 0 }, |
102 | | { NULL, "ebl_v800", "v800", 4, EM_V800, 0, 0 }, |
103 | | { NULL, "ebl_fr20", "fr20", 4, EM_FR20, 0, 0 }, |
104 | | { NULL, "ebl_rh32", "rh32", 4, EM_RH32, 0, 0 }, |
105 | | { NULL, "ebl_rce", "rce", 3, EM_RCE, 0, 0 }, |
106 | | { NULL, "elf_tricore", "tricore", 7, EM_TRICORE, 0, 0 }, |
107 | | { NULL, "elf_arc", "arc", 3, EM_ARC, 0, 0 }, |
108 | | { NULL, "elf_h8_300", "h8_300", 6, EM_H8_300, 0, 0 }, |
109 | | { NULL, "elf_h8_300h", "h8_300h", 6, EM_H8_300H, 0, 0 }, |
110 | | { NULL, "elf_h8s", "h8s", 6, EM_H8S, 0, 0 }, |
111 | | { NULL, "elf_h8_500", "h8_500", 6, EM_H8_500, 0, 0 }, |
112 | | { NULL, "elf_coldfire", "coldfire", 8, EM_COLDFIRE, 0, 0 }, |
113 | | { m68k_init, "elf_68hc12", "68hc12", 6, EM_68HC12, 0, 0 }, |
114 | | { NULL, "elf_mma", "mma", 3, EM_MMA, 0, 0 }, |
115 | | { NULL, "elf_pcp", "pcp", 3, EM_PCP, 0, 0 }, |
116 | | { NULL, "elf_ncpu", "ncpu", 4, EM_NCPU, 0, 0 }, |
117 | | { NULL, "elf_ndr1", "ndr1", 4, EM_NDR1, 0, 0 }, |
118 | | { NULL, "elf_starcore", "starcore", 8, EM_STARCORE, 0, 0 }, |
119 | | { NULL, "elf_me16", "em16", 4, EM_ME16, 0, 0 }, |
120 | | { NULL, "elf_st100", "st100", 5, EM_ST100, 0, 0 }, |
121 | | { NULL, "elf_tinyj", "tinyj", 5, EM_TINYJ, 0, 0 }, |
122 | | { NULL, "elf_pdsp", "pdsp", 4, EM_PDSP, 0, 0 }, |
123 | | { NULL, "elf_fx66", "fx66", 4, EM_FX66, 0, 0 }, |
124 | | { NULL, "elf_st9plus", "st9plus", 7, EM_ST9PLUS, 0, 0 }, |
125 | | { NULL, "elf_st7", "st7", 3, EM_ST7, 0, 0 }, |
126 | | { m68k_init, "elf_68hc16", "68hc16", 6, EM_68HC16, 0, 0 }, |
127 | | { m68k_init, "elf_68hc11", "68hc11", 6, EM_68HC11, 0, 0 }, |
128 | | { m68k_init, "elf_68hc08", "68hc08", 6, EM_68HC08, 0, 0 }, |
129 | | { m68k_init, "elf_68hc05", "68hc05", 6, EM_68HC05, 0, 0 }, |
130 | | { NULL, "elf_svx", "svx", 3, EM_SVX, 0, 0 }, |
131 | | { NULL, "elf_st19", "st19", 4, EM_ST19, 0, 0 }, |
132 | | { NULL, "elf_vax", "vax", 3, EM_VAX, 0, 0 }, |
133 | | { NULL, "elf_cris", "cris", 4, EM_CRIS, 0, 0 }, |
134 | | { NULL, "elf_javelin", "javelin", 7, EM_JAVELIN, 0, 0 }, |
135 | | { NULL, "elf_firepath", "firepath", 8, EM_FIREPATH, 0, 0 }, |
136 | | { NULL, "elf_zsp", "zsp", 3, EM_ZSP, 0, 0 }, |
137 | | { NULL, "elf_mmix", "mmix", 4, EM_MMIX, 0, 0 }, |
138 | | { NULL, "elf_huany", "huany", 5, EM_HUANY, 0, 0 }, |
139 | | { NULL, "elf_prism", "prism", 5, EM_PRISM, 0, 0 }, |
140 | | { NULL, "elf_avr", "avr", 3, EM_AVR, 0, 0 }, |
141 | | { NULL, "elf_fr30", "fr30", 4, EM_FR30, 0, 0 }, |
142 | | { NULL, "elf_dv10", "dv10", 4, EM_D10V, 0, 0 }, |
143 | | { NULL, "elf_dv30", "dv30", 4, EM_D30V, 0, 0 }, |
144 | | { NULL, "elf_v850", "v850", 4, EM_V850, 0, 0 }, |
145 | | { NULL, "elf_m32r", "m32r", 4, EM_M32R, 0, 0 }, |
146 | | { NULL, "elf_mn10300", "mn10300", 7, EM_MN10300, 0, 0 }, |
147 | | { NULL, "elf_mn10200", "mn10200", 7, EM_MN10200, 0, 0 }, |
148 | | { NULL, "elf_pj", "pj", 2, EM_PJ, 0, 0 }, |
149 | | { NULL, "elf_openrisc", "openrisc", 8, EM_OPENRISC, 0, 0 }, |
150 | | { NULL, "elf_arc_a5", "arc_a5", 6, EM_ARC_A5, 0, 0 }, |
151 | | { NULL, "elf_xtensa", "xtensa", 6, EM_XTENSA, 0, 0 }, |
152 | | { aarch64_init, "elf_aarch64", "aarch64", 7, EM_AARCH64, ELFCLASS64, 0 }, |
153 | | { bpf_init, "elf_bpf", "bpf", 3, EM_BPF, 0, 0 }, |
154 | | { riscv_init, "elf_riscv", "riscv", 5, EM_RISCV, ELFCLASS64, ELFDATA2LSB }, |
155 | | { riscv_init, "elf_riscv", "riscv", 5, EM_RISCV, ELFCLASS32, ELFDATA2LSB }, |
156 | | { csky_init, "elf_csky", "csky", 4, EM_CSKY, ELFCLASS32, ELFDATA2LSB }, |
157 | | { loongarch_init, "elf_loongarch", "loongarch", 9, EM_LOONGARCH, ELFCLASS64, ELFDATA2LSB }, |
158 | | { arc_init, "elf_arc", "arc", 3, EM_ARCV2, ELFCLASS32, ELFDATA2LSB }, |
159 | | { mips_init, "elf_mips", "mips", 4, EM_MIPS, 0, 0 }, |
160 | | { hexagon_init, "elf_hexagon", "hexagon", 9, EM_QDSP6, ELFCLASS32, ELFDATA2LSB }, |
161 | | }; |
162 | 877k | #define nmachines (sizeof (machines) / sizeof (machines[0])) |
163 | | |
164 | | /* No machine prefix should be larger than this. */ |
165 | | #define MAX_PREFIX_LEN 16 |
166 | | |
167 | | /* Default callbacks. Mostly they just return the error value. */ |
168 | | static const char *default_reloc_type_name (int ignore, char *buf, size_t len); |
169 | | static bool default_reloc_type_check (int ignore); |
170 | | static bool default_reloc_valid_use (Elf *elf, int ignore); |
171 | | static Elf_Type default_reloc_simple_type (Ebl *ebl, int ignore, int *addsub); |
172 | | static bool default_gotpc_reloc_check (Elf *elf, int ignore); |
173 | | static const char *default_segment_type_name (int ignore, char *buf, |
174 | | size_t len); |
175 | | static const char *default_section_type_name (int ignore, char *buf, |
176 | | size_t len); |
177 | | static const char *default_section_name (int ignore, int ignore2, char *buf, |
178 | | size_t len); |
179 | | static const char *default_machine_flag_name (Elf64_Word orig, Elf64_Word *ignore); |
180 | | static bool default_machine_flag_check (Elf64_Word flags); |
181 | | static bool default_machine_section_flag_check (GElf_Xword flags); |
182 | | static const char *default_symbol_type_name (int ignore, char *buf, |
183 | | size_t len); |
184 | | static const char *default_symbol_binding_name (int ignore, char *buf, |
185 | | size_t len); |
186 | | static const char *default_dynamic_tag_name (int64_t ignore, char *buf, |
187 | | size_t len); |
188 | | static bool default_dynamic_tag_check (int64_t ignore); |
189 | | static const char *default_osabi_name (int ignore, char *buf, size_t len); |
190 | | static void default_destr (struct ebl *ignore); |
191 | | static const char *default_core_note_type_name (uint32_t, char *buf, |
192 | | size_t len); |
193 | | static const char *default_object_note_type_name (const char *name, uint32_t, |
194 | | char *buf, size_t len); |
195 | | static int default_core_note (const GElf_Nhdr *nhdr, const char *name, |
196 | | GElf_Word *regs_offset, size_t *nregloc, |
197 | | const Ebl_Register_Location **reglocs, |
198 | | size_t *nitems, const Ebl_Core_Item **); |
199 | | static int default_auxv_info (GElf_Xword a_type, |
200 | | const char **name, const char **format); |
201 | | static bool default_object_note (const char *name, uint32_t type, |
202 | | uint32_t descsz, const char *desc); |
203 | | static bool default_debugscn_p (const char *name); |
204 | | static bool default_copy_reloc_p (int reloc); |
205 | | static bool default_none_reloc_p (int reloc); |
206 | | static bool default_relative_reloc_p (int reloc); |
207 | | static bool default_check_special_symbol (Elf *elf, |
208 | | const GElf_Sym *sym, |
209 | | const char *name, |
210 | | const GElf_Shdr *destshdr); |
211 | | static bool default_data_marker_symbol (const GElf_Sym *sym, const char *sname); |
212 | | static bool default_check_st_other_bits (unsigned char st_other); |
213 | | static bool default_check_special_section (Ebl *, int, |
214 | | const GElf_Shdr *, const char *); |
215 | | static bool default_bss_plt_p (Elf *elf); |
216 | | static int default_return_value_location (Dwarf_Die *functypedie, |
217 | | const Dwarf_Op **locops); |
218 | | static ssize_t default_register_info (Ebl *ebl, |
219 | | int regno, char *name, size_t namelen, |
220 | | const char **prefix, |
221 | | const char **setname, |
222 | | int *bits, int *type); |
223 | | static bool default_check_object_attribute (Ebl *ebl, const char *vendor, |
224 | | int tag, uint64_t value, |
225 | | const char **tag_name, |
226 | | const char **value_name); |
227 | | static bool default_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type); |
228 | | static int default_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info); |
229 | | |
230 | | |
231 | | static void |
232 | | fill_defaults (Ebl *result) |
233 | 24.8k | { |
234 | 24.8k | result->reloc_type_name = default_reloc_type_name; |
235 | 24.8k | result->reloc_type_check = default_reloc_type_check; |
236 | 24.8k | result->reloc_valid_use = default_reloc_valid_use; |
237 | 24.8k | result->reloc_simple_type = default_reloc_simple_type; |
238 | 24.8k | result->gotpc_reloc_check = default_gotpc_reloc_check; |
239 | 24.8k | result->segment_type_name = default_segment_type_name; |
240 | 24.8k | result->section_type_name = default_section_type_name; |
241 | 24.8k | result->section_name = default_section_name; |
242 | 24.8k | result->machine_flag_name = default_machine_flag_name; |
243 | 24.8k | result->machine_flag_check = default_machine_flag_check; |
244 | 24.8k | result->machine_section_flag_check = default_machine_section_flag_check; |
245 | 24.8k | result->check_special_section = default_check_special_section; |
246 | 24.8k | result->symbol_type_name = default_symbol_type_name; |
247 | 24.8k | result->symbol_binding_name = default_symbol_binding_name; |
248 | 24.8k | result->dynamic_tag_name = default_dynamic_tag_name; |
249 | 24.8k | result->dynamic_tag_check = default_dynamic_tag_check; |
250 | 24.8k | result->osabi_name = default_osabi_name; |
251 | 24.8k | result->core_note_type_name = default_core_note_type_name; |
252 | 24.8k | result->object_note_type_name = default_object_note_type_name; |
253 | 24.8k | result->core_note = default_core_note; |
254 | 24.8k | result->auxv_info = default_auxv_info; |
255 | 24.8k | result->object_note = default_object_note; |
256 | 24.8k | result->debugscn_p = default_debugscn_p; |
257 | 24.8k | result->copy_reloc_p = default_copy_reloc_p; |
258 | 24.8k | result->none_reloc_p = default_none_reloc_p; |
259 | 24.8k | result->relative_reloc_p = default_relative_reloc_p; |
260 | 24.8k | result->check_special_symbol = default_check_special_symbol; |
261 | 24.8k | result->data_marker_symbol = default_data_marker_symbol; |
262 | 24.8k | result->check_st_other_bits = default_check_st_other_bits; |
263 | 24.8k | result->bss_plt_p = default_bss_plt_p; |
264 | 24.8k | result->return_value_location = default_return_value_location; |
265 | 24.8k | result->register_info = default_register_info; |
266 | 24.8k | result->check_object_attribute = default_check_object_attribute; |
267 | 24.8k | result->check_reloc_target_type = default_check_reloc_target_type; |
268 | 24.8k | result->disasm = NULL; |
269 | 24.8k | result->abi_cfi = default_abi_cfi; |
270 | 24.8k | result->destr = default_destr; |
271 | 24.8k | result->sysvhash_entrysize = sizeof (Elf32_Word); |
272 | 24.8k | } |
273 | | |
274 | | /* Find an appropriate backend for the file associated with ELF. */ |
275 | | static Ebl * |
276 | | openbackend (Elf *elf, const char *emulation, GElf_Half machine) |
277 | 15.7k | { |
278 | 15.7k | Ebl *result; |
279 | 15.7k | size_t cnt; |
280 | | |
281 | | /* First allocate the data structure for the result. We do this |
282 | | here since this assures that the structure is always large |
283 | | enough. */ |
284 | 15.7k | result = calloc (1, sizeof (Ebl)); |
285 | 15.7k | if (result == NULL) |
286 | 0 | { |
287 | | // XXX uncomment |
288 | | // __libebl_seterror (ELF_E_NOMEM); |
289 | 0 | return NULL; |
290 | 0 | } |
291 | | |
292 | | /* Fill in the default callbacks. The initializer for the machine |
293 | | specific module can overwrite the values. */ |
294 | 15.7k | fill_defaults (result); |
295 | | |
296 | | /* XXX Currently all we do is to look at 'e_machine' value in the |
297 | | ELF header. With an internal mapping table from EM_* value to |
298 | | DSO name we try to load the appropriate module to handle this |
299 | | binary type. |
300 | | |
301 | | Multiple modules for the same machine type are possible and they |
302 | | will be tried in sequence. The lookup process will only stop |
303 | | when a module which can handle the machine type is found or all |
304 | | available matching modules are tried. */ |
305 | 877k | for (cnt = 0; cnt < nmachines; ++cnt) |
306 | 868k | if ((emulation != NULL && strcmp (emulation, machines[cnt].emulation) == 0) |
307 | 868k | || (emulation == NULL && machines[cnt].em == machine)) |
308 | 6.88k | { |
309 | | /* Well, we know the emulation name now. */ |
310 | 6.88k | result->emulation = machines[cnt].emulation; |
311 | | |
312 | | /* We access some data structures directly. Make sure the 32 and |
313 | | 64 bit variants are laid out the same. */ |
314 | 6.88k | assert (offsetof (Elf32_Ehdr, e_machine) |
315 | 6.88k | == offsetof (Elf64_Ehdr, e_machine)); |
316 | 6.88k | assert (sizeof (((Elf32_Ehdr *) 0)->e_machine) |
317 | 6.88k | == sizeof (((Elf64_Ehdr *) 0)->e_machine)); |
318 | 6.88k | assert (offsetof (Elf, state.elf32.ehdr) |
319 | 6.88k | == offsetof (Elf, state.elf64.ehdr)); |
320 | | |
321 | | /* Prefer taking the information from the ELF file. */ |
322 | 6.88k | if (elf == NULL) |
323 | 0 | { |
324 | 0 | result->machine = machines[cnt].em; |
325 | 0 | result->class = machines[cnt].class; |
326 | 0 | result->data = machines[cnt].data; |
327 | 0 | } |
328 | 6.88k | else |
329 | 6.88k | { |
330 | 6.88k | result->machine = elf->state.elf32.ehdr->e_machine; |
331 | 6.88k | result->class = elf->state.elf32.ehdr->e_ident[EI_CLASS]; |
332 | 6.88k | result->data = elf->state.elf32.ehdr->e_ident[EI_DATA]; |
333 | 6.88k | } |
334 | | |
335 | 6.88k | if (machines[cnt].init && |
336 | 6.88k | machines[cnt].init (elf, machine, result)) |
337 | 6.66k | { |
338 | 6.66k | result->elf = elf; |
339 | | /* A few entries are mandatory. */ |
340 | 6.66k | assert (result->destr != NULL); |
341 | 6.66k | return result; |
342 | 6.66k | } |
343 | | |
344 | | /* We don't have a backend but the emulation/machine ID matches. |
345 | | Return that information. */ |
346 | 223 | result->elf = elf; |
347 | 223 | fill_defaults (result); |
348 | | |
349 | 223 | return result; |
350 | 6.88k | } |
351 | | |
352 | | /* Nothing matched. We use only the default callbacks. */ |
353 | 8.89k | result->elf = elf; |
354 | 8.89k | result->emulation = "<unknown>"; |
355 | 8.89k | fill_defaults (result); |
356 | | |
357 | 8.89k | return result; |
358 | 15.7k | } |
359 | | |
360 | | |
361 | | /* Find an appropriate backend for the file associated with ELF. */ |
362 | | Ebl * |
363 | | ebl_openbackend (Elf *elf) |
364 | 15.7k | { |
365 | 15.7k | GElf_Ehdr ehdr_mem; |
366 | 15.7k | GElf_Ehdr *ehdr; |
367 | | |
368 | | /* Get the ELF header of the object. */ |
369 | 15.7k | ehdr = gelf_getehdr (elf, &ehdr_mem); |
370 | 15.7k | if (ehdr == NULL) |
371 | 0 | { |
372 | | // XXX uncomment |
373 | | // __libebl_seterror (elf_errno ()); |
374 | 0 | return NULL; |
375 | 0 | } |
376 | | |
377 | 15.7k | return openbackend (elf, NULL, ehdr->e_machine); |
378 | 15.7k | } |
379 | | |
380 | | |
381 | | /* Find backend without underlying ELF file. */ |
382 | | Ebl * |
383 | | ebl_openbackend_machine (GElf_Half machine) |
384 | 0 | { |
385 | 0 | return openbackend (NULL, NULL, machine); |
386 | 0 | } |
387 | | |
388 | | |
389 | | /* Find backend with given emulation name. */ |
390 | | Ebl * |
391 | | ebl_openbackend_emulation (const char *emulation) |
392 | 0 | { |
393 | 0 | return openbackend (NULL, emulation, EM_NONE); |
394 | 0 | } |
395 | | |
396 | | |
397 | | /* Default callbacks. Mostly they just return the error value. */ |
398 | | static const char * |
399 | | default_reloc_type_name (int ignore __attribute__ ((unused)), |
400 | | char *buf __attribute__ ((unused)), |
401 | | size_t len __attribute__ ((unused))) |
402 | 0 | { |
403 | 0 | return NULL; |
404 | 0 | } |
405 | | |
406 | | static bool |
407 | | default_reloc_type_check (int ignore __attribute__ ((unused))) |
408 | 0 | { |
409 | 0 | return false; |
410 | 0 | } |
411 | | |
412 | | static bool |
413 | | default_reloc_valid_use (Elf *elf __attribute__ ((unused)), |
414 | | int ignore __attribute__ ((unused))) |
415 | 0 | { |
416 | 0 | return false; |
417 | 0 | } |
418 | | |
419 | | static Elf_Type |
420 | | default_reloc_simple_type (Ebl *eh __attribute__ ((unused)), |
421 | | int ignore __attribute__ ((unused)), |
422 | | int *addsub __attribute__ ((unused))) |
423 | 0 | { |
424 | 0 | return ELF_T_NUM; |
425 | 0 | } |
426 | | |
427 | | static bool |
428 | | default_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), |
429 | | int ignore __attribute__ ((unused))) |
430 | 0 | { |
431 | 0 | return false; |
432 | 0 | } |
433 | | |
434 | | static const char * |
435 | | default_segment_type_name (int ignore __attribute__ ((unused)), |
436 | | char *buf __attribute__ ((unused)), |
437 | | size_t len __attribute__ ((unused))) |
438 | 0 | { |
439 | 0 | return NULL; |
440 | 0 | } |
441 | | |
442 | | static const char * |
443 | | default_section_type_name (int ignore __attribute__ ((unused)), |
444 | | char *buf __attribute__ ((unused)), |
445 | | size_t len __attribute__ ((unused))) |
446 | 0 | { |
447 | 0 | return NULL; |
448 | 0 | } |
449 | | |
450 | | static const char * |
451 | | default_section_name (int ignore __attribute__ ((unused)), |
452 | | int ignore2 __attribute__ ((unused)), |
453 | | char *buf __attribute__ ((unused)), |
454 | | size_t len __attribute__ ((unused))) |
455 | 0 | { |
456 | 0 | return NULL; |
457 | 0 | } |
458 | | |
459 | | static const char * |
460 | | default_machine_flag_name (Elf64_Word orig __attribute__ ((unused)), |
461 | | Elf64_Word *ignore __attribute__ ((unused))) |
462 | 0 | { |
463 | 0 | return NULL; |
464 | 0 | } |
465 | | |
466 | | static bool |
467 | | default_machine_flag_check (Elf64_Word flags __attribute__ ((unused))) |
468 | 0 | { |
469 | 0 | return flags == 0; |
470 | 0 | } |
471 | | |
472 | | static bool |
473 | | default_machine_section_flag_check (GElf_Xword flags) |
474 | 0 | { |
475 | 0 | return flags == 0; |
476 | 0 | } |
477 | | |
478 | | static bool |
479 | | default_check_special_section (Ebl *ebl __attribute__ ((unused)), |
480 | | int ndx __attribute__ ((unused)), |
481 | | const GElf_Shdr *shdr __attribute__ ((unused)), |
482 | | const char *sname __attribute__ ((unused))) |
483 | 0 | { |
484 | 0 | return false; |
485 | 0 | } |
486 | | |
487 | | static const char * |
488 | | default_symbol_type_name (int ignore __attribute__ ((unused)), |
489 | | char *buf __attribute__ ((unused)), |
490 | | size_t len __attribute__ ((unused))) |
491 | 0 | { |
492 | 0 | return NULL; |
493 | 0 | } |
494 | | |
495 | | static const char * |
496 | | default_symbol_binding_name (int ignore __attribute__ ((unused)), |
497 | | char *buf __attribute__ ((unused)), |
498 | | size_t len __attribute__ ((unused))) |
499 | 0 | { |
500 | 0 | return NULL; |
501 | 0 | } |
502 | | |
503 | | static const char * |
504 | | default_dynamic_tag_name (int64_t ignore __attribute__ ((unused)), |
505 | | char *buf __attribute__ ((unused)), |
506 | | size_t len __attribute__ ((unused))) |
507 | 0 | { |
508 | 0 | return NULL; |
509 | 0 | } |
510 | | |
511 | | static bool |
512 | | default_dynamic_tag_check (int64_t ignore __attribute__ ((unused))) |
513 | 0 | { |
514 | 0 | return false; |
515 | 0 | } |
516 | | |
517 | | static void |
518 | | default_destr (struct ebl *ignore __attribute__ ((unused))) |
519 | 15.7k | { |
520 | 15.7k | } |
521 | | |
522 | | static const char * |
523 | | default_osabi_name (int ignore __attribute__ ((unused)), |
524 | | char *buf __attribute__ ((unused)), |
525 | | size_t len __attribute__ ((unused))) |
526 | 0 | { |
527 | 0 | return NULL; |
528 | 0 | } |
529 | | |
530 | | static const char * |
531 | | default_core_note_type_name (uint32_t ignore __attribute__ ((unused)), |
532 | | char *buf __attribute__ ((unused)), |
533 | | size_t len __attribute__ ((unused))) |
534 | 0 | { |
535 | 0 | return NULL; |
536 | 0 | } |
537 | | |
538 | | static int |
539 | | default_auxv_info (GElf_Xword a_type __attribute__ ((unused)), |
540 | | const char **name __attribute__ ((unused)), |
541 | | const char **format __attribute__ ((unused))) |
542 | 0 | { |
543 | 0 | return 0; |
544 | 0 | } |
545 | | |
546 | | static int |
547 | | default_core_note (const GElf_Nhdr *nhdr __attribute__ ((unused)), |
548 | | const char *name __attribute__ ((unused)), |
549 | | GElf_Word *ro __attribute__ ((unused)), |
550 | | size_t *nregloc __attribute__ ((unused)), |
551 | | const Ebl_Register_Location **reglocs |
552 | | __attribute__ ((unused)), |
553 | | size_t *nitems __attribute__ ((unused)), |
554 | | const Ebl_Core_Item **items __attribute__ ((unused))) |
555 | 209 | { |
556 | 209 | return 0; |
557 | 209 | } |
558 | | |
559 | | static const char * |
560 | | default_object_note_type_name (const char *name __attribute__ ((unused)), |
561 | | uint32_t ignore __attribute__ ((unused)), |
562 | | char *buf __attribute__ ((unused)), |
563 | | size_t len __attribute__ ((unused))) |
564 | 0 | { |
565 | 0 | return NULL; |
566 | 0 | } |
567 | | |
568 | | static bool |
569 | | default_object_note (const char *name __attribute__ ((unused)), |
570 | | uint32_t type __attribute__ ((unused)), |
571 | | uint32_t descsz __attribute__ ((unused)), |
572 | | const char *desc __attribute__ ((unused))) |
573 | 0 | { |
574 | 0 | return NULL; |
575 | 0 | } |
576 | | |
577 | | static bool |
578 | | default_debugscn_p (const char *name) |
579 | 0 | { |
580 | | /* We know by default only about the DWARF debug sections which have |
581 | | fixed names. */ |
582 | 0 | static const char *dwarf_scn_names[] = |
583 | 0 | { |
584 | | /* DWARF 1 */ |
585 | 0 | ".debug", |
586 | 0 | ".line", |
587 | | /* GNU DWARF 1 extensions */ |
588 | 0 | ".debug_srcinfo", |
589 | 0 | ".debug_sfnames", |
590 | | /* DWARF 1.1 and DWARF 2 */ |
591 | 0 | ".debug_aranges", |
592 | 0 | ".debug_pubnames", |
593 | | /* DWARF 2 */ |
594 | 0 | ".debug_info", |
595 | 0 | ".debug_abbrev", |
596 | 0 | ".debug_line", |
597 | 0 | ".debug_frame", |
598 | 0 | ".debug_str", |
599 | 0 | ".debug_loc", |
600 | 0 | ".debug_macinfo", |
601 | | /* DWARF 3 */ |
602 | 0 | ".debug_ranges", |
603 | 0 | ".debug_pubtypes", |
604 | | /* DWARF 4 */ |
605 | 0 | ".debug_types", |
606 | | /* GDB DWARF 4 extension */ |
607 | 0 | ".gdb_index", |
608 | | /* GNU/DWARF 5 extension/proposal */ |
609 | 0 | ".debug_macro", |
610 | | /* DWARF 5 */ |
611 | 0 | ".debug_addr", |
612 | 0 | ".debug_line_str", |
613 | 0 | ".debug_loclists", |
614 | 0 | ".debug_names", |
615 | 0 | ".debug_rnglists", |
616 | 0 | ".debug_str_offsets", |
617 | | /* SGI/MIPS DWARF 2 extensions */ |
618 | 0 | ".debug_weaknames", |
619 | 0 | ".debug_funcnames", |
620 | 0 | ".debug_typenames", |
621 | 0 | ".debug_varnames" |
622 | 0 | }; |
623 | 0 | const size_t ndwarf_scn_names = (sizeof (dwarf_scn_names) |
624 | 0 | / sizeof (dwarf_scn_names[0])); |
625 | 0 | for (size_t cnt = 0; cnt < ndwarf_scn_names; ++cnt) |
626 | 0 | if (strcmp (name, dwarf_scn_names[cnt]) == 0 |
627 | 0 | || (startswith (name, ".zdebug") |
628 | 0 | && strcmp (&name[2], &dwarf_scn_names[cnt][1]) == 0) |
629 | 0 | || (startswith (name, ".gnu.debuglto_") |
630 | 0 | && strcmp (&name[14], dwarf_scn_names[cnt]) == 0)) |
631 | 0 | return true; |
632 | | |
633 | 0 | return false; |
634 | 0 | } |
635 | | |
636 | | static bool |
637 | | default_copy_reloc_p (int reloc __attribute__ ((unused))) |
638 | 0 | { |
639 | 0 | return false; |
640 | 0 | } |
641 | | strong_alias (default_copy_reloc_p, default_none_reloc_p) |
642 | | strong_alias (default_copy_reloc_p, default_relative_reloc_p) |
643 | | |
644 | | static bool |
645 | | default_check_special_symbol (Elf *elf __attribute__ ((unused)), |
646 | | const GElf_Sym *sym __attribute__ ((unused)), |
647 | | const char *name __attribute__ ((unused)), |
648 | | const GElf_Shdr *destshdr __attribute__ ((unused))) |
649 | 0 | { |
650 | 0 | return false; |
651 | 0 | } |
652 | | |
653 | | static bool |
654 | | default_data_marker_symbol (const GElf_Sym *sym __attribute__ ((unused)), |
655 | | const char *sname __attribute__ ((unused))) |
656 | 0 | { |
657 | 0 | return false; |
658 | 0 | } |
659 | | |
660 | | static bool |
661 | | default_check_st_other_bits (unsigned char st_other __attribute__ ((unused))) |
662 | 0 | { |
663 | 0 | return false; |
664 | 0 | } |
665 | | |
666 | | |
667 | | static bool |
668 | | default_bss_plt_p (Elf *elf __attribute__ ((unused))) |
669 | 0 | { |
670 | 0 | return false; |
671 | 0 | } |
672 | | |
673 | | static int |
674 | | default_return_value_location (Dwarf_Die *functypedie __attribute__ ((unused)), |
675 | | const Dwarf_Op **locops __attribute__ ((unused))) |
676 | 0 | { |
677 | 0 | return -2; |
678 | 0 | } |
679 | | |
680 | | static ssize_t |
681 | | default_register_info (Ebl *ebl __attribute__ ((unused)), |
682 | | int regno, char *name, size_t namelen, |
683 | | const char **prefix, |
684 | | const char **setname, |
685 | | int *bits, int *type) |
686 | 0 | { |
687 | 0 | if (name == NULL) |
688 | 0 | return 0; |
689 | | |
690 | 0 | *setname = "???"; |
691 | 0 | *prefix = ""; |
692 | 0 | *bits = -1; |
693 | 0 | *type = DW_ATE_void; |
694 | 0 | return snprintf (name, namelen, "reg%d", regno); |
695 | 0 | } |
696 | | |
697 | | static bool |
698 | | default_check_object_attribute (Ebl *ebl __attribute__ ((unused)), |
699 | | const char *vendor __attribute__ ((unused)), |
700 | | int tag __attribute__ ((unused)), |
701 | | uint64_t value __attribute__ ((unused)), |
702 | | const char **tag_name, const char **value_name) |
703 | 0 | { |
704 | 0 | *tag_name = NULL; |
705 | 0 | *value_name = NULL; |
706 | 0 | return false; |
707 | 0 | } |
708 | | |
709 | | static bool |
710 | | default_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), |
711 | | Elf64_Word sh_type __attribute__ ((unused))) |
712 | 0 | { |
713 | 0 | return false; |
714 | 0 | } |
715 | | |
716 | | static int |
717 | | default_abi_cfi (Ebl *ebl __attribute__ ((unused)), |
718 | | Dwarf_CIE *abi_info __attribute__ ((unused))) |
719 | 0 | { |
720 | 0 | return -1; |
721 | 0 | } |