old-cross-binutils/gdb/guile/scm-objfile.c

397 lines
10 KiB
C
Raw Normal View History

Add Guile as an extension language. * NEWS: Mention Guile scripting. * Makefile.in (SUBDIR_GUILE_OBS): New variable. (SUBDIR_GUILE_SRCS, SUBDIR_GUILE_DEPS): New variables (SUBDIR_GUILE_LDFLAGS, SUBDIR_GUILE_CFLAGS): New variables. (INTERNAL_CPPFLAGS): Add GUILE_CPPFLAGS. (CLIBS): Add GUILE_LIBS. (install-guile): New rule. (guile.o): New rule. (scm-arch.o, scm-auto-load.o, scm-block.o): New rules. (scm-breakpoint.o, scm-disasm.o, scm-exception.o): New rules. (scm-frame.o, scm-iterator.o, scm-lazy-string.o): New rules. (scm-math.o, scm-objfile.o, scm-ports.o): New rules. (scm-pretty-print.o, scm-safe-call.o, scm-gsmob.o): New rules. (scm-string.o, scm-symbol.o, scm-symtab.o): New rules. (scm-type.o, scm-utils.o, scm-value.o): New rules. * configure.ac: New option --with-guile. * configure: Regenerate. * config.in: Regenerate. * auto-load.c: Remove #include "python/python.h". Add #include "gdb/section-scripts.h". (source_section_scripts): Handle Guile scripts. (_initialize_auto_load): Add name of Guile objfile script to scripts-directory help text. * breakpoint.c (condition_command): Tweak comment to include Scheme. * breakpoint.h (gdbscm_breakpoint_object): Add forward decl. (struct breakpoint): New member scm_bp_object. * defs.h (enum command_control_type): New value guile_control. * cli/cli-cmds.c: Remove #include "python/python.h". Add #include "extension.h". (show_user): Update comment. (_initialize_cli_cmds): Update help text for "show user". Update help text for max-user-call-depth. * cli/cli-script.c: Remove #include "python/python.h". Add #include "extension.h". (multi_line_command_p): Add guile_control. (print_command_lines): Handle guile_control. (execute_control_command, recurse_read_control_structure): Ditto. (process_next_line): Recognize "guile" commands. * disasm.c (gdb_disassemble_info): Make non-static. * disasm.h: #include "dis-asm.h". (struct gdbarch): Add forward decl. (gdb_disassemble_info): Declare. * extension.c: #include "guile/guile.h". (extension_languages): Add guile. (get_ext_lang_defn): Handle EXT_LANG_GDB. * extension.h (enum extension_language): New value EXT_LANG_GUILE. * gdbtypes.c (get_unsigned_type_max): New function. (get_signed_type_minmax): New function. * gdbtypes.h (get_unsigned_type_max): Declare. (get_signed_type_minmax): Declare. * guile/README: New file. * guile/guile-internal.h: New file. * guile/guile.c: New file. * guile/guile.h: New file. * guile/scm-arch.c: New file. * guile/scm-auto-load.c: New file. * guile/scm-block.c: New file. * guile/scm-breakpoint.c: New file. * guile/scm-disasm.c: New file. * guile/scm-exception.c: New file. * guile/scm-frame.c: New file. * guile/scm-gsmob.c: New file. * guile/scm-iterator.c: New file. * guile/scm-lazy-string.c: New file. * guile/scm-math.c: New file. * guile/scm-objfile.c: New file. * guile/scm-ports.c: New file. * guile/scm-pretty-print.c: New file. * guile/scm-safe-call.c: New file. * guile/scm-string.c: New file. * guile/scm-symbol.c: New file. * guile/scm-symtab.c: New file. * guile/scm-type.c: New file. * guile/scm-utils.c: New file. * guile/scm-value.c: New file. * guile/lib/gdb.scm: New file. * guile/lib/gdb/boot.scm: New file. * guile/lib/gdb/experimental.scm: New file. * guile/lib/gdb/init.scm: New file. * guile/lib/gdb/iterator.scm: New file. * guile/lib/gdb/printing.scm: New file. * guile/lib/gdb/types.scm: New file. * data-directory/Makefile.in (GUILE_SRCDIR): New variable. (VPATH): Add $(GUILE_SRCDIR). (GUILE_DIR): New variable. (GUILE_INSTALL_DIR, GUILE_FILES): New variables. (all): Add stamp-guile dependency. (stamp-guile): New rule. (clean-guile, install-guile, uninstall-guile): New rules. (install-only): Add install-guile dependency. (uninstall): Add uninstall-guile dependency. (clean): Add clean-guile dependency. doc/ * Makefile.in (GDB_DOC_FILES): Add guile.texi. * gdb.texinfo (Auto-loading): Add set/show auto-load guile-scripts. (Extending GDB): New menu entries Guile, Multiple Extension Languages. (Guile docs): Include guile.texi. (objfile-gdbdotext file): Add objfile-gdb.scm. (dotdebug_gdb_scripts section): Mention Guile scripts. (Multiple Extension Languages): New node. * guile.texi: New file. testsuite/ * configure.ac (AC_OUTPUT): Add gdb.guile. * configure: Regenerate. * lib/gdb-guile.exp: New file. * lib/gdb.exp (get_target_charset): New function. * gdb.base/help.exp: Update expected output from "apropos apropos". * gdb.guile/Makefile.in: New file. * gdb.guile/guile.exp: New file. * gdb.guile/scm-arch.c: New file. * gdb.guile/scm-arch.exp: New file. * gdb.guile/scm-block.c: New file. * gdb.guile/scm-block.exp: New file. * gdb.guile/scm-breakpoint.c: New file. * gdb.guile/scm-breakpoint.exp: New file. * gdb.guile/scm-disasm.c: New file. * gdb.guile/scm-disasm.exp: New file. * gdb.guile/scm-equal.c: New file. * gdb.guile/scm-equal.exp: New file. * gdb.guile/scm-error.exp: New file. * gdb.guile/scm-error.scm: New file. * gdb.guile/scm-frame-args.c: New file. * gdb.guile/scm-frame-args.exp: New file. * gdb.guile/scm-frame-args.scm: New file. * gdb.guile/scm-frame-inline.c: New file. * gdb.guile/scm-frame-inline.exp: New file. * gdb.guile/scm-frame.c: New file. * gdb.guile/scm-frame.exp: New file. * gdb.guile/scm-generics.exp: New file. * gdb.guile/scm-gsmob.exp: New file. * gdb.guile/scm-iterator.c: New file. * gdb.guile/scm-iterator.exp: New file. * gdb.guile/scm-math.c: New file. * gdb.guile/scm-math.exp: New file. * gdb.guile/scm-objfile-script-gdb.in: New file. * gdb.guile/scm-objfile-script.c: New file. * gdb.guile/scm-objfile-script.exp: New file. * gdb.guile/scm-objfile.c: New file. * gdb.guile/scm-objfile.exp: New file. * gdb.guile/scm-ports.exp: New file. * gdb.guile/scm-pretty-print.c: New file. * gdb.guile/scm-pretty-print.exp: New file. * gdb.guile/scm-pretty-print.scm: New file. * gdb.guile/scm-section-script.c: New file. * gdb.guile/scm-section-script.exp: New file. * gdb.guile/scm-section-script.scm: New file. * gdb.guile/scm-symbol.c: New file. * gdb.guile/scm-symbol.exp: New file. * gdb.guile/scm-symtab-2.c: New file. * gdb.guile/scm-symtab.c: New file. * gdb.guile/scm-symtab.exp: New file. * gdb.guile/scm-type.c: New file. * gdb.guile/scm-type.exp: New file. * gdb.guile/scm-value-cc.cc: New file. * gdb.guile/scm-value-cc.exp: New file. * gdb.guile/scm-value.c: New file. * gdb.guile/scm-value.exp: New file. * gdb.guile/source2.scm: New file. * gdb.guile/types-module.cc: New file. * gdb.guile/types-module.exp: New file.
2014-02-10 03:40:01 +00:00
/* Scheme interface to objfiles.
Copyright (C) 2008-2014 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 3 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, see <http://www.gnu.org/licenses/>. */
/* See README file in this directory for implementation notes, coding
conventions, et.al. */
#include "defs.h"
#include "objfiles.h"
#include "language.h"
#include "guile-internal.h"
/* The <gdb:objfile> smob.
The typedef for this struct is in guile-internal.h. */
struct _objfile_smob
{
/* This always appears first. */
gdb_smob base;
/* The corresponding objfile. */
struct objfile *objfile;
/* The pretty-printer list of functions. */
SCM pretty_printers;
/* The <gdb:objfile> object we are contained in, needed to protect/unprotect
the object since a reference to it comes from non-gc-managed space
(the objfile). */
SCM containing_scm;
};
static const char objfile_smob_name[] = "gdb:objfile";
/* The tag Guile knows the objfile smob by. */
static scm_t_bits objfile_smob_tag;
static const struct objfile_data *ofscm_objfile_data_key;
/* Return the list of pretty-printers registered with O_SMOB. */
SCM
ofscm_objfile_smob_pretty_printers (objfile_smob *o_smob)
{
return o_smob->pretty_printers;
}
/* Administrivia for objfile smobs. */
/* The smob "print" function for <gdb:objfile>. */
static int
ofscm_print_objfile_smob (SCM self, SCM port, scm_print_state *pstate)
{
objfile_smob *o_smob = (objfile_smob *) SCM_SMOB_DATA (self);
gdbscm_printf (port, "#<%s ", objfile_smob_name);
gdbscm_printf (port, "%s",
o_smob->objfile != NULL
? objfile_name (o_smob->objfile)
: "{invalid}");
scm_puts (">", port);
scm_remember_upto_here_1 (self);
/* Non-zero means success. */
return 1;
}
/* Low level routine to create a <gdb:objfile> object.
It's empty in the sense that an OBJFILE still needs to be associated
with it. */
static SCM
ofscm_make_objfile_smob (void)
{
objfile_smob *o_smob = (objfile_smob *)
scm_gc_malloc (sizeof (objfile_smob), objfile_smob_name);
SCM o_scm;
o_smob->objfile = NULL;
o_smob->pretty_printers = SCM_EOL;
o_scm = scm_new_smob (objfile_smob_tag, (scm_t_bits) o_smob);
o_smob->containing_scm = o_scm;
gdbscm_init_gsmob (&o_smob->base);
return o_scm;
}
/* Clear the OBJFILE pointer in O_SMOB and unprotect the object from GC. */
static void
ofscm_release_objfile (objfile_smob *o_smob)
{
o_smob->objfile = NULL;
scm_gc_unprotect_object (o_smob->containing_scm);
}
/* Objfile registry cleanup handler for when an objfile is deleted. */
static void
ofscm_handle_objfile_deleted (struct objfile *objfile, void *datum)
{
objfile_smob *o_smob = datum;
gdb_assert (o_smob->objfile == objfile);
ofscm_release_objfile (o_smob);
}
/* Return non-zero if SCM is a <gdb:objfile> object. */
static int
ofscm_is_objfile (SCM scm)
{
return SCM_SMOB_PREDICATE (objfile_smob_tag, scm);
}
/* (objfile? object) -> boolean */
static SCM
gdbscm_objfile_p (SCM scm)
{
return scm_from_bool (ofscm_is_objfile (scm));
}
/* Return a pointer to the objfile_smob that encapsulates OBJFILE,
creating one if necessary.
The result is cached so that we have only one copy per objfile. */
objfile_smob *
ofscm_objfile_smob_from_objfile (struct objfile *objfile)
{
objfile_smob *o_smob;
o_smob = objfile_data (objfile, ofscm_objfile_data_key);
if (o_smob == NULL)
{
SCM o_scm = ofscm_make_objfile_smob ();
o_smob = (objfile_smob *) SCM_SMOB_DATA (o_scm);
o_smob->objfile = objfile;
set_objfile_data (objfile, ofscm_objfile_data_key, o_smob);
scm_gc_protect_object (o_smob->containing_scm);
}
return o_smob;
}
/* Return the <gdb:objfile> object that encapsulates OBJFILE. */
SCM
ofscm_scm_from_objfile (struct objfile *objfile)
{
objfile_smob *o_smob = ofscm_objfile_smob_from_objfile (objfile);
return o_smob->containing_scm;
}
/* Returns the <gdb:objfile> object in SELF.
Throws an exception if SELF is not a <gdb:objfile> object. */
static SCM
ofscm_get_objfile_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
SCM_ASSERT_TYPE (ofscm_is_objfile (self), self, arg_pos, func_name,
objfile_smob_name);
return self;
}
/* Returns a pointer to the objfile smob of SELF.
Throws an exception if SELF is not a <gdb:objfile> object. */
static objfile_smob *
ofscm_get_objfile_smob_arg_unsafe (SCM self, int arg_pos,
const char *func_name)
{
SCM o_scm = ofscm_get_objfile_arg_unsafe (self, arg_pos, func_name);
objfile_smob *o_smob = (objfile_smob *) SCM_SMOB_DATA (o_scm);
return o_smob;
}
/* Return non-zero if objfile O_SMOB is valid. */
static int
ofscm_is_valid (objfile_smob *o_smob)
{
return o_smob->objfile != NULL;
}
/* Return the objfile smob in SELF, verifying it's valid.
Throws an exception if SELF is not a <gdb:objfile> object or is invalid. */
static objfile_smob *
ofscm_get_valid_objfile_smob_arg_unsafe (SCM self, int arg_pos,
const char *func_name)
{
objfile_smob *o_smob
= ofscm_get_objfile_smob_arg_unsafe (self, arg_pos, func_name);
if (!ofscm_is_valid (o_smob))
{
gdbscm_invalid_object_error (func_name, arg_pos, self,
_("<gdb:objfile>"));
}
return o_smob;
}
/* Objfile methods. */
/* (objfile-valid? <gdb:objfile>) -> boolean
Returns #t if this object file still exists in GDB. */
static SCM
gdbscm_objfile_valid_p (SCM self)
{
objfile_smob *o_smob
= ofscm_get_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
return scm_from_bool (o_smob->objfile != NULL);
}
/* (objfile-filename <gdb:objfile>) -> string
Returns the objfile's file name.
Throw's an exception if the underlying objfile is invalid. */
static SCM
gdbscm_objfile_filename (SCM self)
{
objfile_smob *o_smob
= ofscm_get_valid_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
return gdbscm_scm_from_c_string (objfile_name (o_smob->objfile));
}
/* (objfile-pretty-printers <gdb:objfile>) -> list
Returns the list of pretty-printers for this objfile. */
static SCM
gdbscm_objfile_pretty_printers (SCM self)
{
objfile_smob *o_smob
= ofscm_get_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
return o_smob->pretty_printers;
}
/* (set-objfile-pretty-printers! <gdb:objfile> list) -> unspecified
Set the pretty-printers for this objfile. */
static SCM
gdbscm_set_objfile_pretty_printers_x (SCM self, SCM printers)
{
objfile_smob *o_smob
= ofscm_get_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (printers)), printers,
SCM_ARG2, FUNC_NAME, _("list"));
o_smob->pretty_printers = printers;
return SCM_UNSPECIFIED;
}
/* The "current" objfile. This is set when gdb detects that a new
objfile has been loaded. It is only set for the duration of a call to
gdbscm_source_objfile_script; it is NULL at other times. */
static struct objfile *ofscm_current_objfile;
/* Set the current objfile to OBJFILE and then read FILE named FILENAME
as Guile code. This does not throw any errors. If an exception
occurs Guile will print the backtrace.
This is the extension_language_script_ops.objfile_script_sourcer
"method". */
void
gdbscm_source_objfile_script (const struct extension_language_defn *extlang,
struct objfile *objfile, FILE *file,
const char *filename)
{
char *msg;
ofscm_current_objfile = objfile;
msg = gdbscm_safe_source_script (filename);
if (msg != NULL)
{
fprintf_filtered (gdb_stderr, "%s", msg);
xfree (msg);
}
ofscm_current_objfile = NULL;
}
/* (current-objfile) -> <gdb:obfjile>
Return the current objfile, or #f if there isn't one.
Ideally this would be named ofscm_current_objfile, but that name is
taken by the variable recording the current objfile. */
static SCM
gdbscm_get_current_objfile (void)
{
if (ofscm_current_objfile == NULL)
return SCM_BOOL_F;
return ofscm_scm_from_objfile (ofscm_current_objfile);
}
/* (objfiles) -> list
Return a list of all objfiles in the current program space. */
static SCM
gdbscm_objfiles (void)
{
struct objfile *objf;
SCM result;
result = SCM_EOL;
ALL_OBJFILES (objf)
{
SCM item = ofscm_scm_from_objfile (objf);
result = scm_cons (item, result);
}
return scm_reverse_x (result, SCM_EOL);
}
/* Initialize the Scheme objfile support. */
static const scheme_function objfile_functions[] =
{
{ "objfile?", 1, 0, 0, gdbscm_objfile_p,
"\
Return #t if the object is a <gdb:objfile> object." },
{ "objfile-valid?", 1, 0, 0, gdbscm_objfile_valid_p,
"\
Return #t if the objfile is valid (hasn't been deleted from gdb)." },
{ "objfile-filename", 1, 0, 0, gdbscm_objfile_filename,
"\
Return the file name of the objfile." },
{ "objfile-pretty-printers", 1, 0, 0, gdbscm_objfile_pretty_printers,
"\
Return a list of pretty-printers of the objfile." },
{ "set-objfile-pretty-printers!", 2, 0, 0,
gdbscm_set_objfile_pretty_printers_x,
"\
Set the list of pretty-printers of the objfile." },
{ "current-objfile", 0, 0, 0, gdbscm_get_current_objfile,
"\
Return the current objfile if there is one or #f if there isn't one." },
{ "objfiles", 0, 0, 0, gdbscm_objfiles,
"\
Return a list of all objfiles in the current program space." },
END_FUNCTIONS
};
void
gdbscm_initialize_objfiles (void)
{
objfile_smob_tag
= gdbscm_make_smob_type (objfile_smob_name, sizeof (objfile_smob));
scm_set_smob_print (objfile_smob_tag, ofscm_print_objfile_smob);
gdbscm_define_functions (objfile_functions, 1);
ofscm_objfile_data_key
= register_objfile_data_with_cleanup (NULL, ofscm_handle_objfile_deleted);
}