* arch-utils.c (target_byte_order_user): Renamed from
	target_byte_order.
	(target_byte_order_auto, selected_byte_order): Removed.
	(show_endian): Check target_byte_order_user.
	(set_endian): Always update the architecture.  Set
	target_byte_order_user after success.
	(target_architecture_auto): Removed.
	(target_architecture_user): New.
	(selected_architecture_name, show_architecture): Check it.
	(set_architecture): Set target_architecture_user after success.
	(gdbarch_from_bfd): Check the argument.
	(default_byte_order): New.
	(initialize_current_architecture): Set the global default
	architecture and endianness.
	(gdbarch_info_fill): Remove GDBARCH argument.  Do not check the
	previous architecture.  Use exec_bfd, global selected architecture
	and endianness, and global defaults.
	* arch-utils.h (selected_byte_order): Remove prototype.
	(gdbarch_info_fill): Update.
	* exec.c (exec_file_attach): Update the architecture after removing
	the current file.
	* gdbarch.sh: Update comments.
	(find_arch_by_info): Remove OLD_GDBARCH argument.  Update call to
	gdbarch_info_fill.
	(gdbarch_find_by_info): Update call to find_arch_by_info.
	* gdbarch.h, gdbarch.c: Regenerated.
	* remote-sim.c (gdbsim_open): Use TARGET_BYTE_ORDER.
gdb/doc/
	* gdbint.texinfo (Target Architecture Definition): Add new
	Initializing a New Architecture section.
This commit is contained in:
Daniel Jacobowitz 2006-11-10 19:20:37 +00:00
parent d8295fe954
commit 7a10774786
10 changed files with 157 additions and 90 deletions

View File

@ -1,3 +1,33 @@
2006-11-10 Daniel Jacobowitz <dan@codesourcery.com>
* arch-utils.c (target_byte_order_user): Renamed from
target_byte_order.
(target_byte_order_auto, selected_byte_order): Removed.
(show_endian): Check target_byte_order_user.
(set_endian): Always update the architecture. Set
target_byte_order_user after success.
(target_architecture_auto): Removed.
(target_architecture_user): New.
(selected_architecture_name, show_architecture): Check it.
(set_architecture): Set target_architecture_user after success.
(gdbarch_from_bfd): Check the argument.
(default_byte_order): New.
(initialize_current_architecture): Set the global default
architecture and endianness.
(gdbarch_info_fill): Remove GDBARCH argument. Do not check the
previous architecture. Use exec_bfd, global selected architecture
and endianness, and global defaults.
* arch-utils.h (selected_byte_order): Remove prototype.
(gdbarch_info_fill): Update.
* exec.c (exec_file_attach): Update the architecture after removing
the current file.
* gdbarch.sh: Update comments.
(find_arch_by_info): Remove OLD_GDBARCH argument. Update call to
gdbarch_info_fill.
(gdbarch_find_by_info): Update call to find_arch_by_info.
* gdbarch.h, gdbarch.c: Regenerated.
* remote-sim.c (gdbsim_open): Use TARGET_BYTE_ORDER.
2006-11-09 Joel Brobecker <brobecker@adacore.com>
* sparc-tdep.c (sparc_fetch_instruction): Read instruction

View File

