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