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