1130803Smarcel/* OS ABI variant handling for GDB.
2130803Smarcel   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
3130803Smarcel
4130803Smarcel   This file is part of GDB.
5130803Smarcel
6130803Smarcel   This program is free software; you can redistribute it and/or modify
7130803Smarcel   it under the terms of the GNU General Public License as published by
8130803Smarcel   the Free Software Foundation; either version 2 of the License, or
9130803Smarcel   (at your option) any later version.
10130803Smarcel
11130803Smarcel   This program is distributed in the hope that it will be useful,
12130803Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
13130803Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14130803Smarcel   GNU General Public License for more details.
15130803Smarcel
16130803Smarcel   You should have received a copy of the GNU General Public License
17130803Smarcel   along with this program; if not, write to the Free Software
18130803Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
19130803Smarcel   Boston, MA 02111-1307, USA.  */
20130803Smarcel
21130803Smarcel#include "defs.h"
22130803Smarcel
23130803Smarcel#include "gdb_assert.h"
24130803Smarcel#include "gdb_string.h"
25130803Smarcel
26130803Smarcel#include "osabi.h"
27130803Smarcel#include "arch-utils.h"
28130803Smarcel#include "gdbcmd.h"
29130803Smarcel#include "command.h"
30130803Smarcel
31130803Smarcel#include "elf-bfd.h"
32130803Smarcel
33130803Smarcel#ifndef GDB_OSABI_DEFAULT
34130803Smarcel#define GDB_OSABI_DEFAULT GDB_OSABI_UNKNOWN
35130803Smarcel#endif
36130803Smarcel
37130803Smarcel/* State for the "set osabi" command.  */
38130803Smarcelstatic enum { osabi_auto, osabi_default, osabi_user } user_osabi_state;
39130803Smarcelstatic enum gdb_osabi user_selected_osabi;
40130803Smarcelstatic const char *gdb_osabi_available_names[GDB_OSABI_INVALID + 3] = {
41130803Smarcel  "auto",
42130803Smarcel  "default",
43130803Smarcel  "none",
44130803Smarcel  NULL
45130803Smarcel};
46130803Smarcelstatic const char *set_osabi_string;
47130803Smarcel
48130803Smarcel/* This table matches the indices assigned to enum gdb_osabi.  Keep
49130803Smarcel   them in sync.  */
50130803Smarcelstatic const char * const gdb_osabi_names[] =
51130803Smarcel{
52130803Smarcel  "none",
53130803Smarcel
54130803Smarcel  "SVR4",
55130803Smarcel  "GNU/Hurd",
56130803Smarcel  "Solaris",
57130803Smarcel  "OSF/1",
58130803Smarcel  "GNU/Linux",
59130803Smarcel  "FreeBSD a.out",
60130803Smarcel  "FreeBSD ELF",
61130803Smarcel  "NetBSD a.out",
62130803Smarcel  "NetBSD ELF",
63130803Smarcel  "OpenBSD ELF",
64130803Smarcel  "Windows CE",
65130803Smarcel  "DJGPP",
66130803Smarcel  "NetWare",
67130803Smarcel  "Irix",
68130803Smarcel  "LynxOS",
69130803Smarcel  "Interix",
70130803Smarcel  "HP/UX ELF",
71130803Smarcel  "HP/UX SOM",
72130803Smarcel
73130803Smarcel  "ARM EABI v1",
74130803Smarcel  "ARM EABI v2",
75130803Smarcel  "ARM APCS",
76130803Smarcel  "QNX Neutrino",
77130803Smarcel
78130803Smarcel  "Cygwin",
79130803Smarcel
80130803Smarcel  "<invalid>"
81130803Smarcel};
82130803Smarcel
83130803Smarcelconst char *
84130803Smarcelgdbarch_osabi_name (enum gdb_osabi osabi)
85130803Smarcel{
86130803Smarcel  if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID)
87130803Smarcel    return gdb_osabi_names[osabi];
88130803Smarcel
89130803Smarcel  return gdb_osabi_names[GDB_OSABI_INVALID];
90130803Smarcel}
91130803Smarcel
92130803Smarcel/* Handler for a given architecture/OS ABI pair.  There should be only
93130803Smarcel   one handler for a given OS ABI each architecture family.  */
94130803Smarcelstruct gdb_osabi_handler
95130803Smarcel{
96130803Smarcel  struct gdb_osabi_handler *next;
97130803Smarcel  const struct bfd_arch_info *arch_info;
98130803Smarcel  enum gdb_osabi osabi;
99130803Smarcel  void (*init_osabi)(struct gdbarch_info, struct gdbarch *);
100130803Smarcel};
101130803Smarcel
102130803Smarcelstatic struct gdb_osabi_handler *gdb_osabi_handler_list;
103130803Smarcel
104130803Smarcelvoid
105130803Smarcelgdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine,
106130803Smarcel			enum gdb_osabi osabi,
107130803Smarcel                        void (*init_osabi)(struct gdbarch_info,
108130803Smarcel					   struct gdbarch *))
109130803Smarcel{
110130803Smarcel  struct gdb_osabi_handler **handler_p;
111130803Smarcel  const struct bfd_arch_info *arch_info = bfd_lookup_arch (arch, machine);
112130803Smarcel  const char **name_ptr;
113130803Smarcel
114130803Smarcel  /* Registering an OS ABI handler for "unknown" is not allowed.  */
115130803Smarcel  if (osabi == GDB_OSABI_UNKNOWN)
116130803Smarcel    {
117130803Smarcel      internal_error
118130803Smarcel	(__FILE__, __LINE__,
119130803Smarcel	 "gdbarch_register_osabi: An attempt to register a handler for "
120130803Smarcel         "OS ABI \"%s\" for architecture %s was made.  The handler will "
121130803Smarcel	 "not be registered",
122130803Smarcel	 gdbarch_osabi_name (osabi),
123130803Smarcel	 bfd_printable_arch_mach (arch, machine));
124130803Smarcel      return;
125130803Smarcel    }
126130803Smarcel
127130803Smarcel  gdb_assert (arch_info);
128130803Smarcel
129130803Smarcel  for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL;
130130803Smarcel       handler_p = &(*handler_p)->next)
131130803Smarcel    {
132130803Smarcel      if ((*handler_p)->arch_info == arch_info
133130803Smarcel	  && (*handler_p)->osabi == osabi)
134130803Smarcel	{
135130803Smarcel	  internal_error
136130803Smarcel	    (__FILE__, __LINE__,
137130803Smarcel	     "gdbarch_register_osabi: A handler for OS ABI \"%s\" "
138130803Smarcel	     "has already been registered for architecture %s",
139130803Smarcel	     gdbarch_osabi_name (osabi),
140130803Smarcel	     arch_info->printable_name);
141130803Smarcel	  /* If user wants to continue, override previous definition.  */
142130803Smarcel	  (*handler_p)->init_osabi = init_osabi;
143130803Smarcel	  return;
144130803Smarcel	}
145130803Smarcel    }
146130803Smarcel
147130803Smarcel  (*handler_p)
148130803Smarcel    = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler));
149130803Smarcel  (*handler_p)->next = NULL;
150130803Smarcel  (*handler_p)->arch_info = arch_info;
151130803Smarcel  (*handler_p)->osabi = osabi;
152130803Smarcel  (*handler_p)->init_osabi = init_osabi;
153130803Smarcel
154130803Smarcel  /* Add this OS ABI to the list of enum values for "set osabi", if it isn't
155130803Smarcel     already there.  */
156130803Smarcel  for (name_ptr = gdb_osabi_available_names; *name_ptr; name_ptr ++)
157130803Smarcel    {
158130803Smarcel      if (*name_ptr == gdbarch_osabi_name (osabi))
159130803Smarcel	return;
160130803Smarcel    }
161130803Smarcel  *name_ptr++ = gdbarch_osabi_name (osabi);
162130803Smarcel  *name_ptr = NULL;
163130803Smarcel}
164130803Smarcel
165130803Smarcel
166130803Smarcel/* Sniffer to find the OS ABI for a given file's architecture and flavour.
167130803Smarcel   It is legal to have multiple sniffers for each arch/flavour pair, to
168130803Smarcel   disambiguate one OS's a.out from another, for example.  The first sniffer
169130803Smarcel   to return something other than GDB_OSABI_UNKNOWN wins, so a sniffer should
170130803Smarcel   be careful to claim a file only if it knows for sure what it is.  */
171130803Smarcelstruct gdb_osabi_sniffer
172130803Smarcel{
173130803Smarcel  struct gdb_osabi_sniffer *next;
174130803Smarcel  enum bfd_architecture arch;   /* bfd_arch_unknown == wildcard */
175130803Smarcel  enum bfd_flavour flavour;
176130803Smarcel  enum gdb_osabi (*sniffer)(bfd *);
177130803Smarcel};
178130803Smarcel
179130803Smarcelstatic struct gdb_osabi_sniffer *gdb_osabi_sniffer_list;
180130803Smarcel
181130803Smarcelvoid
182130803Smarcelgdbarch_register_osabi_sniffer (enum bfd_architecture arch,
183130803Smarcel                                enum bfd_flavour flavour,
184130803Smarcel				enum gdb_osabi (*sniffer_fn)(bfd *))
185130803Smarcel{
186130803Smarcel  struct gdb_osabi_sniffer *sniffer;
187130803Smarcel
188130803Smarcel  sniffer =
189130803Smarcel    (struct gdb_osabi_sniffer *) xmalloc (sizeof (struct gdb_osabi_sniffer));
190130803Smarcel  sniffer->arch = arch;
191130803Smarcel  sniffer->flavour = flavour;
192130803Smarcel  sniffer->sniffer = sniffer_fn;
193130803Smarcel
194130803Smarcel  sniffer->next = gdb_osabi_sniffer_list;
195130803Smarcel  gdb_osabi_sniffer_list = sniffer;
196130803Smarcel}
197130803Smarcel
198130803Smarcel
199130803Smarcelenum gdb_osabi
200130803Smarcelgdbarch_lookup_osabi (bfd *abfd)
201130803Smarcel{
202130803Smarcel  struct gdb_osabi_sniffer *sniffer;
203130803Smarcel  enum gdb_osabi osabi, match;
204130803Smarcel  int match_specific;
205130803Smarcel
206130803Smarcel  /* If we aren't in "auto" mode, return the specified OS ABI.  */
207130803Smarcel  if (user_osabi_state == osabi_user)
208130803Smarcel    return user_selected_osabi;
209130803Smarcel
210130803Smarcel  /* If we don't have a binary, return the default OS ABI (if set) or
211130803Smarcel     an inconclusive result (otherwise).  */
212130803Smarcel  if (abfd == NULL)
213130803Smarcel    {
214130803Smarcel      if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN)
215130803Smarcel	return GDB_OSABI_DEFAULT;
216130803Smarcel      else
217130803Smarcel	return GDB_OSABI_UNINITIALIZED;
218130803Smarcel    }
219130803Smarcel
220130803Smarcel  match = GDB_OSABI_UNKNOWN;
221130803Smarcel  match_specific = 0;
222130803Smarcel
223130803Smarcel  for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL;
224130803Smarcel       sniffer = sniffer->next)
225130803Smarcel    {
226130803Smarcel      if ((sniffer->arch == bfd_arch_unknown /* wildcard */
227130803Smarcel	   || sniffer->arch == bfd_get_arch (abfd))
228130803Smarcel	  && sniffer->flavour == bfd_get_flavour (abfd))
229130803Smarcel	{
230130803Smarcel	  osabi = (*sniffer->sniffer) (abfd);
231130803Smarcel	  if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID)
232130803Smarcel	    {
233130803Smarcel	      internal_error
234130803Smarcel		(__FILE__, __LINE__,
235130803Smarcel		 "gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer "
236130803Smarcel		 "for architecture %s flavour %d",
237130803Smarcel		 (int) osabi,
238130803Smarcel		 bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
239130803Smarcel		 (int) bfd_get_flavour (abfd));
240130803Smarcel	    }
241130803Smarcel	  else if (osabi != GDB_OSABI_UNKNOWN)
242130803Smarcel	    {
243130803Smarcel	      /* A specific sniffer always overrides a generic sniffer.
244130803Smarcel		 Croak on multiple match if the two matches are of the
245130803Smarcel		 same class.  If the user wishes to continue, we'll use
246130803Smarcel		 the first match.  */
247130803Smarcel	      if (match != GDB_OSABI_UNKNOWN)
248130803Smarcel		{
249130803Smarcel		  if ((match_specific && sniffer->arch != bfd_arch_unknown)
250130803Smarcel		   || (!match_specific && sniffer->arch == bfd_arch_unknown))
251130803Smarcel		    {
252130803Smarcel		      internal_error
253130803Smarcel		        (__FILE__, __LINE__,
254130803Smarcel		         "gdbarch_lookup_osabi: multiple %sspecific OS ABI "
255130803Smarcel			 "match for architecture %s flavour %d: first "
256130803Smarcel			 "match \"%s\", second match \"%s\"",
257130803Smarcel			 match_specific ? "" : "non-",
258130803Smarcel		         bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
259130803Smarcel		         (int) bfd_get_flavour (abfd),
260130803Smarcel		         gdbarch_osabi_name (match),
261130803Smarcel		         gdbarch_osabi_name (osabi));
262130803Smarcel		    }
263130803Smarcel		  else if (sniffer->arch != bfd_arch_unknown)
264130803Smarcel		    {
265130803Smarcel		      match = osabi;
266130803Smarcel		      match_specific = 1;
267130803Smarcel		    }
268130803Smarcel		}
269130803Smarcel	      else
270130803Smarcel		{
271130803Smarcel		  match = osabi;
272130803Smarcel		  if (sniffer->arch != bfd_arch_unknown)
273130803Smarcel		    match_specific = 1;
274130803Smarcel		}
275130803Smarcel	    }
276130803Smarcel	}
277130803Smarcel    }
278130803Smarcel
279130803Smarcel  /* If we didn't find a match, but a default was specified at configure
280130803Smarcel     time, return the default.  */
281130803Smarcel  if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN && match == GDB_OSABI_UNKNOWN)
282130803Smarcel    return GDB_OSABI_DEFAULT;
283130803Smarcel  else
284130803Smarcel    return match;
285130803Smarcel}
286130803Smarcel
287130803Smarcel
288130803Smarcel/* Return non-zero if architecture A can run code written for
289130803Smarcel   architecture B.  */
290130803Smarcelstatic int
291130803Smarcelcan_run_code_for (const struct bfd_arch_info *a, const struct bfd_arch_info *b)
292130803Smarcel{
293130803Smarcel  /* BFD's 'A->compatible (A, B)' functions return zero if A and B are
294130803Smarcel     incompatible.  But if they are compatible, it returns the 'more
295130803Smarcel     featureful' of the two arches.  That is, if A can run code
296130803Smarcel     written for B, but B can't run code written for A, then it'll
297130803Smarcel     return A.
298130803Smarcel
299130803Smarcel     struct bfd_arch_info objects are singletons: that is, there's
300130803Smarcel     supposed to be exactly one instance for a given machine.  So you
301130803Smarcel     can tell whether two are equivalent by comparing pointers.  */
302130803Smarcel  return (a == b || a->compatible (a, b) == a);
303130803Smarcel}
304130803Smarcel
305130803Smarcel
306130803Smarcelvoid
307130803Smarcelgdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
308130803Smarcel{
309130803Smarcel  struct gdb_osabi_handler *handler;
310130803Smarcel
311130803Smarcel  if (info.osabi == GDB_OSABI_UNKNOWN)
312130803Smarcel    {
313130803Smarcel      /* Don't complain about an unknown OSABI.  Assume the user knows
314130803Smarcel         what they are doing.  */
315130803Smarcel      return;
316130803Smarcel    }
317130803Smarcel
318130803Smarcel  for (handler = gdb_osabi_handler_list; handler != NULL;
319130803Smarcel       handler = handler->next)
320130803Smarcel    {
321130803Smarcel      if (handler->osabi != info.osabi)
322130803Smarcel	continue;
323130803Smarcel
324130803Smarcel      /* If the architecture described by ARCH_INFO can run code for
325130803Smarcel         the architcture we registered the handler for, then the
326130803Smarcel         handler is applicable.  Note, though, that if the handler is
327130803Smarcel         for an architecture that is a superset of ARCH_INFO, we can't
328130803Smarcel         use that --- it would be perfectly correct for it to install
329130803Smarcel         gdbarch methods that refer to registers / instructions /
330130803Smarcel         other facilities ARCH_INFO doesn't have.
331130803Smarcel
332130803Smarcel         NOTE: kettenis/20021027: There may be more than one machine
333130803Smarcel	 type that is compatible with the desired machine type.  Right
334130803Smarcel	 now we simply return the first match, which is fine for now.
335130803Smarcel	 However, we might want to do something smarter in the future.  */
336130803Smarcel      /* NOTE: cagney/2003-10-23: The code for "a can_run_code_for b"
337130803Smarcel         is implemented using BFD's compatible method (a->compatible
338130803Smarcel         (b) == a -- the lowest common denominator between a and b is
339130803Smarcel         a).  That method's definition of compatible may not be as you
340130803Smarcel         expect.  For instance the test "amd64 can run code for i386"
341130803Smarcel         (or more generally "64-bit ISA can run code for the 32-bit
342130803Smarcel         ISA").  BFD doesn't normally consider 32-bit and 64-bit
343130803Smarcel         "compatible" so it doesn't succeed.  */
344130803Smarcel      if (can_run_code_for (info.bfd_arch_info, handler->arch_info))
345130803Smarcel	{
346130803Smarcel	  (*handler->init_osabi) (info, gdbarch);
347130803Smarcel	  return;
348130803Smarcel	}
349130803Smarcel    }
350130803Smarcel
351130803Smarcel  warning
352130803Smarcel    ("A handler for the OS ABI \"%s\" is not built into this configuration\n"
353130803Smarcel     "of GDB.  Attempting to continue with the default %s settings.\n",
354130803Smarcel     gdbarch_osabi_name (info.osabi),
355130803Smarcel     info.bfd_arch_info->printable_name);
356130803Smarcel}
357130803Smarcel
358130803Smarcel/* Limit on the amount of data to be read.  */
359130803Smarcel#define MAX_NOTESZ	128
360130803Smarcel
361130803Smarcel/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE.  */
362130803Smarcel
363130803Smarcelstatic int
364130803Smarcelcheck_note (bfd *abfd, asection *sect, const char *note,
365130803Smarcel	    const char *name, unsigned long descsz, unsigned long type)
366130803Smarcel{
367130803Smarcel  unsigned long notesz;
368261787Sjmg  unsigned long rdescsz;
369130803Smarcel
370130803Smarcel  /* Calculate the size of this note.  */
371261787Sjmg  notesz = 4 * 3;	/* namelen, optlen, type */
372261787Sjmg  notesz += strlen (name) + 1;
373130803Smarcel  notesz = ((notesz + 3) & ~3);
374130803Smarcel
375130803Smarcel  /* If this assertion triggers, increase MAX_NOTESZ.  */
376130803Smarcel  gdb_assert (notesz <= MAX_NOTESZ);
377130803Smarcel
378130803Smarcel  /* Check whether SECT is big enough to comtain the complete note.  */
379130803Smarcel  if (notesz > bfd_section_size (abfd, sect))
380130803Smarcel    return 0;
381130803Smarcel
382130803Smarcel  /* Check the note name.  */
383130803Smarcel  if (bfd_h_get_32 (abfd, note) != (strlen (name) + 1)
384130803Smarcel      || strcmp (note + 12, name) != 0)
385130803Smarcel    return 0;
386130803Smarcel
387130803Smarcel  /* Check the descriptor size.  */
388261787Sjmg  rdescsz = bfd_h_get_32 (abfd, note + 4);
389261787Sjmg  if (descsz != (unsigned long)-1 && rdescsz != descsz)
390130803Smarcel    return 0;
391130803Smarcel
392261787Sjmg  notesz += rdescsz;
393261787Sjmg  notesz = ((notesz + 3) & ~3);
394261787Sjmg
395261787Sjmg  /* Check whether SECT is big enough to comtain the complete note.  */
396261787Sjmg  if (notesz > bfd_section_size (abfd, sect))
397261787Sjmg    return 0;
398261787Sjmg
399130803Smarcel  /* Check the note type.  */
400130803Smarcel  if (bfd_h_get_32 (abfd, note + 8) != type)
401130803Smarcel    return 0;
402130803Smarcel
403130803Smarcel  return 1;
404130803Smarcel}
405130803Smarcel
406130803Smarcel/* Generic sniffer for ELF flavoured files.  */
407130803Smarcel
408130803Smarcelvoid
409130803Smarcelgeneric_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
410130803Smarcel{
411130803Smarcel  enum gdb_osabi *osabi = obj;
412130803Smarcel  const char *name;
413130803Smarcel  unsigned int sectsize;
414130803Smarcel  char *note;
415130803Smarcel
416130803Smarcel  name = bfd_get_section_name (abfd, sect);
417130803Smarcel  sectsize = bfd_section_size (abfd, sect);
418130803Smarcel
419130803Smarcel  /* Limit the amount of data to read.  */
420130803Smarcel  if (sectsize > MAX_NOTESZ)
421130803Smarcel    sectsize = MAX_NOTESZ;
422130803Smarcel
423130803Smarcel  note = alloca (sectsize);
424130803Smarcel  bfd_get_section_contents (abfd, sect, note, 0, sectsize);
425130803Smarcel
426130803Smarcel  /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD.  */
427130803Smarcel  if (strcmp (name, ".note.ABI-tag") == 0)
428130803Smarcel    {
429130803Smarcel      /* GNU.  */
430130803Smarcel      if (check_note (abfd, sect, note, "GNU", 16, NT_GNU_ABI_TAG))
431130803Smarcel	{
432130803Smarcel	  unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16);
433130803Smarcel
434130803Smarcel	  switch (abi_tag)
435130803Smarcel	    {
436130803Smarcel	    case GNU_ABI_TAG_LINUX:
437130803Smarcel	      *osabi = GDB_OSABI_LINUX;
438130803Smarcel	      break;
439130803Smarcel
440130803Smarcel	    case GNU_ABI_TAG_HURD:
441130803Smarcel	      *osabi = GDB_OSABI_HURD;
442130803Smarcel	      break;
443130803Smarcel
444130803Smarcel	    case GNU_ABI_TAG_SOLARIS:
445130803Smarcel	      *osabi = GDB_OSABI_SOLARIS;
446130803Smarcel	      break;
447130803Smarcel
448130803Smarcel	    case GNU_ABI_TAG_FREEBSD:
449130803Smarcel	      *osabi = GDB_OSABI_FREEBSD_ELF;
450130803Smarcel	      break;
451130803Smarcel
452130803Smarcel	    case GNU_ABI_TAG_NETBSD:
453130803Smarcel	      *osabi = GDB_OSABI_NETBSD_ELF;
454130803Smarcel	      break;
455130803Smarcel
456130803Smarcel	    default:
457130803Smarcel	      internal_error (__FILE__, __LINE__, "\
458130803Smarcelgeneric_elf_osabi_sniff_abi_tag_sections: unknown OS number %d",
459130803Smarcel			      abi_tag);
460130803Smarcel	    }
461130803Smarcel	  return;
462130803Smarcel	}
463130803Smarcel
464130803Smarcel      /* FreeBSD.  */
465130803Smarcel      if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_ABI_TAG))
466130803Smarcel	{
467130803Smarcel	  /* There is no need to check the version yet.  */
468130803Smarcel	  *osabi = GDB_OSABI_FREEBSD_ELF;
469130803Smarcel	  return;
470130803Smarcel	}
471130803Smarcel
472130803Smarcel      return;
473130803Smarcel    }
474246312Sandrew
475246312Sandrew  /* .note.tag notes, used by FreeBSD.  */
476246312Sandrew  if (strcmp (name, ".note.tag") == 0)
477246312Sandrew   {
478246312Sandrew      /* FreeBSD.  */
479246312Sandrew      if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_TAG))
480246312Sandrew	{
481246312Sandrew	  /* There is no need to check the version yet.  */
482246312Sandrew	  *osabi = GDB_OSABI_FREEBSD_ELF;
483246312Sandrew	  return;
484246312Sandrew	}
485249603Sandrew      if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_NOINIT_TAG))
486249603Sandrew	{
487249603Sandrew	  /* There is no need to check the version yet.  */
488249603Sandrew	  *osabi = GDB_OSABI_FREEBSD_ELF;
489249603Sandrew	  return;
490249603Sandrew	}
491261787Sjmg      if (check_note (abfd, sect, note, "FreeBSD", -1, NT_FREEBSD_ARCH_TAG))
492261787Sjmg	{
493261787Sjmg	  /* There is no need to check the version yet.  */
494261787Sjmg	  *osabi = GDB_OSABI_FREEBSD_ELF;
495261787Sjmg	  return;
496261787Sjmg	}
497246312Sandrew
498246312Sandrew      return;
499246312Sandrew    }
500130803Smarcel
501130803Smarcel  /* .note.netbsd.ident notes, used by NetBSD.  */
502130803Smarcel  if (strcmp (name, ".note.netbsd.ident") == 0
503130803Smarcel      && check_note (abfd, sect, note, "NetBSD", 4, NT_NETBSD_IDENT))
504130803Smarcel    {
505130803Smarcel      /* There is no need to check the version yet.  */
506130803Smarcel      *osabi = GDB_OSABI_NETBSD_ELF;
507130803Smarcel      return;
508130803Smarcel    }
509130803Smarcel
510130803Smarcel  /* .note.openbsd.ident notes, used by OpenBSD.  */
511130803Smarcel  if (strcmp (name, ".note.openbsd.ident") == 0
512130803Smarcel      && check_note (abfd, sect, note, "OpenBSD", 4, NT_OPENBSD_IDENT))
513130803Smarcel    {
514130803Smarcel      /* There is no need to check the version yet.  */
515130803Smarcel      *osabi = GDB_OSABI_OPENBSD_ELF;
516130803Smarcel      return;
517130803Smarcel    }
518130803Smarcel
519130803Smarcel  /* .note.netbsdcore.procinfo notes, used by NetBSD.  */
520130803Smarcel  if (strcmp (name, ".note.netbsdcore.procinfo") == 0)
521130803Smarcel    {
522130803Smarcel      *osabi = GDB_OSABI_NETBSD_ELF;
523130803Smarcel      return;
524130803Smarcel    }
525130803Smarcel}
526130803Smarcel
527130803Smarcelstatic enum gdb_osabi
528130803Smarcelgeneric_elf_osabi_sniffer (bfd *abfd)
529130803Smarcel{
530130803Smarcel  unsigned int elfosabi;
531130803Smarcel  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
532130803Smarcel
533130803Smarcel  elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
534130803Smarcel
535130803Smarcel  switch (elfosabi)
536130803Smarcel    {
537130803Smarcel    case ELFOSABI_NONE:
538130803Smarcel      /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the
539130803Smarcel         file are conforming to the base specification for that machine
540130803Smarcel	 (there are no OS-specific extensions).  In order to determine the
541130803Smarcel	 real OS in use we must look for OS notes that have been added.  */
542130803Smarcel      bfd_map_over_sections (abfd,
543130803Smarcel			     generic_elf_osabi_sniff_abi_tag_sections,
544130803Smarcel			     &osabi);
545130803Smarcel      break;
546130803Smarcel
547130803Smarcel    case ELFOSABI_FREEBSD:
548130803Smarcel      osabi = GDB_OSABI_FREEBSD_ELF;
549130803Smarcel      break;
550130803Smarcel
551130803Smarcel    case ELFOSABI_NETBSD:
552130803Smarcel      osabi = GDB_OSABI_NETBSD_ELF;
553130803Smarcel      break;
554130803Smarcel
555130803Smarcel    case ELFOSABI_LINUX:
556130803Smarcel      osabi = GDB_OSABI_LINUX;
557130803Smarcel      break;
558130803Smarcel
559130803Smarcel    case ELFOSABI_HURD:
560130803Smarcel      osabi = GDB_OSABI_HURD;
561130803Smarcel      break;
562130803Smarcel
563130803Smarcel    case ELFOSABI_SOLARIS:
564130803Smarcel      osabi = GDB_OSABI_SOLARIS;
565130803Smarcel      break;
566130803Smarcel
567130803Smarcel    case ELFOSABI_HPUX:
568130803Smarcel      osabi = GDB_OSABI_HPUX_ELF;
569130803Smarcel      break;
570130803Smarcel    }
571130803Smarcel
572130803Smarcel  if (osabi == GDB_OSABI_UNKNOWN)
573130803Smarcel    {
574130803Smarcel      /* The FreeBSD folks have been naughty; they stored the string
575130803Smarcel         "FreeBSD" in the padding of the e_ident field of the ELF
576130803Smarcel         header to "brand" their ELF binaries in FreeBSD 3.x.  */
577130803Smarcel      if (strcmp (&elf_elfheader (abfd)->e_ident[8], "FreeBSD") == 0)
578130803Smarcel	osabi = GDB_OSABI_FREEBSD_ELF;
579130803Smarcel    }
580130803Smarcel
581130803Smarcel  return osabi;
582130803Smarcel}
583130803Smarcel
584130803Smarcelstatic void
585130803Smarcelset_osabi (char *args, int from_tty, struct cmd_list_element *c)
586130803Smarcel{
587130803Smarcel  struct gdbarch_info info;
588130803Smarcel
589130803Smarcel  if (strcmp (set_osabi_string, "auto") == 0)
590130803Smarcel    user_osabi_state = osabi_auto;
591130803Smarcel  else if (strcmp (set_osabi_string, "default") == 0)
592130803Smarcel    {
593130803Smarcel      user_selected_osabi = GDB_OSABI_DEFAULT;
594130803Smarcel      user_osabi_state = osabi_user;
595130803Smarcel    }
596130803Smarcel  else if (strcmp (set_osabi_string, "none") == 0)
597130803Smarcel    {
598130803Smarcel      user_selected_osabi = GDB_OSABI_UNKNOWN;
599130803Smarcel      user_osabi_state = osabi_user;
600130803Smarcel    }
601130803Smarcel  else
602130803Smarcel    {
603130803Smarcel      int i;
604130803Smarcel      for (i = 1; i < GDB_OSABI_INVALID; i++)
605130803Smarcel	if (strcmp (set_osabi_string, gdbarch_osabi_name (i)) == 0)
606130803Smarcel	  {
607130803Smarcel	    user_selected_osabi = i;
608130803Smarcel	    user_osabi_state = osabi_user;
609130803Smarcel	    break;
610130803Smarcel	  }
611130803Smarcel      if (i == GDB_OSABI_INVALID)
612130803Smarcel	internal_error (__FILE__, __LINE__,
613130803Smarcel			"Invalid OS ABI \"%s\" passed to command handler.",
614130803Smarcel			set_osabi_string);
615130803Smarcel    }
616130803Smarcel
617130803Smarcel  /* NOTE: At some point (true multiple architectures) we'll need to be more
618130803Smarcel     graceful here.  */
619130803Smarcel  gdbarch_info_init (&info);
620130803Smarcel  if (! gdbarch_update_p (info))
621130803Smarcel    internal_error (__FILE__, __LINE__, "Updating OS ABI failed.");
622130803Smarcel}
623130803Smarcel
624130803Smarcelstatic void
625130803Smarcelshow_osabi (char *args, int from_tty)
626130803Smarcel{
627130803Smarcel  if (user_osabi_state == osabi_auto)
628130803Smarcel    printf_filtered ("The current OS ABI is \"auto\" (currently \"%s\").\n",
629130803Smarcel		     gdbarch_osabi_name (gdbarch_osabi (current_gdbarch)));
630130803Smarcel  else
631130803Smarcel    printf_filtered ("The current OS ABI is \"%s\".\n",
632130803Smarcel		     gdbarch_osabi_name (user_selected_osabi));
633130803Smarcel
634130803Smarcel  if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN)
635130803Smarcel    printf_filtered ("The default OS ABI is \"%s\".\n",
636130803Smarcel		     gdbarch_osabi_name (GDB_OSABI_DEFAULT));
637130803Smarcel}
638130803Smarcel
639130803Smarcelextern initialize_file_ftype _initialize_gdb_osabi; /* -Wmissing-prototype */
640130803Smarcel
641130803Smarcelvoid
642130803Smarcel_initialize_gdb_osabi (void)
643130803Smarcel{
644130803Smarcel  struct cmd_list_element *c;
645130803Smarcel
646130803Smarcel  if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID], "<invalid>") != 0)
647130803Smarcel    internal_error
648130803Smarcel      (__FILE__, __LINE__,
649130803Smarcel       "_initialize_gdb_osabi: gdb_osabi_names[] is inconsistent");
650130803Smarcel
651130803Smarcel  /* Register a generic sniffer for ELF flavoured files.  */
652130803Smarcel  gdbarch_register_osabi_sniffer (bfd_arch_unknown,
653130803Smarcel				  bfd_target_elf_flavour,
654130803Smarcel				  generic_elf_osabi_sniffer);
655130803Smarcel
656130803Smarcel  /* Register the "set osabi" command.  */
657130803Smarcel  c = add_set_enum_cmd ("osabi", class_support, gdb_osabi_available_names,
658130803Smarcel			&set_osabi_string, "Set OS ABI of target.", &setlist);
659130803Smarcel
660130803Smarcel  set_cmd_sfunc (c, set_osabi);
661130803Smarcel  add_cmd ("osabi", class_support, show_osabi, "Show OS/ABI of target.",
662130803Smarcel	   &showlist);
663130803Smarcel  user_osabi_state = osabi_auto;
664130803Smarcel}
665