Add DT_MIPS_RLD_MAP case for 64-bit targets.
[deliverable/binutils-gdb.git] / gdb / osabi.c
CommitLineData
70f80edf
JT
1/* OS ABI variant handling for GDB.
2 Copyright 2001, 2002 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21#include "defs.h"
309367d4 22#include "gdb_string.h"
70f80edf
JT
23#include "osabi.h"
24
25#include "elf-bfd.h"
26
27
28/* This table matches the indices assigned to enum gdb_osabi. Keep
29 them in sync. */
30static const char * const gdb_osabi_names[] =
31{
32 "<unknown>",
33
34 "SVR4",
35 "GNU/Hurd",
36 "Solaris",
37 "OSF/1",
38 "GNU/Linux",
39 "FreeBSD a.out",
40 "FreeBSD ELF",
41 "NetBSD a.out",
42 "NetBSD ELF",
43 "Windows CE",
1029b7fa
MK
44 "DJGPP",
45 "NetWare",
b96d0a4e 46 "Irix",
daa66587 47 "LynxOS",
e64f66d1 48 "Interix",
a09a320d
JB
49 "HP/UX ELF",
50 "HP/UX SOM",
70f80edf
JT
51
52 "ARM EABI v1",
53 "ARM EABI v2",
54 "ARM APCS",
55
56 "<invalid>"
57};
58
59const char *
60gdbarch_osabi_name (enum gdb_osabi osabi)
61{
62 if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID)
63 return gdb_osabi_names[osabi];
64
65 return gdb_osabi_names[GDB_OSABI_INVALID];
66}
67
68/* Handler for a given architecture/OS ABI pair. There should be only
69 one handler for a given OS ABI each architecture family. */
70struct gdb_osabi_handler
71{
72 struct gdb_osabi_handler *next;
73 enum bfd_architecture arch;
74 enum gdb_osabi osabi;
75 void (*init_osabi)(struct gdbarch_info, struct gdbarch *);
76};
77
78static struct gdb_osabi_handler *gdb_osabi_handler_list;
79
80void
81gdbarch_register_osabi (enum bfd_architecture arch, enum gdb_osabi osabi,
82 void (*init_osabi)(struct gdbarch_info,
83 struct gdbarch *))
84{
85 struct gdb_osabi_handler **handler_p;
86
87 /* Registering an OS ABI handler for "unknown" is not allowed. */
88 if (osabi == GDB_OSABI_UNKNOWN)
89 {
90 internal_error
91 (__FILE__, __LINE__,
92 "gdbarch_register_osabi: An attempt to register a handler for "
93 "OS ABI \"%s\" for architecture %s was made. The handler will "
94 "not be registered",
95 gdbarch_osabi_name (osabi),
96 bfd_printable_arch_mach (arch, 0));
97 return;
98 }
99
100 for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL;
101 handler_p = &(*handler_p)->next)
102 {
103 if ((*handler_p)->arch == arch
104 && (*handler_p)->osabi == osabi)
105 {
106 internal_error
107 (__FILE__, __LINE__,
108 "gdbarch_register_osabi: A handler for OS ABI \"%s\" "
109 "has already been registered for architecture %s",
110 gdbarch_osabi_name (osabi),
111 bfd_printable_arch_mach (arch, 0));
112 /* If user wants to continue, override previous definition. */
113 (*handler_p)->init_osabi = init_osabi;
114 return;
115 }
116 }
117
118 (*handler_p)
119 = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler));
120 (*handler_p)->next = NULL;
121 (*handler_p)->arch = arch;
122 (*handler_p)->osabi = osabi;
123 (*handler_p)->init_osabi = init_osabi;
124}
125\f
126
127/* Sniffer to find the OS ABI for a given file's architecture and flavour.
128 It is legal to have multiple sniffers for each arch/flavour pair, to
129 disambiguate one OS's a.out from another, for example. The first sniffer
130 to return something other than GDB_OSABI_UNKNOWN wins, so a sniffer should
131 be careful to claim a file only if it knows for sure what it is. */
132struct gdb_osabi_sniffer
133{
134 struct gdb_osabi_sniffer *next;
135 enum bfd_architecture arch; /* bfd_arch_unknown == wildcard */
136 enum bfd_flavour flavour;
137 enum gdb_osabi (*sniffer)(bfd *);
138};
139
140static struct gdb_osabi_sniffer *gdb_osabi_sniffer_list;
141
142void
143gdbarch_register_osabi_sniffer (enum bfd_architecture arch,
144 enum bfd_flavour flavour,
145 enum gdb_osabi (*sniffer_fn)(bfd *))
146{
147 struct gdb_osabi_sniffer *sniffer;
148
149 sniffer =
150 (struct gdb_osabi_sniffer *) xmalloc (sizeof (struct gdb_osabi_sniffer));
151 sniffer->arch = arch;
152 sniffer->flavour = flavour;
153 sniffer->sniffer = sniffer_fn;
154
155 sniffer->next = gdb_osabi_sniffer_list;
156 gdb_osabi_sniffer_list = sniffer;
157}
158\f
159
160enum gdb_osabi
161gdbarch_lookup_osabi (bfd *abfd)
162{
163 struct gdb_osabi_sniffer *sniffer;
164 enum gdb_osabi osabi, match;
165 int match_specific;
166
167 match = GDB_OSABI_UNKNOWN;
168 match_specific = 0;
169
170 for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL;
171 sniffer = sniffer->next)
172 {
173 if ((sniffer->arch == bfd_arch_unknown /* wildcard */
174 || sniffer->arch == bfd_get_arch (abfd))
175 && sniffer->flavour == bfd_get_flavour (abfd))
176 {
177 osabi = (*sniffer->sniffer) (abfd);
178 if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID)
179 {
180 internal_error
181 (__FILE__, __LINE__,
182 "gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer "
183 "for architecture %s flavour %d",
184 (int) osabi,
185 bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
186 (int) bfd_get_flavour (abfd));
187 }
188 else if (osabi != GDB_OSABI_UNKNOWN)
189 {
190 /* A specific sniffer always overrides a generic sniffer.
191 Croak on multiple match if the two matches are of the
192 same class. If the user wishes to continue, we'll use
193 the first match. */
194 if (match != GDB_OSABI_UNKNOWN)
195 {
196 if ((match_specific && sniffer->arch != bfd_arch_unknown)
197 || (!match_specific && sniffer->arch == bfd_arch_unknown))
198 {
199 internal_error
200 (__FILE__, __LINE__,
201 "gdbarch_lookup_osabi: multiple %sspecific OS ABI "
202 "match for architecture %s flavour %d: first "
203 "match \"%s\", second match \"%s\"",
204 match_specific ? "" : "non-",
205 bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
206 (int) bfd_get_flavour (abfd),
207 gdbarch_osabi_name (match),
208 gdbarch_osabi_name (osabi));
209 }
210 else if (sniffer->arch != bfd_arch_unknown)
211 {
212 match = osabi;
213 match_specific = 1;
214 }
215 }
216 else
217 {
218 match = osabi;
219 if (sniffer->arch != bfd_arch_unknown)
220 match_specific = 1;
221 }
222 }
223 }
224 }
225
226 return match;
227}
228
229void
230gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch,
231 enum gdb_osabi osabi)
232{
233 struct gdb_osabi_handler *handler;
234 bfd *abfd = info.abfd;
235 const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
236
237 if (osabi == GDB_OSABI_UNKNOWN)
238 {
01fc4e33
AC
239 /* Don't complain about an unknown OSABI. Assume the user knows
240 what they are doing. */
70f80edf
JT
241 return;
242 }
243
244 for (handler = gdb_osabi_handler_list; handler != NULL;
245 handler = handler->next)
246 {
247 if (handler->arch == bfd_get_arch (abfd)
248 && handler->osabi == osabi)
249 {
250 (*handler->init_osabi) (info, gdbarch);
251 return;
252 }
253 }
254
255 /* We assume that if GDB_MULTI_ARCH is less than GDB_MULTI_ARCH_TM
256 that an ABI variant can be supported by overriding definitions in
257 the tm-file. */
258 if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
259 fprintf_filtered
260 (gdb_stderr,
261 "A handler for the OS ABI \"%s\" is not built into this "
262 "configuration of GDB. "
263 "Attempting to continue with the default %s settings",
264 gdbarch_osabi_name (osabi),
265 bfd_printable_arch_mach (arch_info->arch, arch_info->mach));
266}
267\f
268
269/* Generic sniffer for ELF flavoured files. */
270
271void
272generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
273{
274 enum gdb_osabi *os_ident_ptr = obj;
275 const char *name;
276 unsigned int sectsize;
277
278 name = bfd_get_section_name (abfd, sect);
279 sectsize = bfd_section_size (abfd, sect);
280
281 /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD. */
282 if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
283 {
284 unsigned int name_length, data_length, note_type;
285 char *note;
286
287 /* If the section is larger than this, it's probably not what we are
288 looking for. */
289 if (sectsize > 128)
290 sectsize = 128;
291
292 note = alloca (sectsize);
293
294 bfd_get_section_contents (abfd, sect, note,
295 (file_ptr) 0, (bfd_size_type) sectsize);
296
297 name_length = bfd_h_get_32 (abfd, note);
298 data_length = bfd_h_get_32 (abfd, note + 4);
299 note_type = bfd_h_get_32 (abfd, note + 8);
300
301 if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG
302 && strcmp (note + 12, "GNU") == 0)
303 {
304 int os_number = bfd_h_get_32 (abfd, note + 16);
305
306 switch (os_number)
307 {
308 case GNU_ABI_TAG_LINUX:
309 *os_ident_ptr = GDB_OSABI_LINUX;
310 break;
311
312 case GNU_ABI_TAG_HURD:
313 *os_ident_ptr = GDB_OSABI_HURD;
314 break;
315
316 case GNU_ABI_TAG_SOLARIS:
317 *os_ident_ptr = GDB_OSABI_SOLARIS;
318 break;
319
320 default:
321 internal_error
322 (__FILE__, __LINE__,
323 "generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d",
324 os_number);
325 }
326 return;
327 }
328 else if (name_length == 8 && data_length == 4
329 && note_type == NT_FREEBSD_ABI_TAG
330 && strcmp (note + 12, "FreeBSD") == 0)
331 {
332 /* XXX Should we check the version here? Probably not
333 necessary yet. */
334 *os_ident_ptr = GDB_OSABI_FREEBSD_ELF;
335 }
336 return;
337 }
338
339 /* .note.netbsd.ident notes, used by NetBSD. */
340 if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
341 {
342 unsigned int name_length, data_length, note_type;
343 char *note;
344
345 /* If the section is larger than this, it's probably not what we are
346 looking for. */
347 if (sectsize > 128)
348 sectsize = 128;
349
350 note = alloca (sectsize);
351
352 bfd_get_section_contents (abfd, sect, note,
353 (file_ptr) 0, (bfd_size_type) sectsize);
354
355 name_length = bfd_h_get_32 (abfd, note);
356 data_length = bfd_h_get_32 (abfd, note + 4);
357 note_type = bfd_h_get_32 (abfd, note + 8);
358
359 if (name_length == 7 && data_length == 4 && note_type == NT_NETBSD_IDENT
360 && strcmp (note + 12, "NetBSD") == 0)
361 {
362 /* XXX Should we check the version here? Probably not
363 necessary yet. */
364 *os_ident_ptr = GDB_OSABI_NETBSD_ELF;
365 }
366 return;
367 }
368}
369
370static enum gdb_osabi
371generic_elf_osabi_sniffer (bfd *abfd)
372{
373 unsigned int elfosabi;
374 enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
375
376 elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
377
378 switch (elfosabi)
379 {
380 case ELFOSABI_NONE:
381 /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the
382 file are conforming to the base specification for that machine
383 (there are no OS-specific extensions). In order to determine the
384 real OS in use we must look for OS notes that have been added. */
385 bfd_map_over_sections (abfd,
386 generic_elf_osabi_sniff_abi_tag_sections,
387 &osabi);
388 break;
389
390 case ELFOSABI_FREEBSD:
391 osabi = GDB_OSABI_FREEBSD_ELF;
392 break;
393
394 case ELFOSABI_NETBSD:
395 osabi = GDB_OSABI_NETBSD_ELF;
396 break;
397
398 case ELFOSABI_LINUX:
399 osabi = GDB_OSABI_LINUX;
400 break;
401
402 case ELFOSABI_HURD:
403 osabi = GDB_OSABI_HURD;
404 break;
405
406 case ELFOSABI_SOLARIS:
407 osabi = GDB_OSABI_SOLARIS;
408 break;
a09a320d
JB
409
410 case ELFOSABI_HPUX:
411 osabi = GDB_OSABI_HPUX_ELF;
412 break;
70f80edf
JT
413 }
414
bb21884d
MK
415 if (osabi == GDB_OSABI_UNKNOWN)
416 {
417 /* The FreeBSD folks have been naughty; they stored the string
418 "FreeBSD" in the padding of the e_ident field of the ELF
419 header to "brand" their ELF binaries in FreeBSD 3.x. */
420 if (strcmp (&elf_elfheader (abfd)->e_ident[8], "FreeBSD") == 0)
421 osabi = GDB_OSABI_FREEBSD_ELF;
422 }
423
70f80edf
JT
424 return osabi;
425}
426\f
427
428void
429_initialize_gdb_osabi (void)
430{
431 if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID], "<invalid>") != 0)
432 internal_error
433 (__FILE__, __LINE__,
434 "_initialize_gdb_osabi: gdb_osabi_names[] is inconsistent");
435
436 /* Register a generic sniffer for ELF flavoured files. */
437 gdbarch_register_osabi_sniffer (bfd_arch_unknown,
438 bfd_target_elf_flavour,
439 generic_elf_osabi_sniffer);
440}
This page took 0.095607 seconds and 4 git commands to generate.