* source.c (openp): Squelch warning about "filename".
[deliverable/binutils-gdb.git] / gdb / osabi.c
1 /* OS ABI variant handling for GDB.
2 Copyright 2001, 2002, 2003 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"
22
23 #include "gdb_assert.h"
24 #include "gdb_string.h"
25
26 #include "osabi.h"
27 #include "arch-utils.h"
28 #include "gdbcmd.h"
29 #include "command.h"
30
31 #include "elf-bfd.h"
32
33 #ifndef GDB_OSABI_DEFAULT
34 #define GDB_OSABI_DEFAULT GDB_OSABI_UNKNOWN
35 #endif
36
37 /* State for the "set osabi" command. */
38 static enum { osabi_auto, osabi_default, osabi_user } user_osabi_state;
39 static enum gdb_osabi user_selected_osabi;
40 static const char *gdb_osabi_available_names[GDB_OSABI_INVALID + 3] = {
41 "auto",
42 "default",
43 "none",
44 NULL
45 };
46 static const char *set_osabi_string;
47
48 /* This table matches the indices assigned to enum gdb_osabi. Keep
49 them in sync. */
50 static const char * const gdb_osabi_names[] =
51 {
52 "none",
53
54 "SVR4",
55 "GNU/Hurd",
56 "Solaris",
57 "OSF/1",
58 "GNU/Linux",
59 "FreeBSD a.out",
60 "FreeBSD ELF",
61 "NetBSD a.out",
62 "NetBSD ELF",
63 "Windows CE",
64 "DJGPP",
65 "NetWare",
66 "Irix",
67 "LynxOS",
68 "Interix",
69 "HP/UX ELF",
70 "HP/UX SOM",
71
72 "ARM EABI v1",
73 "ARM EABI v2",
74 "ARM APCS",
75
76 "<invalid>"
77 };
78
79 const char *
80 gdbarch_osabi_name (enum gdb_osabi osabi)
81 {
82 if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID)
83 return gdb_osabi_names[osabi];
84
85 return gdb_osabi_names[GDB_OSABI_INVALID];
86 }
87
88 /* Handler for a given architecture/OS ABI pair. There should be only
89 one handler for a given OS ABI each architecture family. */
90 struct gdb_osabi_handler
91 {
92 struct gdb_osabi_handler *next;
93 const struct bfd_arch_info *arch_info;
94 enum gdb_osabi osabi;
95 void (*init_osabi)(struct gdbarch_info, struct gdbarch *);
96 };
97
98 static struct gdb_osabi_handler *gdb_osabi_handler_list;
99
100 void
101 gdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine,
102 enum gdb_osabi osabi,
103 void (*init_osabi)(struct gdbarch_info,
104 struct gdbarch *))
105 {
106 struct gdb_osabi_handler **handler_p;
107 const struct bfd_arch_info *arch_info = bfd_lookup_arch (arch, machine);
108 const char **name_ptr;
109
110 /* Registering an OS ABI handler for "unknown" is not allowed. */
111 if (osabi == GDB_OSABI_UNKNOWN)
112 {
113 internal_error
114 (__FILE__, __LINE__,
115 "gdbarch_register_osabi: An attempt to register a handler for "
116 "OS ABI \"%s\" for architecture %s was made. The handler will "
117 "not be registered",
118 gdbarch_osabi_name (osabi),
119 bfd_printable_arch_mach (arch, machine));
120 return;
121 }
122
123 gdb_assert (arch_info);
124
125 for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL;
126 handler_p = &(*handler_p)->next)
127 {
128 if ((*handler_p)->arch_info == arch_info
129 && (*handler_p)->osabi == osabi)
130 {
131 internal_error
132 (__FILE__, __LINE__,
133 "gdbarch_register_osabi: A handler for OS ABI \"%s\" "
134 "has already been registered for architecture %s",
135 gdbarch_osabi_name (osabi),
136 arch_info->printable_name);
137 /* If user wants to continue, override previous definition. */
138 (*handler_p)->init_osabi = init_osabi;
139 return;
140 }
141 }
142
143 (*handler_p)
144 = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler));
145 (*handler_p)->next = NULL;
146 (*handler_p)->arch_info = arch_info;
147 (*handler_p)->osabi = osabi;
148 (*handler_p)->init_osabi = init_osabi;
149
150 /* Add this OS ABI to the list of enum values for "set osabi", if it isn't
151 already there. */
152 for (name_ptr = gdb_osabi_available_names; *name_ptr; name_ptr ++)
153 {
154 if (*name_ptr == gdbarch_osabi_name (osabi))
155 return;
156 }
157 *name_ptr++ = gdbarch_osabi_name (osabi);
158 *name_ptr = NULL;
159 }
160 \f
161
162 /* Sniffer to find the OS ABI for a given file's architecture and flavour.
163 It is legal to have multiple sniffers for each arch/flavour pair, to
164 disambiguate one OS's a.out from another, for example. The first sniffer
165 to return something other than GDB_OSABI_UNKNOWN wins, so a sniffer should
166 be careful to claim a file only if it knows for sure what it is. */
167 struct gdb_osabi_sniffer
168 {
169 struct gdb_osabi_sniffer *next;
170 enum bfd_architecture arch; /* bfd_arch_unknown == wildcard */
171 enum bfd_flavour flavour;
172 enum gdb_osabi (*sniffer)(bfd *);
173 };
174
175 static struct gdb_osabi_sniffer *gdb_osabi_sniffer_list;
176
177 void
178 gdbarch_register_osabi_sniffer (enum bfd_architecture arch,
179 enum bfd_flavour flavour,
180 enum gdb_osabi (*sniffer_fn)(bfd *))
181 {
182 struct gdb_osabi_sniffer *sniffer;
183
184 sniffer =
185 (struct gdb_osabi_sniffer *) xmalloc (sizeof (struct gdb_osabi_sniffer));
186 sniffer->arch = arch;
187 sniffer->flavour = flavour;
188 sniffer->sniffer = sniffer_fn;
189
190 sniffer->next = gdb_osabi_sniffer_list;
191 gdb_osabi_sniffer_list = sniffer;
192 }
193 \f
194
195 enum gdb_osabi
196 gdbarch_lookup_osabi (bfd *abfd)
197 {
198 struct gdb_osabi_sniffer *sniffer;
199 enum gdb_osabi osabi, match;
200 int match_specific;
201
202 /* If we aren't in "auto" mode, return the specified OS ABI. */
203 if (user_osabi_state == osabi_user)
204 return user_selected_osabi;
205
206 /* If we don't have a binary, return the default OS ABI (if set) or
207 an inconclusive result (otherwise). */
208 if (abfd == NULL)
209 {
210 if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN)
211 return GDB_OSABI_DEFAULT;
212 else
213 return GDB_OSABI_UNINITIALIZED;
214 }
215
216 match = GDB_OSABI_UNKNOWN;
217 match_specific = 0;
218
219 for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL;
220 sniffer = sniffer->next)
221 {
222 if ((sniffer->arch == bfd_arch_unknown /* wildcard */
223 || sniffer->arch == bfd_get_arch (abfd))
224 && sniffer->flavour == bfd_get_flavour (abfd))
225 {
226 osabi = (*sniffer->sniffer) (abfd);
227 if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID)
228 {
229 internal_error
230 (__FILE__, __LINE__,
231 "gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer "
232 "for architecture %s flavour %d",
233 (int) osabi,
234 bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
235 (int) bfd_get_flavour (abfd));
236 }
237 else if (osabi != GDB_OSABI_UNKNOWN)
238 {
239 /* A specific sniffer always overrides a generic sniffer.
240 Croak on multiple match if the two matches are of the
241 same class. If the user wishes to continue, we'll use
242 the first match. */
243 if (match != GDB_OSABI_UNKNOWN)
244 {
245 if ((match_specific && sniffer->arch != bfd_arch_unknown)
246 || (!match_specific && sniffer->arch == bfd_arch_unknown))
247 {
248 internal_error
249 (__FILE__, __LINE__,
250 "gdbarch_lookup_osabi: multiple %sspecific OS ABI "
251 "match for architecture %s flavour %d: first "
252 "match \"%s\", second match \"%s\"",
253 match_specific ? "" : "non-",
254 bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
255 (int) bfd_get_flavour (abfd),
256 gdbarch_osabi_name (match),
257 gdbarch_osabi_name (osabi));
258 }
259 else if (sniffer->arch != bfd_arch_unknown)
260 {
261 match = osabi;
262 match_specific = 1;
263 }
264 }
265 else
266 {
267 match = osabi;
268 if (sniffer->arch != bfd_arch_unknown)
269 match_specific = 1;
270 }
271 }
272 }
273 }
274
275 /* If we didn't find a match, but a default was specified at configure
276 time, return the default. */
277 if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN && match == GDB_OSABI_UNKNOWN)
278 return GDB_OSABI_DEFAULT;
279 else
280 return match;
281 }
282
283 void
284 gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
285 {
286 const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
287 const struct bfd_arch_info *compatible;
288 struct gdb_osabi_handler *handler;
289
290 if (info.osabi == GDB_OSABI_UNKNOWN)
291 {
292 /* Don't complain about an unknown OSABI. Assume the user knows
293 what they are doing. */
294 return;
295 }
296
297 for (handler = gdb_osabi_handler_list; handler != NULL;
298 handler = handler->next)
299 {
300 if (handler->osabi != info.osabi)
301 continue;
302
303 /* Check whether the machine type and architecture of the
304 handler are compatible with the desired machine type and
305 architecture.
306
307 NOTE: kettenis/20021027: There may be more than one machine
308 type that is compatible with the desired machine type. Right
309 now we simply return the first match, which is fine for now.
310 However, we might want to do something smarter in the future. */
311 compatible = arch_info->compatible (arch_info, handler->arch_info);
312 if (compatible == handler->arch_info)
313 {
314 (*handler->init_osabi) (info, gdbarch);
315 return;
316 }
317 }
318
319 /* We assume that if GDB_MULTI_ARCH is less than GDB_MULTI_ARCH_TM
320 that an ABI variant can be supported by overriding definitions in
321 the tm-file. */
322 if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
323 fprintf_filtered
324 (gdb_stderr,
325 "A handler for the OS ABI \"%s\" is not built into this "
326 "configuration of GDB. "
327 "Attempting to continue with the default %s settings",
328 gdbarch_osabi_name (info.osabi),
329 bfd_printable_arch_mach (arch_info->arch, arch_info->mach));
330 }
331 \f
332
333 /* Generic sniffer for ELF flavoured files. */
334
335 void
336 generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
337 {
338 enum gdb_osabi *os_ident_ptr = obj;
339 const char *name;
340 unsigned int sectsize;
341
342 name = bfd_get_section_name (abfd, sect);
343 sectsize = bfd_section_size (abfd, sect);
344
345 /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD. */
346 if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
347 {
348 unsigned int name_length, data_length, note_type;
349 char *note;
350
351 /* If the section is larger than this, it's probably not what we are
352 looking for. */
353 if (sectsize > 128)
354 sectsize = 128;
355
356 note = alloca (sectsize);
357
358 bfd_get_section_contents (abfd, sect, note,
359 (file_ptr) 0, (bfd_size_type) sectsize);
360
361 name_length = bfd_h_get_32 (abfd, note);
362 data_length = bfd_h_get_32 (abfd, note + 4);
363 note_type = bfd_h_get_32 (abfd, note + 8);
364
365 if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG
366 && strcmp (note + 12, "GNU") == 0)
367 {
368 int os_number = bfd_h_get_32 (abfd, note + 16);
369
370 switch (os_number)
371 {
372 case GNU_ABI_TAG_LINUX:
373 *os_ident_ptr = GDB_OSABI_LINUX;
374 break;
375
376 case GNU_ABI_TAG_HURD:
377 *os_ident_ptr = GDB_OSABI_HURD;
378 break;
379
380 case GNU_ABI_TAG_SOLARIS:
381 *os_ident_ptr = GDB_OSABI_SOLARIS;
382 break;
383
384 default:
385 internal_error
386 (__FILE__, __LINE__,
387 "generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d",
388 os_number);
389 }
390 return;
391 }
392 else if (name_length == 8 && data_length == 4
393 && note_type == NT_FREEBSD_ABI_TAG
394 && strcmp (note + 12, "FreeBSD") == 0)
395 {
396 /* XXX Should we check the version here? Probably not
397 necessary yet. */
398 *os_ident_ptr = GDB_OSABI_FREEBSD_ELF;
399 }
400 return;
401 }
402
403 /* .note.netbsd.ident notes, used by NetBSD. */
404 if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
405 {
406 unsigned int name_length, data_length, note_type;
407 char *note;
408
409 /* If the section is larger than this, it's probably not what we are
410 looking for. */
411 if (sectsize > 128)
412 sectsize = 128;
413
414 note = alloca (sectsize);
415
416 bfd_get_section_contents (abfd, sect, note,
417 (file_ptr) 0, (bfd_size_type) sectsize);
418
419 name_length = bfd_h_get_32 (abfd, note);
420 data_length = bfd_h_get_32 (abfd, note + 4);
421 note_type = bfd_h_get_32 (abfd, note + 8);
422
423 if (name_length == 7 && data_length == 4 && note_type == NT_NETBSD_IDENT
424 && strcmp (note + 12, "NetBSD") == 0)
425 {
426 /* XXX Should we check the version here? Probably not
427 necessary yet. */
428 *os_ident_ptr = GDB_OSABI_NETBSD_ELF;
429 }
430 return;
431 }
432 }
433
434 static enum gdb_osabi
435 generic_elf_osabi_sniffer (bfd *abfd)
436 {
437 unsigned int elfosabi;
438 enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
439
440 elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
441
442 switch (elfosabi)
443 {
444 case ELFOSABI_NONE:
445 /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the
446 file are conforming to the base specification for that machine
447 (there are no OS-specific extensions). In order to determine the
448 real OS in use we must look for OS notes that have been added. */
449 bfd_map_over_sections (abfd,
450 generic_elf_osabi_sniff_abi_tag_sections,
451 &osabi);
452 break;
453
454 case ELFOSABI_FREEBSD:
455 osabi = GDB_OSABI_FREEBSD_ELF;
456 break;
457
458 case ELFOSABI_NETBSD:
459 osabi = GDB_OSABI_NETBSD_ELF;
460 break;
461
462 case ELFOSABI_LINUX:
463 osabi = GDB_OSABI_LINUX;
464 break;
465
466 case ELFOSABI_HURD:
467 osabi = GDB_OSABI_HURD;
468 break;
469
470 case ELFOSABI_SOLARIS:
471 osabi = GDB_OSABI_SOLARIS;
472 break;
473
474 case ELFOSABI_HPUX:
475 osabi = GDB_OSABI_HPUX_ELF;
476 break;
477 }
478
479 if (osabi == GDB_OSABI_UNKNOWN)
480 {
481 /* The FreeBSD folks have been naughty; they stored the string
482 "FreeBSD" in the padding of the e_ident field of the ELF
483 header to "brand" their ELF binaries in FreeBSD 3.x. */
484 if (strcmp (&elf_elfheader (abfd)->e_ident[8], "FreeBSD") == 0)
485 osabi = GDB_OSABI_FREEBSD_ELF;
486 }
487
488 return osabi;
489 }
490 \f
491 static void
492 set_osabi (char *args, int from_tty, struct cmd_list_element *c)
493 {
494 struct gdbarch_info info;
495
496 if (strcmp (set_osabi_string, "auto") == 0)
497 user_osabi_state = osabi_auto;
498 else if (strcmp (set_osabi_string, "default") == 0)
499 {
500 user_selected_osabi = GDB_OSABI_DEFAULT;
501 user_osabi_state = osabi_user;
502 }
503 else if (strcmp (set_osabi_string, "none") == 0)
504 {
505 user_selected_osabi = GDB_OSABI_UNKNOWN;
506 user_osabi_state = osabi_user;
507 }
508 else
509 {
510 int i;
511 for (i = 1; i < GDB_OSABI_INVALID; i++)
512 if (strcmp (set_osabi_string, gdbarch_osabi_name (i)) == 0)
513 {
514 user_selected_osabi = i;
515 user_osabi_state = osabi_user;
516 break;
517 }
518 if (i == GDB_OSABI_INVALID)
519 internal_error (__FILE__, __LINE__,
520 "Invalid OS ABI \"%s\" passed to command handler.",
521 set_osabi_string);
522 }
523
524 /* NOTE: At some point (true multiple architectures) we'll need to be more
525 graceful here. */
526 gdbarch_info_init (&info);
527 if (! gdbarch_update_p (info))
528 internal_error (__FILE__, __LINE__, "Updating OS ABI failed.");
529 }
530
531 void
532 show_osabi (char *args, int from_tty)
533 {
534 if (user_osabi_state == osabi_auto)
535 printf_filtered ("The current OS ABI is \"auto\" (currently \"%s\").\n",
536 gdbarch_osabi_name (gdbarch_osabi (current_gdbarch)));
537 else
538 printf_filtered ("The current OS ABI is \"%s\".\n",
539 gdbarch_osabi_name (user_selected_osabi));
540
541 if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN)
542 printf_filtered ("The default OS ABI is \"%s\".\n",
543 gdbarch_osabi_name (GDB_OSABI_DEFAULT));
544 }
545 \f
546 void
547 _initialize_gdb_osabi (void)
548 {
549 struct cmd_list_element *c;
550
551 if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID], "<invalid>") != 0)
552 internal_error
553 (__FILE__, __LINE__,
554 "_initialize_gdb_osabi: gdb_osabi_names[] is inconsistent");
555
556 /* Register a generic sniffer for ELF flavoured files. */
557 gdbarch_register_osabi_sniffer (bfd_arch_unknown,
558 bfd_target_elf_flavour,
559 generic_elf_osabi_sniffer);
560
561 if (!GDB_MULTI_ARCH)
562 return;
563
564 /* Register the "set osabi" command. */
565 c = add_set_enum_cmd ("osabi", class_support, gdb_osabi_available_names,
566 &set_osabi_string, "Set OS ABI of target.", &setlist);
567
568 set_cmd_sfunc (c, set_osabi);
569 add_cmd ("osabi", class_support, show_osabi, "Show OS/ABI of target.",
570 &showlist);
571 user_osabi_state = osabi_auto;
572 }
This page took 0.039906 seconds and 4 git commands to generate.