* osabi.c (gdb_osabi_name): Add entry for GDB_OSABI_INTERIX.
[platform/upstream/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 "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 }