@ -335,24 +335,7 @@ generic_instruction_nullified (struct gdbarch *gdbarch,
/* Functions to manipulate the endianness of the target. */
/* ``target_byte_order'' is only used when non- multi-arch.
Multi-arch targets obtain the current byte order using the
TARGET_BYTE_ORDER gdbarch method.
The choice of initial value is entirely arbitrary. During startup,
the function initialize_current_architecture() updates this value
based on default byte-order information extracted from BFD. */
static int target_byte_order = BFD_ENDIAN_BIG;
static int target_byte_order_auto = 1;
enum bfd_endian
selected_byte_order (void)
{
if (target_byte_order_auto)
return BFD_ENDIAN_UNKNOWN;
else
return target_byte_order;
}
static int target_byte_order_user = BFD_ENDIAN_UNKNOWN;
static const char endian_big[] = "big";
static const char endian_little[] = "little";
@ -372,7 +355,7 @@ static void
show_endian (struct ui_file *file, int from_tty, struct cmd_list_element *c,
const char *value)
{
if (target_byte_order_auto)
if (target_byte_order_user != BFD_ENDIAN_UNKNOWN)
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
fprintf_unfiltered (file, _("The target endianness is set automatically "
"(currently big endian)\n"));
@ -391,31 +374,37 @@ show_endian (struct ui_file *file, int from_tty, struct cmd_list_element *c,
static void
set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
{
struct gdbarch_info info;
gdbarch_info_init (&info);
if (set_endian_string == endian_auto)
{
target_byte_order_auto = 1;
target_byte_order_user = BFD_ENDIAN_UNKNOWN;
if (! gdbarch_update_p (info))
internal_error (__FILE__, __LINE__,
_("set_endian: architecture update failed"));
}
else if (set_endian_string == endian_little)
{
struct gdbarch_info info;
target_byte_order_auto = 0;
gdbarch_info_init (&info);
info.byte_order = BFD_ENDIAN_LITTLE;
if (! gdbarch_update_p (info))
printf_unfiltered (_("Little endian target not supported by GDB\n"));
else
target_byte_order_user = BFD_ENDIAN_LITTLE;
}
else if (set_endian_string == endian_big)
{
struct gdbarch_info info;
target_byte_order_auto = 0;
gdbarch_info_init (&info);
info.byte_order = BFD_ENDIAN_BIG;
if (! gdbarch_update_p (info))
printf_unfiltered (_("Big endian target not supported by GDB\n"));
else
target_byte_order_user = BFD_ENDIAN_BIG;
}
else
internal_error (__FILE__, __LINE__,
_("set_endian: bad value"));
show_endian (gdb_stdout, from_tty, NULL, NULL);
}
@ -423,14 +412,14 @@ set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
enum set_arch { set_arch_auto, set_arch_manual };
static int target_architecture_auto = 1;
static const struct bfd_arch_info *target_architecture_user;
static const char *set_architecture_string;
const char *
selected_architecture_name (void)
{
if (target_architecture_auto)
if (target_architecture_user == NULL)
return NULL;
else
return set_architecture_string;
@ -445,7 +434,7 @@ show_architecture (struct ui_file *file, int from_tty,
{
const char *arch;
arch = TARGET_ARCHITECTURE->printable_name;
if (target_architecture_auto)
if (target_architecture_user == NULL)
fprintf_filtered (file, _("\
The target architecture is set automatically (currently %s)\n"), arch);
else
@ -460,20 +449,25 @@ The target architecture is assumed to be %s\n"), arch);
static void
set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c)
{
struct gdbarch_info info;
gdbarch_info_init (&info);
if (strcmp (set_architecture_string, "auto") == 0)
{
target_architecture_auto = 1;
target_architecture_user = NULL;
if (!gdbarch_update_p (info))
internal_error (__FILE__, __LINE__,
_("could not select an architecture automatically"));
}
else
{
struct gdbarch_info info;
gdbarch_info_init (&info);
info.bfd_arch_info = bfd_scan_arch (set_architecture_string);
if (info.bfd_arch_info == NULL)
internal_error (__FILE__, __LINE__,
_("set_architecture: bfd_scan_arch failed"));
if (gdbarch_update_p (info))
target_architecture_auto = 0;
target_architecture_user = info.bfd_arch_info;
else
printf_unfiltered (_("Architecture `%s' not recognized.\n"),
set_architecture_string);
@ -530,6 +524,13 @@ gdbarch_from_bfd (bfd *abfd)
struct gdbarch *new_gdbarch;
struct gdbarch_info info;
/* If we call gdbarch_find_by_info without filling in info.abfd,
then it will use the global exec_bfd. That's fine if we don't
have one of those either. And that's the only time we should
reach here with a NULL ABFD argument - when we are discarding
the executable. */
gdb_assert (abfd != NULL || exec_bfd == NULL);
gdbarch_info_init (&info);
info.abfd = abfd;
return gdbarch_find_by_info (info);
@ -567,6 +568,8 @@ static const bfd_target *default_bfd_vec = &DEFAULT_BFD_VEC;
static const bfd_target *default_bfd_vec;
#endif
static int default_byte_order = BFD_ENDIAN_UNKNOWN;
void
initialize_current_architecture (void)
{
@ -577,10 +580,7 @@ initialize_current_architecture (void)
gdbarch_info_init (&info);
/* Find a default architecture. */
if (info.bfd_arch_info == NULL
&& default_bfd_arch != NULL)
info.bfd_arch_info = default_bfd_arch;
if (info.bfd_arch_info == NULL)
if (default_bfd_arch == NULL)
{
/* Choose the architecture by taking the first one
alphabetically. */
@ -594,30 +594,32 @@ initialize_current_architecture (void)
if (chosen == NULL)
internal_error (__FILE__, __LINE__,
_("initialize_current_architecture: No arch"));
info.bfd_arch_info = bfd_scan_arch (chosen);
if (info.bfd_arch_info == NULL)
default_bfd_arch = bfd_scan_arch (chosen);
if (default_bfd_arch == NULL)
internal_error (__FILE__, __LINE__,
_("initialize_current_architecture: Arch not found"));
}
info.bfd_arch_info = default_bfd_arch;
/* Take several guesses at a byte order. */
if (info.byte_order == BFD_ENDIAN_UNKNOWN
if (default_byte_order == BFD_ENDIAN_UNKNOWN
&& default_bfd_vec != NULL)
{
/* Extract BFD's default vector's byte order. */
switch (default_bfd_vec->byteorder)
{
case BFD_ENDIAN_BIG:
info.byte_order = BFD_ENDIAN_BIG;
default_byte_order = BFD_ENDIAN_BIG;
break;
case BFD_ENDIAN_LITTLE:
info.byte_order = BFD_ENDIAN_LITTLE;
default_byte_order = BFD_ENDIAN_LITTLE;
break;
default:
break;
}
}
if (info.byte_order == BFD_ENDIAN_UNKNOWN)
if (default_byte_order == BFD_ENDIAN_UNKNOWN)
{
/* look for ``*el-*'' in the target name. */
const char *chp;
@ -625,14 +627,16 @@ initialize_current_architecture (void)
if (chp != NULL
&& chp - 2 >= target_name
&& strncmp (chp - 2, "el", 2) == 0)
info.byte_order = BFD_ENDIAN_LITTLE;
default_byte_order = BFD_ENDIAN_LITTLE;
}
if (info.byte_order == BFD_ENDIAN_UNKNOWN)
if (default_byte_order == BFD_ENDIAN_UNKNOWN)
{
/* Wire it to big-endian!!! */
info.byte_order = BFD_ENDIAN_BIG;
default_byte_order = BFD_ENDIAN_BIG;
}
info.byte_order = default_byte_order;
if (! gdbarch_update_p (info))
internal_error (__FILE__, __LINE__,
_("initialize_current_architecture: Selection of "
@ -674,48 +678,46 @@ gdbarch_info_init (struct gdbarch_info *info)
}
/* Similar to init, but this time fill in the blanks. Information is
obtained from the specified architecture, global "set ..." options,
and explicitly initialized INFO fields. */
obtained from the global "set ..." options and explicitly
initialized INFO fields. */
void
gdbarch_info_fill (struct gdbarch *gdbarch, struct gdbarch_info *info)
gdbarch_info_fill (struct gdbarch_info *info)
{
/* Check for the current file. */
if (info->abfd == NULL)
info->abfd = exec_bfd;
/* "(gdb) set architecture ...". */
if (info->bfd_arch_info == NULL
&& !target_architecture_auto
&& gdbarch != NULL)
info->bfd_arch_info = gdbarch_bfd_arch_info (gdbarch);
&& target_architecture_user)
info->bfd_arch_info = target_architecture_user;
if (info->bfd_arch_info == NULL
&& info->abfd != NULL
&& bfd_get_arch (info->abfd) != bfd_arch_unknown
&& bfd_get_arch (info->abfd) != bfd_arch_obscure)
info->bfd_arch_info = bfd_get_arch_info (info->abfd);
if (info->bfd_arch_info == NULL
&& gdbarch != NULL)
info->bfd_arch_info = gdbarch_bfd_arch_info (gdbarch);
/* From the default. */
if (info->bfd_arch_info == NULL)
info->bfd_arch_info = default_bfd_arch;
/* "(gdb) set byte-order ...". */
if (info->byte_order == BFD_ENDIAN_UNKNOWN
&& !target_byte_order_auto
&& gdbarch != NULL)
info->byte_order = gdbarch_byte_order (gdbarch);
&& target_byte_order_user != BFD_ENDIAN_UNKNOWN)
info->byte_order = target_byte_order_user;
/* From the INFO struct. */
if (info->byte_order == BFD_ENDIAN_UNKNOWN
&& info->abfd != NULL)
info->byte_order = (bfd_big_endian (info->abfd) ? BFD_ENDIAN_BIG
: bfd_little_endian (info->abfd) ? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_UNKNOWN);
/* From the current target. */
if (info->byte_order == BFD_ENDIAN_UNKNOWN
&& gdbarch != NULL)
info->byte_order = gdbarch_byte_order (gdbarch);
: bfd_little_endian (info->abfd) ? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_UNKNOWN);
/* From the default. */
if (info->byte_order == BFD_ENDIAN_UNKNOWN)
info->byte_order = default_byte_order;
/* "(gdb) set osabi ...". Handled by gdbarch_lookup_osabi. */
if (info->osabi == GDB_OSABI_UNINITIALIZED)
info->osabi = gdbarch_lookup_osabi (info->abfd);
if (info->osabi == GDB_OSABI_UNINITIALIZED
&& gdbarch != NULL)
info->osabi = gdbarch_osabi (gdbarch);
/* Must have at least filled in the architecture. */
gdb_assert (info->bfd_arch_info != NULL);

View File

@ -126,10 +126,6 @@ extern int generic_instruction_nullified (struct gdbarch *gdbarch,
extern int legacy_register_sim_regno (int regnum);
/* Return the selected byte order, or BFD_ENDIAN_UNKNOWN if no byte
order was explicitly selected. */
extern enum bfd_endian selected_byte_order (void);
/* Return the selected architecture's name, or NULL if no architecture
was explicitly selected. */
extern const char *selected_architecture_name (void);
@ -141,10 +137,9 @@ extern const char *selected_architecture_name (void);
extern void gdbarch_info_init (struct gdbarch_info *info);
/* Similar to init, but this time fill in the blanks. Information is
obtained from the specified architecture, global "set ..." options,
and explicitly initialized INFO fields. */
extern void gdbarch_info_fill (struct gdbarch *gdbarch,
struct gdbarch_info *info);
obtained from the global "set ..." options and explicitly
initialized INFO fields. */
extern void gdbarch_info_fill (struct gdbarch_info *info);
/* Return the architecture for ABFD. If no suitable architecture
could be find, return NULL. */

View File

@ -1,3 +1,8 @@
2006-11-10 Daniel Jacobowitz <dan@codesourcery.com>
* gdbint.texinfo (Target Architecture Definition): Add new
Initializing a New Architecture section.
2006-10-31 David Taylor <dtaylor@emc.com>
* stabs.texinfo (Macro define and undefine): New node describing

View File

@ -2722,6 +2722,41 @@ architecture, a warning will be issued and the debugging session will continue
with the defaults already established for @var{gdbarch}.
@end deftypefun
@section Initializing a New Architecture
Each @code{gdbarch} is associated with a single @sc{bfd} architecture,
via a @code{bfd_arch_@var{arch}} constant. The @code{gdbarch} is
registered by a call to @code{register_gdbarch_init}, usually from
the file's @code{_initialize_@var{filename}} routine, which will
be automatically called during @value{GDBN} startup. The arguments
are a @sc{bfd} architecture constant and an initialization function.
The initialization function has this type:
@smallexample
static struct gdbarch *
@var{arch}_gdbarch_init (struct gdbarch_info @var{info},
struct gdbarch_list *@var{arches})
@end smallexample
The @var{info} argument contains parameters used to select the correct
architecture, and @var{arches} is a list of architectures which
have already been created with the same @code{bfd_arch_@var{arch}}
value.
The initialization function should first make sure that @var{info}
is acceptable, and return @code{NULL} if it is not. Then, it should
search through @var{arches} for an exact match to @var{info}, and
return one if found. Lastly, if no exact match was found, it should
create a new architecture based on @var{info} and return it.
Only information in @var{info} should be used to choose the new
architecture. Historically, @var{info} could be sparse, and
defaults would be collected from the first element on @var{arches}.
However, @value{GDBN} now fills in @var{info} more thoroughly,
so new @code{gdbarch} initialization functions should not take
defaults from @var{arches}.
@section Registers and Memory
@value{GDBN}'s model of the target machine is rather simple.

View File

@ -188,6 +188,8 @@ exec_file_attach (char *filename, int from_tty)
{
if (from_tty)
printf_unfiltered (_("No executable file now.\n"));
set_gdbarch_from_file (NULL);
}
else
{

View File

@ -3987,7 +3987,7 @@ gdbarch_list_lookup_by_info (struct gdbarch_list *arches,
that there is no current architecture. */
static struct gdbarch *
find_arch_by_info (struct gdbarch *old_gdbarch, struct gdbarch_info info)
find_arch_by_info (struct gdbarch_info info)
{
struct gdbarch *new_gdbarch;
struct gdbarch_registration *rego;
@ -3997,9 +3997,9 @@ find_arch_by_info (struct gdbarch *old_gdbarch, struct gdbarch_info info)
gdb_assert (current_gdbarch == NULL);
/* Fill in missing parts of the INFO struct using a number of
sources: "set ..."; INFOabfd supplied; and the existing
architecture. */
gdbarch_info_fill (old_gdbarch, &info);
sources: "set ..."; INFOabfd supplied; and the global
defaults. */
gdbarch_info_fill (&info);
/* Must have found some sort of architecture. */
gdb_assert (info.bfd_arch_info != NULL);
@ -4130,7 +4130,7 @@ gdbarch_find_by_info (struct gdbarch_info info)
struct gdbarch *old_gdbarch = current_gdbarch_swap_out_hack ();
/* Find the specified architecture. */
struct gdbarch *new_gdbarch = find_arch_by_info (old_gdbarch, info);
struct gdbarch *new_gdbarch = find_arch_by_info (info);
/* Restore the existing architecture. */
gdb_assert (current_gdbarch == NULL);

View File

@ -1420,8 +1420,7 @@ extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
``struct gdbarch'' for this architecture.
The INFO parameter is, as far as possible, be pre-initialized with
information obtained from INFO.ABFD or the previously selected
architecture.
information obtained from INFO.ABFD or the global defaults.
The ARCHES parameter is a linked list (sorted most recently used)
of all the previously created architures for this architecture

View File

@ -943,8 +943,7 @@ extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
\`\`struct gdbarch'' for this architecture.
The INFO parameter is, as far as possible, be pre-initialized with
information obtained from INFO.ABFD or the previously selected
architecture.
information obtained from INFO.ABFD or the global defaults.
The ARCHES parameter is a linked list (sorted most recently used)
of all the previously created architures for this architecture
@ -2050,7 +2049,7 @@ gdbarch_list_lookup_by_info (struct gdbarch_list *arches,
that there is no current architecture. */
static struct gdbarch *
find_arch_by_info (struct gdbarch *old_gdbarch, struct gdbarch_info info)
find_arch_by_info (struct gdbarch_info info)
{
struct gdbarch *new_gdbarch;
struct gdbarch_registration *rego;
@ -2060,9 +2059,9 @@ find_arch_by_info (struct gdbarch *old_gdbarch, struct gdbarch_info info)
gdb_assert (current_gdbarch == NULL);
/* Fill in missing parts of the INFO struct using a number of
sources: "set ..."; INFOabfd supplied; and the existing
architecture. */
gdbarch_info_fill (old_gdbarch, &info);
sources: "set ..."; INFOabfd supplied; and the global
defaults. */
gdbarch_info_fill (&info);
/* Must have found some sort of architecture. */
gdb_assert (info.bfd_arch_info != NULL);
@ -2193,7 +2192,7 @@ gdbarch_find_by_info (struct gdbarch_info info)
struct gdbarch *old_gdbarch = current_gdbarch_swap_out_hack ();
/* Find the specified architecture. */
struct gdbarch *new_gdbarch = find_arch_by_info (old_gdbarch, info);
struct gdbarch *new_gdbarch = find_arch_by_info (info);
/* Restore the existing architecture. */
gdb_assert (current_gdbarch == NULL);

View File

@ -506,7 +506,7 @@ gdbsim_open (char *args, int from_tty)
strcpy (arg_buf, "gdbsim"); /* 7 */
/* Specify the byte order for the target when it is both selectable
and explicitly specified by the user (not auto detected). */
switch (selected_byte_order ())
switch (TARGET_BYTE_ORDER)
{
case BFD_ENDIAN_BIG:
strcat (arg_buf, " -E big");