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