From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16815 invoked by alias); 16 May 2002 21:57:43 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 16667 invoked from network); 16 May 2002 21:57:38 -0000 Received: from unknown (HELO cygnus.com) (205.180.83.203) by sources.redhat.com with SMTP; 16 May 2002 21:57:38 -0000 Received: from localhost.redhat.com (romulus.sfbay.redhat.com [172.16.27.251]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id OAA00227 for ; Thu, 16 May 2002 14:57:34 -0700 (PDT) Received: by localhost.redhat.com (Postfix, from userid 469) id E0EC510FC9; Thu, 16 May 2002 17:57:01 -0400 (EDT) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15588.11053.545829.689213@localhost.redhat.com> Date: Thu, 16 May 2002 14:57:00 -0000 To: thorpej@wasabisystems.com Cc: gdb-patches@sources.redhat.com Subject: Re: [PATCH/RFA] Generic OS ABI handling In-Reply-To: <20020513120839.X3435@dr-evil.shagadelic.org> References: <20020513120839.X3435@dr-evil.shagadelic.org> X-SW-Source: 2002-05/txt/msg00669.txt.bz2 Jason R Thorpe writes: > Ok, I think it's reached the point where I'd like to ask for formal > approval. I completely missed the fact that the sh-tdep.c changes were included here, sorry. The sh* part is approved. A question, should be osabi.h be included in defs.h? I see that in one file you add both include osabi.h and defs.h. Another question, have you thought about whether this new generic mechanism applies to the rs6000-tdep.c file as well? If so, I can make the required changes. Elena > > Included in this patch are some additional internal consistency checking > points, and documentation updates. I also moved the inclusion of osabi.h > into defs.h, since this stuff is somewhat tightly coupled to the whole > gdbarch framework. > > * Makefile.in (SFILES): Add osabi.c. > (defs_h): Add osabi.h. > (COMMON_OBS): Add osabi.o. > (osabi.o): New dependency list. > * defs.h: Include osabi.h. > * osabi.c: New file. > * osabi.h: New file. > * doc/gdbint.texinfo: Document new generic OS ABI framework. > > * alpha-tdep.c (alpha_abi_names, process_note_abi_tag_sections, > get_elfosabi, alpha_abi_handler_list, alpha_gdbarch_register_os_abi): > Remove. > (alpha_gdbarch_init, alpha_dump_tdep): Use generic OS ABI framework. > * alpha-tdep.h (alpha_abi): Remove. > (gdbarch_tdep): Use generic OS ABI framework. > * alpha-linux-tdep.c (_initialize_alpha_linux_tdep): Use > gdbarch_register_osabi. > * alpha-osf1-tdep.c (_initialize_alpha_osf1_tdep): Likewise. > * alphafbsd-tdep.c (_initialize_alphafbsd_tdep): Likewise. > * alphanbsd-tdep.c (_initialize_alphanbsd_tdep): Likewise. > > * config/sh/tm-sh.h (sh_osabi): Remove. > (sh_abi, gdbarch_tdep, register enum): Move to... > * sh-tdep.h: ...here. > (gdbarch_tdep): Use generic OS ABI framework. > * sh-tdep.c: Include sh-tdep.h. > (sh_osabi_names, process_note_abi_tag_sections, > sh_osabi_handler_list, sh_gdbarch_register_os_abi): Remove. > (sh_gdbarch_init, sh_dump_tdep): Use generic OS ABI framework. > * sh3-rom.c: Include sh-tdep.h. > * shnbsd-tdep.c: Include sh-tdep.h. > (_initialize_shnbsd_tdep): Use gdbarch_register_osabi. > > -- > -- Jason R. Thorpe > Index: Makefile.in > =================================================================== > RCS file: /cvs/src/src/gdb/Makefile.in,v > retrieving revision 1.184 > diff -u -r1.184 Makefile.in > --- Makefile.in 11 May 2002 22:14:19 -0000 1.184 > +++ Makefile.in 13 May 2002 18:41:37 -0000 > @@ -530,7 +530,7 @@ > demangle.c dwarfread.c dwarf2read.c elfread.c environ.c eval.c \ > event-loop.c event-top.c \ > expprint.c f-exp.y f-lang.c f-typeprint.c f-valprint.c \ > - findvar.c regcache.c gdbarch.c arch-utils.c gdbtypes.c \ > + findvar.c regcache.c gdbarch.c arch-utils.c gdbtypes.c osabi.c \ > inf-loop.c infcmd.c inflow.c infrun.c language.c \ > kod.c kod-cisco.c \ > ui-out.c cli-out.c \ > @@ -612,7 +612,7 @@ > cp_abi_h = cp-abi.h > dcache_h = dcache.h > defs_h = defs.h $(xm_h) $(tm_h) $(nm_h) config.status config.h \ > - gdbarch.h ui-file.h $(INCLUDE_DIR)/gdb/signals.h > + gdbarch.h osabi.h ui-file.h $(INCLUDE_DIR)/gdb/signals.h > doublest_h = doublest.h $(floatformat_h) > dwarf2cfi_h = dwarf2cfi.h > event_loop_h = event-loop.h > @@ -712,7 +712,7 @@ > symtab.o symfile.o symmisc.o linespec.o infcmd.o infrun.o \ > expprint.o environ.o stack.o thread.o \ > event-loop.o event-top.o inf-loop.o completer.o \ > - gdbarch.o arch-utils.o gdbtypes.o copying.o $(DEPFILES) \ > + gdbarch.o arch-utils.o gdbtypes.o osabi.o copying.o $(DEPFILES) \ > memattr.o mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \ > builtin-regs.o std-regs.o \ > signals.o \ > @@ -1556,6 +1556,8 @@ > gdbtypes.o: gdbtypes.c $(bfd_h) $(complaints_h) $(defs_h) $(expression_h) \ > $(gdbtypes_h) $(language_h) $(objfiles_h) $(symfile_h) $(symtab_h) \ > $(target_h) $(value_h) $(gdb_string_h) $(wrapper_h) $(cp_abi_h) > + > +osabi.o: osabi.c $(defs_h) $(BFD_SRC)/elf-bfd.h > > go32-nat.o: go32-nat.c $(defs_h) $(inferior_h) gdb_wait.h $(gdbcore_h) \ > $(command_h) $(floatformat_h) $(target_h) i387-tdep.h $(regcache_h) > Index: alpha-linux-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/alpha-linux-tdep.c,v > retrieving revision 1.5 > diff -u -r1.5 alpha-linux-tdep.c > --- alpha-linux-tdep.c 26 Apr 2002 07:05:34 -0000 1.5 > +++ alpha-linux-tdep.c 13 May 2002 18:41:37 -0000 > @@ -116,5 +116,6 @@ > void > _initialize_alpha_linux_tdep (void) > { > - alpha_gdbarch_register_os_abi (ALPHA_ABI_LINUX, alpha_linux_init_abi); > + gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_LINUX, > + alpha_linux_init_abi); > } > Index: alpha-osf1-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/alpha-osf1-tdep.c,v > retrieving revision 1.4 > diff -u -r1.4 alpha-osf1-tdep.c > --- alpha-osf1-tdep.c 26 Apr 2002 07:05:34 -0000 1.4 > +++ alpha-osf1-tdep.c 13 May 2002 18:41:37 -0000 > @@ -69,5 +69,5 @@ > void > _initialize_alpha_osf1_tdep (void) > { > - alpha_gdbarch_register_os_abi (ALPHA_ABI_OSF1, alpha_osf1_init_abi); > + gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_OSF1, alpha_osf1_init_abi); > } > Index: alpha-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/alpha-tdep.c,v > retrieving revision 1.33 > diff -u -r1.33 alpha-tdep.c > --- alpha-tdep.c 5 May 2002 18:49:57 -0000 1.33 > +++ alpha-tdep.c 13 May 2002 18:41:42 -0000 > @@ -1766,186 +1766,6 @@ > } > > > -/* This table matches the indices assigned to enum alpha_abi. Keep > - them in sync. */ > -static const char * const alpha_abi_names[] = > -{ > - "", > - "OSF/1", > - "GNU/Linux", > - "FreeBSD", > - "NetBSD", > - NULL > -}; > - > -static void > -process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj) > -{ > - enum alpha_abi *os_ident_ptr = obj; > - const char *name; > - unsigned int sectsize; > - > - name = bfd_get_section_name (abfd, sect); > - sectsize = bfd_section_size (abfd, sect); > - > - if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0) > - { > - unsigned int name_length, data_length, note_type; > - char *note; > - > - /* If the section is larger than this, it's probably not what we are > - looking for. */ > - if (sectsize > 128) > - sectsize = 128; > - > - note = alloca (sectsize); > - > - bfd_get_section_contents (abfd, sect, note, > - (file_ptr) 0, (bfd_size_type) sectsize); > - > - name_length = bfd_h_get_32 (abfd, note); > - data_length = bfd_h_get_32 (abfd, note + 4); > - note_type = bfd_h_get_32 (abfd, note + 8); > - > - if (name_length == 4 && data_length == 16 && note_type == 1 > - && strcmp (note + 12, "GNU") == 0) > - { > - int os_number = bfd_h_get_32 (abfd, note + 16); > - > - /* The case numbers are from abi-tags in glibc. */ > - switch (os_number) > - { > - case 0 : > - *os_ident_ptr = ALPHA_ABI_LINUX; > - break; > - > - case 1 : > - internal_error > - (__FILE__, __LINE__, > - "process_note_abi_sections: Hurd objects not supported"); > - break; > - > - case 2 : > - internal_error > - (__FILE__, __LINE__, > - "process_note_abi_sections: Solaris objects not supported"); > - break; > - > - default : > - internal_error > - (__FILE__, __LINE__, > - "process_note_abi_sections: unknown OS number %d", > - os_number); > - break; > - } > - } > - } > - /* NetBSD uses a similar trick. */ > - else if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0) > - { > - unsigned int name_length, desc_length, note_type; > - char *note; > - > - /* If the section is larger than this, it's probably not what we are > - looking for. */ > - if (sectsize > 128) > - sectsize = 128; > - > - note = alloca (sectsize); > - > - bfd_get_section_contents (abfd, sect, note, > - (file_ptr) 0, (bfd_size_type) sectsize); > - > - name_length = bfd_h_get_32 (abfd, note); > - desc_length = bfd_h_get_32 (abfd, note + 4); > - note_type = bfd_h_get_32 (abfd, note + 8); > - > - if (name_length == 7 && desc_length == 4 && note_type == 1 > - && strcmp (note + 12, "NetBSD") == 0) > - /* XXX Should we check the version here? > - Probably not necessary yet. */ > - *os_ident_ptr = ALPHA_ABI_NETBSD; > - } > -} > - > -static int > -get_elfosabi (bfd *abfd) > -{ > - int elfosabi; > - enum alpha_abi alpha_abi = ALPHA_ABI_UNKNOWN; > - > - elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; > - > - /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate > - what we're on a SYSV system. However, GNU/Linux uses a note section > - to record OS/ABI info, but leaves e_ident[EI_OSABI] zero. So we > - have to check the note sections too. */ > - if (elfosabi == 0) > - { > - bfd_map_over_sections (abfd, > - process_note_abi_tag_sections, > - &alpha_abi); > - } > - > - if (alpha_abi != ALPHA_ABI_UNKNOWN) > - return alpha_abi; > - > - switch (elfosabi) > - { > - case ELFOSABI_NONE: > - /* Leave it as unknown. */ > - break; > - > - case ELFOSABI_NETBSD: > - return ALPHA_ABI_NETBSD; > - > - case ELFOSABI_FREEBSD: > - return ALPHA_ABI_FREEBSD; > - > - case ELFOSABI_LINUX: > - return ALPHA_ABI_LINUX; > - } > - > - return ALPHA_ABI_UNKNOWN; > -} > - > -struct alpha_abi_handler > -{ > - struct alpha_abi_handler *next; > - enum alpha_abi abi; > - void (*init_abi)(struct gdbarch_info, struct gdbarch *); > -}; > - > -struct alpha_abi_handler *alpha_abi_handler_list = NULL; > - > -void > -alpha_gdbarch_register_os_abi (enum alpha_abi abi, > - void (*init_abi)(struct gdbarch_info, > - struct gdbarch *)) > -{ > - struct alpha_abi_handler **handler_p; > - > - for (handler_p = &alpha_abi_handler_list; *handler_p != NULL; > - handler_p = &(*handler_p)->next) > - { > - if ((*handler_p)->abi == abi) > - { > - internal_error > - (__FILE__, __LINE__, > - "alpha_gdbarch_register_os_abi: A handler for this ABI variant " > - "(%d) has already been registered", (int) abi); > - /* If user wants to continue, override previous definition. */ > - (*handler_p)->init_abi = init_abi; > - return; > - } > - } > - > - (*handler_p) > - = (struct alpha_abi_handler *) xmalloc (sizeof (struct alpha_abi_handler)); > - (*handler_p)->next = NULL; > - (*handler_p)->abi = abi; > - (*handler_p)->init_abi = init_abi; > -} > > /* Initialize the current architecture based on INFO. If possible, re-use an > architecture from ARCHES, which is a list of architectures already created > @@ -1959,27 +1779,18 @@ > { > struct gdbarch_tdep *tdep; > struct gdbarch *gdbarch; > - enum alpha_abi alpha_abi = ALPHA_ABI_UNKNOWN; > - struct alpha_abi_handler *abi_handler; > + enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; > > /* Try to determine the ABI of the object we are loading. */ > > if (info.abfd != NULL) > { > - switch (bfd_get_flavour (info.abfd)) > + osabi = gdbarch_lookup_osabi (info.abfd); > + if (osabi == GDB_OSABI_UNKNOWN) > { > - case bfd_target_elf_flavour: > - alpha_abi = get_elfosabi (info.abfd); > - break; > - > - case bfd_target_ecoff_flavour: > - /* Assume it's OSF/1. */ > - alpha_abi = ALPHA_ABI_OSF1; > - break; > - > - default: > - /* Not sure what to do here, leave the ABI as unknown. */ > - break; > + /* If it's an ECOFF file, assume it's OSF/1. */ > + if (bfd_get_flavour (info.abfd) == bfd_target_ecoff_flavour) > + osabi = GDB_OSABI_OSF1; > } > } > > @@ -1990,22 +1801,14 @@ > { > /* Make sure the ABI selection matches. */ > tdep = gdbarch_tdep (arches->gdbarch); > - if (tdep && tdep->alpha_abi == alpha_abi) > + if (tdep && tdep->osabi == osabi) > return arches->gdbarch; > } > > tdep = xmalloc (sizeof (struct gdbarch_tdep)); > gdbarch = gdbarch_alloc (&info, tdep); > > - tdep->alpha_abi = alpha_abi; > - if (alpha_abi < ALPHA_ABI_INVALID) > - tdep->abi_name = alpha_abi_names[alpha_abi]; > - else > - { > - internal_error (__FILE__, __LINE__, "Invalid setting of alpha_abi %d", > - (int) alpha_abi); > - tdep->abi_name = ""; > - } > + tdep->osabi = osabi; > > /* Lowest text address. This is used by heuristic_proc_start() to > decide when to stop looking. */ > @@ -2122,38 +1925,7 @@ > set_gdbarch_frame_args_skip (gdbarch, 0); > > /* Hook in ABI-specific overrides, if they have been registered. */ > - if (alpha_abi == ALPHA_ABI_UNKNOWN) > - { > - /* Don't complain about not knowing the ABI variant if we don't > - have an inferior. */ > - if (info.abfd) > - fprintf_filtered > - (gdb_stderr, "GDB doesn't recognize the ABI of the inferior. " > - "Attempting to continue with the default Alpha settings"); > - } > - else > - { > - for (abi_handler = alpha_abi_handler_list; abi_handler != NULL; > - abi_handler = abi_handler->next) > - if (abi_handler->abi == alpha_abi) > - break; > - > - if (abi_handler) > - abi_handler->init_abi (info, gdbarch); > - else > - { > - /* We assume that if GDB_MULTI_ARCH is less than > - GDB_MULTI_ARCH_TM that an ABI variant can be supported by > - overriding definitions in this file. */ > - if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) > - fprintf_filtered > - (gdb_stderr, > - "A handler for the ABI variant \"%s\" is not built into this " > - "configuration of GDB. " > - "Attempting to continue with the default Alpha settings", > - alpha_abi_names[alpha_abi]); > - } > - } > + gdbarch_init_osabi (info, gdbarch, osabi); > > /* Now that we have tuned the configuration, set a few final things > based on what the OS ABI has told us. */ > @@ -2172,12 +1944,8 @@ > if (tdep == NULL) > return; > > - if (tdep->abi_name != NULL) > - fprintf_unfiltered (file, "alpha_dump_tdep: ABI = %s\n", tdep->abi_name); > - else > - internal_error (__FILE__, __LINE__, > - "alpha_dump_tdep: illegal setting of tdep->alpha_abi (%d)", > - (int) tdep->alpha_abi); > + fprintf_unfiltered (file, "alpha_dump_tdep: OS ABI = %s\n", > + gdbarch_osabi_name (tdep->osabi)); > > fprintf_unfiltered (file, > "alpha_dump_tdep: vm_min_address = 0x%lx\n", > Index: alpha-tdep.h > =================================================================== > RCS file: /cvs/src/src/gdb/alpha-tdep.h,v > retrieving revision 1.7 > diff -u -r1.7 alpha-tdep.h > --- alpha-tdep.h 26 Apr 2002 07:05:34 -0000 1.7 > +++ alpha-tdep.h 13 May 2002 18:41:42 -0000 > @@ -76,24 +76,10 @@ > pointer, the value of localoff is obtained from the PDR. */ > #define ALPHA_NUM_ARG_REGS 6 > > -/* ABI variants that we know about. If you add to this enum, please > - update the table of names in alpha-tdep.c. */ > -enum alpha_abi > -{ > - ALPHA_ABI_UNKNOWN = 0, > - ALPHA_ABI_OSF1, > - ALPHA_ABI_LINUX, > - ALPHA_ABI_FREEBSD, > - ALPHA_ABI_NETBSD, > - > - ALPHA_ABI_INVALID /* Keep this last. */ > -}; > - > /* Target-dependent structure in gdbarch. */ > struct gdbarch_tdep > { > - enum alpha_abi alpha_abi; /* OS/ABI of inferior. */ > - const char *abi_name; /* Name of the above. */ > + enum gdb_osabi osabi; /* OS/ABI of inferior. */ > > CORE_ADDR vm_min_address; /* used by heuristic_proc_start */ > > @@ -117,9 +103,5 @@ > }; > > void alpha_software_single_step (enum target_signal, int); > - > -void alpha_gdbarch_register_os_abi (enum alpha_abi, > - void (*init_abi)(struct gdbarch_info, > - struct gdbarch *)); > > #endif /* ALPHA_TDEP_H */ > Index: alphafbsd-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/alphafbsd-tdep.c,v > retrieving revision 1.4 > diff -u -r1.4 alphafbsd-tdep.c > --- alphafbsd-tdep.c 26 Apr 2002 01:08:19 -0000 1.4 > +++ alphafbsd-tdep.c 13 May 2002 18:41:43 -0000 > @@ -78,5 +78,6 @@ > void > _initialize_alphafbsd_tdep (void) > { > - alpha_gdbarch_register_os_abi (ALPHA_ABI_FREEBSD, alphafbsd_init_abi); > + gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_FREEBSD_ELF, > + alphafbsd_init_abi); > } > Index: alphanbsd-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/alphanbsd-tdep.c,v > retrieving revision 1.5 > diff -u -r1.5 alphanbsd-tdep.c > --- alphanbsd-tdep.c 11 May 2002 22:14:19 -0000 1.5 > +++ alphanbsd-tdep.c 13 May 2002 18:41:43 -0000 > @@ -203,7 +203,8 @@ > void > _initialize_alphanbsd_tdep (void) > { > - alpha_gdbarch_register_os_abi (ALPHA_ABI_NETBSD, alphanbsd_init_abi); > + gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_NETBSD_ELF, > + alphanbsd_init_abi); > > add_core_fns (&alphanbsd_core_fns); > add_core_fns (&alphanbsd_elfcore_fns); > Index: defs.h > =================================================================== > RCS file: /cvs/src/src/gdb/defs.h,v > retrieving revision 1.88 > diff -u -r1.88 defs.h > --- defs.h 18 Apr 2002 18:08:59 -0000 1.88 > +++ defs.h 13 May 2002 18:41:50 -0000 > @@ -1029,6 +1029,10 @@ > #include "arch-utils.h" > #endif > > +/* Operating system ABI variant handling for dynamic > + target-system-dependent parameters. */ > +#include "osabi.h" > + > /* Static target-system-dependent parameters for GDB. */ > > /* Number of bits in a char or unsigned char for the target machine. > Index: osabi.c > =================================================================== > RCS file: osabi.c > diff -N osabi.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ osabi.c 13 May 2002 18:41:56 -0000 > @@ -0,0 +1,404 @@ > +/* OS ABI variant handling for GDB. > + Copyright 2001, 2002 Free Software Foundation, Inc. > + > + This file is part of GDB. > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 2 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 59 Temple Place - Suite 330, > + Boston, MA 02111-1307, USA. */ > + > +#include "defs.h" > +#include "osabi.h" > + > +#include "elf-bfd.h" > + > + > +/* This table matches the indices assigned to enum gdb_osabi. Keep > + them in sync. */ > +static const char * const gdb_osabi_names[] = > +{ > + "", > + > + "SVR4", > + "GNU Hurd", > + "Solaris", > + "OSF/1", > + "GNU/Linux", > + "FreeBSD a.out", > + "FreeBSD ELF", > + "NetBSD a.out", > + "NetBSD ELF", > + "Windows CE", > + > + "ARM EABI v1", > + "ARM EABI v2", > + "ARM APCS", > + > + "" > +}; > + > +const char * > +gdbarch_osabi_name (enum gdb_osabi osabi) > +{ > + if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID) > + return gdb_osabi_names[osabi]; > + > + return gdb_osabi_names[GDB_OSABI_INVALID]; > +} > + > +/* Handler for a given architecture/OS ABI pair. There should be only > + one handler for a given OS ABI each architecture family. */ > +struct gdb_osabi_handler > +{ > + struct gdb_osabi_handler *next; > + enum bfd_architecture arch; > + enum gdb_osabi osabi; > + void (*init_osabi)(struct gdbarch_info, struct gdbarch *); > +}; > + > +static struct gdb_osabi_handler *gdb_osabi_handler_list; > + > +void > +gdbarch_register_osabi (enum bfd_architecture arch, enum gdb_osabi osabi, > + void (*init_osabi)(struct gdbarch_info, > + struct gdbarch *)) > +{ > + struct gdb_osabi_handler **handler_p; > + > + /* Registering an OS ABI handler for "unknown" is not allowed. */ > + if (osabi == GDB_OSABI_UNKNOWN) > + { > + internal_error > + (__FILE__, __LINE__, > + "gdbarch_register_osabi: An attempt to register a handler for " > + "OS ABI \"%s\" for architecture %s was made. The handler will " > + "not be registered", > + gdbarch_osabi_name (osabi), > + bfd_printable_arch_mach (arch, 0)); > + return; > + } > + > + for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL; > + handler_p = &(*handler_p)->next) > + { > + if ((*handler_p)->arch == arch > + && (*handler_p)->osabi == osabi) > + { > + internal_error > + (__FILE__, __LINE__, > + "gdbarch_register_osabi: A handler for OS ABI \"%s\" " > + "has already been registered for architecture %s", > + gdbarch_osabi_name (osabi), > + bfd_printable_arch_mach (arch, 0)); > + /* If user wants to continue, override previous definition. */ > + (*handler_p)->init_osabi = init_osabi; > + return; > + } > + } > + > + (*handler_p) > + = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler)); > + (*handler_p)->next = NULL; > + (*handler_p)->arch = arch; > + (*handler_p)->osabi = osabi; > + (*handler_p)->init_osabi = init_osabi; > +} > + > + > +/* Sniffer to find the OS ABI for a given file's architecture and flavour. > + It is legal to have multiple sniffers for each arch/flavour pair, to > + disambiguate one OS's a.out from another, for example. The first sniffer > + to return something other than GDB_OSABI_UNKNOWN wins, so a sniffer should > + be careful to claim a file only if it knows for sure what it is. */ > +struct gdb_osabi_sniffer > +{ > + struct gdb_osabi_sniffer *next; > + enum bfd_architecture arch; /* bfd_arch_unknown == wildcard */ > + enum bfd_flavour flavour; > + enum gdb_osabi (*sniffer)(bfd *); > +}; > + > +static struct gdb_osabi_sniffer *gdb_osabi_sniffer_list; > + > +void > +gdbarch_register_osabi_sniffer (enum bfd_architecture arch, > + enum bfd_flavour flavour, > + enum gdb_osabi (*sniffer_fn)(bfd *)) > +{ > + struct gdb_osabi_sniffer *sniffer; > + > + sniffer = > + (struct gdb_osabi_sniffer *) xmalloc (sizeof (struct gdb_osabi_sniffer)); > + sniffer->arch = arch; > + sniffer->flavour = flavour; > + sniffer->sniffer = sniffer_fn; > + > + sniffer->next = gdb_osabi_sniffer_list; > + gdb_osabi_sniffer_list = sniffer; > +} > + > + > +enum gdb_osabi > +gdbarch_lookup_osabi (bfd *abfd) > +{ > + struct gdb_osabi_sniffer *sniffer; > + enum gdb_osabi osabi, match; > + > + match = GDB_OSABI_UNKNOWN; > + > + for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL; > + sniffer = sniffer->next) > + { > + if ((sniffer->arch == bfd_arch_unknown /* wildcard */ > + || sniffer->arch == bfd_get_arch (abfd)) > + && sniffer->flavour == bfd_get_flavour (abfd)) > + { > + osabi = (*sniffer->sniffer) (abfd); > + if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID) > + { > + internal_error > + (__FILE__, __LINE__, > + "gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer " > + "for architecture %s flavour %d", > + (int) osabi, > + bfd_printable_arch_mach (bfd_get_arch (abfd), 0), > + (int) bfd_get_flavour (abfd)); > + } > + else if (osabi != GDB_OSABI_UNKNOWN) > + { > + /* Croak on multiple match. If the user wishes to > + continue, we'll use the first match. */ > + if (match != GDB_OSABI_UNKNOWN) > + internal_error > + (__FILE__, __LINE__, > + "gdbarch_lookup_osabi: multiple OS ABI match for " > + "architecture %s flavour %d: first match \"%s\", second " > + "match \"%s\"", > + bfd_printable_arch_mach (bfd_get_arch (abfd), 0), > + (int) bfd_get_flavour (abfd), > + gdbarch_osabi_name (match), > + gdbarch_osabi_name (osabi)); > + else > + match = osabi; > + } > + } > + } > + > + return match; > +} > + > +void > +gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch, > + enum gdb_osabi osabi) > +{ > + struct gdb_osabi_handler *handler; > + bfd *abfd = info.abfd; > + const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch); > + > + if (osabi == GDB_OSABI_UNKNOWN) > + { > + /* Don't complain about not knowing the OS ABI if we don't > + have an inferior. */ > + if (info.abfd) > + fprintf_filtered > + (gdb_stderr, "GDB doesn't recognize the OS ABI of the inferior. " > + "Attempting to continue with the default %s settings", > + bfd_printable_arch_mach (arch_info->arch, arch_info->mach)); > + return; > + } > + > + for (handler = gdb_osabi_handler_list; handler != NULL; > + handler = handler->next) > + { > + if (handler->arch == bfd_get_arch (abfd) > + && handler->osabi == osabi) > + { > + (*handler->init_osabi) (info, gdbarch); > + return; > + } > + } > + > + /* We assume that if GDB_MULTI_ARCH is less than GDB_MULTI_ARCH_TM > + that an ABI variant can be supported by overriding definitions in > + the tm-file. */ > + if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) > + fprintf_filtered > + (gdb_stderr, > + "A handler for the OS ABI \"%s\" is not built into this " > + "configuration of GDB. " > + "Attempting to continue with the default %s settings", > + gdbarch_osabi_name (osabi), > + bfd_printable_arch_mach (arch_info->arch, arch_info->mach)); > +} > + > + > +/* Generic sniffer for ELF flavoured files. */ > + > +static void > +process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj) > +{ > + enum gdb_osabi *os_ident_ptr = obj; > + const char *name; > + unsigned int sectsize; > + > + name = bfd_get_section_name (abfd, sect); > + sectsize = bfd_section_size (abfd, sect); > + > + /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD. */ > + if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0) > + { > + unsigned int name_length, data_length, note_type; > + char *note; > + > + /* If the section is larger than this, it's probably not what we are > + looking for. */ > + if (sectsize > 128) > + sectsize = 128; > + > + note = alloca (sectsize); > + > + bfd_get_section_contents (abfd, sect, note, > + (file_ptr) 0, (bfd_size_type) sectsize); > + > + name_length = bfd_h_get_32 (abfd, note); > + data_length = bfd_h_get_32 (abfd, note + 4); > + note_type = bfd_h_get_32 (abfd, note + 8); > + > + if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG > + && strcmp (note + 12, "GNU") == 0) > + { > + int os_number = bfd_h_get_32 (abfd, note + 16); > + > + switch (os_number) > + { > + case GNU_ABI_TAG_LINUX: > + *os_ident_ptr = GDB_OSABI_LINUX; > + break; > + > + case GNU_ABI_TAG_HURD: > + *os_ident_ptr = GDB_OSABI_HURD; > + break; > + > + case GNU_ABI_TAG_SOLARIS: > + *os_ident_ptr = GDB_OSABI_SOLARIS; > + break; > + > + default: > + internal_error > + (__FILE__, __LINE__, > + "process_note_abi_sections: unknown OS number %d", > + os_number); > + } > + return; > + } > + else if (name_length == 8 && data_length == 4 > + && note_type == NT_FREEBSD_ABI_TAG > + && strcmp (note + 12, "FreeBSD") == 0) > + { > + /* XXX Should we check the version here? Probably not > + necessary yet. */ > + *os_ident_ptr = GDB_OSABI_FREEBSD_ELF; > + } > + return; > + } > + > + /* .note.netbsd.ident notes, used by NetBSD. */ > + if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0) > + { > + unsigned int name_length, data_length, note_type; > + char *note; > + > + /* If the section is larger than this, it's probably not what we are > + looking for. */ > + if (sectsize > 128) > + sectsize = 128; > + > + note = alloca (sectsize); > + > + bfd_get_section_contents (abfd, sect, note, > + (file_ptr) 0, (bfd_size_type) sectsize); > + > + name_length = bfd_h_get_32 (abfd, note); > + data_length = bfd_h_get_32 (abfd, note + 4); > + note_type = bfd_h_get_32 (abfd, note + 8); > + > + if (name_length == 7 && data_length == 4 && note_type == NT_NETBSD_IDENT > + && strcmp (note + 12, "NetBSD") == 0) > + { > + /* XXX Should we check the version here? Probably not > + necessary yet. */ > + *os_ident_ptr = GDB_OSABI_NETBSD_ELF; > + } > + return; > + } > +} > + > +static enum gdb_osabi > +generic_elf_osabi_sniffer (bfd *abfd) > +{ > + int elfosabi; > + enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; > + > + elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; > + > + switch (elfosabi) > + { > + case ELFOSABI_NONE: > + /* When elfosabi is ELFOSABI_NONE (0), this is supposed to indicate > + that we're on a SVR4 system. However, some systems use note sections > + to record OS/ABI info, but leave e_ident[EI_OSABI] zero. So we > + have to check the note sections, too. */ > + bfd_map_over_sections (abfd, > + process_note_abi_tag_sections, > + &osabi); > + break; > + > + case ELFOSABI_FREEBSD: > + osabi = GDB_OSABI_FREEBSD_ELF; > + break; > + > + case ELFOSABI_NETBSD: > + osabi = GDB_OSABI_NETBSD_ELF; > + break; > + > + case ELFOSABI_LINUX: > + osabi = GDB_OSABI_LINUX; > + break; > + > + case ELFOSABI_HURD: > + osabi = GDB_OSABI_HURD; > + break; > + > + case ELFOSABI_SOLARIS: > + osabi = GDB_OSABI_SOLARIS; > + break; > + } > + > + return osabi; > +} > + > + > +void > +_initialize_gdb_osabi (void) > +{ > + if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID], "") != 0) > + internal_error > + (__FILE__, __LINE__, > + "_initialize_gdb_osabi: gdb_osabi_names[] is inconsistent"); > + > + /* Register a generic sniffer for ELF flavoured files. */ > + gdbarch_register_osabi_sniffer (bfd_arch_unknown, > + bfd_target_elf_flavour, > + generic_elf_osabi_sniffer); > +} > Index: osabi.h > =================================================================== > RCS file: osabi.h > diff -N osabi.h > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ osabi.h 13 May 2002 18:41:56 -0000 > @@ -0,0 +1,73 @@ > +/* OS ABI variant handling for GDB. > + Copyright 2001, 2002 Free Software Foundation, Inc. > + > + This file is part of GDB. > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 2 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 59 Temple Place - Suite 330, > + Boston, MA 02111-1307, USA. */ > + > +#ifndef OSABI_H > +#define OSABI_H > + > +/* List of known OS ABIs. If you change this, make sure to update the > + table in osabi.c. */ > +enum gdb_osabi > +{ > + GDB_OSABI_UNKNOWN = 0, /* keep this first */ > + > + GDB_OSABI_SVR4, > + GDB_OSABI_HURD, > + GDB_OSABI_SOLARIS, > + GDB_OSABI_OSF1, > + GDB_OSABI_LINUX, > + GDB_OSABI_FREEBSD_AOUT, > + GDB_OSABI_FREEBSD_ELF, > + GDB_OSABI_NETBSD_AOUT, > + GDB_OSABI_NETBSD_ELF, > + GDB_OSABI_WINCE, > + > + GDB_OSABI_ARM_EABI_V1, > + GDB_OSABI_ARM_EABI_V2, > + GDB_OSABI_ARM_APCS, > + > + GDB_OSABI_INVALID /* keep this last */ > +}; > + > +/* Register an OS ABI sniffer. Each arch/flavour may have more than > + one sniffer. This is used to e.g. differentiate one OS's a.out from > + another. The first sniffer to return something other than > + GDB_OSABI_UNKNOWN wins, so a sniffer should be careful to claim a file > + only if it knows for sure what it is. */ > +void gdbarch_register_osabi_sniffer (enum bfd_architecture, > + enum bfd_flavour, > + enum gdb_osabi (*)(bfd *)); > + > +/* Register a handler for an OS ABI variant for a given architecture. There > + should be only one handler for a given OS ABI each architecture family. */ > +void gdbarch_register_osabi (enum bfd_architecture, enum gdb_osabi, > + void (*)(struct gdbarch_info, > + struct gdbarch *)); > + > +/* Lookup the OS ABI corresponding to the specified BFD. */ > +enum gdb_osabi gdbarch_lookup_osabi (bfd *); > + > +/* Initialize the gdbarch for the specified OS ABI variant. */ > +void gdbarch_init_osabi (struct gdbarch_info, struct gdbarch *, > + enum gdb_osabi); > + > +/* Return the name of the specified OS ABI. */ > +const char *gdbarch_osabi_name (enum gdb_osabi); > + > +#endif /* OSABI_H */ > Index: sh-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/sh-tdep.c,v > retrieving revision 1.58 > diff -u -r1.58 sh-tdep.c > --- sh-tdep.c 10 May 2002 23:59:09 -0000 1.58 > +++ sh-tdep.c 13 May 2002 18:42:23 -0000 > @@ -41,6 +41,8 @@ > #include "regcache.h" > #include "doublest.h" > > +#include "sh-tdep.h" > + > #include "elf-bfd.h" > #include "solib-svr4.h" > > @@ -4198,175 +4200,6 @@ > #endif /* SVR4_SHARED_LIBS */ > > > -/* This table matches the indices assigned to enum sh_osabi. Keep > - them in sync. */ > -static const char * const sh_osabi_names[] = > -{ > - "", > - "GNU/Linux", > - "NetBSD ELF", > - NULL > -}; > - > -static void > -process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj) > -{ > - enum sh_osabi *os_ident_ptr = obj; > - const char *name; > - unsigned int sectsize; > - > - name = bfd_get_section_name (abfd, sect); > - sectsize = bfd_section_size (abfd, sect); > - > - if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0) > - { > - unsigned int name_length, data_length, note_type; > - char *note; > - > - /* If the section is larger than this, it's probably not what we are > - looking for. */ > - if (sectsize > 128) > - sectsize = 128; > - > - note = alloca (sectsize); > - > - bfd_get_section_contents (abfd, sect, note, > - (file_ptr) 0, (bfd_size_type) sectsize); > - > - name_length = bfd_h_get_32 (abfd, note); > - data_length = bfd_h_get_32 (abfd, note + 4); > - note_type = bfd_h_get_32 (abfd, note + 8); > - > - if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG > - && strcmp (note + 12, "GNU") == 0) > - { > - int os_number = bfd_h_get_32 (abfd, note + 16); > - > - /* The case numbers are from abi-tags in glibc. */ > - switch (os_number) > - { > - case GNU_ABI_TAG_LINUX: > - *os_ident_ptr = SH_OSABI_LINUX; > - break; > - > - case GNU_ABI_TAG_HURD: > - internal_error > - (__FILE__, __LINE__, > - "process_note_abi_sections: Hurd objects not supported"); > - break; > - > - case GNU_ABI_TAG_SOLARIS: > - internal_error > - (__FILE__, __LINE__, > - "process_note_abi_sections: Solaris objects not supported"); > - break; > - > - default: > - internal_error > - (__FILE__, __LINE__, > - "process_note_abi_sections: unknown OS number %d", > - os_number); > - } > - } > - } > - /* NetBSD uses a similar trick. */ > - else if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0) > - { > - unsigned int name_length, desc_length, note_type; > - char *note; > - > - /* If the section is larger than this, it's probably not what we are > - looking for. */ > - if (sectsize > 128) > - sectsize = 128; > - > - note = alloca (sectsize); > - > - bfd_get_section_contents (abfd, sect, note, > - (file_ptr) 0, (bfd_size_type) sectsize); > - > - name_length = bfd_h_get_32 (abfd, note); > - desc_length = bfd_h_get_32 (abfd, note + 4); > - note_type = bfd_h_get_32 (abfd, note + 8); > - > - if (name_length == 7 && desc_length == 4 && note_type == NT_NETBSD_IDENT > - && strcmp (note + 12, "NetBSD") == 0) > - /* XXX Should we check the version here? > - Probably not necessary yet. */ > - *os_ident_ptr = SH_OSABI_NETBSD_ELF; > - } > -} > - > -static int > -get_elfosabi (bfd *abfd) > -{ > - int elfosabi; > - enum sh_osabi sh_osabi = SH_OSABI_UNKNOWN; > - > - elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; > - > - switch (elfosabi) > - { > - case ELFOSABI_NONE: > - /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate > - that we're on a SYSV system. However, some systems use note sections > - to record OS/ABI info, but leave e_ident[EI_OSABI] zero. So we > - have to check the note sections too. */ > - bfd_map_over_sections (abfd, > - process_note_abi_tag_sections, > - &sh_osabi); > - break; > - > - case ELFOSABI_NETBSD: > - sh_osabi = SH_OSABI_NETBSD_ELF; > - break; > - > - case ELFOSABI_LINUX: > - sh_osabi = SH_OSABI_LINUX; > - break; > - } > - > - return (sh_osabi); > -} > - > -struct sh_osabi_handler > -{ > - struct sh_osabi_handler *next; > - enum sh_osabi abi; > - void (*init_osabi)(struct gdbarch_info, struct gdbarch *); > -}; > - > -struct sh_osabi_handler *sh_osabi_handler_list = NULL; > - > -void > -sh_gdbarch_register_os_abi (enum sh_osabi abi, > - void (*init_osabi)(struct gdbarch_info, > - struct gdbarch *)) > -{ > - struct sh_osabi_handler **handler_p; > - > - for (handler_p = &sh_osabi_handler_list; *handler_p != NULL; > - handler_p = &(*handler_p)->next) > - { > - if ((*handler_p)->abi == abi) > - { > - internal_error > - (__FILE__, __LINE__, > - "sh_gdbarch_register_os_abi: A handler for this ABI variant " > - "(%d) has already been registered", (int) abi); > - /* If user wants to continue, override previous definition. */ > - (*handler_p)->init_osabi = init_osabi; > - return; > - } > - } > - > - (*handler_p) > - = (struct sh_osabi_handler *) xmalloc (sizeof (struct sh_osabi_handler)); > - (*handler_p)->next = NULL; > - (*handler_p)->abi = abi; > - (*handler_p)->init_osabi = init_osabi; > -} > - > static gdbarch_init_ftype sh_gdbarch_init; > > static struct gdbarch * > @@ -4378,23 +4211,14 @@ > gdbarch_register_name_ftype *sh_register_name; > gdbarch_store_return_value_ftype *sh_store_return_value; > gdbarch_register_virtual_type_ftype *sh_register_virtual_type; > - enum sh_osabi sh_osabi = SH_OSABI_UNKNOWN; > - struct sh_osabi_handler *osabi_handler; > + enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; > > /* Try to determine the ABI of the object we are loading. */ > > if (info.abfd != NULL) > { > - switch (bfd_get_flavour (info.abfd)) > - { > - case bfd_target_elf_flavour: > - sh_osabi = get_elfosabi (info.abfd); > - break; > - > - default: > - /* Just leave it as "unkown". */ > - break; > - } > + osabi = gdbarch_lookup_osabi (info.abfd); > + /* If we get "unknown" back, just leave it that way. */ > } > > /* Find a candidate among the list of pre-declared architectures. */ > @@ -4404,7 +4228,7 @@ > { > /* Make sure the ABI selection matches. */ > tdep = gdbarch_tdep (arches->gdbarch); > - if (tdep && tdep->sh_osabi == sh_osabi) > + if (tdep && tdep->osabi == osabi) > return arches->gdbarch; > } > > @@ -4413,15 +4237,7 @@ > tdep = XMALLOC (struct gdbarch_tdep); > gdbarch = gdbarch_alloc (&info, tdep); > > - tdep->sh_osabi = sh_osabi; > - if (sh_osabi < SH_OSABI_INVALID) > - tdep->osabi_name = sh_osabi_names[sh_osabi]; > - else > - { > - internal_error (__FILE__, __LINE__, "Invalid setting of sh_osabi %d", > - (int) sh_osabi); > - tdep->osabi_name = ""; > - } > + tdep->osabi = osabi; > > /* Initialize the register numbers that are not common to all the > variants to -1, if necessary thse will be overwritten in the case > @@ -4774,32 +4590,11 @@ > set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown); > set_gdbarch_believe_pcc_promotion (gdbarch, 1); > > - /* Hook in ABI-specific overrides, if they have been registered. If > - the ABI is unknown, this is probably an embedded target, so we > - should not warn about this situation. */ > - if (sh_osabi != SH_OSABI_UNKNOWN) > - { > - for (osabi_handler = sh_osabi_handler_list; osabi_handler != NULL; > - osabi_handler = osabi_handler->next) > - if (osabi_handler->abi == sh_osabi) > - break; > + /* Hook in ABI-specific overrides, if they have been registered. > > - if (osabi_handler) > - osabi_handler->init_osabi (info, gdbarch); > - else > - { > - /* We assume that if GDB_MULTI_ARCH is less than > - GDB_MULTI_ARCH_TM that an ABI variant can be supported by > - overriding definitions in this file. */ > - if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) > - fprintf_filtered > - (gdb_stderr, > - "A handler for the ABI variant \"%s\" is not built into this " > - "configuration of GDB. " > - "Attempting to continue with the default SuperH settings", > - sh_osabi_names[sh_osabi]); > - } > - } > + FIXME: if the ABI is unknown, this is probably an embedded target, > + so we should not warn about this situation. */ > + gdbarch_init_osabi (info, gdbarch, osabi); > > return gdbarch; > } > @@ -4812,12 +4607,8 @@ > if (tdep == NULL) > return; > > - if (tdep->osabi_name != NULL) > - fprintf_unfiltered (file, "sh_dump_tdep: OS ABI = %s\n", tdep->osabi_name); > - else > - internal_error (__FILE__, __LINE__, > - "sh_dump_tdep: illegal setting of tdep->sh_osabi (%d)", > - (int) tdep->sh_osabi); > + fprintf_unfiltered (file, "sh_dump_tdep: OS ABI = %s\n", > + gdbarch_osabi_name (tdep->osabi)); > } > > void > Index: sh-tdep.h > =================================================================== > RCS file: sh-tdep.h > diff -N sh-tdep.h > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ sh-tdep.h 13 May 2002 18:42:23 -0000 > @@ -0,0 +1,109 @@ > +/* Target-specific definition for a Hitachi Super-H. > + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 > + Free Software Foundation, Inc. > + > + This file is part of GDB. > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 2 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 59 Temple Place - Suite 330, > + Boston, MA 02111-1307, USA. */ > + > +#ifndef SH_TDEP_H > +#define SH_TDEP_H > + > +/* Contributed by Steve Chamberlain sac@cygnus.com */ > + > +/* Information that is dependent on the processor variant. */ > + > +enum sh_abi > + { > + SH_ABI_UNKNOWN, > + SH_ABI_32, > + SH_ABI_64 > + }; > + > +struct gdbarch_tdep > + { > + int PR_REGNUM; > + int FPUL_REGNUM; /* sh3e, sh4 */ > + int FPSCR_REGNUM; /* sh3e, sh4 */ > + int SR_REGNUM; /* sh-dsp, sh3, sh3-dsp, sh3e, sh4 */ > + int DSR_REGNUM; /* sh-dsp, sh3-dsp */ > + int FP_LAST_REGNUM; /* sh3e, sh4 */ > + int A0G_REGNUM; /* sh-dsp, sh3-dsp */ > + int A0_REGNUM; /* sh-dsp, sh3-dsp */ > + int A1G_REGNUM; /* sh-dsp, sh3-dsp */ > + int A1_REGNUM; /* sh-dsp, sh3-dsp */ > + int M0_REGNUM; /* sh-dsp, sh3-dsp */ > + int M1_REGNUM; /* sh-dsp, sh3-dsp */ > + int X0_REGNUM; /* sh-dsp, sh3-dsp */ > + int X1_REGNUM; /* sh-dsp, sh3-dsp */ > + int Y0_REGNUM; /* sh-dsp, sh3-dsp */ > + int Y1_REGNUM; /* sh-dsp, sh3-dsp */ > + int MOD_REGNUM; /* sh-dsp, sh3-dsp */ > + int SSR_REGNUM; /* sh3, sh3-dsp, sh3e, sh4 */ > + int SPC_REGNUM; /* sh3, sh3-dsp, sh3e, sh4 */ > + int RS_REGNUM; /* sh-dsp, sh3-dsp */ > + int RE_REGNUM; /* sh-dsp, sh3-dsp */ > + int DR0_REGNUM; /* sh4 */ > + int DR_LAST_REGNUM; /* sh4 */ > + int FV0_REGNUM; /* sh4 */ > + int FV_LAST_REGNUM; /* sh4 */ > + /* FPP stands for Floating Point Pair, to avoid confusion with > + GDB's FP0_REGNUM, which is the number of the first Floating > + point register. Unfortunately on the sh5, the floating point > + registers are called FR, and the floating point pairs are called FP. */ > + int TR7_REGNUM; /* sh5-media*/ > + int FPP0_REGNUM; /* sh5-media*/ > + int FPP_LAST_REGNUM; /* sh5-media*/ > + int R0_C_REGNUM; /* sh5-compact*/ > + int R_LAST_C_REGNUM; /* sh5-compact*/ > + int PC_C_REGNUM; /* sh5-compact*/ > + int GBR_C_REGNUM; /* sh5-compact*/ > + int MACH_C_REGNUM; /* sh5-compact*/ > + int MACL_C_REGNUM; /* sh5-compact*/ > + int PR_C_REGNUM; /* sh5-compact*/ > + int T_C_REGNUM; /* sh5-compact*/ > + int FPSCR_C_REGNUM; /* sh5-compact*/ > + int FPUL_C_REGNUM; /* sh5-compact*/ > + int FP0_C_REGNUM; /* sh5-compact*/ > + int FP_LAST_C_REGNUM; /* sh5-compact*/ > + int DR0_C_REGNUM; /* sh5-compact*/ > + int DR_LAST_C_REGNUM; /* sh5-compact*/ > + int FV0_C_REGNUM; /* sh5-compact*/ > + int FV_LAST_C_REGNUM; /* sh5-compact*/ > + int ARG0_REGNUM; > + int ARGLAST_REGNUM; > + int FLOAT_ARGLAST_REGNUM; > + int RETURN_REGNUM; > + enum gdb_osabi osabi; /* OS/ABI of the inferior */ > + enum sh_abi sh_abi; > + }; > + > +/* Registers common to all the SH variants. */ > +enum > + { > + R0_REGNUM = 0, > + STRUCT_RETURN_REGNUM = 2, > + ARG0_REGNUM = 4, /* Used in h8300-tdep.c */ > + ARGLAST_REGNUM = 7, /* Used in h8300-tdep.c */ > + PR_REGNUM = 17, /* used in sh3-rom.c */ > + GBR_REGNUM = 18, > + VBR_REGNUM = 19, > + MACH_REGNUM = 20, > + MACL_REGNUM = 21, > + SR_REGNUM = 22 > + }; > + > +#endif /* SH_TDEP_H */ > Index: sh3-rom.c > =================================================================== > RCS file: /cvs/src/src/gdb/sh3-rom.c,v > retrieving revision 1.11 > diff -u -r1.11 sh3-rom.c > --- sh3-rom.c 15 Jul 2001 20:34:14 -0000 1.11 > +++ sh3-rom.c 13 May 2002 18:42:25 -0000 > @@ -28,6 +28,8 @@ > #include "arch-utils.h" > #include "regcache.h" > > +#include "sh-tdep.h" > + > static struct serial *parallel; > static int parallel_in_use; > > Index: shnbsd-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/shnbsd-tdep.c,v > retrieving revision 1.3 > diff -u -r1.3 shnbsd-tdep.c > --- shnbsd-tdep.c 11 May 2002 22:14:19 -0000 1.3 > +++ shnbsd-tdep.c 13 May 2002 18:42:25 -0000 > @@ -25,6 +25,7 @@ > #include "value.h" > > #include "nbsd-tdep.h" > +#include "sh-tdep.h" > #include "shnbsd-tdep.h" > > /* Convert an r0-r15 register number into an offset into a ptrace > @@ -176,5 +177,5 @@ > add_core_fns (&shnbsd_core_fns); > add_core_fns (&shnbsd_elfcore_fns); > > - sh_gdbarch_register_os_abi (SH_OSABI_NETBSD_ELF, shnbsd_init_abi); > + gdbarch_register_osabi (bfd_arch_sh, GDB_OSABI_NETBSD_ELF, shnbsd_init_abi); > } > Index: config/sh/tm-sh.h > =================================================================== > RCS file: /cvs/src/src/gdb/config/sh/tm-sh.h,v > retrieving revision 1.18 > diff -u -r1.18 tm-sh.h > --- config/sh/tm-sh.h 10 May 2002 23:00:23 -0000 1.18 > +++ config/sh/tm-sh.h 13 May 2002 18:42:26 -0000 > @@ -23,100 +23,6 @@ > > #define GDB_MULTI_ARCH 1 > > -/* Information that is dependent on the processor variant. */ > - > -/* ABI variants that we know about. If you add to this enum, please > - update the table of names in sh-tdep.c. */ > -enum sh_osabi > -{ > - SH_OSABI_UNKNOWN = 0, > - SH_OSABI_LINUX, > - SH_OSABI_NETBSD_ELF, > - > - SH_OSABI_INVALID /* Keep this last. */ > -}; > - > -enum sh_abi > - { > - SH_ABI_UNKNOWN, > - SH_ABI_32, > - SH_ABI_64 > - }; > - > -struct gdbarch_tdep > - { > - int PR_REGNUM; > - int FPUL_REGNUM; /* sh3e, sh4 */ > - int FPSCR_REGNUM; /* sh3e, sh4 */ > - int SR_REGNUM; /* sh-dsp, sh3, sh3-dsp, sh3e, sh4 */ > - int DSR_REGNUM; /* sh-dsp, sh3-dsp */ > - int FP_LAST_REGNUM; /* sh3e, sh4 */ > - int A0G_REGNUM; /* sh-dsp, sh3-dsp */ > - int A0_REGNUM; /* sh-dsp, sh3-dsp */ > - int A1G_REGNUM; /* sh-dsp, sh3-dsp */ > - int A1_REGNUM; /* sh-dsp, sh3-dsp */ > - int M0_REGNUM; /* sh-dsp, sh3-dsp */ > - int M1_REGNUM; /* sh-dsp, sh3-dsp */ > - int X0_REGNUM; /* sh-dsp, sh3-dsp */ > - int X1_REGNUM; /* sh-dsp, sh3-dsp */ > - int Y0_REGNUM; /* sh-dsp, sh3-dsp */ > - int Y1_REGNUM; /* sh-dsp, sh3-dsp */ > - int MOD_REGNUM; /* sh-dsp, sh3-dsp */ > - int SSR_REGNUM; /* sh3, sh3-dsp, sh3e, sh4 */ > - int SPC_REGNUM; /* sh3, sh3-dsp, sh3e, sh4 */ > - int RS_REGNUM; /* sh-dsp, sh3-dsp */ > - int RE_REGNUM; /* sh-dsp, sh3-dsp */ > - int DR0_REGNUM; /* sh4 */ > - int DR_LAST_REGNUM; /* sh4 */ > - int FV0_REGNUM; /* sh4 */ > - int FV_LAST_REGNUM; /* sh4 */ > - /* FPP stands for Floating Point Pair, to avoid confusion with > - GDB's FP0_REGNUM, which is the number of the first Floating > - point register. Unfortunately on the sh5, the floating point > - registers are called FR, and the floating point pairs are called FP. */ > - int TR7_REGNUM; /* sh5-media*/ > - int FPP0_REGNUM; /* sh5-media*/ > - int FPP_LAST_REGNUM; /* sh5-media*/ > - int R0_C_REGNUM; /* sh5-compact*/ > - int R_LAST_C_REGNUM; /* sh5-compact*/ > - int PC_C_REGNUM; /* sh5-compact*/ > - int GBR_C_REGNUM; /* sh5-compact*/ > - int MACH_C_REGNUM; /* sh5-compact*/ > - int MACL_C_REGNUM; /* sh5-compact*/ > - int PR_C_REGNUM; /* sh5-compact*/ > - int T_C_REGNUM; /* sh5-compact*/ > - int FPSCR_C_REGNUM; /* sh5-compact*/ > - int FPUL_C_REGNUM; /* sh5-compact*/ > - int FP0_C_REGNUM; /* sh5-compact*/ > - int FP_LAST_C_REGNUM; /* sh5-compact*/ > - int DR0_C_REGNUM; /* sh5-compact*/ > - int DR_LAST_C_REGNUM; /* sh5-compact*/ > - int FV0_C_REGNUM; /* sh5-compact*/ > - int FV_LAST_C_REGNUM; /* sh5-compact*/ > - int ARG0_REGNUM; > - int ARGLAST_REGNUM; > - int FLOAT_ARGLAST_REGNUM; > - int RETURN_REGNUM; > - enum sh_osabi sh_osabi; /* OS/ABI of the inferior */ > - const char *osabi_name; /* Name of the above */ > - enum sh_abi sh_abi; > - }; > - > -/* Registers common to all the SH variants. */ > -enum > - { > - R0_REGNUM = 0, > - STRUCT_RETURN_REGNUM = 2, > - ARG0_REGNUM = 4, /* Used in h8300-tdep.c */ > - ARGLAST_REGNUM = 7, /* Used in h8300-tdep.c */ > - PR_REGNUM = 17, /* used in sh3-rom.c */ > - GBR_REGNUM = 18, > - VBR_REGNUM = 19, > - MACH_REGNUM = 20, > - MACL_REGNUM = 21, > - SR_REGNUM = 22 > - }; > - > #define NUM_REALREGS 59 /* used in remote-e7000.c which is not multiarched. */ > > #define REGISTER_TYPE long /* used in standalone.c */ > Index: doc/gdbint.texinfo > =================================================================== > RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v > retrieving revision 1.81 > diff -u -r1.81 gdbint.texinfo > --- doc/gdbint.texinfo 4 May 2002 19:57:22 -0000 1.81 > +++ doc/gdbint.texinfo 13 May 2002 18:42:57 -0000 > @@ -2312,6 +2312,58 @@ > @code{struct gdbarch *}. The structure, and its methods, are generated > using the Bourne shell script @file{gdbarch.sh}. > > +@section Operating System ABI Variant Handling > + > +@value{GDBN} provides a mechanism for handling variations in OS > +ABIs. An OS ABI variant may have influence over any number of > +variables in the target architecture definition. There are two major > +components in the OS ABI mechanism: sniffers and handlers. > + > +A sniffer examines a file matching a BFD architecture/flavour pair > +(the architecture may be wildcarded) in an attempt to determine the > +OS ABI of that file. Multiple sniffers for an architecture/flavour > +may exist, in order to differentiate between two different operating > +systems which use the same basic file format. The OS ABI framework > +provides a generic sniffer for ELF-format files which examines the > +@code{EI_OSABI} field of the ELF header, as well as note sections known > +to be used by several operating systems. > + > +A handler is used to fine-tune the @code{gdbarch} structure for the > +selected OS ABI. There may be only one handler for a given OS ABI > +for each BFD architecture. > + > +Here are the functions that make up the OS ABI framework: > + > +@deftypefun const char *gdbarch_osabi_name (enum gdb_osabi @var{osabi}) > +Return the name of the OS ABI corresponding to @var{osabi}. > +@end deftypefun > + > +@deftypefun void gdbarch_register_osabi (enum bfd_architecture @var{arch}, enum gdb_osabi @var{osabi}, void (*@var{init_osabi})(struct gdbarch_info @var{info}, struct gdbarch *@var{gdbarch})) > +Register the OS ABI handler specified by @var{init_osabi} for the > +architecture/OS ABI pair specified by @var{arch} and @var{osabi}. > +@end deftypefun > + > +@deftypefun void gdbarch_register_osabi_sniffer (enum bfd_architecture @var{arch}, enum bfd_flavour @var{flavour}, enum gdb_osabi (*@var{sniffer})(bfd *@var{abfd})) > +Register the OS ABI file sniffer specified by @var{sniffer} for the > +BFD architecture/flavour pair specified by @var{arch} and @var{flavour}. > +If @var{arch} is @code{bfd_arch_unknown}, the sniffer is allowed to examine > +@var{flavour}-flavoured files for any architecture. > +@end deftypefun > + > +@deftypefun enum gdb_osabi gdbarch_lookup_osabi (bfd *@var{abfd}) > +Examine the file described by @var{abfd} to determine its OS ABI. > +The value @code{GDB_OSABI_UNKNOWN} is returned if the OS ABI cannot > +be determined. > +@end deftypefun > + > +@deftypefun void gdbarch_init_osabi (struct gdbarch info @var{info}, struct gdbarch *@var{gdbarch}, enum gdb_osabi @var{osabi}) > +Invoke the OS ABI handler corresponding to @var{osabi} to fine-tune the > +@code{gdbarch} structure specified by @var{gdbarch}. If a handler > +corresponding to @var{osabi} has not been registered or @var{gdbarch}'s > +architecture, a warning will be issued and the debugging session will continue > +with the defaults already established for @var{gdbarch}. > +@end deftypefun > + > @section Registers and Memory > > @value{GDBN}'s model of the target machine is rather simple.