* [PATCH/RFA] Add OS/ABI infrastructure to SuperH target
@ 2002-05-07 1:45 Jason R Thorpe
2002-05-07 8:18 ` Elena Zannoni
0 siblings, 1 reply; 6+ messages in thread
From: Jason R Thorpe @ 2002-05-07 1:45 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 581 bytes --]
The following adds OS/ABI handling a'la the ARM and Alpha targets
to the SuperH target.
Once this is in, I'll be able to commit my NetBSD/sh variant.
OK to commit?
* sh-tdep.c (sh_abi_names): Declare.
(process_note_abi_tag_sections): New function.
(get_elfosabi): Ditto.
(sh_gdbarch_register_os_abi): Ditto.
(sh_dump_tdep): Ditto.
(_initialize_sh_tdep): Use gdbarch_register to register
sh_gdbarch_init and sh_dump_tdep.
* config/sh/tm-sh.h (sh_abi): Declare.
(gdbarch_tdep): Add sh_abi and abi_name members.
--
-- Jason R. Thorpe <thorpej@wasabisystems.com>
[-- Attachment #2: sh-abi-patch --]
[-- Type: text/plain, Size: 9725 bytes --]
Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.52
diff -u -r1.52 sh-tdep.c
--- sh-tdep.c 12 Apr 2002 18:18:57 -0000 1.52
+++ sh-tdep.c 7 May 2002 08:21:59 -0000
@@ -41,6 +41,8 @@
#include "regcache.h"
#include "doublest.h"
+#include "elf-bfd.h"
+
#include "solib-svr4.h"
void (*sh_show_regs) (void);
@@ -1895,6 +1897,182 @@
}
#endif /* SVR4_SHARED_LIBS */
+\f
+/* This table matches the indices assigned to enum sh_abi. Keep
+ them in sync. */
+static const char * const sh_abi_names[] =
+{
+ "<unknown>",
+ "GNU/Linux",
+ "NetBSD ELF",
+ NULL
+};
+
+static void
+process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
+{
+ enum sh_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 = SH_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);
+ }
+ }
+ }
+ /* 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 = SH_ABI_NETBSD_ELF;
+ }
+}
+
+static int
+get_elfosabi (bfd *abfd)
+{
+ int elfosabi;
+ enum sh_abi sh_abi = SH_ABI_UNKNOWN;
+
+ elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
+
+ /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate
+ that 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,
+ &sh_abi);
+ }
+
+ if (sh_abi != SH_ABI_UNKNOWN)
+ return sh_abi;
+
+ switch (elfosabi)
+ {
+ case ELFOSABI_NONE:
+ /* Leave it as unknown. */
+ break;
+
+ case ELFOSABI_NETBSD:
+ return SH_ABI_NETBSD_ELF;
+
+ case ELFOSABI_LINUX:
+ return SH_ABI_LINUX;
+ }
+
+ return SH_ABI_UNKNOWN;
+}
+
+struct sh_abi_handler
+{
+ struct sh_abi_handler *next;
+ enum sh_abi abi;
+ void (*init_abi)(struct gdbarch_info, struct gdbarch *);
+};
+
+struct sh_abi_handler *sh_abi_handler_list = NULL;
+
+void
+sh_gdbarch_register_os_abi (enum sh_abi abi,
+ void (*init_abi)(struct gdbarch_info,
+ struct gdbarch *))
+{
+ struct sh_abi_handler **handler_p;
+
+ for (handler_p = &sh_abi_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_abi = init_abi;
+ return;
+ }
+ }
+
+ (*handler_p)
+ = (struct sh_abi_handler *) xmalloc (sizeof (struct sh_abi_handler));
+ (*handler_p)->next = NULL;
+ (*handler_p)->abi = abi;
+ (*handler_p)->init_abi = init_abi;
+}
+
static gdbarch_init_ftype sh_gdbarch_init;
static struct gdbarch *
@@ -1906,17 +2084,51 @@
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_abi sh_abi = SH_ABI_UNKNOWN;
+ struct sh_abi_handler *abi_handler;
+
+ /* 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_abi = get_elfosabi (info.abfd);
+ break;
+
+ default:
+ /* Just leave it as "unkown". */
+ break;
+ }
+ }
/* Find a candidate among the list of pre-declared architectures. */
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ /* Make sure the ABI selection matches. */
+ tdep = gdbarch_tdep (arches->gdbarch);
+ if (tdep && tdep->sh_abi == sh_abi)
+ return arches->gdbarch;
+ }
/* None found, create a new architecture from the information
provided. */
tdep = XMALLOC (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
+ tdep->sh_abi = sh_abi;
+ if (sh_abi < SH_ABI_INVALID)
+ tdep->abi_name = sh_abi_names[sh_abi];
+ else
+ {
+ internal_error (__FILE__, __LINE__, "Invalid setting of sh_abi %d",
+ (int) sh_abi);
+ tdep->abi_name = "<invalid>";
+ }
+
/* Initialize the register numbers that are not common to all the
variants to -1, if necessary thse will be overwritten in the case
statement below. */
@@ -2167,15 +2379,58 @@
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_abi != SH_ABI_UNKNOWN)
+ {
+ for (abi_handler = sh_abi_handler_list; abi_handler != NULL;
+ abi_handler = abi_handler->next)
+ if (abi_handler->abi == sh_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 SuperH settings",
+ sh_abi_names[sh_abi]);
+ }
+ }
+
return gdbarch;
}
+static void
+sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (tdep == NULL)
+ return;
+
+ if (tdep->abi_name != NULL)
+ fprintf_unfiltered (file, "sh_dump_tdep: ABI = %s\n", tdep->abi_name);
+ else
+ internal_error (__FILE__, __LINE__,
+ "sh_dump_tdep: illegal setting of tdep->sh_abi (%d)",
+ (int) tdep->sh_abi);
+}
+
void
_initialize_sh_tdep (void)
{
struct cmd_list_element *c;
- register_gdbarch_init (bfd_arch_sh, sh_gdbarch_init);
+ gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep);
add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
}
Index: config/sh/tm-sh.h
===================================================================
RCS file: /cvs/src/src/gdb/config/sh/tm-sh.h,v
retrieving revision 1.16
diff -u -r1.16 tm-sh.h
--- config/sh/tm-sh.h 12 Jul 2001 02:29:33 -0000 1.16
+++ config/sh/tm-sh.h 7 May 2002 08:22:00 -0000
@@ -23,6 +23,17 @@
#define GDB_MULTI_ARCH 1
+/* ABI variants that we know about. If you add to this enum, please
+ update the table of names in sh-tdep.c. */
+enum sh_abi
+{
+ SH_ABI_UNKNOWN = 0,
+ SH_ABI_LINUX,
+ SH_ABI_NETBSD_ELF,
+
+ SH_ABI_INVALID /* Keep this last. */
+};
+
/* Information that is dependent on the processor variant. */
struct gdbarch_tdep
@@ -56,6 +67,9 @@
int ARGLAST_REGNUM;
int FLOAT_ARGLAST_REGNUM;
int RETURN_REGNUM;
+
+ enum sh_abi sh_abi; /* OS/ABI of the inferior */
+ const char *abi_name; /* Name of the above */
};
/* Registers common to all the SH variants. */
@@ -81,4 +95,3 @@
#define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */
/*#define NOP {0x20, 0x0b}*/ /* Who uses this???*/
-
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH/RFA] Add OS/ABI infrastructure to SuperH target 2002-05-07 1:45 [PATCH/RFA] Add OS/ABI infrastructure to SuperH target Jason R Thorpe @ 2002-05-07 8:18 ` Elena Zannoni 2002-05-07 9:29 ` Jason R Thorpe 2002-05-07 13:31 ` Jason R Thorpe 0 siblings, 2 replies; 6+ messages in thread From: Elena Zannoni @ 2002-05-07 8:18 UTC (permalink / raw) To: thorpej; +Cc: gdb-patches Jason R Thorpe writes: > The following adds OS/ABI handling a'la the ARM and Alpha targets > to the SuperH target. > > Once this is in, I'll be able to commit my NetBSD/sh variant. > > OK to commit? > > * sh-tdep.c (sh_abi_names): Declare. > (process_note_abi_tag_sections): New function. > (get_elfosabi): Ditto. > (sh_gdbarch_register_os_abi): Ditto. > (sh_dump_tdep): Ditto. > (_initialize_sh_tdep): Use gdbarch_register to register > sh_gdbarch_init and sh_dump_tdep. > * config/sh/tm-sh.h (sh_abi): Declare. > (gdbarch_tdep): Add sh_abi and abi_name members. > Ah, great! But hmmm...it would be ok, except that I am afraid there may be some conflict with the sh5 work. In there I defined: enum sh_abi { SH_ABI_UNKNOWN, SH_ABI_32, SH_ABI_64 }; The ABI is unknown for all the architectures except for sh5 where it is set to either 32 or 64 depending on the bfd. I am not saying this is completely correct, note. Is there any chance you could take a look at the sh5 patch I posted a while back, and see if/how your patch integrates (in principle, at least)? The patch is here: http://sources.redhat.com/ml/gdb-patches/2002-02/msg00218.html About your patch, I would prefer if the switch on the os_number used names instead of 0,1,2, is this possible? Same for this line: + if (elfosabi == 0) thanks Elena > -- > -- Jason R. Thorpe <thorpej@wasabisystems.com> > Index: sh-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/sh-tdep.c,v > retrieving revision 1.52 > diff -u -r1.52 sh-tdep.c > --- sh-tdep.c 12 Apr 2002 18:18:57 -0000 1.52 > +++ sh-tdep.c 7 May 2002 08:21:59 -0000 > @@ -41,6 +41,8 @@ > #include "regcache.h" > #include "doublest.h" > > +#include "elf-bfd.h" > + > #include "solib-svr4.h" > > void (*sh_show_regs) (void); > @@ -1895,6 +1897,182 @@ > } > #endif /* SVR4_SHARED_LIBS */ > > +\f > +/* This table matches the indices assigned to enum sh_abi. Keep > + them in sync. */ > +static const char * const sh_abi_names[] = > +{ > + "<unknown>", > + "GNU/Linux", > + "NetBSD ELF", > + NULL > +}; > + > +static void > +process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj) > +{ > + enum sh_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 = SH_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); > + } > + } > + } > + /* 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 = SH_ABI_NETBSD_ELF; > + } > +} > + > +static int > +get_elfosabi (bfd *abfd) > +{ > + int elfosabi; > + enum sh_abi sh_abi = SH_ABI_UNKNOWN; > + > + elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; > + > + /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate > + that 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, > + &sh_abi); > + } > + > + if (sh_abi != SH_ABI_UNKNOWN) > + return sh_abi; > + > + switch (elfosabi) > + { > + case ELFOSABI_NONE: > + /* Leave it as unknown. */ > + break; > + > + case ELFOSABI_NETBSD: > + return SH_ABI_NETBSD_ELF; > + > + case ELFOSABI_LINUX: > + return SH_ABI_LINUX; > + } > + > + return SH_ABI_UNKNOWN; > +} > + > +struct sh_abi_handler > +{ > + struct sh_abi_handler *next; > + enum sh_abi abi; > + void (*init_abi)(struct gdbarch_info, struct gdbarch *); > +}; > + > +struct sh_abi_handler *sh_abi_handler_list = NULL; > + > +void > +sh_gdbarch_register_os_abi (enum sh_abi abi, > + void (*init_abi)(struct gdbarch_info, > + struct gdbarch *)) > +{ > + struct sh_abi_handler **handler_p; > + > + for (handler_p = &sh_abi_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_abi = init_abi; > + return; > + } > + } > + > + (*handler_p) > + = (struct sh_abi_handler *) xmalloc (sizeof (struct sh_abi_handler)); > + (*handler_p)->next = NULL; > + (*handler_p)->abi = abi; > + (*handler_p)->init_abi = init_abi; > +} > + > static gdbarch_init_ftype sh_gdbarch_init; > > static struct gdbarch * > @@ -1906,17 +2084,51 @@ > 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_abi sh_abi = SH_ABI_UNKNOWN; > + struct sh_abi_handler *abi_handler; > + > + /* 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_abi = get_elfosabi (info.abfd); > + break; > + > + default: > + /* Just leave it as "unkown". */ > + break; > + } > + } > > /* Find a candidate among the list of pre-declared architectures. */ > - arches = gdbarch_list_lookup_by_info (arches, &info); > - if (arches != NULL) > - return arches->gdbarch; > + for (arches = gdbarch_list_lookup_by_info (arches, &info); > + arches != NULL; > + arches = gdbarch_list_lookup_by_info (arches->next, &info)) > + { > + /* Make sure the ABI selection matches. */ > + tdep = gdbarch_tdep (arches->gdbarch); > + if (tdep && tdep->sh_abi == sh_abi) > + return arches->gdbarch; > + } > > /* None found, create a new architecture from the information > provided. */ > tdep = XMALLOC (struct gdbarch_tdep); > gdbarch = gdbarch_alloc (&info, tdep); > > + tdep->sh_abi = sh_abi; > + if (sh_abi < SH_ABI_INVALID) > + tdep->abi_name = sh_abi_names[sh_abi]; > + else > + { > + internal_error (__FILE__, __LINE__, "Invalid setting of sh_abi %d", > + (int) sh_abi); > + tdep->abi_name = "<invalid>"; > + } > + > /* Initialize the register numbers that are not common to all the > variants to -1, if necessary thse will be overwritten in the case > statement below. */ > @@ -2167,15 +2379,58 @@ > 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_abi != SH_ABI_UNKNOWN) > + { > + for (abi_handler = sh_abi_handler_list; abi_handler != NULL; > + abi_handler = abi_handler->next) > + if (abi_handler->abi == sh_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 SuperH settings", > + sh_abi_names[sh_abi]); > + } > + } > + > return gdbarch; > } > > +static void > +sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) > +{ > + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > + > + if (tdep == NULL) > + return; > + > + if (tdep->abi_name != NULL) > + fprintf_unfiltered (file, "sh_dump_tdep: ABI = %s\n", tdep->abi_name); > + else > + internal_error (__FILE__, __LINE__, > + "sh_dump_tdep: illegal setting of tdep->sh_abi (%d)", > + (int) tdep->sh_abi); > +} > + > void > _initialize_sh_tdep (void) > { > struct cmd_list_element *c; > > - register_gdbarch_init (bfd_arch_sh, sh_gdbarch_init); > + gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep); > > add_com ("regs", class_vars, sh_show_regs_command, "Print all registers"); > } > Index: config/sh/tm-sh.h > =================================================================== > RCS file: /cvs/src/src/gdb/config/sh/tm-sh.h,v > retrieving revision 1.16 > diff -u -r1.16 tm-sh.h > --- config/sh/tm-sh.h 12 Jul 2001 02:29:33 -0000 1.16 > +++ config/sh/tm-sh.h 7 May 2002 08:22:00 -0000 > @@ -23,6 +23,17 @@ > > #define GDB_MULTI_ARCH 1 > > +/* ABI variants that we know about. If you add to this enum, please > + update the table of names in sh-tdep.c. */ > +enum sh_abi > +{ > + SH_ABI_UNKNOWN = 0, > + SH_ABI_LINUX, > + SH_ABI_NETBSD_ELF, > + > + SH_ABI_INVALID /* Keep this last. */ > +}; > + > /* Information that is dependent on the processor variant. */ > > struct gdbarch_tdep > @@ -56,6 +67,9 @@ > int ARGLAST_REGNUM; > int FLOAT_ARGLAST_REGNUM; > int RETURN_REGNUM; > + > + enum sh_abi sh_abi; /* OS/ABI of the inferior */ > + const char *abi_name; /* Name of the above */ > }; > > /* Registers common to all the SH variants. */ > @@ -81,4 +95,3 @@ > #define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */ > > /*#define NOP {0x20, 0x0b}*/ /* Who uses this???*/ > - ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH/RFA] Add OS/ABI infrastructure to SuperH target 2002-05-07 8:18 ` Elena Zannoni @ 2002-05-07 9:29 ` Jason R Thorpe 2002-05-07 13:31 ` Jason R Thorpe 1 sibling, 0 replies; 6+ messages in thread From: Jason R Thorpe @ 2002-05-07 9:29 UTC (permalink / raw) To: Elena Zannoni; +Cc: gdb-patches On Tue, May 07, 2002 at 11:18:01AM -0400, Elena Zannoni wrote: > The ABI is unknown for all the architectures except for sh5 where it > is set to either 32 or 64 depending on the bfd. I am not saying this > is completely correct, note. Hm. Well, I'm happy to change the OS/ABI stuff to "sh_osabi". Might be more appropriate, anyway (eventually, I want to make the osabi stuff generic and plop it into a common file). > Is there any chance you could take a look at the sh5 patch I posted a > while back, and see if/how your patch integrates (in principle, at least)? > The patch is here: > http://sources.redhat.com/ml/gdb-patches/2002-02/msg00218.html Yah, I'll peek at it in a couple of hours. > About your patch, I would prefer if the switch on the os_number used > names instead of 0,1,2, is this possible? Same for this line: > + if (elfosabi == 0) Hm, are there manifest constants defined in our header files for the GNU OS numbers? Heh, if not, I guess it wouldn't be hard to add them :-) Anyway, I'll tweak this in a bit and re-post. -- -- Jason R. Thorpe <thorpej@wasabisystems.com> ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH/RFA] Add OS/ABI infrastructure to SuperH target 2002-05-07 8:18 ` Elena Zannoni 2002-05-07 9:29 ` Jason R Thorpe @ 2002-05-07 13:31 ` Jason R Thorpe 2002-05-07 13:35 ` Elena Zannoni 1 sibling, 1 reply; 6+ messages in thread From: Jason R Thorpe @ 2002-05-07 13:31 UTC (permalink / raw) To: Elena Zannoni; +Cc: gdb-patches [-- Attachment #1: Type: text/plain, Size: 1367 bytes --] On Tue, May 07, 2002 at 11:18:01AM -0400, Elena Zannoni wrote: > Is there any chance you could take a look at the sh5 patch I posted a > while back, and see if/how your patch integrates (in principle, at least)? > The patch is here: > http://sources.redhat.com/ml/gdb-patches/2002-02/msg00218.html I looked over this patch -- with my rename of "sh_abi" to "sh_osabi", I don't really see any conflict (SHcompact vs. SHmedia [32 vs 64] seems orthogonal to OS ABI variations -- sort of like ARM vs. Thumb and Linux vs. NetBSD). > About your patch, I would prefer if the switch on the os_number used > names instead of 0,1,2, is this possible? Same for this line: > + if (elfosabi == 0) ...also made these suggested changes, and submitted the patch that defines the constants to binutils for approval (err, did I follow protocol correctly in doing so?) Anyway, updated patch attached. OK to commit once the elf/common.h patch goes in? * sh-tdep.c (sh_osabi_names): Declare. (process_note_abi_tag_sections): New function. (get_elfosabi): Ditto. (sh_gdbarch_register_os_abi): Ditto. (sh_dump_tdep): Ditto. _initialize_sh_tdep): Use gdbarch_register to register sh_gdbarch_init and sh_dump_tdep. * config/sh/tm-sh.h (sh_osabi): Declare. (gdbarch_tdep): Add sh_osabi and osabi_name members. -- -- Jason R. Thorpe <thorpej@wasabisystems.com> [-- Attachment #2: sh-abi-patch --] [-- Type: text/plain, Size: 9843 bytes --] Index: sh-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/sh-tdep.c,v retrieving revision 1.52 diff -u -r1.52 sh-tdep.c --- sh-tdep.c 12 Apr 2002 18:18:57 -0000 1.52 +++ sh-tdep.c 7 May 2002 20:19:36 -0000 @@ -41,6 +41,8 @@ #include "regcache.h" #include "doublest.h" +#include "elf-bfd.h" + #include "solib-svr4.h" void (*sh_show_regs) (void); @@ -1895,6 +1897,176 @@ } #endif /* SVR4_SHARED_LIBS */ +\f +/* This table matches the indices assigned to enum sh_osabi. Keep + them in sync. */ +static const char * const sh_osabi_names[] = +{ + "<unknown>", + "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 * @@ -1906,17 +2078,51 @@ 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; + + /* 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; + } + } /* Find a candidate among the list of pre-declared architectures. */ - arches = gdbarch_list_lookup_by_info (arches, &info); - if (arches != NULL) - return arches->gdbarch; + for (arches = gdbarch_list_lookup_by_info (arches, &info); + arches != NULL; + arches = gdbarch_list_lookup_by_info (arches->next, &info)) + { + /* Make sure the ABI selection matches. */ + tdep = gdbarch_tdep (arches->gdbarch); + if (tdep && tdep->sh_osabi == sh_osabi) + return arches->gdbarch; + } /* None found, create a new architecture from the information provided. */ 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 = "<invalid>"; + } + /* Initialize the register numbers that are not common to all the variants to -1, if necessary thse will be overwritten in the case statement below. */ @@ -2167,15 +2373,58 @@ 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; + + 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]); + } + } + return gdbarch; } +static void +sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (tdep == NULL) + return; + + if (tdep->osabi_name != NULL) + fprintf_unfiltered (file, "sh_dump_tdep: 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); +} + void _initialize_sh_tdep (void) { struct cmd_list_element *c; - register_gdbarch_init (bfd_arch_sh, sh_gdbarch_init); + gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep); add_com ("regs", class_vars, sh_show_regs_command, "Print all registers"); } Index: config/sh/tm-sh.h =================================================================== RCS file: /cvs/src/src/gdb/config/sh/tm-sh.h,v retrieving revision 1.16 diff -u -r1.16 tm-sh.h --- config/sh/tm-sh.h 12 Jul 2001 02:29:33 -0000 1.16 +++ config/sh/tm-sh.h 7 May 2002 20:19:36 -0000 @@ -23,6 +23,17 @@ #define GDB_MULTI_ARCH 1 +/* 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. */ +}; + /* Information that is dependent on the processor variant. */ struct gdbarch_tdep @@ -56,6 +67,9 @@ 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 */ }; /* Registers common to all the SH variants. */ @@ -81,4 +95,3 @@ #define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */ /*#define NOP {0x20, 0x0b}*/ /* Who uses this???*/ - ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH/RFA] Add OS/ABI infrastructure to SuperH target 2002-05-07 13:31 ` Jason R Thorpe @ 2002-05-07 13:35 ` Elena Zannoni 2002-05-08 7:54 ` Jason R Thorpe 0 siblings, 1 reply; 6+ messages in thread From: Elena Zannoni @ 2002-05-07 13:35 UTC (permalink / raw) To: thorpej; +Cc: Elena Zannoni, gdb-patches Jason R Thorpe writes: > On Tue, May 07, 2002 at 11:18:01AM -0400, Elena Zannoni wrote: > > > Is there any chance you could take a look at the sh5 patch I posted a > > while back, and see if/how your patch integrates (in principle, at least)? > > The patch is here: > > http://sources.redhat.com/ml/gdb-patches/2002-02/msg00218.html > > I looked over this patch -- with my rename of "sh_abi" to "sh_osabi", I > don't really see any conflict (SHcompact vs. SHmedia [32 vs 64] seems > orthogonal to OS ABI variations -- sort of like ARM vs. Thumb and Linux > vs. NetBSD). > Cool, thanks. > > About your patch, I would prefer if the switch on the os_number used > > names instead of 0,1,2, is this possible? Same for this line: > > + if (elfosabi == 0) > > ...also made these suggested changes, and submitted the patch that defines > the constants to binutils for approval (err, did I follow protocol correctly > in doing so?) > Yes, I think so. > Anyway, updated patch attached. OK to commit once the elf/common.h patch > goes in? > Sure, thanks. Elena > * sh-tdep.c (sh_osabi_names): Declare. > (process_note_abi_tag_sections): New function. > (get_elfosabi): Ditto. > (sh_gdbarch_register_os_abi): Ditto. > (sh_dump_tdep): Ditto. > _initialize_sh_tdep): Use gdbarch_register to register > sh_gdbarch_init and sh_dump_tdep. > * config/sh/tm-sh.h (sh_osabi): Declare. > (gdbarch_tdep): Add sh_osabi and osabi_name members. > > -- > -- Jason R. Thorpe <thorpej@wasabisystems.com> > Index: sh-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/sh-tdep.c,v > retrieving revision 1.52 > diff -u -r1.52 sh-tdep.c > --- sh-tdep.c 12 Apr 2002 18:18:57 -0000 1.52 > +++ sh-tdep.c 7 May 2002 20:19:36 -0000 > @@ -41,6 +41,8 @@ > #include "regcache.h" > #include "doublest.h" > > +#include "elf-bfd.h" > + > #include "solib-svr4.h" > > void (*sh_show_regs) (void); > @@ -1895,6 +1897,176 @@ > } > #endif /* SVR4_SHARED_LIBS */ > > +\f > +/* This table matches the indices assigned to enum sh_osabi. Keep > + them in sync. */ > +static const char * const sh_osabi_names[] = > +{ > + "<unknown>", > + "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 * > @@ -1906,17 +2078,51 @@ > 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; > + > + /* 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; > + } > + } > > /* Find a candidate among the list of pre-declared architectures. */ > - arches = gdbarch_list_lookup_by_info (arches, &info); > - if (arches != NULL) > - return arches->gdbarch; > + for (arches = gdbarch_list_lookup_by_info (arches, &info); > + arches != NULL; > + arches = gdbarch_list_lookup_by_info (arches->next, &info)) > + { > + /* Make sure the ABI selection matches. */ > + tdep = gdbarch_tdep (arches->gdbarch); > + if (tdep && tdep->sh_osabi == sh_osabi) > + return arches->gdbarch; > + } > > /* None found, create a new architecture from the information > provided. */ > 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 = "<invalid>"; > + } > + > /* Initialize the register numbers that are not common to all the > variants to -1, if necessary thse will be overwritten in the case > statement below. */ > @@ -2167,15 +2373,58 @@ > 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; > + > + 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]); > + } > + } > + > return gdbarch; > } > > +static void > +sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) > +{ > + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > + > + if (tdep == NULL) > + return; > + > + if (tdep->osabi_name != NULL) > + fprintf_unfiltered (file, "sh_dump_tdep: 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); > +} > + > void > _initialize_sh_tdep (void) > { > struct cmd_list_element *c; > > - register_gdbarch_init (bfd_arch_sh, sh_gdbarch_init); > + gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep); > > add_com ("regs", class_vars, sh_show_regs_command, "Print all registers"); > } > Index: config/sh/tm-sh.h > =================================================================== > RCS file: /cvs/src/src/gdb/config/sh/tm-sh.h,v > retrieving revision 1.16 > diff -u -r1.16 tm-sh.h > --- config/sh/tm-sh.h 12 Jul 2001 02:29:33 -0000 1.16 > +++ config/sh/tm-sh.h 7 May 2002 20:19:36 -0000 > @@ -23,6 +23,17 @@ > > #define GDB_MULTI_ARCH 1 > > +/* 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. */ > +}; > + > /* Information that is dependent on the processor variant. */ > > struct gdbarch_tdep > @@ -56,6 +67,9 @@ > 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 */ > }; > > /* Registers common to all the SH variants. */ > @@ -81,4 +95,3 @@ > #define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */ > > /*#define NOP {0x20, 0x0b}*/ /* Who uses this???*/ > - ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH/RFA] Add OS/ABI infrastructure to SuperH target 2002-05-07 13:35 ` Elena Zannoni @ 2002-05-08 7:54 ` Jason R Thorpe 0 siblings, 0 replies; 6+ messages in thread From: Jason R Thorpe @ 2002-05-08 7:54 UTC (permalink / raw) To: Elena Zannoni; +Cc: gdb-patches On Tue, May 07, 2002 at 04:35:17PM -0400, Elena Zannoni wrote: > > Anyway, updated patch attached. OK to commit once the elf/common.h patch > > goes in? > > > > Sure, > thanks. Ok, it's in. Thanks for the feedback! -- -- Jason R. Thorpe <thorpej@wasabisystems.com> ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2002-05-08 14:54 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-05-07 1:45 [PATCH/RFA] Add OS/ABI infrastructure to SuperH target Jason R Thorpe 2002-05-07 8:18 ` Elena Zannoni 2002-05-07 9:29 ` Jason R Thorpe 2002-05-07 13:31 ` Jason R Thorpe 2002-05-07 13:35 ` Elena Zannoni 2002-05-08 7:54 ` Jason R Thorpe
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox