* Makefile.in (SFILES): Add osabi.c.
(COMMON_OBS): Add osabi.o. (osabi.o): New dependency list. * osabi.c: New file. * osabi.h: New file. * doc/gdbint.texinfo: Document new generic OS ABI framework. * Makefile.in (alpha_tdep_h): Define and use instead of alpha-tdep.h. * 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: Include osabi.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. * Makefile.in (sh_tdep_h): Add osabi.h. * sh-tdep.h (sh_osabi): Remove. (gdbarch_tdep): Use generic OS ABI framework. * sh-tdep.c (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. * shnbsd-tdep.c (_initialize_shnbsd_tdep): Use gdbarch_register_osabi. * Makefile.in (arm_tdep_h): Define and use instead of arm-tdep.h. * arm-linux-tdep.c (_initialize_arm_linux_tdep): Use gdbarch_register_osabi. * arm-tdep.c (arm_abi_names, process_note_abi_tag_sections, arm_abi_handler_list, arm_gdbarch_register_os_abi): Remove. (get_elfosabi): Rename to... (arm_elf_osabi_sniffer): ...this. Adjust to use generic OS ABI framework support routines. (arm_gdbarch_init): Use generic OS ABI framework. (arm_dump_tdep): Likewise. (_initialize_arm_tdep): Likewise. * arm-tdep.h: Include osabi.h. (arm_abi): Remove. (gdbarch_tdep): Remove arm_abi and abi_name members. Add osabi member. (arm_gdbarch_register_os_abi): Remove prototype. * armnbsd-tdep.c (arm_netbsd_aout_osabi_sniffer): New function. (_initialize_arm_netbsd_tdep): Use gdbarch_register_osabi. * Makefile.in (mips-tdep.o): Add osabi.h to dependency list. * mips-tdep.c: Include osabi.h. (gdbarch_tdep, mips_gdbarch_init, mips_dump_tdep): Use generic OS ABI framework.
This commit is contained in:
parent
658f25883a
commit
70f80edf7c
|
@ -1,3 +1,59 @@
|
|||
2002-05-21 Jason Thorpe <thorpej@wasabisystems.com>
|
||||
|
||||
* Makefile.in (SFILES): Add osabi.c.
|
||||
(COMMON_OBS): Add osabi.o.
|
||||
(osabi.o): New dependency list.
|
||||
* osabi.c: New file.
|
||||
* osabi.h: New file.
|
||||
* doc/gdbint.texinfo: Document new generic OS ABI framework.
|
||||
|
||||
* Makefile.in (alpha_tdep_h): Define and use instead of
|
||||
alpha-tdep.h.
|
||||
* 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: Include osabi.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.
|
||||
|
||||
* Makefile.in (sh_tdep_h): Add osabi.h.
|
||||
* sh-tdep.h (sh_osabi): Remove.
|
||||
(gdbarch_tdep): Use generic OS ABI framework.
|
||||
* sh-tdep.c (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.
|
||||
* shnbsd-tdep.c (_initialize_shnbsd_tdep): Use gdbarch_register_osabi.
|
||||
|
||||
* Makefile.in (arm_tdep_h): Define and use instead of arm-tdep.h.
|
||||
* arm-linux-tdep.c (_initialize_arm_linux_tdep): Use
|
||||
gdbarch_register_osabi.
|
||||
* arm-tdep.c (arm_abi_names, process_note_abi_tag_sections,
|
||||
arm_abi_handler_list, arm_gdbarch_register_os_abi): Remove.
|
||||
(get_elfosabi): Rename to...
|
||||
(arm_elf_osabi_sniffer): ...this. Adjust to use generic OS
|
||||
ABI framework support routines.
|
||||
(arm_gdbarch_init): Use generic OS ABI framework.
|
||||
(arm_dump_tdep): Likewise.
|
||||
(_initialize_arm_tdep): Likewise.
|
||||
* arm-tdep.h: Include osabi.h.
|
||||
(arm_abi): Remove.
|
||||
(gdbarch_tdep): Remove arm_abi and abi_name members. Add
|
||||
osabi member.
|
||||
(arm_gdbarch_register_os_abi): Remove prototype.
|
||||
* armnbsd-tdep.c (arm_netbsd_aout_osabi_sniffer): New function.
|
||||
(_initialize_arm_netbsd_tdep): Use gdbarch_register_osabi.
|
||||
|
||||
* Makefile.in (mips-tdep.o): Add osabi.h to dependency list.
|
||||
* mips-tdep.c: Include osabi.h.
|
||||
(gdbarch_tdep, mips_gdbarch_init, mips_dump_tdep): Use generic
|
||||
OS ABI framework.
|
||||
|
||||
2002-05-20 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* h8300-tdep.c: Fix formatting.
|
||||
|
|
|
@ -530,7 +530,7 @@ SFILES = ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \
|
|||
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 \
|
||||
|
@ -593,8 +593,10 @@ xm_h = @xm_h@
|
|||
tm_h = @tm_h@
|
||||
nm_h = @nm_h@
|
||||
|
||||
alpha_tdep_h = alpha-tdep.h osabi.h
|
||||
annotate_h = annotate.h $(symtab_h) $(gdbtypes_h)
|
||||
arch_utils_h = arch-utils.h
|
||||
arm_tdep_h = arm-tdep.h osabi.h
|
||||
ax_h = ax.h $(doublest_h)
|
||||
bcache_h = bcache.h
|
||||
builtin_regs_h = builtin-regs.h
|
||||
|
@ -649,7 +651,7 @@ remote_h = remote.h
|
|||
remote_utils_h = remote-utils.h $(target_h)
|
||||
ser_unix_h = ser-unix.h
|
||||
serial_h = serial.h
|
||||
sh_tdep_h = sh-tdep.h
|
||||
sh_tdep_h = sh-tdep.h osabi.h
|
||||
solist_h = solist.h
|
||||
source_h = source.h
|
||||
stabsread_h = stabsread.h
|
||||
|
@ -724,7 +726,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
|
|||
expprint.o environ.o stack.o thread.o \
|
||||
macrotab.o macrocmd.o macroexp.o macroscope.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 \
|
||||
|
@ -1256,44 +1258,44 @@ a68v-nat.o: a68v-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) \
|
|||
$(regcache_h)
|
||||
|
||||
alpha-nat.o: alpha-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) $(target_h) \
|
||||
$(regcache_h) alpha-tdep.h
|
||||
$(regcache_h) $(alpha_tdep_h)
|
||||
|
||||
alphabsd-nat.o: alphabsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
|
||||
alpha-tdep.h alphabsd-tdep.h
|
||||
$(alpha_tdep_h) alphabsd-tdep.h
|
||||
|
||||
alpha-tdep.o: alpha-tdep.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
|
||||
$(inferior_h) $(symtab_h) $(dis_asm_h) $(gdb_string_h) $(linespec_h) \
|
||||
$(regcache_h) $(doublest_h) $(BFD_SRC)/elf-bfd.h alpha-tdep.h
|
||||
$(regcache_h) $(doublest_h) $(BFD_SRC)/elf-bfd.h $(alpha_tdep_h)
|
||||
|
||||
alpha-linux-tdep.o: alpha-linux-tdep.c $(defs_h) $(value_h) alpha-tdep.h
|
||||
alpha-linux-tdep.o: alpha-linux-tdep.c $(defs_h) $(value_h) $(alpha_tdep_h)
|
||||
|
||||
alpha-osf1-tdep.o: alpha-osf1-tdep.c $(defs_h) $(value_h) alpha-tdep.h
|
||||
alpha-osf1-tdep.o: alpha-osf1-tdep.c $(defs_h) $(value_h) $(alpha_tdep_h)
|
||||
|
||||
alphabsd-tdep.o: alphabsd-tdep.c $(defs_h) $(regcache_h) alphabsd-tdep.h
|
||||
|
||||
alphafbsd-tdep.o: alphafbsd-tdep.c $(defs_h) $(value_h) alpha-tdep.h
|
||||
alphafbsd-tdep.o: alphafbsd-tdep.c $(defs_h) $(value_h) $(alpha_tdep_h)
|
||||
|
||||
alphanbsd-tdep.o: alphanbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \
|
||||
$(value_h) alpha-tdep.h alphabsd-tdep.h nbsd-tdep.h
|
||||
$(value_h) $(alpha_tdep_h) alphabsd-tdep.h nbsd-tdep.h
|
||||
|
||||
annotate.o: annotate.c $(defs_h) $(annotate_h) $(value_h) $(target_h) $(gdbtypes_h)
|
||||
|
||||
arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
|
||||
$(gdb_string_h) $(regcache_h) arm-tdep.h
|
||||
$(gdb_string_h) $(regcache_h) $(arm_tdep_h)
|
||||
|
||||
arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \
|
||||
$(gdbtypes_h) $(floatformat_h) $(regcache_h) $(doublest_h) arm-tdep.h
|
||||
$(gdbtypes_h) $(floatformat_h) $(regcache_h) $(doublest_h) $(arm_tdep_h)
|
||||
|
||||
arm-tdep.o: arm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(gdbcmd_h) \
|
||||
$(gdbcore_h) $(gdb_string_h) $(dis_asm_h) $(regcache_h) $(doublest_h) \
|
||||
$(value_h) $(arch_utils_h) $(solib_svr4_h) arm-tdep.h \
|
||||
$(value_h) $(arch_utils_h) $(solib_svr4_h) $(arm_tdep_h) \
|
||||
$(BFD_SRC)/elf-bfd.h $(INCLUDE_DIR)/coff/internal.h \
|
||||
$(INCLUDE_DIR)/elf/arm.h
|
||||
|
||||
armnbsd-nat.o: armnbsd-nat.c $(defs_h) arm-tdep.h $(inferior_h) $(regcache_h) \
|
||||
$(gdbcore_h)
|
||||
armnbsd-nat.o: armnbsd-nat.c $(defs_h) $(arm_tdep_h) $(inferior_h) \
|
||||
$(regcache_h) $(gdbcore_h)
|
||||
|
||||
armnbsd-tdep.o: armnbsd-tdep.c $(defs_h) arm-tdep.h
|
||||
armnbsd-tdep.o: armnbsd-tdep.c $(defs_h) $(arm_tdep_h)
|
||||
|
||||
avr-tdep.o: avr-tdep.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) $(inferior_h) \
|
||||
$(symfile_h) $(regcache_h) $(arch_utils_h)
|
||||
|
@ -1585,6 +1587,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)
|
||||
|
||||
|
@ -1811,7 +1815,8 @@ mips-nat.o: mips-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) $(regcache_h)
|
|||
|
||||
mips-tdep.o: mips-tdep.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
|
||||
$(arch_utils_h) $(regcache_h) \
|
||||
$(inferior_h) $(language_h) $(objfiles_h) $(symfile_h) $(gdb_string_h)
|
||||
$(inferior_h) $(language_h) $(objfiles_h) $(symfile_h) \
|
||||
$(gdb_string_h) osabi.h
|
||||
|
||||
mipsread.o: mipsread.c $(buildsym_h) $(complaints_h) $(bfd_h) $(defs_h) \
|
||||
$(expression_h) $(gdb_stabs_h) $(gdbcore_h) $(gdbtypes_h) \
|
||||
|
@ -1933,7 +1938,7 @@ remote-array.o: remote-array.c $(defs_h) $(gdbcore_h) $(target_h) \
|
|||
$(version_h) $(regcache_h)
|
||||
|
||||
remote-rdi.o: remote-rdi.c $(defs_h) $(gdbcore_h) \
|
||||
$(inferior_h) $(gdb_string_h) $(completer_h) arm-tdep.h
|
||||
$(inferior_h) $(gdb_string_h) $(completer_h) $(arm_tdep_h)
|
||||
|
||||
rdi-share/libangsd.a: force
|
||||
@dir=rdi-share; \
|
||||
|
@ -1946,7 +1951,7 @@ rdi-share/libangsd.a: force
|
|||
fi
|
||||
|
||||
remote-rdp.o: remote-rdp.c $(defs_h) $(gdbcore_h) \
|
||||
$(inferior_h) $(gdb_string_h) arm-tdep.h
|
||||
$(inferior_h) $(gdb_string_h) $(arm_tdep_h)
|
||||
|
||||
remote-bug.o: remote-bug.c $(defs_h) $(gdbcore_h) $(serial_h) \
|
||||
$(inferior_h) $(target_h) $(terminal_h) $(remote_utils_h) \
|
||||
|
|
|
@ -116,5 +116,6 @@ alpha_linux_init_abi (struct gdbarch_info info,
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -69,5 +69,5 @@ alpha_osf1_init_abi (struct gdbarch_info info,
|
|||
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);
|
||||
}
|
||||
|
|
254
gdb/alpha-tdep.c
254
gdb/alpha-tdep.c
|
@ -1766,186 +1766,6 @@ alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
|
|||
}
|
||||
|
||||
|
||||
/* This table matches the indices assigned to enum alpha_abi. Keep
|
||||
them in sync. */
|
||||
static const char * const alpha_abi_names[] =
|
||||
{
|
||||
"<unknown>",
|
||||
"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 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
{
|
||||
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 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
{
|
||||
/* 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 = "<invalid>";
|
||||
}
|
||||
tdep->osabi = osabi;
|
||||
|
||||
/* Lowest text address. This is used by heuristic_proc_start() to
|
||||
decide when to stop looking. */
|
||||
|
@ -2122,38 +1925,7 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
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 @@ alpha_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
|
|||
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",
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#ifndef ALPHA_TDEP_H
|
||||
#define ALPHA_TDEP_H
|
||||
|
||||
#include "osabi.h"
|
||||
|
||||
/* Say how long (ordinary) registers are. This is a piece of bogosity
|
||||
used in push_word and a few other places; REGISTER_RAW_SIZE is the
|
||||
real way to know how big a register is. */
|
||||
|
@ -76,24 +78,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 */
|
||||
|
||||
|
@ -118,8 +106,4 @@ struct gdbarch_tdep
|
|||
|
||||
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 */
|
||||
|
|
|
@ -78,5 +78,6 @@ alphafbsd_init_abi (struct gdbarch_info info,
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -203,7 +203,8 @@ alphanbsd_init_abi (struct gdbarch_info info,
|
|||
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);
|
||||
|
|
|
@ -543,5 +543,5 @@ arm_linux_init_abi (struct gdbarch_info info,
|
|||
void
|
||||
_initialize_arm_linux_tdep (void)
|
||||
{
|
||||
arm_gdbarch_register_os_abi (ARM_ABI_LINUX, arm_linux_init_abi);
|
||||
gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_LINUX, arm_linux_init_abi);
|
||||
}
|
||||
|
|
359
gdb/arm-tdep.c
359
gdb/arm-tdep.c
|
@ -93,23 +93,6 @@
|
|||
#define MSYMBOL_SIZE(msym) \
|
||||
((long) MSYMBOL_INFO (msym) & 0x7fffffff)
|
||||
|
||||
/* This table matches the indices assigned to enum arm_abi.
|
||||
Keep them in sync. */
|
||||
|
||||
static const char * const arm_abi_names[] =
|
||||
{
|
||||
"<unknown>",
|
||||
"ARM EABI (version 1)",
|
||||
"ARM EABI (version 2)",
|
||||
"GNU/Linux",
|
||||
"NetBSD (a.out)",
|
||||
"NetBSD (ELF)",
|
||||
"APCS",
|
||||
"FreeBSD",
|
||||
"Windows CE",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Number of different reg name sets (options). */
|
||||
static int num_flavor_options;
|
||||
|
||||
|
@ -2608,208 +2591,82 @@ arm_coff_make_msymbol_special(int val, struct minimal_symbol *msym)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
|
||||
static enum gdb_osabi
|
||||
arm_elf_osabi_sniffer (bfd *abfd)
|
||||
{
|
||||
enum arm_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 = ARM_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 = ARM_ABI_NETBSD_ELF;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return one of the ELFOSABI_ constants for BFDs representing ELF
|
||||
executables. If it's not an ELF executable or if the OS/ABI couldn't
|
||||
be determined, simply return -1. */
|
||||
|
||||
static int
|
||||
get_elfosabi (bfd *abfd)
|
||||
{
|
||||
int elfosabi;
|
||||
enum arm_abi arm_abi = ARM_ABI_UNKNOWN;
|
||||
unsigned int elfosabi, eflags;
|
||||
enum gdb_osabi osabi = GDB_OSABI_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.
|
||||
|
||||
GNU/ARM tools set the EI_OSABI field to ELFOSABI_ARM, so handle that
|
||||
as well. */
|
||||
if (elfosabi == 0 || elfosabi == ELFOSABI_ARM)
|
||||
{
|
||||
bfd_map_over_sections (abfd,
|
||||
process_note_abi_tag_sections,
|
||||
&arm_abi);
|
||||
}
|
||||
|
||||
if (arm_abi != ARM_ABI_UNKNOWN)
|
||||
return arm_abi;
|
||||
|
||||
switch (elfosabi)
|
||||
{
|
||||
case ELFOSABI_NONE:
|
||||
/* Existing ARM Tools don't set this field, so look at the EI_FLAGS
|
||||
field for more information. */
|
||||
|
||||
switch (EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags))
|
||||
case ELFOSABI_NONE:
|
||||
/* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the
|
||||
file are conforming to the base specification for that machine
|
||||
(there are no OS-specific extensions). In order to determine the
|
||||
real OS in use we must look for OS notes that have been added. */
|
||||
bfd_map_over_sections (abfd,
|
||||
generic_elf_osabi_sniff_abi_tag_sections,
|
||||
&osabi);
|
||||
if (osabi == GDB_OSABI_UNKNOWN)
|
||||
{
|
||||
case EF_ARM_EABI_VER1:
|
||||
return ARM_ABI_EABI_V1;
|
||||
/* Existing ARM tools don't set this field, so look at the EI_FLAGS
|
||||
field for more information. */
|
||||
eflags = EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags);
|
||||
switch (eflags)
|
||||
{
|
||||
case EF_ARM_EABI_VER1:
|
||||
osabi = GDB_OSABI_ARM_EABI_V1;
|
||||
break;
|
||||
|
||||
case EF_ARM_EABI_VER2:
|
||||
return ARM_ABI_EABI_V2;
|
||||
case EF_ARM_EABI_VER2:
|
||||
osabi = GDB_OSABI_ARM_EABI_V2;
|
||||
break;
|
||||
|
||||
case EF_ARM_EABI_UNKNOWN:
|
||||
/* Assume GNU tools. */
|
||||
return ARM_ABI_APCS;
|
||||
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"get_elfosabi: Unknown ARM EABI version 0x%lx",
|
||||
EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags));
|
||||
case EF_ARM_EABI_UNKNOWN:
|
||||
/* Assume GNU tools. */
|
||||
osabi = GDB_OSABI_ARM_APCS;
|
||||
break;
|
||||
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"arm_elf_osabi_sniffer: Unknown ARM EABI "
|
||||
"version 0x%x", eflags);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ELFOSABI_NETBSD:
|
||||
return ARM_ABI_NETBSD_ELF;
|
||||
case ELFOSABI_ARM:
|
||||
/* GNU tools use this value. Check note sections in this case,
|
||||
as well. */
|
||||
bfd_map_over_sections (abfd,
|
||||
generic_elf_osabi_sniff_abi_tag_sections,
|
||||
&osabi);
|
||||
if (osabi == GDB_OSABI_UNKNOWN)
|
||||
{
|
||||
/* Assume APCS ABI. */
|
||||
osabi = GDB_OSABI_ARM_APCS;
|
||||
}
|
||||
break;
|
||||
|
||||
case ELFOSABI_FREEBSD:
|
||||
return ARM_ABI_FREEBSD;
|
||||
osabi = GDB_OSABI_FREEBSD_ELF;
|
||||
break;
|
||||
|
||||
case ELFOSABI_NETBSD:
|
||||
osabi = GDB_OSABI_NETBSD_ELF;
|
||||
break;
|
||||
|
||||
case ELFOSABI_LINUX:
|
||||
return ARM_ABI_LINUX;
|
||||
|
||||
case ELFOSABI_ARM:
|
||||
/* Assume GNU tools with the old APCS abi. */
|
||||
return ARM_ABI_APCS;
|
||||
|
||||
default:
|
||||
osabi = GDB_OSABI_LINUX;
|
||||
break;
|
||||
}
|
||||
|
||||
return ARM_ABI_UNKNOWN;
|
||||
}
|
||||
|
||||
struct arm_abi_handler
|
||||
{
|
||||
struct arm_abi_handler *next;
|
||||
enum arm_abi abi;
|
||||
void (*init_abi)(struct gdbarch_info, struct gdbarch *);
|
||||
};
|
||||
|
||||
struct arm_abi_handler *arm_abi_handler_list = NULL;
|
||||
|
||||
void
|
||||
arm_gdbarch_register_os_abi (enum arm_abi abi,
|
||||
void (*init_abi)(struct gdbarch_info,
|
||||
struct gdbarch *))
|
||||
{
|
||||
struct arm_abi_handler **handler_p;
|
||||
|
||||
for (handler_p = &arm_abi_handler_list; *handler_p != NULL;
|
||||
handler_p = &(*handler_p)->next)
|
||||
{
|
||||
if ((*handler_p)->abi == abi)
|
||||
{
|
||||
internal_error
|
||||
(__FILE__, __LINE__,
|
||||
"arm_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 arm_abi_handler *) xmalloc (sizeof (struct arm_abi_handler));
|
||||
(*handler_p)->next = NULL;
|
||||
(*handler_p)->abi = abi;
|
||||
(*handler_p)->init_abi = init_abi;
|
||||
return osabi;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the current architecture based on INFO. If possible,
|
||||
re-use an architecture from ARCHES, which is a list of
|
||||
architectures already created during this debugging session.
|
||||
|
@ -2822,36 +2679,31 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
{
|
||||
struct gdbarch_tdep *tdep;
|
||||
struct gdbarch *gdbarch;
|
||||
enum arm_abi arm_abi = ARM_ABI_UNKNOWN;
|
||||
struct arm_abi_handler *abi_handler;
|
||||
enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
|
||||
|
||||
/* Try to deterimine 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:
|
||||
arm_abi = get_elfosabi (info.abfd);
|
||||
break;
|
||||
switch (bfd_get_flavour (info.abfd))
|
||||
{
|
||||
case bfd_target_aout_flavour:
|
||||
/* Assume it's an old APCS-style ABI. */
|
||||
osabi = GDB_OSABI_ARM_APCS;
|
||||
break;
|
||||
|
||||
case bfd_target_aout_flavour:
|
||||
if (strcmp (bfd_get_target(info.abfd), "a.out-arm-netbsd") == 0)
|
||||
arm_abi = ARM_ABI_NETBSD_AOUT;
|
||||
else
|
||||
/* Assume it's an old APCS-style ABI. */
|
||||
arm_abi = ARM_ABI_APCS;
|
||||
break;
|
||||
case bfd_target_coff_flavour:
|
||||
/* Assume it's an old APCS-style ABI. */
|
||||
/* XXX WinCE? */
|
||||
osabi = GDB_OSABI_ARM_APCS;
|
||||
break;
|
||||
|
||||
case bfd_target_coff_flavour:
|
||||
/* Assume it's an old APCS-style ABI. */
|
||||
/* XXX WinCE? */
|
||||
arm_abi = ARM_ABI_APCS;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Not sure what to do here, leave the ABI as unknown. */
|
||||
break;
|
||||
default:
|
||||
/* Leave it as "unknown". */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2862,22 +2714,14 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
{
|
||||
/* Make sure the ABI selection matches. */
|
||||
tdep = gdbarch_tdep (arches->gdbarch);
|
||||
if (tdep && tdep->arm_abi == arm_abi)
|
||||
if (tdep && tdep->osabi == osabi)
|
||||
return arches->gdbarch;
|
||||
}
|
||||
|
||||
tdep = xmalloc (sizeof (struct gdbarch_tdep));
|
||||
gdbarch = gdbarch_alloc (&info, tdep);
|
||||
|
||||
tdep->arm_abi = arm_abi;
|
||||
if (arm_abi < ARM_ABI_INVALID)
|
||||
tdep->abi_name = arm_abi_names[arm_abi];
|
||||
else
|
||||
{
|
||||
internal_error (__FILE__, __LINE__, "Invalid setting of arm_abi %d",
|
||||
(int) arm_abi);
|
||||
tdep->abi_name = "<invalid>";
|
||||
}
|
||||
tdep->osabi = osabi;
|
||||
|
||||
/* This is the way it has always defaulted. */
|
||||
tdep->fp_model = ARM_FLOAT_FPA;
|
||||
|
@ -3047,38 +2891,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
arm_coff_make_msymbol_special);
|
||||
|
||||
/* Hook in the ABI-specific overrides, if they have been registered. */
|
||||
if (arm_abi == ARM_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 ARM settings");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (abi_handler = arm_abi_handler_list; abi_handler != NULL;
|
||||
abi_handler = abi_handler->next)
|
||||
if (abi_handler->abi == arm_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 ARM settings",
|
||||
arm_abi_names[arm_abi]);
|
||||
}
|
||||
}
|
||||
gdbarch_init_osabi (info, gdbarch, osabi);
|
||||
|
||||
/* Now we have tuned the configuration, set a few final things,
|
||||
based on what the OS ABI has told us. */
|
||||
|
@ -3144,12 +2957,8 @@ arm_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
|
|||
if (tdep == NULL)
|
||||
return;
|
||||
|
||||
if (tdep->abi_name != NULL)
|
||||
fprintf_unfiltered (file, "arm_dump_tdep: ABI = %s\n", tdep->abi_name);
|
||||
else
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"arm_dump_tdep: illegal setting of tdep->arm_abi (%d)",
|
||||
(int) tdep->arm_abi);
|
||||
fprintf_unfiltered (file, "arm_dump_tdep: OS ABI = %s\n",
|
||||
gdbarch_osabi_name (tdep->osabi));
|
||||
|
||||
fprintf_unfiltered (file, "arm_dump_tdep: Lowest pc = 0x%lx",
|
||||
(unsigned long) tdep->lowest_pc);
|
||||
|
@ -3191,10 +3000,18 @@ _initialize_arm_tdep (void)
|
|||
if (GDB_MULTI_ARCH)
|
||||
gdbarch_register (bfd_arch_arm, arm_gdbarch_init, arm_dump_tdep);
|
||||
|
||||
/* Register an ELF OS ABI sniffer for ARM binaries. */
|
||||
gdbarch_register_osabi_sniffer (bfd_arch_arm,
|
||||
bfd_target_elf_flavour,
|
||||
arm_elf_osabi_sniffer);
|
||||
|
||||
/* Register some ABI variants for embedded systems. */
|
||||
arm_gdbarch_register_os_abi (ARM_ABI_EABI_V1, arm_init_abi_eabi_v1);
|
||||
arm_gdbarch_register_os_abi (ARM_ABI_EABI_V2, arm_init_abi_eabi_v2);
|
||||
arm_gdbarch_register_os_abi (ARM_ABI_APCS, arm_init_abi_apcs);
|
||||
gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_ARM_EABI_V1,
|
||||
arm_init_abi_eabi_v1);
|
||||
gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_ARM_EABI_V2,
|
||||
arm_init_abi_eabi_v2);
|
||||
gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_ARM_APCS,
|
||||
arm_init_abi_apcs);
|
||||
|
||||
tm_print_insn = gdb_print_insn_arm;
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "osabi.h"
|
||||
|
||||
/* Register numbers of various important registers. Note that some of
|
||||
these values are "real" register numbers, and correspond to the
|
||||
general registers of the machine, and some are "phony" register
|
||||
|
@ -104,23 +106,6 @@ enum gdb_regnum {
|
|||
#define FLAG_C 0x20000000
|
||||
#define FLAG_V 0x10000000
|
||||
|
||||
/* ABI variants that we know about. If you add to this enum, please
|
||||
update the table of names in tm-arm.c. */
|
||||
enum arm_abi
|
||||
{
|
||||
ARM_ABI_UNKNOWN = 0,
|
||||
ARM_ABI_EABI_V1,
|
||||
ARM_ABI_EABI_V2,
|
||||
ARM_ABI_LINUX,
|
||||
ARM_ABI_NETBSD_AOUT,
|
||||
ARM_ABI_NETBSD_ELF,
|
||||
ARM_ABI_APCS,
|
||||
ARM_ABI_FREEBSD,
|
||||
ARM_ABI_WINCE,
|
||||
|
||||
ARM_ABI_INVALID /* Keep this last. */
|
||||
};
|
||||
|
||||
/* Type of floating-point code in use by inferior. There are really 3 models
|
||||
that are traditionally supported (plus the endianness issue), but gcc can
|
||||
only generate 2 of those. The third is APCS_FLOAT, where arguments to
|
||||
|
@ -139,8 +124,7 @@ enum arm_float_model
|
|||
/* Target-dependent structure in gdbarch. */
|
||||
struct gdbarch_tdep
|
||||
{
|
||||
enum arm_abi arm_abi; /* OS/ABI of inferior. */
|
||||
const char *abi_name; /* Name of the above. */
|
||||
enum gdb_osabi osabi; /* OS/ABI of inferior. */
|
||||
|
||||
enum arm_float_model fp_model; /* Floating point calling conventions. */
|
||||
|
||||
|
@ -170,10 +154,3 @@ int arm_pc_is_thumb (CORE_ADDR);
|
|||
CORE_ADDR thumb_get_next_pc (CORE_ADDR);
|
||||
|
||||
CORE_ADDR arm_get_next_pc (CORE_ADDR);
|
||||
|
||||
/* How a OS variant tells the ARM generic code that it can handle an ABI
|
||||
type. */
|
||||
void
|
||||
arm_gdbarch_register_os_abi (enum arm_abi abi,
|
||||
void (*init_abi)(struct gdbarch_info,
|
||||
struct gdbarch *));
|
||||
|
|
|
@ -77,9 +77,23 @@ arm_netbsd_elf_init_abi (struct gdbarch_info info,
|
|||
tdep->fp_model = ARM_FLOAT_SOFT_VFP;
|
||||
}
|
||||
|
||||
static enum gdb_osabi
|
||||
arm_netbsd_aout_osabi_sniffer (bfd *abfd)
|
||||
{
|
||||
if (strcmp (bfd_get_target (abfd), "a.out-arm-netbsd") == 0)
|
||||
return GDB_OSABI_NETBSD_AOUT;
|
||||
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_arm_netbsd_tdep (void)
|
||||
{
|
||||
arm_gdbarch_register_os_abi (ARM_ABI_NETBSD_AOUT, arm_netbsd_aout_init_abi);
|
||||
arm_gdbarch_register_os_abi (ARM_ABI_NETBSD_ELF, arm_netbsd_elf_init_abi);
|
||||
gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_aout_flavour,
|
||||
arm_netbsd_aout_osabi_sniffer);
|
||||
|
||||
gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_NETBSD_AOUT,
|
||||
arm_netbsd_aout_init_abi);
|
||||
gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_NETBSD_ELF,
|
||||
arm_netbsd_elf_init_abi);
|
||||
}
|
||||
|
|
|
@ -2312,6 +2312,127 @@ The target architecture object is implemented as the C structure
|
|||
@code{struct gdbarch *}. The structure, and its methods, are generated
|
||||
using the Bourne shell script @file{gdbarch.sh}.
|
||||
|
||||
@section Operating System ABI Variant Handling
|
||||
@cindex OS ABI variants
|
||||
|
||||
@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 @dfn{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. Sniffers with a wildcarded architecture are considered
|
||||
to be @dfn{generic}, while sniffers for a specific architecture are
|
||||
considered to be @dfn{specific}. A match from a specific sniffer
|
||||
overrides a match from a generic sniffer. 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.
|
||||
|
||||
@cindex fine-tuning @code{gdbarch} structure
|
||||
A @dfn{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.
|
||||
|
||||
The following OS ABI variants are defined in @file{osabi.h}:
|
||||
|
||||
@table @code
|
||||
|
||||
@findex GDB_OSABI_UNKNOWN
|
||||
@item GDB_OSABI_UNKNOWN
|
||||
The ABI of the inferior is unknown. The default @code{gdbarch}
|
||||
settings for the architecture will be used.
|
||||
|
||||
@findex GDB_OSABI_SVR4
|
||||
@item GDB_OSABI_SVR4
|
||||
UNIX System V Release 4
|
||||
|
||||
@findex GDB_OSABI_HURD
|
||||
@item GDB_OSABI_HURD
|
||||
GNU using the Hurd kernel
|
||||
|
||||
@findex GDB_OSABI_SOLARIS
|
||||
@item GDB_OSABI_SOLARIS
|
||||
Sun Solaris
|
||||
|
||||
@findex GDB_OSABI_OSF1
|
||||
@item GDB_OSABI_OSF1
|
||||
OSF/1, including Digital UNIX and Compaq Tru64 UNIX
|
||||
|
||||
@findex GDB_OSABI_LINUX
|
||||
@item GDB_OSABI_LINUX
|
||||
GNU using the Linux kernel
|
||||
|
||||
@findex GDB_OSABI_FREEBSD_AOUT
|
||||
@item GDB_OSABI_FREEBSD_AOUT
|
||||
FreeBSD using the a.out executable format
|
||||
|
||||
@findex GDB_OSABI_FREEBSD_ELF
|
||||
@item GDB_OSABI_FREEBSD_ELF
|
||||
FreeBSD using the ELF executable format
|
||||
|
||||
@findex GDB_OSABI_NETBSD_AOUT
|
||||
@item GDB_OSABI_NETBSD_AOUT
|
||||
NetBSD using the a.out executable format
|
||||
|
||||
@findex GDB_OSABI_NETBSD_ELF
|
||||
@item GDB_OSABI_NETBSD_ELF
|
||||
NetBSD using the ELF executable format
|
||||
|
||||
@findex GDB_OSABI_WINCE
|
||||
@item GDB_OSABI_WINCE
|
||||
Windows CE
|
||||
|
||||
@findex GDB_OSABI_ARM_EABI_V1
|
||||
@item GDB_OSABI_ARM_EABI_V1
|
||||
ARM Embedded ABI version 1
|
||||
|
||||
@findex GDB_OSABI_ARM_EABI_V2
|
||||
@item GDB_OSABI_ARM_EABI_V2
|
||||
ARM Embedded ABI version 2
|
||||
|
||||
@findex GDB_OSABI_ARM_APCS
|
||||
@item GDB_OSABI_ARM_APCS
|
||||
Generic ARM Procedure Call Standard
|
||||
|
||||
@end table
|
||||
|
||||
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 considered to
|
||||
be generic, and 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 for @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.
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "target.h"
|
||||
#include "arch-utils.h"
|
||||
#include "regcache.h"
|
||||
#include "osabi.h"
|
||||
|
||||
#include "opcode/mips.h"
|
||||
#include "elf/mips.h"
|
||||
|
@ -119,6 +120,7 @@ struct gdbarch_tdep
|
|||
{
|
||||
/* from the elf header */
|
||||
int elf_flags;
|
||||
|
||||
/* mips options */
|
||||
enum mips_abi mips_abi;
|
||||
const char *mips_abi_string;
|
||||
|
@ -131,6 +133,8 @@ struct gdbarch_tdep
|
|||
int mips_default_stack_argsize;
|
||||
int gdb_target_is_mips64;
|
||||
int default_mask_address_p;
|
||||
|
||||
enum gdb_osabi osabi;
|
||||
};
|
||||
|
||||
#if GDB_MULTI_ARCH
|
||||
|
@ -4132,6 +4136,7 @@ mips_gdbarch_init (struct gdbarch_info info,
|
|||
struct gdbarch_tdep *tdep;
|
||||
int elf_flags;
|
||||
enum mips_abi mips_abi;
|
||||
enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
|
||||
|
||||
/* Reset the disassembly info, in case it was set to something
|
||||
non-default. */
|
||||
|
@ -4139,12 +4144,18 @@ mips_gdbarch_init (struct gdbarch_info info,
|
|||
tm_print_insn_info.arch = bfd_arch_unknown;
|
||||
tm_print_insn_info.mach = 0;
|
||||
|
||||
/* Extract the elf_flags if available */
|
||||
if (info.abfd != NULL
|
||||
&& bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
|
||||
elf_flags = elf_elfheader (info.abfd)->e_flags;
|
||||
else
|
||||
elf_flags = 0;
|
||||
elf_flags = 0;
|
||||
|
||||
if (info.abfd)
|
||||
{
|
||||
/* First of all, extract the elf_flags, if available. */
|
||||
if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
|
||||
elf_flags = elf_elfheader (info.abfd)->e_flags;
|
||||
|
||||
/* Try to determine the OS ABI of the object we are loading. If
|
||||
we end up with `unknown', just leave it that way. */
|
||||
osabi = gdbarch_lookup_osabi (info.abfd);
|
||||
}
|
||||
|
||||
/* Check ELF_FLAGS to see if it specifies the ABI being used. */
|
||||
switch ((elf_flags & EF_MIPS_ABI))
|
||||
|
@ -4215,13 +4226,15 @@ mips_gdbarch_init (struct gdbarch_info info,
|
|||
continue;
|
||||
if (gdbarch_tdep (arches->gdbarch)->mips_abi != mips_abi)
|
||||
continue;
|
||||
return arches->gdbarch;
|
||||
if (gdbarch_tdep (arches->gdbarch)->osabi == osabi)
|
||||
return arches->gdbarch;
|
||||
}
|
||||
|
||||
/* Need a new architecture. Fill in a target specific vector. */
|
||||
tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
|
||||
gdbarch = gdbarch_alloc (&info, tdep);
|
||||
tdep->elf_flags = elf_flags;
|
||||
tdep->osabi = osabi;
|
||||
|
||||
/* Initially set everything according to the default ABI/ISA. */
|
||||
set_gdbarch_short_bit (gdbarch, 16);
|
||||
|
@ -4433,6 +4446,10 @@ mips_gdbarch_init (struct gdbarch_info info,
|
|||
set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address);
|
||||
set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer);
|
||||
set_gdbarch_integer_to_address (gdbarch, mips_integer_to_address);
|
||||
|
||||
/* Hook in OS ABI-specific overrides, if they have been registered. */
|
||||
gdbarch_init_osabi (info, gdbarch, osabi);
|
||||
|
||||
return gdbarch;
|
||||
}
|
||||
|
||||
|
@ -4841,6 +4858,10 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
|
|||
fprintf_unfiltered (file,
|
||||
"mips_dump_tdep: _PROC_MAGIC_ = %d\n",
|
||||
_PROC_MAGIC_);
|
||||
|
||||
fprintf_unfiltered (file,
|
||||
"mips_dump_tdep: OS ABI = %s\n",
|
||||
gdbarch_osabi_name (tdep->osabi));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -0,0 +1,424 @@
|
|||
/* 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[] =
|
||||
{
|
||||
"<unknown>",
|
||||
|
||||
"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",
|
||||
|
||||
"<invalid>"
|
||||
};
|
||||
|
||||
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;
|
||||
int match_specific;
|
||||
|
||||
match = GDB_OSABI_UNKNOWN;
|
||||
match_specific = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
/* A specific sniffer always overrides a generic sniffer.
|
||||
Croak on multiple match if the two matches are of the
|
||||
same class. If the user wishes to continue, we'll use
|
||||
the first match. */
|
||||
if (match != GDB_OSABI_UNKNOWN)
|
||||
{
|
||||
if ((match_specific && sniffer->arch != bfd_arch_unknown)
|
||||
|| (!match_specific && sniffer->arch == bfd_arch_unknown))
|
||||
{
|
||||
internal_error
|
||||
(__FILE__, __LINE__,
|
||||
"gdbarch_lookup_osabi: multiple %sspecific OS ABI "
|
||||
"match for architecture %s flavour %d: first "
|
||||
"match \"%s\", second match \"%s\"",
|
||||
match_specific ? "" : "non-",
|
||||
bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
|
||||
(int) bfd_get_flavour (abfd),
|
||||
gdbarch_osabi_name (match),
|
||||
gdbarch_osabi_name (osabi));
|
||||
}
|
||||
else if (sniffer->arch != bfd_arch_unknown)
|
||||
{
|
||||
match = osabi;
|
||||
match_specific = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
match = osabi;
|
||||
if (sniffer->arch != bfd_arch_unknown)
|
||||
match_specific = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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. */
|
||||
|
||||
void
|
||||
generic_elf_osabi_sniff_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__,
|
||||
"generic_elf_osabi_sniff_abi_tag_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)
|
||||
{
|
||||
unsigned 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), then the ELF structures in the
|
||||
file are conforming to the base specification for that machine
|
||||
(there are no OS-specific extensions). In order to determine the
|
||||
real OS in use we must look for OS notes that have been added. */
|
||||
bfd_map_over_sections (abfd,
|
||||
generic_elf_osabi_sniff_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], "<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);
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/* 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);
|
||||
|
||||
/* Helper routine for ELF file sniffers. This looks at ABI tag note
|
||||
sections to determine the OS ABI from the note. It should be called
|
||||
via bfd_map_over_sections. */
|
||||
void generic_elf_osabi_sniff_abi_tag_sections (bfd *, asection *, void *);
|
||||
|
||||
#endif /* OSABI_H */
|
233
gdb/sh-tdep.c
233
gdb/sh-tdep.c
|
@ -4179,175 +4179,6 @@ sh_linux_svr4_fetch_link_map_offsets (void)
|
|||
#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[] =
|
||||
{
|
||||
"<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 *
|
||||
|
@ -4359,23 +4190,14 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
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. */
|
||||
|
@ -4385,7 +4207,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -4394,15 +4216,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
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>";
|
||||
}
|
||||
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
|
||||
|
@ -4754,32 +4568,11 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
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;
|
||||
}
|
||||
|
@ -4792,12 +4585,8 @@ sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
|
|||
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
|
||||
|
|
|
@ -22,21 +22,12 @@
|
|||
#ifndef SH_TDEP_H
|
||||
#define SH_TDEP_H
|
||||
|
||||
#include "osabi.h"
|
||||
|
||||
/* Contributed by Steve Chamberlain sac@cygnus.com */
|
||||
|
||||
/* 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,
|
||||
|
@ -98,8 +89,7 @@ struct gdbarch_tdep
|
|||
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 gdb_osabi osabi; /* OS/ABI of the inferior */
|
||||
enum sh_abi sh_abi;
|
||||
};
|
||||
|
||||
|
|
|
@ -177,5 +177,5 @@ _initialize_shnbsd_tdep (void)
|
|||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue