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