* Check in Fred Fish's changes in these modules. Fred

will make ChangeLog entries for all of them.
This commit is contained in:
John Gilmore 1992-02-22 01:46:16 +00:00
parent 8e48d87af6
commit 1ab3bf1b14
50 changed files with 5270 additions and 1385 deletions

View File

@ -44,6 +44,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/user.h> /* After a.out.h */
#include <sys/file.h>
#include <sys/stat.h>
/* Work with core dump and executable files, for GDB.
This code would be in core.c if it weren't machine-dependent. */

View File

@ -63,11 +63,11 @@ examine_prologue (pc, rsize, msize, mfp_used)
{
long insn;
CORE_ADDR p = pc;
int misc_index = find_pc_misc_function (pc);
struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
struct prologue_info *mi = 0;
if (misc_index >= 0)
mi = (struct prologue_info *)misc_function_vector[misc_index].misc_info;
if (msymbol != NULL)
mi = (struct prologue_info *) msymbol -> misc_info;
if (mi != 0)
{
@ -247,13 +247,13 @@ examine_prologue (pc, rsize, msize, mfp_used)
}
done:
if (misc_index >= 0)
if (msymbol != NULL)
{
if (mi == 0)
{
/* Add a new cache entry. */
mi = (struct prologue_info *)xmalloc (sizeof (struct prologue_info));
misc_function_vector[misc_index].misc_info = (char *)mi;
msymbol -> misc_info = (char *)mi;
mi->rsize_valid = 0;
mi->msize_valid = 0;
mi->mfp_valid = 0;

View File

@ -43,9 +43,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
void
fetch_inferior_registers (regno)
int regno;
int regno; /* Original value discarded */
{
register int regno;
register unsigned int regaddr;
char buf[MAX_REGISTER_RAW_SIZE];
register int i;
@ -83,6 +82,7 @@ fetch_inferior_registers (regno)
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
store_inferior_registers (regno)
int regno;
{

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,9 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (BUILDSYM_H)
#define BUILDSYM_H 1
/* This module provides definitions used for creating and adding to
the symbol table. These routines are called from various symbol-
file-reading routines.
@ -33,36 +36,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define EXTERN extern
#endif
extern void add_symbol_to_list ();
struct symbol *find_symbol_in_list ();
extern void read_type_number ();
extern struct type *read_type ();
extern struct type *read_range_type ();
extern struct type *read_enum_type ();
extern struct type *read_struct_type ();
extern struct type *read_array_type ();
extern struct type **read_args ();
extern struct type **dbx_lookup_type ();
extern long read_number ();
extern void finish_block ();
extern struct blockvector *make_blockvector ();
extern void add_undefined_type ();
extern void really_free_pendings ();
extern void start_subfile ();
extern void push_subfile ();
extern char *pop_subfile ();
extern struct symtab *end_symtab ();
extern void scan_file_globals ();
extern void buildsym_new_init ();
extern void buildsym_init ();
extern struct context_stack *push_context ();
extern void record_line ();
extern void start_symtab ();
extern struct symbol *define_symbol ();
extern struct partial_symtab *start_psymtab ();
extern void end_psymtab();
/* Convert stab register number (from `r' declaration) to a gdb REGNUM. */
#ifndef STAB_REG_TO_REGNUM
@ -309,4 +282,82 @@ extern struct complaint unknown_symtype_complaint;
/* Function to invoke get the next symbol. Return the symbol name. */
EXTERN char * (*next_symbol_text_func)();
EXTERN char *(*next_symbol_text_func) PARAMS ((void));
extern void
add_symbol_to_list PARAMS ((struct symbol *, struct pending **));
extern struct symbol *
find_symbol_in_list PARAMS ((struct pending *, char *, int));
extern void
read_type_number PARAMS ((char **, int *));
extern struct type *
read_type PARAMS ((char **, struct objfile *));
extern struct type **
dbx_lookup_type PARAMS ((int [2]));
extern long
read_number PARAMS ((char **, int));
extern void
finish_block PARAMS ((struct symbol *, struct pending **,
struct pending_block *, CORE_ADDR, CORE_ADDR,
struct objfile *));
extern void
add_undefined_type PARAMS ((struct type *));
extern void
really_free_pendings PARAMS ((int foo));
extern void
start_subfile PARAMS ((char *, char *));
extern void
push_subfile PARAMS ((void));
extern char *
pop_subfile PARAMS ((void));
extern struct symtab *
end_symtab PARAMS ((CORE_ADDR, int, int,struct objfile *));
extern void
scan_file_globals PARAMS ((struct objfile *));
extern void
buildsym_new_init PARAMS ((void));
extern void
buildsym_init PARAMS ((void));
extern struct context_stack *
push_context PARAMS ((int, CORE_ADDR));
extern void
record_line PARAMS ((struct subfile *, int, CORE_ADDR));
extern void
start_symtab PARAMS ((char *, char *, CORE_ADDR));
extern struct symbol *
define_symbol PARAMS ((unsigned int, char *, int, int, struct objfile *));
extern struct partial_symtab *
start_psymtab PARAMS ((struct objfile *, CORE_ADDR, char *, CORE_ADDR, int,
struct partial_symbol *, struct partial_symbol *));
extern void
end_psymtab PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR,
struct partial_symtab **, int));
extern void
process_one_symbol PARAMS ((int, int, CORE_ADDR, char *, int));
extern int
hashname PARAMS ((char *));
#endif /* defined (BUILDSYM_H) */

View File

@ -32,6 +32,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <string.h>
#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "frame.h"
#include "expression.h"
#include "parser-defs.h"
@ -68,10 +69,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define yyval c_val
#define yylloc c_lloc
/* Forward decls */
void yyerror ();
static int parse_number ();
int yyparse ();
static void
__yy_bcopy PARAMS ((char *, char *, int));
int
yyparse PARAMS ((void));
int
yylex PARAMS ((void));
void
yyerror PARAMS ((char *));
/* #define YYDEBUG 1 */
@ -100,6 +108,12 @@ int yyparse ();
int *ivec;
}
%{
/* YYSTYPE gets defined by %union */
static int
parse_number PARAMS ((char *, int, int, YYSTYPE *));
%}
%type <voidval> exp exp1 type_exp start variable
%type <tval> type typebase
%type <tvec> nonempty_typelist
@ -564,7 +578,7 @@ variable: typebase COLONCOLON name
{
char *name = copy_name ($2);
struct symbol *sym;
int i;
struct minimal_symbol *msymbol;
sym =
lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);
@ -575,31 +589,27 @@ variable: typebase COLONCOLON name
write_exp_elt_opcode (OP_VAR_VALUE);
break;
}
for (i = 0; i < misc_function_count; i++)
if (!strcmp (misc_function_vector[i].name, name))
break;
if (i < misc_function_count)
msymbol = lookup_minimal_symbol (name,
(struct objfile *) NULL);
if (msymbol != NULL)
{
enum misc_function_type mft =
misc_function_vector[i].type;
write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_int);
write_exp_elt_longcst ((LONGEST) misc_function_vector[i].address);
write_exp_elt_longcst ((LONGEST) msymbol -> address);
write_exp_elt_opcode (OP_LONG);
write_exp_elt_opcode (UNOP_MEMVAL);
if (mft == mf_data || mft == mf_bss)
if (msymbol -> type == mst_data ||
msymbol -> type == mst_bss)
write_exp_elt_type (builtin_type_int);
else if (mft == mf_text)
else if (msymbol -> type == mst_text)
write_exp_elt_type (lookup_function_type (builtin_type_int));
else
write_exp_elt_type (builtin_type_char);
write_exp_elt_opcode (UNOP_MEMVAL);
}
else
if (symtab_list == 0
&& partial_symtab_list == 0)
if (!have_full_symbols () && !have_partial_symbols ())
error ("No symbol table is loaded. Use the \"file\" command.");
else
error ("No symbol \"%s\" in current context.", name);
@ -662,35 +672,28 @@ variable: name_not_typename
}
else
{
register int i;
struct minimal_symbol *msymbol;
register char *arg = copy_name ($1.stoken);
/* FIXME, this search is linear! At least
optimize the strcmp with a 1-char cmp... */
for (i = 0; i < misc_function_count; i++)
if (!strcmp (misc_function_vector[i].name, arg))
break;
if (i < misc_function_count)
msymbol = lookup_minimal_symbol (arg,
(struct objfile *) NULL);
if (msymbol != NULL)
{
enum misc_function_type mft =
misc_function_vector[i].type;
write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_int);
write_exp_elt_longcst ((LONGEST) misc_function_vector[i].address);
write_exp_elt_longcst ((LONGEST) msymbol -> address);
write_exp_elt_opcode (OP_LONG);
write_exp_elt_opcode (UNOP_MEMVAL);
if (mft == mf_data || mft == mf_bss)
if (msymbol -> type == mst_data ||
msymbol -> type == mst_bss)
write_exp_elt_type (builtin_type_int);
else if (mft == mf_text)
else if (msymbol -> type == mst_text)
write_exp_elt_type (lookup_function_type (builtin_type_int));
else
write_exp_elt_type (builtin_type_char);
write_exp_elt_opcode (UNOP_MEMVAL);
}
else if (symtab_list == 0
&& partial_symtab_list == 0)
else if (!have_full_symbols () && !have_partial_symbols ())
error ("No symbol table is loaded. Use the \"file\" command.");
else
error ("No symbol \"%s\" in current context.",
@ -869,7 +872,7 @@ nonempty_typelist
}
| nonempty_typelist ',' type
{ int len = sizeof (struct type *) * ++($<ivec>1[0]);
$$ = (struct type **)xrealloc ($1, len);
$$ = (struct type **)xrealloc ((char *) $1, len);
$$[$<ivec>$[0]] = $3;
}
;
@ -915,8 +918,6 @@ parse_number (p, len, parsed_float, putithere)
register int base = input_radix;
int unsigned_p = 0;
extern double atof ();
if (parsed_float)
{
/* It's a float since it contains a point or an exponent. */
@ -1535,53 +1536,69 @@ void
_initialize_c_exp ()
{
builtin_type_void =
init_type (TYPE_CODE_VOID, 1, 0,
"void");
init_type (TYPE_CODE_VOID, 1,
0,
"void", (struct objfile *) NULL);
builtin_type_char =
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, 0,
"char");
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
0,
"char", (struct objfile *) NULL);
builtin_type_unsigned_char =
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, 1,
"unsigned char");
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"unsigned char", (struct objfile *) NULL);
builtin_type_short =
init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT, 0,
"short");
init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
0,
"short", (struct objfile *) NULL);
builtin_type_unsigned_short =
init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT, 1,
"unsigned short");
init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"unsigned short", (struct objfile *) NULL);
builtin_type_int =
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, 0,
"int");
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
0,
"int", (struct objfile *) NULL);
builtin_type_unsigned_int =
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, 1,
"unsigned int");
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"unsigned int", (struct objfile *) NULL);
builtin_type_long =
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT, 0,
"long");
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
0,
"long", (struct objfile *) NULL);
builtin_type_unsigned_long =
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT, 1,
"unsigned long");
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"unsigned long", (struct objfile *) NULL);
builtin_type_long_long =
init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, 0,
"long long");
init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
0,
"long long", (struct objfile *) NULL);
builtin_type_unsigned_long_long =
init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, 1,
"unsigned long long");
init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"unsigned long long", (struct objfile *) NULL);
builtin_type_float =
init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT, 0,
"float");
init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
0,
"float", (struct objfile *) NULL);
builtin_type_double =
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, 0,
"double");
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
0,
"double", (struct objfile *) NULL);
builtin_type_long_double =
init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, 0,
"long double");
init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
0,
"long double", (struct objfile *) NULL);
builtin_type_complex =
init_type (TYPE_CODE_FLT, TARGET_COMPLEX_BIT / TARGET_CHAR_BIT, 0,
"complex");
init_type (TYPE_CODE_FLT, TARGET_COMPLEX_BIT / TARGET_CHAR_BIT,
0,
"complex", (struct objfile *) NULL);
builtin_type_double_complex =
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT, 0,
"double complex");
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
0,
"double complex", (struct objfile *) NULL);
add_language (&c_language_defn);
add_language (&cplus_language_defn);

View File

@ -23,7 +23,28 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <ctype.h>
#include <string.h>
extern char *getenv ();
/* Prototypes for local functions */
static void
undef_cmd_error PARAMS ((char *, char *));
static void
show_user PARAMS ((char *, int));
static void
show_user_1 PARAMS ((struct cmd_list_element *, FILE *));
static void
make_command PARAMS ((char *, int));
static void
shell_escape PARAMS ((char *, int));
static int
parse_binary_operation PARAMS ((char *));
static void
print_doc_line PARAMS ((FILE *, char *));
/* Add element named NAME to command list *LIST.
FUN should be the function to execute the command;
@ -39,7 +60,7 @@ struct cmd_list_element *
add_cmd (name, class, fun, doc, list)
char *name;
enum command_class class;
void (*fun) ();
void (*fun) PARAMS ((char *, int));
char *doc;
struct cmd_list_element **list;
{
@ -50,7 +71,7 @@ add_cmd (name, class, fun, doc, list)
c->next = *list;
c->name = name;
c->class = class;
c->function = fun;
c->function.cfunc = fun;
c->doc = doc;
c->prefixlist = 0;
c->prefixname = (char *)NULL;
@ -68,11 +89,13 @@ add_cmd (name, class, fun, doc, list)
/* Same as above, except that the abbrev_flag is set. */
#if 0 /* Currently unused */
struct cmd_list_element *
add_abbrev_cmd (name, class, fun, doc, list)
char *name;
enum command_class class;
void (*fun) ();
void (*fun) PARAMS ((char *, int));
char *doc;
struct cmd_list_element **list;
{
@ -83,6 +106,8 @@ add_abbrev_cmd (name, class, fun, doc, list)
return c;
}
#endif
struct cmd_list_element *
add_alias_cmd (name, oldname, class, abbrev_flag, list)
char *name;
@ -105,7 +130,7 @@ add_alias_cmd (name, oldname, class, abbrev_flag, list)
return 0;
}
c = add_cmd (name, class, old->function, old->doc, list);
c = add_cmd (name, class, old->function.cfunc, old->doc, list);
c->prefixlist = old->prefixlist;
c->prefixname = old->prefixname;
c->allow_unknown = old->allow_unknown;
@ -124,7 +149,7 @@ add_prefix_cmd (name, class, fun, doc, prefixlist, prefixname,
allow_unknown, list)
char *name;
enum command_class class;
void (*fun) ();
void (*fun) PARAMS ((char *, int));
char *doc;
struct cmd_list_element **prefixlist;
char *prefixname;
@ -142,10 +167,10 @@ add_prefix_cmd (name, class, fun, doc, prefixlist, prefixname,
struct cmd_list_element *
add_abbrev_prefix_cmd (name, class, fun, doc, prefixlist, prefixname,
allow_unknown, list)
allow_unknown, list)
char *name;
enum command_class class;
void (*fun) ();
void (*fun) PARAMS ((char *, int));
char *doc;
struct cmd_list_element **prefixlist;
char *prefixname;
@ -175,6 +200,7 @@ not_just_help_class_command (args, from_tty, c)
VAR_TYPE is the kind of thing we are setting.
VAR is address of the variable being controlled by this command.
DOC is the documentation string. */
struct cmd_list_element *
add_set_cmd (name, class, var_type, var, doc, list)
char *name;
@ -300,7 +326,7 @@ help_cmd (command, stream)
fputs_filtered (c->doc, stream);
fputs_filtered ("\n", stream);
if (c->prefixlist == 0 && c->function != 0)
if (c->prefixlist == 0 && c->function.cfunc != NULL)
return;
fprintf_filtered (stream, "\n");
@ -309,7 +335,7 @@ help_cmd (command, stream)
help_list (*c->prefixlist, c->prefixname, all_commands, stream);
/* If this is a class name, print all of the commands in the class */
if (c->function == 0)
if (c->function.cfunc == NULL)
help_list (cmdlist, "", c->class, stream);
}
@ -413,7 +439,7 @@ print_doc_line (stream, str)
* ALL_CLASSES to list all classes in list.
*
* Note that RECURSE will be active on *all* sublists, not just the
* ones seclected by the criteria above (ie. the selection mechanism
* ones selected by the criteria above (ie. the selection mechanism
* is at the low level, not the high-level).
*/
void
@ -430,8 +456,8 @@ help_cmd_list (list, class, prefix, recurse, stream)
{
if (c->abbrev_flag == 0 &&
(class == all_commands
|| (class == all_classes && c->function == 0)
|| (class == c->class && c->function != 0)))
|| (class == all_classes && c->function.cfunc == NULL)
|| (class == c->class && c->function.cfunc != NULL)))
{
fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
print_doc_line (stream, c->doc);
@ -519,7 +545,7 @@ lookup_cmd_1 (text, clist, result_list, ignore_help_classes)
nfound = 0;
for (c = clist; c; c = c->next)
if (!strncmp (command, c->name, len)
&& (!ignore_help_classes || c->function))
&& (!ignore_help_classes || c->function.cfunc))
{
found = c;
nfound++;
@ -587,7 +613,7 @@ lookup_cmd_1 (text, clist, result_list, ignore_help_classes)
/* All this hair to move the space to the front of cmdtype */
void
static void
undef_cmd_error (cmdtype, q)
char *cmdtype, *q;
{
@ -881,7 +907,7 @@ complete_on_cmdlist (list, text)
for (ptr = list; ptr; ptr = ptr->next)
if (!strncmp (ptr->name, text, textlen)
&& !ptr->abbrev_flag
&& (ptr->function
&& (ptr->function.cfunc
|| ptr->prefixlist))
{
if (matches == sizeof_matchlist)
@ -967,7 +993,7 @@ do_setshow_command (arg, from_tty, c)
arg = "";
new = (char *) xmalloc (strlen (arg) + 2);
p = arg; q = new;
while (ch = *p++)
while ((ch = *p++) != '\000')
{
if (ch == '\\')
{
@ -1069,7 +1095,7 @@ do_setshow_command (arg, from_tty, c)
}
else
error ("gdb internal error: bad cmd_type in do_setshow_command");
(*c->function) (NULL, from_tty, c);
(*c->function.sfunc) (NULL, from_tty, c);
}
/* Show all the settings in a list of show commands. */
@ -1103,13 +1129,12 @@ shell_escape (arg, from_tty)
{
int rc, status, pid;
char *p, *user_shell;
extern char *rindex ();
if ((user_shell = (char *) getenv ("SHELL")) == NULL)
user_shell = "/bin/sh";
/* Get the name of the shell for arg0 */
if ((p = rindex (user_shell, '/')) == NULL)
if ((p = strrchr (user_shell, '/')) == NULL)
p = user_shell;
else
p++; /* Get past '/' */

View File

@ -258,6 +258,7 @@ fetch_inferior_registers (regno)
/* Store our register values back into the inferior.
For Convex, do this only once, right before resuming inferior. */
void
store_inferior_registers (regno)
int regno;
{

View File

@ -35,7 +35,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/ptrace.h>
#endif
/* Extract the register values out of the core file and store
them where `read_register' will find them.

View File

@ -60,10 +60,6 @@
#include <string.h>
#else
#include <strings.h>
#define memcpy(s1, s2, n) bcopy ((s2), (s1), (n))
#define memcmp(s1, s2, n) bcmp ((s2), (s1), (n))
#define strchr index
#define strrchr rindex
#endif
/* This is '$' on systems where the assembler can deal with that.
@ -187,49 +183,60 @@ typedef struct string {
char *e; /* pointer after end of allocated space */
} string;
#ifdef __STDC__
static void string_need (string *s, int n);
static void string_delete (string *s);
static void string_init (string *s);
static void string_clear (string *s);
static int string_empty (string *s);
static void string_append (string *p, const char *s);
static void string_appends (string *p, string *s);
static void string_appendn (string *p, const char *s, int n);
static void string_prepend (string *p, const char *s);
static void
string_need PARAMS ((string *, int));
static void
string_delete PARAMS ((string *));
static void
string_init PARAMS ((string *));
static void
string_clear PARAMS ((string *));
static int
string_empty PARAMS ((string *));
static void
string_append PARAMS ((string *, const char *));
static void
string_appends PARAMS ((string *, string *));
static void
string_appendn PARAMS ((string *, const char *, int));
static void
string_prepend PARAMS ((string *, const char *));
static void
string_prependn PARAMS ((string *, const char *, int));
static int
get_count PARAMS ((const char **, int *));
static int
do_args PARAMS ((const char **, string *, int));
static int
do_type PARAMS ((const char **, string *, int));
static int
do_arg PARAMS ((const char **, string *, int));
static void
munge_function_name PARAMS ((string *, int));
static void
remember_type PARAMS ((const char *, int));
#if 0
static void string_prepends (string *p, string *s);
#endif
static void string_prependn (string *p, const char *s, int n);
static int get_count (const char **type, int *count);
static int do_args (const char **type, string *decl, int arg_mode);
static int do_type (const char **type, string *result, int arg_mode);
static int do_arg (const char **type, string *result, int arg_mode);
static void munge_function_name (string *name, int arg_mode);
static void remember_type (const char *type, int len);
#else
static void string_need ();
static void string_delete ();
static void string_init ();
static void string_clear ();
static int string_empty ();
static void string_append ();
static void string_appends ();
static void string_appendn ();
static void string_prepend ();
#if 0
static void string_prepends ();
#endif
static void string_prependn ();
static int get_count ();
static int do_args ();
static int do_type ();
static int do_arg ();
static int do_args ();
static void munge_function_name ();
static void remember_type ();
static void
string_prepends PARAMS ((string *, string *));
#endif
/* Takes operator name as e.g. "++" and returns mangled
operator name (e.g. "postincrement_expr"), or NULL if not found.

File diff suppressed because it is too large Load Diff

View File

@ -29,10 +29,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
* FIXME Still needs support for shared libraries. *
* FIXME Still needs support for core files. *
* FIXME The ".debug" and ".line" section names are hardwired. *
* FIXME Still needs support ELF symbol tables (as distinct *
* from DWARF support). Can use them to build the misc *
* function vector at least. This is fairly trivial once *
* bfd is extended to handle ELF symbol tables. *
* *
************************************************************************/
@ -43,15 +39,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "elf/external.h"
#include "elf/internal.h"
#include "bfd.h"
#include "symfile.h"
#include "symtab.h"
#include "ansidecl.h"
extern int EXFUN (strcmp, (CONST char *a, CONST char *b));
extern int EXFUN (dwarf_build_psymtabs,
(int desc, char *filename, CORE_ADDR addr, int mainline,
unsigned int dbfoff, unsigned int dbsize, unsigned int lnoffset,
unsigned int lnsize, struct objfile *objfile));
#include "symfile.h"
#define STREQ(a,b) (strcmp((a),(b))==0)
@ -62,6 +51,25 @@ struct elfinfo {
unsigned int lnsize; /* Size of dwarf line number section */
};
static void
elf_symfile_init PARAMS ((struct sym_fns *));
static void
elf_new_init PARAMS ((void));
static void
elf_symfile_read PARAMS ((struct sym_fns *, CORE_ADDR, int));
static void
elf_symtab_read PARAMS ((bfd *, CORE_ADDR, int, struct objfile *));
static void
record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type,
struct objfile *));
static void
elf_locate_sections PARAMS ((bfd *, asection *, PTR));
/* We are called once per section from elf_symfile_read. We
need to examine each section we are passed, check to see
if it is something we are interested in processing, and
@ -76,11 +84,14 @@ struct elfinfo {
FIXME: The section names should not be hardwired strings. */
static void
DEFUN(elf_locate_sections, (abfd, sectp, ei),
bfd *abfd AND
asection *sectp AND
struct elfinfo *ei)
elf_locate_sections (abfd, sectp, eip)
bfd *abfd;
asection *sectp;
PTR eip;
{
register struct elfinfo *ei;
ei = (struct elfinfo *) eip;
if (STREQ (sectp -> name, ".debug"))
{
ei -> dboffset = sectp -> filepos;
@ -93,9 +104,11 @@ DEFUN(elf_locate_sections, (abfd, sectp, ei),
}
}
#if 0 /* Currently unused */
char *
DEFUN(elf_interpreter, (abfd),
bfd *abfd)
elf_interpreter (abfd)
bfd *abfd;
{
sec_ptr interp_sec;
unsigned size;
@ -119,35 +132,35 @@ DEFUN(elf_interpreter, (abfd),
return (interp);
}
#endif
/*
LOCAL FUNCTION
record_misc_function -- add entry to miscellaneous function vector
record_minimal_symbol -- add entry to minimal symbol table
SYNOPSIS
static void record_misc_function (char *name, CORE_ADDR address)
static void record_minimal_symbol (char *name, CORE_ADDR address)
DESCRIPTION
Given a pointer to the name of a symbol that should be added to the
miscellaneous function vector, and the address associated with that
symbol, records this information for later use in building the
miscellaneous function vector.
minimal symbol table and the address associated with that symbol, records
this information for later use in building the minimal symbol table.
NOTES
FIXME: For now we just use mf_unknown as the type. This should be
fixed.
*/
static void
DEFUN(record_misc_function, (name, address, mf_type),
char *name AND CORE_ADDR address AND enum misc_function_type mf_type)
record_minimal_symbol (name, address, ms_type, objfile)
char *name;
CORE_ADDR address;
enum minimal_symbol_type ms_type;
struct objfile *objfile;
{
prim_record_misc_function (obsavestring (name, strlen (name)), address,
mf_type);
name = obsavestring (name, strlen (name), &objfile -> symbol_obstack);
prim_record_minimal_symbol (name, address, ms_type);
}
/*
@ -158,22 +171,24 @@ LOCAL FUNCTION
SYNOPSIS
void elf_symtab_read (bfd *abfd, CORE_ADDR addr, int mainline)
void elf_symtab_read (bfd *abfd, CORE_ADDR addr, int mainline,
struct objfile *objfile)
DESCRIPTION
Given an open bfd, a base address to relocate symbols to, and a
flag that specifies whether or not this bfd is for an executable
or not (may be shared library for example), add all the global
function and data symbols to the miscellaneous function vector.
function and data symbols to the minimal symbol table.
*/
static void
DEFUN (elf_symtab_read, (abfd, addr, mainline),
bfd *abfd AND
CORE_ADDR addr AND
int mainline)
elf_symtab_read (abfd, addr, mainline, objfile)
bfd *abfd;
CORE_ADDR addr;
int mainline;
struct objfile *objfile;
{
unsigned int storage_needed;
asymbol *sym;
@ -182,7 +197,7 @@ DEFUN (elf_symtab_read, (abfd, addr, mainline),
unsigned int i;
struct cleanup *back_to;
CORE_ADDR symaddr;
enum misc_function_type mf_type;
enum minimal_symbol_type ms_type;
storage_needed = get_symtab_upper_bound (abfd);
@ -214,17 +229,17 @@ DEFUN (elf_symtab_read, (abfd, addr, mainline),
no way of figuring this out for absolute symbols. */
if (sym -> section -> flags & SEC_CODE)
{
mf_type = mf_text;
ms_type = mst_text;
}
else if (sym -> section -> flags & SEC_DATA)
{
mf_type = mf_data;
ms_type = mst_data;
}
else
{
mf_type = mf_unknown;
ms_type = mst_unknown;
}
record_misc_function ((char *) sym -> name, symaddr, mf_type);
record_minimal_symbol ((char *) sym -> name, symaddr, ms_type, objfile);
}
}
do_cleanups (back_to);
@ -253,32 +268,32 @@ DEFUN (elf_symtab_read, (abfd, addr, mainline),
Note that ELF files have a "minimal" symbol table, which looks a lot
like a COFF symbol table, but has only the minimal information necessary
for linking. We process this also, and just use the information to
add to the misc function vector. This gives us some minimal debugging
add to gdb's minimal symbol table. This gives us some minimal debugging
capability even for files compiled without -g.
*/
static void
DEFUN(elf_symfile_read, (sf, addr, mainline),
struct sym_fns *sf AND
CORE_ADDR addr AND
int mainline)
elf_symfile_read (sf, addr, mainline)
struct sym_fns *sf;
CORE_ADDR addr;
int mainline;
{
bfd *abfd = sf->objfile->obfd;
struct elfinfo ei;
struct cleanup *back_to;
init_misc_bunches ();
back_to = make_cleanup (discard_misc_bunches, 0);
init_minimal_symbol_collection ();
back_to = make_cleanup (discard_minimal_symbols, 0);
/* Process the normal ELF symbol table first. */
elf_symtab_read (abfd, addr, mainline);
elf_symtab_read (abfd, addr, mainline, sf->objfile);
/* Now process the DWARF debugging information, which is contained in
special ELF sections. We first have to find them... */
(void) memset ((char *) &ei, 0, sizeof (ei));
bfd_map_over_sections (abfd, elf_locate_sections, &ei);
bfd_map_over_sections (abfd, elf_locate_sections, (PTR) &ei);
if (ei.dboffset && ei.lnoffset)
{
dwarf_build_psymtabs (fileno ((FILE *)(abfd -> iostream)),
@ -288,17 +303,18 @@ DEFUN(elf_symfile_read, (sf, addr, mainline),
ei.lnoffset, ei.lnsize, sf->objfile);
}
if (!partial_symtab_list)
if (!have_partial_symbols ())
{
wrap_here ("");
printf_filtered ("(no debugging symbols found)...");
wrap_here ("");
}
/* Go over the miscellaneous functions and install them in the
miscellaneous function vector. */
condense_misc_bunches (!mainline);
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
install_minimal_symbols (!mainline, sf -> objfile);
do_cleanups (back_to);
}
@ -310,7 +326,7 @@ DEFUN(elf_symfile_read, (sf, addr, mainline),
just a stub. */
static void
DEFUN_VOID (elf_new_init)
elf_new_init ()
{
}
@ -324,8 +340,8 @@ DEFUN_VOID (elf_new_init)
just a stub. */
static void
DEFUN(elf_symfile_init, (sf),
struct sym_fns *sf)
elf_symfile_init (sf)
struct sym_fns *sf;
{
}
@ -358,7 +374,7 @@ static struct sym_fns elf_sym_fns = {
};
void
DEFUN_VOID (_initialize_elfread)
_initialize_elfread ()
{
add_symtab_fns (&elf_sym_fns);
}

956
gdb/gdbtypes.c Normal file
View File

@ -0,0 +1,956 @@
/* Support routines for manipulating internal types for GDB.
Copyright (C) 1992 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "defs.h"
#include "bfd.h"
#include "symtab.h"
#include "symfile.h"
#include "gdbtypes.h"
#include "expression.h"
#include "language.h"
#include "target.h"
#include "value.h"
/* Alloc a new type structure and fill it with some defaults. If
OBJFILE is non-NULL, then allocate the space for the type structure
in that objfile's type_obstack. */
struct type *
alloc_type (objfile)
struct objfile *objfile;
{
register struct type *type;
/* Alloc the structure and start off with all fields zeroed. */
if (objfile == NULL)
{
type = (struct type *) xmalloc (sizeof (struct type));
}
else
{
type = (struct type *) obstack_alloc (&objfile -> type_obstack,
sizeof (struct type));
}
(void) memset (type, 0, sizeof (struct type));
/* Initialize the fields that might not be zero. */
TYPE_CODE (type) = TYPE_CODE_UNDEF;
TYPE_OBJFILE (type) = objfile;
TYPE_VPTR_FIELDNO (type) = -1;
return (type);
}
/* Given a type TYPE, return a type of pointers to that type.
May need to construct such a type if this is the first use. */
struct type *
lookup_pointer_type (type)
struct type *type;
{
register struct type *ptype;
if ((ptype = TYPE_POINTER_TYPE (type)) == NULL)
{
/* This is the first time anyone wanted a pointer to a TYPE. */
ptype = alloc_type (TYPE_OBJFILE (type));
TYPE_TARGET_TYPE (ptype) = type;
TYPE_POINTER_TYPE (type) = ptype;
/* We assume the machine has only one representation for pointers! */
/* FIXME: This confuses host<->target data representations, and is a
poor assumption besides. */
TYPE_LENGTH (ptype) = sizeof (char *);
TYPE_CODE (ptype) = TYPE_CODE_PTR;
}
return (ptype);
}
struct type *
lookup_reference_type (type)
struct type *type;
{
register struct type *rtype;
if ((rtype = TYPE_REFERENCE_TYPE (type)) == NULL)
{
/* This is the first time anyone wanted a pointer to a TYPE. */
rtype = alloc_type (TYPE_OBJFILE (type));
TYPE_TARGET_TYPE (rtype) = type;
TYPE_REFERENCE_TYPE (type) = rtype;
/* We assume the machine has only one representation for pointers! */
/* FIXME: This confuses host<->target data representations, and is a
poor assumption besides. */
TYPE_LENGTH (rtype) = sizeof (char *);
TYPE_CODE (rtype) = TYPE_CODE_REF;
}
return (rtype);
}
/* Given a type TYPE, return a type of functions that return that type.
May need to construct such a type if this is the first use. */
struct type *
lookup_function_type (type)
struct type *type;
{
register struct type *ptype;
if ((ptype = TYPE_FUNCTION_TYPE (type)) == NULL)
{
/* This is the first time anyone wanted a function returning a TYPE. */
ptype = alloc_type (TYPE_OBJFILE (type));
TYPE_TARGET_TYPE (ptype) = type;
TYPE_FUNCTION_TYPE (type) = ptype;
TYPE_LENGTH (ptype) = 1;
TYPE_CODE (ptype) = TYPE_CODE_FUNC;
}
return (ptype);
}
/* Implement direct support for MEMBER_TYPE in GNU C++.
May need to construct such a type if this is the first use.
The TYPE is the type of the member. The DOMAIN is the type
of the aggregate that the member belongs to. */
struct type *
lookup_member_type (type, domain)
struct type *type;
struct type *domain;
{
register struct type *mtype;
mtype = alloc_type (TYPE_OBJFILE (type));
smash_to_member_type (mtype, domain, type);
return (mtype);
}
/* Allocate a stub method whose return type is TYPE.
This apparently happens for speed of symbol reading, since parsing
out the arguments to the method is cpu-intensive, the way we are doing
it. So, we will fill in arguments later.
This always returns a fresh type. */
struct type *
allocate_stub_method (type)
struct type *type;
{
struct type *mtype;
mtype = alloc_type (TYPE_OBJFILE (type));
TYPE_TARGET_TYPE (mtype) = type;
/* _DOMAIN_TYPE (mtype) = unknown yet */
/* _ARG_TYPES (mtype) = unknown yet */
TYPE_FLAGS (mtype) = TYPE_FLAG_STUB;
TYPE_CODE (mtype) = TYPE_CODE_METHOD;
TYPE_LENGTH (mtype) = 1;
return (mtype);
}
/* Create an array type. Elements will be of type TYPE, and there will
be NUM of them.
Eventually this should be extended to take two more arguments which
specify the bounds of the array and the type of the index.
It should also be changed to be a "lookup" function, with the
appropriate data structures added to the type field.
Then read array type should call here. */
struct type *
create_array_type (element_type, number)
struct type *element_type;
int number;
{
struct type *result_type;
struct type *range_type;
result_type = alloc_type (TYPE_OBJFILE (element_type));
TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
TYPE_TARGET_TYPE (result_type) = element_type;
TYPE_LENGTH (result_type) = number * TYPE_LENGTH (element_type);
TYPE_NFIELDS (result_type) = 1;
TYPE_FIELDS (result_type) = (struct field *)
obstack_alloc (&TYPE_OBJFILE (result_type) -> type_obstack,
sizeof (struct field));
{
/* Create range type. */
range_type = alloc_type (TYPE_OBJFILE (result_type));
TYPE_CODE (range_type) = TYPE_CODE_RANGE;
TYPE_TARGET_TYPE (range_type) = builtin_type_int; /* FIXME */
/* This should never be needed. */
TYPE_LENGTH (range_type) = sizeof (int);
TYPE_NFIELDS (range_type) = 2;
TYPE_FIELDS (range_type) = (struct field *)
obstack_alloc (&TYPE_OBJFILE (range_type) -> type_obstack,
2 * sizeof (struct field));
TYPE_FIELD_BITPOS (range_type, 0) = 0; /* FIXME */
TYPE_FIELD_BITPOS (range_type, 1) = number-1; /* FIXME */
TYPE_FIELD_TYPE (range_type, 0) = builtin_type_int; /* FIXME */
TYPE_FIELD_TYPE (range_type, 1) = builtin_type_int; /* FIXME */
}
TYPE_FIELD_TYPE(result_type,0)=range_type;
TYPE_VPTR_FIELDNO (result_type) = -1;
return (result_type);
}
/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE.
A MEMBER is a wierd thing -- it amounts to a typed offset into
a struct, e.g. "an int at offset 8". A MEMBER TYPE doesn't
include the offset (that's the value of the MEMBER itself), but does
include the structure type into which it points (for some reason).
FIXME: When "smashing" the type, we preserve the objfile that the
old type pointed to, since we aren't changing where the type is actually
allocated. If the two types aren't associated with the same objfile,
then we are in deep-s**t anyway... */
void
smash_to_member_type (type, domain, to_type)
struct type *type;
struct type *domain;
struct type *to_type;
{
struct objfile *objfile;
objfile = TYPE_OBJFILE (type);
(void) memset (type, 0, sizeof (struct type));
TYPE_OBJFILE (type) = objfile;
TYPE_TARGET_TYPE (type) = to_type;
TYPE_DOMAIN_TYPE (type) = domain;
TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
TYPE_CODE (type) = TYPE_CODE_MEMBER;
}
/* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE.
METHOD just means `function that gets an extra "this" argument'.
FIXME: When "smashing" the type, we preserve the objfile that the
old type pointed to, since we aren't changing where the type is actually
allocated. If the two types aren't associated with the same objfile,
then we are in deep-s**t anyway... */
void
smash_to_method_type (type, domain, to_type, args)
struct type *type;
struct type *domain;
struct type *to_type;
struct type **args;
{
struct objfile *objfile;
objfile = TYPE_OBJFILE (type);
(void) memset (type, 0, sizeof (struct type));
TYPE_OBJFILE (type) = objfile;
TYPE_TARGET_TYPE (type) = to_type;
TYPE_DOMAIN_TYPE (type) = domain;
TYPE_ARG_TYPES (type) = args;
TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
TYPE_CODE (type) = TYPE_CODE_METHOD;
}
/* Return a typename for a struct/union/enum type
without the tag qualifier. If the type has a NULL name,
NULL is returned. */
char *
type_name_no_tag (type)
register const struct type *type;
{
register char *name;
if ((name = TYPE_NAME (type)) != NULL)
{
switch (TYPE_CODE (type))
{
case TYPE_CODE_STRUCT:
if(!strncmp (name, "struct ", 7))
{
name += 7;
}
break;
case TYPE_CODE_UNION:
if(!strncmp (name, "union ", 6))
{
name += 6;
}
break;
case TYPE_CODE_ENUM:
if(!strncmp (name, "enum ", 5))
{
name += 5;
}
break;
}
}
return (name);
}
/* Lookup a primitive type named NAME.
Return zero if NAME is not a primitive type.*/
struct type *
lookup_primitive_typename (name)
char *name;
{
struct type ** const *p;
for (p = current_language -> la_builtin_type_vector; *p != NULL; p++)
{
if (!strcmp ((**p) -> name, name))
{
return (**p);
}
}
return (NULL);
}
/* Lookup a typedef or primitive type named NAME,
visible in lexical block BLOCK.
If NOERR is nonzero, return zero if NAME is not suitably defined. */
struct type *
lookup_typename (name, block, noerr)
char *name;
struct block *block;
int noerr;
{
register struct symbol *sym;
register struct type *tmp;
sym = lookup_symbol (name, block, VAR_NAMESPACE, 0, (struct symtab **) NULL);
if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
{
tmp = lookup_primitive_typename (name);
if (tmp)
{
return (tmp);
}
else if (!tmp && noerr)
{
return (NULL);
}
else
{
error ("No type named %s.", name);
}
}
return (SYMBOL_TYPE (sym));
}
struct type *
lookup_unsigned_typename (name)
char *name;
{
char *uns = alloca (strlen (name) + 10);
strcpy (uns, "unsigned ");
strcpy (uns + 9, name);
return (lookup_typename (uns, (struct block *) NULL, 0));
}
/* Lookup a structure type named "struct NAME",
visible in lexical block BLOCK. */
struct type *
lookup_struct (name, block)
char *name;
struct block *block;
{
register struct symbol *sym;
sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
(struct symtab **) NULL);
if (sym == NULL)
{
error ("No struct type named %s.", name);
}
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
{
error ("This context has class, union or enum %s, not a struct.", name);
}
return (SYMBOL_TYPE (sym));
}
/* Lookup a union type named "union NAME",
visible in lexical block BLOCK. */
struct type *
lookup_union (name, block)
char *name;
struct block *block;
{
register struct symbol *sym;
sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
(struct symtab **) NULL);
if (sym == NULL)
{
error ("No union type named %s.", name);
}
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_UNION)
{
error ("This context has class, struct or enum %s, not a union.", name);
}
return (SYMBOL_TYPE (sym));
}
/* Lookup an enum type named "enum NAME",
visible in lexical block BLOCK. */
struct type *
lookup_enum (name, block)
char *name;
struct block *block;
{
register struct symbol *sym;
sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
(struct symtab **) NULL);
if (sym == NULL)
{
error ("No enum type named %s.", name);
}
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_ENUM)
{
error ("This context has class, struct or union %s, not an enum.", name);
}
return (SYMBOL_TYPE (sym));
}
/* Lookup a template type named "template NAME<TYPE>",
visible in lexical block BLOCK. */
struct type *
lookup_template_type (name, type, block)
char *name;
struct type *type;
struct block *block;
{
struct symbol *sym;
char *nam = (char*) alloca(strlen(name) + strlen(type->name) + 4);
strcpy (nam, name);
strcat (nam, "<");
strcat (nam, type->name);
strcat (nam, " >"); /* FIXME, extra space still introduced in gcc? */
sym = lookup_symbol (nam, block, VAR_NAMESPACE, 0, (struct symtab **)NULL);
if (sym == NULL)
{
error ("No template type named %s.", name);
}
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
{
error ("This context has class, union or enum %s, not a struct.", name);
}
return (SYMBOL_TYPE (sym));
}
/* Given a type TYPE, lookup the type of the component of type named
NAME.
If NOERR is nonzero, return zero if NAME is not suitably defined. */
struct type *
lookup_struct_elt_type (type, name, noerr)
struct type *type;
char *name;
int noerr;
{
int i;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT &&
TYPE_CODE (type) != TYPE_CODE_UNION)
{
target_terminal_ours ();
fflush (stdout);
fprintf (stderr, "Type ");
type_print (type, "", stderr, -1);
error (" is not a structure or union type.");
}
check_stub_type (type);
for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
{
char *t_field_name = TYPE_FIELD_NAME (type, i);
if (t_field_name && !strcmp (t_field_name, name))
{
return TYPE_FIELD_TYPE (type, i);
}
}
/* OK, it's not in this class. Recursively check the baseclasses. */
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
{
struct type *t;
t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, 0);
if (t != NULL)
{
return t;
}
}
if (noerr)
{
return NULL;
}
target_terminal_ours ();
fflush (stdout);
fprintf (stderr, "Type ");
type_print (type, "", stderr, -1);
fprintf (stderr, " has no component named ");
fputs_filtered (name, stderr);
error (".");
return (struct type *)-1; /* For lint */
}
/* This function is really horrible, but to avoid it, there would need
to be more filling in of forward references. */
void
fill_in_vptr_fieldno (type)
struct type *type;
{
if (TYPE_VPTR_FIELDNO (type) < 0)
{
int i;
for (i = 1; i < TYPE_N_BASECLASSES (type); i++)
{
fill_in_vptr_fieldno (TYPE_BASECLASS (type, i));
if (TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i)) >= 0)
{
TYPE_VPTR_FIELDNO (type)
= TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i));
TYPE_VPTR_BASETYPE (type)
= TYPE_VPTR_BASETYPE (TYPE_BASECLASS (type, i));
break;
}
}
}
}
/* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989.
If this is a stubbed struct (i.e. declared as struct foo *), see if
we can find a full definition in some other file. If so, copy this
definition, so we can use it in future. If not, set a flag so we
don't waste too much time in future. (FIXME, this doesn't seem
to be happening...)
This used to be coded as a macro, but I don't think it is called
often enough to merit such treatment.
*/
struct complaint stub_noname_complaint =
{"stub type has NULL name", 0, 0};
void
check_stub_type (type)
struct type *type;
{
if (TYPE_FLAGS(type) & TYPE_FLAG_STUB)
{
char* name = type_name_no_tag (type);
struct symbol *sym;
if (name == NULL)
{
complain (&stub_noname_complaint, 0);
return;
}
sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0,
(struct symtab **) NULL);
if (sym)
{
memcpy (type, SYMBOL_TYPE(sym), sizeof (struct type));
}
}
}
/* Ugly hack to convert method stubs into method types.
He ain't kiddin'. This demangles the name of the method into a string
including argument types, parses out each argument type, generates
a string casting a zero to that type, evaluates the string, and stuffs
the resulting type into an argtype vector!!! Then it knows the type
of the whole function (including argument types for overloading),
which info used to be in the stab's but was removed to hack back
the space required for them. */
void
check_stub_method (type, i, j)
struct type *type;
int i;
int j;
{
struct fn_field *f;
char *mangled_name = gdb_mangle_name (type, i, j);
char *demangled_name = cplus_demangle (mangled_name, 0);
char *argtypetext, *p;
int depth = 0, argcount = 1;
struct type **argtypes;
struct type *mtype;
if (demangled_name == NULL)
{
error ("Internal: Cannot demangle mangled name `%s'.", mangled_name);
}
/* Now, read in the parameters that define this type. */
argtypetext = strchr (demangled_name, '(') + 1;
p = argtypetext;
while (*p)
{
if (*p == '(')
{
depth += 1;
}
else if (*p == ')')
{
depth -= 1;
}
else if (*p == ',' && depth == 0)
{
argcount += 1;
}
p += 1;
}
/* We need two more slots: one for the THIS pointer, and one for the
NULL [...] or void [end of arglist]. */
argtypes = (struct type **)
obstack_alloc (&TYPE_OBJFILE (type) -> type_obstack,
(argcount+2) * sizeof (struct type *));
p = argtypetext;
argtypes[0] = lookup_pointer_type (type);
argcount = 1;
if (*p != ')') /* () means no args, skip while */
{
depth = 0;
while (*p)
{
if (depth <= 0 && (*p == ',' || *p == ')'))
{
argtypes[argcount] =
parse_and_eval_type (argtypetext, p - argtypetext);
argcount += 1;
argtypetext = p + 1;
}
if (*p == '(')
{
depth += 1;
}
else if (*p == ')')
{
depth -= 1;
}
p += 1;
}
}
if (p[-2] != '.') /* ... */
{
argtypes[argcount] = builtin_type_void; /* Ellist terminator */
}
else
{
argtypes[argcount] = NULL; /* List terminator */
}
free (demangled_name);
f = TYPE_FN_FIELDLIST1 (type, i);
TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name;
/* Now update the old "stub" type into a real type. */
mtype = TYPE_FN_FIELD_TYPE (f, j);
TYPE_DOMAIN_TYPE (mtype) = type;
TYPE_ARG_TYPES (mtype) = argtypes;
TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB;
TYPE_FN_FIELD_STUB (f, j) = 0;
}
const struct cplus_struct_type cplus_struct_default;
void
allocate_cplus_struct_type (type)
struct type *type;
{
if (!HAVE_CPLUS_STRUCT (type))
{
TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
obstack_alloc (&current_objfile -> type_obstack,
sizeof (struct cplus_struct_type));
*(TYPE_CPLUS_SPECIFIC(type)) = cplus_struct_default;
}
}
/* Helper function to initialize the standard scalar types. */
struct type *
init_type (code, length, flags, name, objfile)
enum type_code code;
int length;
int flags;
char *name;
struct objfile *objfile;
{
register struct type *type;
type = alloc_type (objfile);
TYPE_CODE (type) = code;
TYPE_LENGTH (type) = length;
TYPE_FLAGS (type) |= flags;
TYPE_NAME (type) = name;
/* C++ fancies. */
if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
{
INIT_CPLUS_SPECIFIC (type);
}
return (type);
}
/* Look up a fundamental type for the specified objfile.
May need to construct such a type if this is the first use.
Some object file formats (ELF, COFF, etc) do not define fundamental
types such as "int" or "double". Others (stabs for example), do
define fundamental types.
For the formats which don't provide fundamental types, gdb can create
such types, using defaults reasonable for the current target machine. */
struct type *
lookup_fundamental_type (objfile, typeid)
struct objfile *objfile;
int typeid;
{
register struct type *type = NULL;
register struct type **typep;
register int nbytes;
if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
{
error ("internal error - invalid fundamental type id %d", typeid);
}
else
{
/* If this is the first time we */
if (objfile -> fundamental_types == NULL)
{
nbytes = FT_NUM_MEMBERS * sizeof (struct type *);
objfile -> fundamental_types = (struct type **)
obstack_alloc (&objfile -> type_obstack, nbytes);
(void) memset (objfile -> fundamental_types, 0, nbytes);
}
typep = objfile -> fundamental_types + typeid;
if ((type = *typep) == NULL)
{
switch (typeid)
{
default:
error ("internal error: unhandled type id %d", typeid);
break;
case FT_VOID:
type = init_type (TYPE_CODE_VOID,
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
0,
"void", objfile);
break;
case FT_BOOLEAN:
type = init_type (TYPE_CODE_INT,
TARGET_INT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"boolean", (struct objfile *) NULL);
break;
case FT_STRING:
type = init_type (TYPE_CODE_PASCAL_ARRAY,
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
0,
"string", (struct objfile *) NULL);
break;
case FT_CHAR:
type = init_type (TYPE_CODE_INT,
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
0,
"char", (struct objfile *) NULL);
break;
case FT_SIGNED_CHAR:
type = init_type (TYPE_CODE_INT,
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED,
"signed char", (struct objfile *) NULL);
break;
case FT_UNSIGNED_CHAR:
type = init_type (TYPE_CODE_INT,
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"unsigned char", (struct objfile *) NULL);
break;
case FT_SHORT:
type = init_type (TYPE_CODE_INT,
TARGET_SHORT_BIT / TARGET_CHAR_BIT,
0,
"short", (struct objfile *) NULL);
break;
case FT_SIGNED_SHORT:
type = init_type (TYPE_CODE_INT,
TARGET_SHORT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED,
"signed short", (struct objfile *) NULL);
break;
case FT_UNSIGNED_SHORT:
type = init_type (TYPE_CODE_INT,
TARGET_SHORT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"unsigned short", (struct objfile *) NULL);
break;
case FT_INTEGER:
type = init_type (TYPE_CODE_INT,
TARGET_INT_BIT / TARGET_CHAR_BIT,
0,
"int", (struct objfile *) NULL);
break;
case FT_SIGNED_INTEGER:
type = init_type (TYPE_CODE_INT,
TARGET_INT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED,
"signed int", (struct objfile *) NULL);
break;
case FT_UNSIGNED_INTEGER:
type = init_type (TYPE_CODE_INT,
TARGET_INT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"unsigned int", (struct objfile *) NULL);
break;
case FT_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_BIT / TARGET_CHAR_BIT,
0,
"long", (struct objfile *) NULL);
break;
case FT_SIGNED_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED,
"signed long", (struct objfile *) NULL);
break;
case FT_UNSIGNED_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"unsigned long", (struct objfile *) NULL);
break;
case FT_LONG_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
0,
"long long", (struct objfile *) NULL);
break;
case FT_SIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED,
"signed long long", (struct objfile *) NULL);
break;
case FT_UNSIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
"unsigned long long",
(struct objfile *) NULL);
break;
case FT_FLOAT:
type = init_type (TYPE_CODE_FLT,
TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
0,
"float", (struct objfile *) NULL);
break;
case FT_DBL_PREC_FLOAT:
type = init_type (TYPE_CODE_FLT,
TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
0,
"double", (struct objfile *) NULL);
break;
case FT_EXT_PREC_FLOAT:
type = init_type (TYPE_CODE_FLT,
TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
0,
"long double", (struct objfile *) NULL);
break;
case FT_COMPLEX:
type = init_type (TYPE_CODE_FLT,
TARGET_COMPLEX_BIT / TARGET_CHAR_BIT,
0,
"complex", (struct objfile *) NULL);
break;
case FT_DBL_PREC_COMPLEX:
type = init_type (TYPE_CODE_FLT,
TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
0,
"double complex", (struct objfile *) NULL);
break;
case FT_EXT_PREC_COMPLEX:
type = init_type (TYPE_CODE_FLT,
TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
0,
"long double complex",
(struct objfile *) NULL);
break;
}
/* Install the newly created type in the objfile's fundamental_types
vector. */
*typep = type;
}
}
return (type);
}

View File

@ -0,0 +1,547 @@
/* Internal type definitions for GDB.
Copyright (C) 1992 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (GDBTYPES_H)
#define GDBTYPES_H 1
/* When gdb creates fundamental types, it uses one of the following
type identifiers. The identifiers are used to index a vector of
pointers to any types that are created. */
#define FT_VOID 0
#define FT_BOOLEAN 1
#define FT_CHAR 2
#define FT_SIGNED_CHAR 3
#define FT_UNSIGNED_CHAR 4
#define FT_SHORT 5
#define FT_SIGNED_SHORT 6
#define FT_UNSIGNED_SHORT 7
#define FT_INTEGER 8
#define FT_SIGNED_INTEGER 9
#define FT_UNSIGNED_INTEGER 10
#define FT_LONG 11
#define FT_SIGNED_LONG 12
#define FT_UNSIGNED_LONG 13
#define FT_LONG_LONG 14
#define FT_SIGNED_LONG_LONG 15
#define FT_UNSIGNED_LONG_LONG 16
#define FT_FLOAT 17
#define FT_DBL_PREC_FLOAT 18
#define FT_EXT_PREC_FLOAT 19
#define FT_COMPLEX 20
#define FT_DBL_PREC_COMPLEX 21
#define FT_EXT_PREC_COMPLEX 22
#define FT_STRING 23
#define FT_NUM_MEMBERS 24
/* Different kinds of data types are distinguished by the `code' field. */
enum type_code
{
TYPE_CODE_UNDEF, /* Not used; catches errors */
TYPE_CODE_PTR, /* Pointer type */
TYPE_CODE_ARRAY, /* Array type, lower bound zero */
TYPE_CODE_STRUCT, /* C struct or Pascal record */
TYPE_CODE_UNION, /* C union or Pascal variant part */
TYPE_CODE_ENUM, /* Enumeration type */
TYPE_CODE_FUNC, /* Function type */
TYPE_CODE_INT, /* Integer type */
TYPE_CODE_FLT, /* Floating type */
TYPE_CODE_VOID, /* Void type (values zero length) */
TYPE_CODE_SET, /* Pascal sets */
TYPE_CODE_RANGE, /* Range (integers within spec'd bounds) */
TYPE_CODE_PASCAL_ARRAY, /* Array with explicit type of index */
TYPE_CODE_ERROR, /* Unknown type */
/* C++ */
TYPE_CODE_MEMBER, /* Member type */
TYPE_CODE_METHOD, /* Method type */
TYPE_CODE_REF, /* C++ Reference types */
/* Modula-2 */
TYPE_CODE_CHAR, /* *real* character type */
TYPE_CODE_BOOL /* Builtin Modula-2 BOOLEAN */
};
/* Some bits for the type's flags word. */
/* Explicitly unsigned integer type */
#define TYPE_FLAG_UNSIGNED (1 << 0)
/* Explicity signed integer type */
#define TYPE_FLAG_SIGNED (1 << 1)
/* This appears in a type's flags word if it is a stub type (eg. if
someone referenced a type that wasn't defined in a source file
via (struct sir_not_appearing_in_this_film *)). */
#define TYPE_FLAG_STUB (1 << 2)
struct type
{
/* Code for kind of type */
enum type_code code;
/* Name of this type, or NULL if none.
This is used for printing only, except by poorly designed C++ code.
Type names specified as input are defined by symbols. */
char *name;
/* Length in bytes of storage for a value of this type */
unsigned length;
/* Every type is now associated with a particular objfile, and the
type is allocated on the type_obstack for that objfile. One problem
however, is that there are times when gdb allocates new types while
it is not in the process of reading symbols from a particular objfile.
Fortunately, these happen when the type being created is a derived
type of an existing type, such as in lookup_pointer_type(). So
we can just allocate the new type using the same objfile as the
existing type, but to do this we need a backpointer to the objfile
from the existing type. Yes this is somewhat ugly, but without
major overhaul of the internal type system, it can't be avoided
for now. */
struct objfile *objfile;
/* For a pointer type, describes the type of object pointed to.
For an array type, describes the type of the elements.
For a function or method type, describes the type of the value.
For a range type, describes the type of the full range.
Unused otherwise. */
struct type *target_type;
/* Type that is a pointer to this type.
NULL if no such pointer-to type is known yet.
The debugger may add the address of such a type
if it has to construct one later. */
struct type *pointer_type;
/* C++: also need a reference type. */
struct type *reference_type;
/* Type that is a function returning this type.
NULL if no such function type is known here.
The debugger may add the address of such a type
if it has to construct one later. */
struct type *function_type;
/* Flags about this type. */
short flags;
/* Number of fields described for this type */
short nfields;
/* For structure and union types, a description of each field.
For set and pascal array types, there is one "field",
whose type is the domain type of the set or array.
For range types, there are two "fields",
the minimum and maximum values (both inclusive).
For enum types, each possible value is described by one "field".
Using a pointer to a separate array of fields
allows all types to have the same size, which is useful
because we can allocate the space for a type before
we know what to put in it. */
struct field
{
/* Position of this field, counting in bits from start of
containing structure. For a function type, this is the
position in the argument list of this argument.
For a range bound or enum value, this is the value itself. */
int bitpos;
/* Size of this field, in bits, or zero if not packed.
For an unpacked field, the field's type's length
says how many bytes the field occupies. */
int bitsize;
/* In a struct or enum type, type of this field.
In a function type, type of this argument.
In an array type, the domain-type of the array. */
struct type *type;
/* Name of field, value or argument.
NULL for range bounds and array domains. */
char *name;
} *fields;
/* For types with virtual functions, VPTR_BASETYPE is the base class which
defined the virtual function table pointer. VPTR_FIELDNO is
the field number of that pointer in the structure.
For types that are pointer to member types, VPTR_BASETYPE
is the type that this pointer is a member of.
Unused otherwise. */
struct type *vptr_basetype;
int vptr_fieldno;
/* Slot to point to additional language-specific fields of this type. */
union type_specific
{
/* ARG_TYPES is for TYPE_CODE_METHOD and TYPE_CODE_FUNC. */
struct type **arg_types;
/* CPLUS_STUFF is for TYPE_CODE_STRUCT. */
struct cplus_struct_type *cplus_stuff;
} type_specific;
};
#define NULL_TYPE ((struct type *) 0)
/* C++ language-specific information for TYPE_CODE_STRUCT and TYPE_CODE_UNION
nodes. */
struct cplus_struct_type
{
B_TYPE *virtual_field_bits; /* if base class is virtual */
B_TYPE *private_field_bits;
B_TYPE *protected_field_bits;
/* Number of methods described for this type */
short nfn_fields;
/* Number of base classes this type derives from. */
short n_baseclasses;
/* Number of methods described for this type plus all the
methods that it derives from. */
int nfn_fields_total;
/* For classes, structures, and unions, a description of each field,
which consists of an overloaded name, followed by the types of
arguments that the method expects, and then the name after it
has been renamed to make it distinct. */
struct fn_fieldlist
{
/* The overloaded name. */
char *name;
/* The number of methods with this name. */
int length;
/* The list of methods. */
struct fn_field
{
/* The return value of the method */
struct type *type;
/* The argument list */
struct type **args;
/* The name after it has been processed */
char *physname;
/* For virtual functions. */
/* First baseclass that defines this virtual function. */
struct type *fcontext;
unsigned int is_const : 1;
unsigned int is_volatile : 1;
unsigned int is_private : 1;
unsigned int is_protected : 1;
unsigned int is_stub : 1;
unsigned int dummy : 3;
/* Index into that baseclass's virtual function table,
minus 2; else if static: VOFFSET_STATIC; else: 0. */
unsigned voffset : 24;
# define VOFFSET_STATIC 1
} *fn_fields;
} *fn_fieldlists;
unsigned char via_protected;
unsigned char via_public;
};
/* The default value of TYPE_CPLUS_SPECIFIC(T) points to the
this shared static structure. */
extern const struct cplus_struct_type cplus_struct_default;
extern void
allocate_cplus_struct_type PARAMS ((struct type *));
#define INIT_CPLUS_SPECIFIC(type) \
(TYPE_CPLUS_SPECIFIC(type)=(struct cplus_struct_type*)&cplus_struct_default)
#define ALLOCATE_CPLUS_STRUCT_TYPE(type) allocate_cplus_struct_type (type)
#define HAVE_CPLUS_STRUCT(type) \
(TYPE_CPLUS_SPECIFIC(type) != &cplus_struct_default)
#define TYPE_NAME(thistype) (thistype)->name
#define TYPE_TARGET_TYPE(thistype) (thistype)->target_type
#define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
#define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
#define TYPE_FUNCTION_TYPE(thistype) (thistype)->function_type
#define TYPE_LENGTH(thistype) (thistype)->length
#define TYPE_OBJFILE(thistype) (thistype)->objfile
#define TYPE_FLAGS(thistype) (thistype)->flags
#define TYPE_UNSIGNED(thistype) ((thistype)->flags & TYPE_FLAG_UNSIGNED)
#define TYPE_CODE(thistype) (thistype)->code
#define TYPE_NFIELDS(thistype) (thistype)->nfields
#define TYPE_FIELDS(thistype) (thistype)->fields
/* C++ */
#define TYPE_VPTR_BASETYPE(thistype) (thistype)->vptr_basetype
#define TYPE_DOMAIN_TYPE(thistype) (thistype)->vptr_basetype
#define TYPE_VPTR_FIELDNO(thistype) (thistype)->vptr_fieldno
#define TYPE_FN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fields
#define TYPE_NFN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields
#define TYPE_NFN_FIELDS_TOTAL(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields_total
#define TYPE_TYPE_SPECIFIC(thistype) (thistype)->type_specific
#define TYPE_ARG_TYPES(thistype) (thistype)->type_specific.arg_types
#define TYPE_CPLUS_SPECIFIC(thistype) (thistype)->type_specific.cplus_stuff
#define TYPE_BASECLASS(thistype,index) (thistype)->fields[index].type
#define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses
#define TYPE_BASECLASS_NAME(thistype,index) (thistype)->fields[index].name
#define TYPE_BASECLASS_BITPOS(thistype,index) (thistype)->fields[index].bitpos
#define BASETYPE_VIA_PUBLIC(thistype, index) (!TYPE_FIELD_PRIVATE(thistype, index))
#define BASETYPE_VIA_VIRTUAL(thistype, index) \
B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (index))
#define TYPE_FIELD(thistype, n) (thistype)->fields[n]
#define TYPE_FIELD_TYPE(thistype, n) (thistype)->fields[n].type
#define TYPE_FIELD_NAME(thistype, n) (thistype)->fields[n].name
#define TYPE_FIELD_VALUE(thistype, n) (* (int*) &(thistype)->fields[n].type)
#define TYPE_FIELD_BITPOS(thistype, n) (thistype)->fields[n].bitpos
#define TYPE_FIELD_BITSIZE(thistype, n) (thistype)->fields[n].bitsize
#define TYPE_FIELD_PACKED(thistype, n) (thistype)->fields[n].bitsize
#define TYPE_FIELD_PRIVATE_BITS(thistype) \
TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits
#define TYPE_FIELD_PROTECTED_BITS(thistype) \
TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits
#define TYPE_FIELD_VIRTUAL_BITS(thistype) \
TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits
#define SET_TYPE_FIELD_PRIVATE(thistype, n) \
B_SET (TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits, (n))
#define SET_TYPE_FIELD_PROTECTED(thistype, n) \
B_SET (TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits, (n))
#define SET_TYPE_FIELD_VIRTUAL(thistype, n) \
B_SET (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n))
#define TYPE_FIELD_PRIVATE(thistype, n) \
(TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits == NULL ? 0 \
: B_TST(TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits, (n)))
#define TYPE_FIELD_PROTECTED(thistype, n) \
(TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits == NULL ? 0 \
: B_TST(TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits, (n)))
#define TYPE_FIELD_VIRTUAL(thistype, n) \
B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n))
#define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitpos == -1)
#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) ((char *)(thistype)->fields[n].bitsize)
#define TYPE_FN_FIELDLISTS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists
#define TYPE_FN_FIELDLIST(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n]
#define TYPE_FN_FIELDLIST1(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].fn_fields
#define TYPE_FN_FIELDLIST_NAME(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].name
#define TYPE_FN_FIELDLIST_LENGTH(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].length
#define TYPE_FN_FIELD(thisfn, n) (thisfn)[n]
#define TYPE_FN_FIELD_NAME(thisfn, n) (thisfn)[n].name
#define TYPE_FN_FIELD_TYPE(thisfn, n) (thisfn)[n].type
#define TYPE_FN_FIELD_ARGS(thisfn, n) TYPE_ARG_TYPES ((thisfn)[n].type)
#define TYPE_FN_FIELD_PHYSNAME(thisfn, n) (thisfn)[n].physname
#define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1)
#define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC)
#define TYPE_FN_FIELD_VOFFSET(thisfn, n) ((thisfn)[n].voffset-2)
#define TYPE_FN_FIELD_FCONTEXT(thisfn, n) ((thisfn)[n].fcontext)
#define TYPE_FN_FIELD_STUB(thisfn, n) ((thisfn)[n].is_stub)
#define TYPE_FN_FIELD_PRIVATE(thisfn, n) ((thisfn)[n].is_private)
#define TYPE_FN_FIELD_PROTECTED(thisfn, n) ((thisfn)[n].is_protected)
extern struct type *builtin_type_void;
extern struct type *builtin_type_char;
extern struct type *builtin_type_short;
extern struct type *builtin_type_int;
extern struct type *builtin_type_long;
extern struct type *builtin_type_unsigned_char;
extern struct type *builtin_type_unsigned_short;
extern struct type *builtin_type_unsigned_int;
extern struct type *builtin_type_unsigned_long;
extern struct type *builtin_type_float;
extern struct type *builtin_type_double;
extern struct type *builtin_type_long_double;
extern struct type *builtin_type_complex;
extern struct type *builtin_type_double_complex;
/* This type represents a type that was unrecognized in symbol
read-in. */
extern struct type *builtin_type_error;
extern struct type *builtin_type_long_long;
extern struct type *builtin_type_unsigned_long_long;
/* Modula-2 types */
extern struct type *builtin_type_m2_char;
extern struct type *builtin_type_m2_int;
extern struct type *builtin_type_m2_card;
extern struct type *builtin_type_m2_real;
extern struct type *builtin_type_m2_bool;
/* LONG_LONG is defined if the host has "long long". */
#ifdef LONG_LONG
#define BUILTIN_TYPE_LONGEST builtin_type_long_long
#define BUILTIN_TYPE_UNSIGNED_LONGEST builtin_type_unsigned_long_long
#else /* not LONG_LONG. */
#define BUILTIN_TYPE_LONGEST builtin_type_long
#define BUILTIN_TYPE_UNSIGNED_LONGEST builtin_type_unsigned_long
#endif /* not LONG_LONG. */
/* Maximum and minimum values of built-in types */
#define MAX_OF_TYPE(t) \
TYPE_UNSIGNED(t) ? UMAX_OF_SIZE(TYPE_LENGTH(t)) \
: MAX_OF_SIZE(TYPE_LENGTH(t))
#define MIN_OF_TYPE(t) \
TYPE_UNSIGNED(t) ? UMIN_OF_SIZE(TYPE_LENGTH(t)) \
: MIN_OF_SIZE(TYPE_LENGTH(t))
extern struct type *
alloc_type PARAMS ((struct objfile *));
extern struct type *
init_type PARAMS ((enum type_code, int, int, char *, struct objfile *));
extern struct type *
lookup_reference_type PARAMS ((struct type *));
extern struct type *
lookup_member_type PARAMS ((struct type *, struct type *));
extern void
smash_to_method_type PARAMS ((struct type *, struct type *, struct type *,
struct type **));
extern void
smash_to_member_type PARAMS ((struct type *, struct type *, struct type *));
extern struct type *
allocate_stub_method PARAMS ((struct type *));
extern char *
type_name_no_tag PARAMS ((const struct type *));
extern struct type *
lookup_struct_elt_type PARAMS ((struct type *, char *, int));
extern struct type *
lookup_pointer_type PARAMS ((struct type *));
extern struct type *
lookup_function_type PARAMS ((struct type *));
extern struct type *
create_array_type PARAMS ((struct type *, int));
extern struct type *
lookup_unsigned_typename PARAMS ((char *));
extern void
check_stub_type PARAMS ((struct type *));
extern void
check_stub_method PARAMS ((struct type *, int, int));
extern struct type *
lookup_primitive_typename PARAMS ((char *));
extern char *
gdb_mangle_name PARAMS ((struct type *, int, int));
extern struct type *
builtin_type PARAMS ((char **));
extern struct type *
error_type PARAMS ((char **));
extern struct type *
lookup_typename PARAMS ((char *, struct block *, int));
extern struct type *
lookup_template_type PARAMS ((char *, struct type *, struct block *));
extern struct type *
lookup_fundamental_type PARAMS ((struct objfile *, int));
/* printcmd.c */
extern void
print_scalar_formatted PARAMS ((char *, struct type *, int, int, FILE *));
#endif /* GDBTYPES_H */

View File

@ -205,7 +205,7 @@ typedef unsigned long size_t;
#include <stddef.h>
#endif
extern void EXFUN(abort, (void));
extern void EXFUN(abort, (NOARGS));
extern void EXFUN(free, (PTR));
extern PTR EXFUN(malloc, (size_t));
extern PTR EXFUN(realloc, (PTR, size_t));
@ -267,7 +267,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
fragments in a block have been freed, the block itself is freed. */
#define INT_BIT (CHAR_BIT * sizeof(int))
#define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
#define BLOCKSIZE (1 << BLOCKLOG)
#define BLOCKSIZE ((unsigned int) 1 << BLOCKLOG)
#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
/* The difference between two pointers is a signed int. On machines where
@ -377,7 +377,7 @@ extern PTR EXFUN((*__malloc_hook), (size_t __size));
extern PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
/* Activate a standard collection of debugging hooks. */
extern void EXFUN(mcheck, (void EXFUN((*func), (void))));
extern void EXFUN(mcheck, (void EXFUN((*func), (NOARGS))));
/* Statistics available to the user. */
struct mstats

View File

@ -143,7 +143,7 @@ extern PTR EXFUN((*__malloc_hook), (size_t __size));
extern PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
/* Activate a standard collection of debugging hooks. */
extern void EXFUN(mcheck, (void EXFUN((*func), (void))));
extern void EXFUN(mcheck, (void EXFUN((*func), (NOARGS))));
/* Statistics available to the user. */
struct mstats

View File

@ -33,6 +33,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/file.h>
#include <sys/stat.h>
/* Work with core dump and executable files, for GDB.
This code would be in core.c if it weren't machine-dependent. */

View File

@ -135,7 +135,6 @@ fetch_inferior_registers (regno)
int regno;
{
struct user u;
register int regno;
register unsigned int ar0_offset;
ar0_offset = (INFERIOR_AR0 (u));
@ -157,6 +156,7 @@ fetch_inferior_registers (regno)
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
store_inferior_registers (regno)
register int regno;
{
@ -194,10 +194,11 @@ store_inferior_registers (regno)
#endif /* HPUX_VERSION_5 */
void
fetch_core_registers (core_reg_sect, core_reg_size, which)
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
int core_reg_size;
int which;
unsigned int reg_addr; /* Unused in this version */
{
int val, regno;
struct user u;

View File

@ -43,9 +43,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "target.h"
extern void print_387_control_word (); /* i387-tdep.h */
extern void print_387_status_word ();
extern struct ext_format ext_format_i387;
/* this table must line up with REGISTER_NAMES in m-i386.h */
@ -61,7 +58,11 @@ static int regmap[] =
/* blockend is the value of u.u_ar0, and points to the
* place where GS is stored
*/
int
i386_register_u_addr (blockend, regnum)
int blockend;
int regnum;
{
#if 0
/* this will be needed if fp registers are reinstated */

View File

@ -48,23 +48,26 @@ struct ext_format ext_format_i387 = {
/* FIXME: Eliminate these routines when we have the time to change all
the callers. */
void
i387_to_double (from, to)
char *from, *to;
char *from;
char *to;
{
ieee_extended_to_double (&ext_format_i387, from, (double *)to);
}
void
double_to_i387 (from, to)
char *from, *to;
char *from;
char *to;
{
double_to_ieee_extended (&ext_format_i387, (double *)from, to);
}
void
print_387_control_word (control)
unsigned short control;
unsigned int control;
{
printf ("control %s: ", local_hex_string(control));
printf ("compute to ");
@ -101,7 +104,7 @@ unsigned short control;
void
print_387_status_word (status)
unsigned short status;
unsigned int status;
{
printf ("status %s: ", local_hex_string (status));
if (status & 0xff)

View File

@ -463,20 +463,18 @@ CORE_ADDR
leafproc_return (ip)
CORE_ADDR ip; /* ip from currently executing function */
{
int i;
register struct misc_function *mf;
register struct minimal_symbol *msymbol;
char *p;
int dst;
unsigned int insn1, insn2;
CORE_ADDR return_addr;
char *index ();
if ((i = find_pc_misc_function (ip)) >= 0)
if ((msymbol = lookup_minimal_symbol_by_pc (ip)) != NULL)
{
mf = &misc_function_vector[i];
if ((p = index (mf->name, '.')) && !strcmp (p, ".lf"))
if ((p = index (msymbol -> name, '.')) && !strcmp (p, ".lf"))
{
if (next_insn (mf->address, &insn1, &insn2)
if (next_insn (msymbol -> address, &insn1, &insn2)
&& (insn1 & 0xff87ffff) == 0x5c80161e /* mov g14, gx */
&& (dst = REG_SRCDST (insn1)) <= G0_REGNUM + 7)
{
@ -485,7 +483,7 @@ leafproc_return (ip)
the return address from g14; otherwise, read it
from the register into which g14 was moved. */
return_addr = read_register ((ip == mf->address)
return_addr = read_register ((ip == msymbol->address)
? G14_REGNUM : dst);
/* We know we are in a leaf procedure, but we don't know
@ -498,7 +496,7 @@ leafproc_return (ip)
if (!next_insn (return_addr, &insn1, &insn2)
|| (insn1 & 0xff000000) != 0xa000000 /* ret */
|| find_pc_misc_function (return_addr) != i)
|| lookup_minimal_symbol_by_pc (return_addr) != msymbol)
return (return_addr);
}
}

View File

@ -33,6 +33,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "gdbcmd.h"
#include "frame.h"
@ -1112,8 +1113,8 @@ _initialize_language()
"Set the current source language.",
&setlist);
show = add_show_from_set (set, &showlist);
set->function = set_language_command;
show->function = show_language_command;
set->function.cfunc = set_language_command;
show->function.cfunc = show_language_command;
add_prefix_cmd ("check", no_class, set_check,
"Set the status of the type/range checker",
@ -1132,16 +1133,16 @@ _initialize_language()
"Set type checking. (on/warn/off/auto)",
&setchecklist);
show = add_show_from_set (set, &showchecklist);
set->function = set_type_command;
show->function = show_type_command;
set->function.cfunc = set_type_command;
show->function.cfunc = show_type_command;
set = add_set_cmd ("range", class_support, var_string_noescape,
(char *)&range,
"Set range checking. (on/warn/off/auto)",
&setchecklist);
show = add_show_from_set (set, &showchecklist);
set->function = set_range_command;
show->function = show_range_command;
set->function.cfunc = set_range_command;
show->function.cfunc = show_range_command;
add_language (&unknown_language_defn);
add_language (&local_language_defn);

View File

@ -33,6 +33,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <string.h>
#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "frame.h"
#include "expression.h"
#include "language.h"
@ -69,10 +70,23 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define yyval m2_val
#define yylloc m2_lloc
/* Forward decl's */
void yyerror ();
static int yylex ();
int yyparse ();
static char *
make_qualname PARAMS ((char *, char *));
static int
parse_number PARAMS ((int));
static int
yylex PARAMS ((void));
static void
yyerror PARAMS ((char *));
static void
__yy_bcopy PARAMS ((char *, char *, int));
int
yyparse PARAMS ((void));
/* The sign of the number being parsed. */
int number_sign = 1;
@ -81,8 +95,6 @@ int number_sign = 1;
contained in, */
struct block *modblock=0;
char *make_qualname();
/* #define YYDEBUG 1 */
%}
@ -602,34 +614,28 @@ variable: NAME
}
else
{
register int i;
struct minimal_symbol *msymbol;
register char *arg = copy_name ($1);
for (i = 0; i < misc_function_count; i++)
if (!strcmp (misc_function_vector[i].name, arg))
break;
if (i < misc_function_count)
msymbol = lookup_minimal_symbol (arg,
(struct objfile *) NULL);
if (msymbol != NULL)
{
enum misc_function_type mft =
(enum misc_function_type)
misc_function_vector[i].type;
write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_int);
write_exp_elt_longcst ((LONGEST) misc_function_vector[i].address);
write_exp_elt_longcst ((LONGEST) msymbol -> address);
write_exp_elt_opcode (OP_LONG);
write_exp_elt_opcode (UNOP_MEMVAL);
if (mft == mf_data || mft == mf_bss)
if (msymbol -> type == mst_data ||
msymbol -> type == mst_bss)
write_exp_elt_type (builtin_type_int);
else if (mft == mf_text)
else if (msymbol -> type == mst_text)
write_exp_elt_type (lookup_function_type (builtin_type_int));
else
write_exp_elt_type (builtin_type_char);
write_exp_elt_opcode (UNOP_MEMVAL);
}
else if (symtab_list == 0
&& partial_symtab_list == 0)
else if (!have_full_symbols () && !have_partial_symbols ())
error ("No symbol table is loaded. Use the \"symbol-file\" command.");
else
error ("No symbol \"%s\" in current context.",
@ -681,8 +687,6 @@ parse_number (olen)
register int len = olen;
int unsigned_p = number_sign == 1 ? 1 : 0;
extern double atof ();
if(p[len-1] == 'H')
{
base = 16;
@ -1131,7 +1135,7 @@ yylex ()
}
}
char *
static char *
make_qualname(mod,ident)
char *mod, *ident;
{
@ -1144,8 +1148,9 @@ make_qualname(mod,ident)
}
void
yyerror()
static void
yyerror(msg)
char *msg; /* unused */
{
printf("Parsing: %s\n",lexptr);
if (yychar < 256)
@ -1223,12 +1228,22 @@ _initialize_m2_exp ()
types are the same on the host and target machines!!! */
/* Modula-2 "pervasive" types. NOTE: these can be redefined!!! */
builtin_type_m2_int = init_type (TYPE_CODE_INT, sizeof(int), 0, "INTEGER");
builtin_type_m2_card = init_type (TYPE_CODE_INT, sizeof(int), 1, "CARDINAL");
builtin_type_m2_real = init_type (TYPE_CODE_FLT, sizeof(float), 0, "REAL");
builtin_type_m2_char = init_type (TYPE_CODE_CHAR, sizeof(char), 1, "CHAR");
builtin_type_m2_int =
init_type (TYPE_CODE_INT, sizeof(int), 0,
"INTEGER", (struct objfile *) NULL);
builtin_type_m2_card =
init_type (TYPE_CODE_INT, sizeof(int), TYPE_FLAG_UNSIGNED,
"CARDINAL", (struct objfile *) NULL);
builtin_type_m2_real =
init_type (TYPE_CODE_FLT, sizeof(float), 0,
"REAL", (struct objfile *) NULL);
builtin_type_m2_char =
init_type (TYPE_CODE_CHAR, sizeof(char), TYPE_FLAG_UNSIGNED,
"CHAR", (struct objfile *) NULL);
builtin_type_m2_bool =
init_type (TYPE_CODE_BOOL, sizeof(int), TYPE_FLAG_UNSIGNED,
"BOOLEAN", (struct objfile *) NULL);
builtin_type_m2_bool = init_type (TYPE_CODE_BOOL, sizeof(int), 1, "BOOLEAN");
TYPE_NFIELDS(builtin_type_m2_bool) = 2;
TYPE_FIELDS(builtin_type_m2_bool) =
(struct field *) malloc (sizeof (struct field) * 2);

View File

@ -24,6 +24,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "opcode/m68k.h"
#include "gdbcore.h"
/* Local function prototypes */
static int
fetch_arg PARAMS ((unsigned char *, int, int));
static void
print_base PARAMS ((int, int, FILE *));
static unsigned char *
print_indexed PARAMS ((int, unsigned char *, CORE_ADDR, FILE *));
static unsigned char *
print_insn_arg PARAMS ((char *, unsigned char *, unsigned char *, CORE_ADDR,
FILE *));
/* 68k instructions are never longer than this many bytes. */
#define MAXLEN 22
@ -34,10 +49,6 @@ extern char *reg_names[];
char *fpcr_names[] = { "", "fpiar", "fpsr", "fpiar/fpsr", "fpcr",
"fpiar/fpcr", "fpsr/fpcr", "fpiar-fpcr"};
static unsigned char *print_insn_arg ();
static unsigned char *print_indexed ();
static void print_base ();
static int fetch_arg ();
#define NEXTBYTE(p) (p += 2, ((char *)p)[-1])
@ -78,7 +89,7 @@ print_insn (memaddr, stream)
register int bestmask;
int best;
read_memory (memaddr, buffer, MAXLEN);
read_memory (memaddr, (char *) buffer, MAXLEN);
bestmask = 0;
best = -1;
@ -574,7 +585,7 @@ print_insn_arg (d, buffer, p, addr, stream)
static int
fetch_arg (buffer, code, bits)
unsigned char *buffer;
char code;
int code;
int bits;
{
register int val;
@ -674,8 +685,8 @@ static unsigned char *
print_indexed (basereg, p, addr, stream)
int basereg;
unsigned char *p;
FILE *stream;
CORE_ADDR addr;
FILE *stream;
{
register int word;
static char *scales[] = {"", "*2", "*4", "*8"};

View File

@ -329,7 +329,7 @@ void sprint_address (addr, buffer)
char *buffer;
{
register int i;
struct minimal_symbol *msymbol;
struct symbol *fs;
char *name;
int name_location;
@ -339,13 +339,13 @@ void sprint_address (addr, buffer)
fs = find_pc_function (addr);
if (!fs) {
i = find_pc_misc_function (addr);
msymbol = lookup_minimal_symbol_by_pc (addr);
if (i < 0) return; /* If nothing comes through, don't
if (i == NULL) return;/* If nothing comes through, don't
print anything symbolic */
name = misc_function_vector[i].name;
name_location = misc_function_vector[i].address;
name = msymbol -> name;
name_location = msymbol -> address;
} else {
name = fs->name;
name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (fs));

View File

@ -66,9 +66,9 @@ extern int errno;
extern char registers[REGISTER_BYTES];
void
fetch_inferior_registers ()
fetch_inferior_registers (regno)
int regno; /* Original value discarded */
{
register int regno;
register unsigned int regaddr;
char buf[MAX_REGISTER_RAW_SIZE];
register int i;
@ -105,6 +105,7 @@ fetch_inferior_registers ()
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
store_inferior_registers (regno)
int regno;
{

View File

@ -39,9 +39,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/core.h>
void
fetch_inferior_registers ()
fetch_inferior_registers (regno)
int regno; /* Original value discarded */
{
struct regs inferior_registers;
struct fp_state inferior_fp_registers;
@ -65,6 +67,7 @@ fetch_inferior_registers ()
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
store_inferior_registers (regno)
int regno;
{
@ -106,12 +109,15 @@ store_inferior_registers (regno)
/* These functions shouldn't be called when we're cross-debugging. */
/* ARGSUSED */
void
fetch_inferior_registers ()
fetch_inferior_registers (regno)
int regno;
{
}
/* ARGSUSED */
void
store_inferior_registers (regno)
int regno;
{
@ -122,10 +128,11 @@ store_inferior_registers (regno)
/* Work with core files, for GDB. */
void
fetch_core_registers (core_reg_sect, core_reg_size, which)
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
unsigned int reg_addr; /* Unused in this version */
{
int val;
extern char registers[];

View File

@ -34,7 +34,7 @@ static PTR EXFUN((*old_realloc_hook), (PTR ptr, size_t size));
/* Function to call when something awful happens. */
extern void abort();
static void EXFUN((*abortfunc), (void)) = (void (*)()) abort;
static void EXFUN((*abortfunc), (NOARGS)) = (void (*)()) abort;
/* Arbitrary magical numbers. */
#define MAGICWORD 0xfedabeeb
@ -103,7 +103,7 @@ DEFUN(reallochook, (ptr, size), PTR ptr AND size_t size)
}
void
DEFUN(mcheck, (func), void EXFUN((*func), (void)))
DEFUN(mcheck, (func), void EXFUN((*func), (NOARGS)))
{
static int mcheck_used = 0;

491
gdb/minsyms.c Normal file
View File

@ -0,0 +1,491 @@
/* GDB routines for manipulating the minimal symbol tables.
Copyright 1992 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This file contains support routines for creating, manipulating, and
destroying minimal symbol tables.
Minimal symbol tables are used to hold some very basic information about
all defined global symbols (text, data, bss, abs, etc). The only two
required pieces of information are the symbol's name and the address
associated with that symbol.
In many cases, even if a file was compiled with no special options for
debugging at all, as long as was not stripped it will contain sufficient
information to build useful minimal symbol tables using this structure.
Even when a file contains enough debugging information to build a full
symbol table, these minimal symbols are still useful for quickly mapping
between names and addresses, and vice versa. They are also sometimes used
to figure out what full symbol table entries need to be read in. */
#include <stdio.h>
#include "defs.h"
#include "symtab.h"
#include "bfd.h"
#include "symfile.h"
/* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
At the end, copy them all into one newly allocated location on an objfile's
symbol obstack. */
#define BUNCH_SIZE 127
struct msym_bunch
{
struct msym_bunch *next;
struct minimal_symbol contents[BUNCH_SIZE];
};
/* Bunch currently being filled up.
The next field points to chain of filled bunches. */
static struct msym_bunch *msym_bunch;
/* Number of slots filled in current bunch. */
static int msym_bunch_index;
/* Total number of minimal symbols recorded so far for the objfile. */
static int msym_count;
/* Prototypes for local functions. */
static int
compare_minimal_symbols PARAMS ((const void *, const void *));
static int
compact_minimal_symbols PARAMS ((struct minimal_symbol *, int));
/* Call the function specified by FUNC for each currently available minimal
symbol, for as long as this function continues to return NULL. If the
function ever returns non-NULL, then the iteration over the minimal
symbols is terminated,, the result is returned to the caller.
The function called has full control over the form and content of the
information returned via the non-NULL result, which may be as simple as a
pointer to the minimal symbol that the iteration terminated on, or as
complex as a pointer to a private structure containing multiple results. */
PTR
iterate_over_msymbols (func, arg1, arg2, arg3)
PTR (*func) PARAMS ((struct objfile *, struct minimal_symbol *,
PTR, PTR, PTR));
PTR arg1;
PTR arg2;
PTR arg3;
{
register struct objfile *objfile;
register struct minimal_symbol *msymbol;
char *result = NULL;
for (objfile = object_files;
objfile != NULL && result == NULL;
objfile = objfile -> next)
{
for (msymbol = objfile -> msymbols;
msymbol != NULL && msymbol -> name != NULL && result == NULL;
msymbol++)
{
result = (*func)(objfile, msymbol, arg1, arg2, arg3);
}
}
return (result);
}
/* Look through all the current minimal symbol tables and find the first
minimal symbol that matches NAME. If OBJF is non-NULL, it specifies a
particular objfile and the search is limited to that objfile. Returns
a pointer to the minimal symbol that matches, or NULL if no match is found.
Note: One instance where their may be duplicate minimal symbols with
the same name is when the symbol tables for a shared library and the
symbol tables for an executable contain global symbols with the same
names (the dynamic linker deals with the duplication). */
struct minimal_symbol *
lookup_minimal_symbol (name, objf)
register const char *name;
struct objfile *objf;
{
struct objfile *objfile;
struct minimal_symbol *msymbol;
struct minimal_symbol *found_symbol = NULL;
for (objfile = object_files;
objfile != NULL && found_symbol == NULL;
objfile = objfile -> next)
{
if (objf == NULL || objf == objfile)
{
for (msymbol = objfile -> msymbols;
msymbol != NULL && msymbol -> name != NULL &&
found_symbol == NULL;
msymbol++)
{
if (strcmp (msymbol -> name, name) == 0)
{
found_symbol = msymbol;
}
}
}
}
return (found_symbol);
}
/* Search through the minimal symbol table for each objfile and find the
symbol whose address is the largest address that is still less than or
equal to PC. Returns a pointer to the minimal symbol if such a symbol
is found, or NULL if PC is not in a suitable range. Note that we need
to look through ALL the minimal symbol tables before deciding on the
symbol that comes closest to the specified PC. */
struct minimal_symbol *
lookup_minimal_symbol_by_pc (pc)
register CORE_ADDR pc;
{
register int lo;
register int hi;
register int new;
register struct objfile *objfile;
register struct minimal_symbol *msymbol;
register struct minimal_symbol *best_symbol = NULL;
for (objfile = object_files;
objfile != NULL;
objfile = objfile -> next)
{
/* If this objfile has a minimal symbol table, go search it using
a binary search. Note that a minimal symbol table always consists
of at least two symbols, a "real" symbol and the terminating
"null symbol". If there are no real symbols, then there is no
minimal symbol table at all. */
if ((msymbol = objfile -> msymbols) != NULL)
{
lo = 0;
hi = objfile -> minimal_symbol_count - 2;
/* This code assumes that the minimal symbols are sorted by
ascending address values. If the pc value is greater than or
equal to the first symbol's address, then some symbol in this
minimal symbol table is a suitable candidate for being the
"best" symbol. This includes the last real symbol, for cases
where the pc value is larger than any address in this vector.
By iterating until the address associated with the current
hi index (the endpoint of the test interval) is less than
or equal to the desired pc value, we accomplish two things:
(1) the case where the pc value is larger than any minimal
symbol address is trivially solved, (2) the address associated
with the hi index is always the one we want when the interation
terminates. In essence, we are iterating the test interval
down until the pc value is pushed out of it from the high end.
Warning: this code is trickier than it would appear at first. */
if (pc >= msymbol[lo].address)
{
while (msymbol[hi].address > pc)
{
/* pc is still strictly less than highest address */
/* Note "new" will always be >= lo */
new = (lo + hi) / 2;
if ((msymbol[new].address >= pc) || (lo == new))
{
hi = new;
}
else
{
lo = new;
}
}
/* The minimal symbol indexed by hi now is the best one in this
objfile's minimal symbol table. See if it is the best one
overall. */
if ((best_symbol == NULL) ||
(best_symbol -> address < msymbol[hi].address))
{
best_symbol = &msymbol[hi];
}
}
}
}
return (best_symbol);
}
/* Prepare to start collecting minimal symbols. Note that presetting
msym_bunch_index to BUNCH_SIZE causes the first call to save a minimal
symbol to allocate the memory for the first bunch. */
void
init_minimal_symbol_collection ()
{
msym_count = 0;
msym_bunch = NULL;
msym_bunch_index = BUNCH_SIZE;
}
void
prim_record_minimal_symbol (name, address, ms_type)
const char *name;
CORE_ADDR address;
enum minimal_symbol_type ms_type;
{
register struct msym_bunch *new;
if (msym_bunch_index == BUNCH_SIZE)
{
new = (struct msym_bunch *) xmalloc (sizeof (struct msym_bunch));
msym_bunch_index = 0;
new -> next = msym_bunch;
msym_bunch = new;
}
msym_bunch -> contents[msym_bunch_index].name = (char *) name;
msym_bunch -> contents[msym_bunch_index].address = address;
msym_bunch -> contents[msym_bunch_index].info = NULL;
msym_bunch -> contents[msym_bunch_index].type = ms_type;
msym_bunch_index++;
msym_count++;
}
/* Compare two minimal symbols by address and return a signed result based
on unsigned comparisons, so that we sort into unsigned numeric order. */
static int
compare_minimal_symbols (fn1p, fn2p)
const PTR fn1p;
const PTR fn2p;
{
register const struct minimal_symbol *fn1;
register const struct minimal_symbol *fn2;
fn1 = (const struct minimal_symbol *) fn1p;
fn2 = (const struct minimal_symbol *) fn2p;
if (fn1 -> address < fn2 -> address)
{
return (-1);
}
else if (fn1 -> address > fn2 -> address)
{
return (1);
}
else
{
return (0);
}
}
/* Discard the currently collected minimal symbols, if any. If we wish
to save them for later use, we must have already copied them somewhere
else before calling this function.
FIXME: We could allocate the minimal symbol bunches on their own
obstack and then simply blow the obstack away when we are done with
it. Is it worth the extra trouble though? */
/* ARGSUSED */
void
discard_minimal_symbols (foo)
int foo;
{
register struct msym_bunch *next;
while (msym_bunch != NULL)
{
next = msym_bunch -> next;
free (msym_bunch);
msym_bunch = next;
}
}
/* Compact duplicate entries out of a minimal symbol table by walking
through the table and compacting out entries with duplicate addresses
and matching names.
When files contain multiple sources of symbol information, it is
possible for the minimal symbol table to contain many duplicate entries.
As an example, SVR4 systems use ELF formatted object files, which
usually contain at least two different types of symbol tables (a
standard ELF one and a smaller dynamic linking table), as well as
DWARF debugging information for files compiled with -g.
Without compacting, the minimal symbol table for gdb itself contains
over a 1000 duplicates, about a third of the total table size. Aside
from the potential trap of not noticing that two successive entries
identify the same location, this duplication impacts the time required
to linearly scan the table, which is done in a number of places. So
just do one linear scan here and toss out the duplicates.
Note that we are not concerned here about recovering the space that
is potentially freed up, because the strings themselves are allocated
on the symbol_obstack, and will get automatically freed when the symbol
table is freed. Also, the unused minimal symbols at the end of the
compacted region will get freed automatically as well by whomever
is responsible for deallocating the entire minimal symbol table. We
can't diddle with the pointer anywhy, so don't worry about the
wasted space.
Also note we only go up to the next to last entry within the loop
and then copy the last entry explicitly after the loop terminates.
Since the different sources of information for each symbol may
have different levels of "completeness", we may have duplicates
that have one entry with type "mst_unknown" and the other with a
known type. So if the one we are leaving alone has type mst_unknown,
overwrite its type with the type from the one we are compacting out. */
static int
compact_minimal_symbols (msymbol, mcount)
struct minimal_symbol *msymbol;
int mcount;
{
struct minimal_symbol *copyfrom;
struct minimal_symbol *copyto;
if (mcount > 0)
{
copyfrom = copyto = msymbol;
while (copyfrom < msymbol + mcount - 1)
{
if (copyfrom -> address == (copyfrom + 1) -> address
&& (strcmp (copyfrom -> name, (copyfrom + 1) -> name) == 0))
{
if ((copyfrom + 1) -> type == mst_unknown)
{
(copyfrom + 1) -> type = copyfrom -> type;
}
copyfrom++;
}
else
{
*copyto++ = *copyfrom++;
}
}
*copyto++ = *copyfrom++;
mcount = copyto - msymbol;
}
return (mcount);
}
/* INCLINK nonzero means bunches are from an incrementally-linked file.
Add them to the existing bunches.
Otherwise INCLINK is zero, and we start from scratch.
FIXME: INCLINK is currently unused, and is a holdover from when all
these symbols were stored in a shared, globally available table. If
it turns out we still need to be able to incrementally add minimal
symbols to an existing minimal symbol table for a given objfile, then
we will need to slightly modify this code so that when INCLINK is
nonzero we copy the existing table to a work area that is allocated
large enough for all the symbols and add the new ones to the end. */
void
install_minimal_symbols (inclink, objfile)
int inclink;
struct objfile *objfile;
{
register int bindex;
register int mcount;
register struct msym_bunch *bunch;
register struct minimal_symbol *msymbols;
int nbytes;
if (msym_count > 0)
{
/* Allocate a temporary work area into which we will gather the
bunches of minimal symbols, sort them, and then compact out
duplicate entries. Once we have a final table, it will be attached
to the specified objfile. */
msymbols = (struct minimal_symbol *)
xmalloc (msym_count * sizeof (struct minimal_symbol));
mcount = 0;
/* Walk through the list of minimal symbol bunches, adding each symbol
to the new contiguous array of symbols. Note that we start with the
current, possibly partially filled bunch (thus we use the current
msym_bunch_index for the first bunch we copy over), and thereafter
each bunch is full. */
for (bunch = msym_bunch; bunch != NULL; bunch = bunch -> next)
{
for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++)
{
msymbols[mcount] = bunch -> contents[bindex];
#ifdef NAMES_HAVE_UNDERSCORE
if (msymbols[mcount].name[0] == '_')
{
msymbols[mcount].name++;
}
#endif
#ifdef SOME_NAMES_HAVE_DOT
if (msymbols[mcount].name[0] == '.')
{
msymbols[mcount].name++;
}
#endif
}
msym_bunch_index = BUNCH_SIZE;
}
/* Sort the minimal symbols by address. */
qsort (msymbols, mcount, sizeof (struct minimal_symbol),
compare_minimal_symbols);
/* Compact out any duplicates. The table is reallocated to a
smaller size, even though it is unnecessary here, as we are just
going to move everything to an obstack anyway. */
mcount = compact_minimal_symbols (msymbols, mcount);
/* Attach the minimal symbol table to the specified objfile, allocating
the table entries in the symbol_obstack. Note that the strings them-
selves are already located in the symbol_obstack. We also terminate
the minimal symbol table with a "null symbol", which is *not* included
in the size of the table. This makes it easier to find the end of
the table when we are handed a pointer to some symbol in the middle
of it. */
objfile -> minimal_symbol_count = mcount;
nbytes = (mcount + 1) * sizeof (struct minimal_symbol);
objfile -> msymbols = (struct minimal_symbol *)
obstack_alloc (&objfile -> symbol_obstack, nbytes);
memcpy (objfile -> msymbols, msymbols, nbytes);
free (msymbols);
/* Zero out the fields in the "null symbol" allocated at the end
of the array. Note that the symbol count does *not* include
this null symbol, which is why it is indexed by mcount and not
mcount-1. */
objfile -> msymbols[mcount].name = NULL;
objfile -> msymbols[mcount].address = 0;
objfile -> msymbols[mcount].info = NULL;
objfile -> msymbols[mcount].type = mst_unknown;
}
}

View File

@ -57,12 +57,16 @@ fetch_core_registers ()
return;
}
/* ARGSUSED */
void
fetch_inferior_registers ()
fetch_inferior_registers (regno)
int regno;
{
return;
}
/* ARGSUSED */
void
store_inferior_registers (regno)
int regno;
{
@ -88,9 +92,9 @@ store_inferior_registers (regno)
/* Get all registers from the inferior */
void
fetch_inferior_registers ()
fetch_inferior_registers (regno)
int regno;
{
register int regno;
register unsigned int regaddr;
char buf[MAX_REGISTER_RAW_SIZE];
register int i;

160
gdb/mmap-alloc.c Executable file
View File

@ -0,0 +1,160 @@
/* GDB support for special malloc using mmap.
Copyright 1992 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "defs.h"
#if defined (HAVE_MMAP)
/* Redefine the external visible symbols in gmalloc.c to be mmap versions */
#define free _mmap_free
#define malloc _mmap_malloc
#define realloc _mmap_realloc
#define valloc _mmap_valloc
#define _bytes_free _mmap__bytes_free
#define _bytes_used _mmap__bytes_used
#define _chunks_free _mmap__chunks_free
#define _chunks_used _mmap__chunks_used
#define _fraghead _mmap__fraghead
#define _heapbase _mmap__heapbase
#define _heapindex _mmap__heapindex
#define _heapinfo _mmap__heapinfo
#define _heaplimit _mmap__heaplimit
#define __default_morecore _mmap___default_morecore
#define __free _mmap___free
#define __free_hook _mmap___free_hook
#define __malloc_hook _mmap___malloc_hook
#define __malloc_initialized _mmap___malloc_initialized
#define __morecore _mmap___morecore
#define __realloc_hook _mmap___realloc_hook
/* Arrange that instead of calling sbrk() we call mmap_sbrk() */
#define sbrk mmap_sbrk
/* Now simply include the standard GNU malloc source, and all the
externally visible symbols will become _mmap_* versions, and
_mmap_sbrk will be called to get more core instead of sbrk. */
#include "gmalloc.c"
/* Like mmap_malloc but get error if no storage available. */
PTR
mmap_xmalloc (size)
long size;
{
register char *val = NULL;
/* Protect against gdb wanting to allocate zero bytes. */
if (size > 0)
{
if ((val = (char *) _mmap_malloc (size)) == NULL)
{
fatal ("virtual memory exhausted.", 0);
}
}
return (val);
}
/* Like mmap_realloc but get error if no storage available. */
PTR
mmap_xrealloc (ptr, size)
PTR ptr;
long size;
{
register char *val;
if ((val = (char *) _mmap_realloc (ptr, size)) == NULL)
{
fatal ("virtual memory exhausted.", 0);
}
return (val);
}
PTR
mmap_malloc (size)
long size;
{
return (_mmap_malloc (size));
}
PTR
mmap_realloc (ptr, size)
PTR ptr;
long size;
{
return (_mmap_realloc (ptr, size));
}
void
mmap_free (ptr)
PTR ptr;
{
_mmap_free (ptr);
}
#else /* !defined (HAVE_MMAP) */
static char *errmsg = "This version of gdb does not support dumpable state.";
PTR
mmap_malloc (size)
long size;
{
error (errmsg);
}
PTR
mmap_xmalloc (size)
long size;
{
error (errmsg);
}
PTR
mmap_realloc (ptr, size)
PTR ptr;
long size;
{
error (errmsg);
}
PTR
mmap_xrealloc (ptr, size)
PTR ptr;
long size;
{
error (errmsg);
}
void
mmap_free (ptr)
PTR ptr;
{
error (errmsg);
}
#endif /* HAVE_MMAP */

145
gdb/mmap-sbrk.c Executable file
View File

@ -0,0 +1,145 @@
/* GDB support for an sbrk-like function that uses mmap.
Copyright 1992 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "defs.h"
#ifdef HAVE_MMAP
#include <fcntl.h>
#include <sys/mman.h>
#ifdef i386
#define MMAP_BASE ((caddr_t) 0x81000000)
#define MMAP_PGSZ 0x00002000 /* Must be multiple of real page size */
#else
#define MMAP_BASE ((caddr_t) 0xC2000000)
#define MMAP_PGSZ 0x00002000 /* Must be multiple of real page size */
#endif
#define PAGE_ALIGN(addr) (caddr_t) (((long)(addr) + MMAP_PGSZ - 1) & \
~(MMAP_PGSZ - 1))
static caddr_t mbase = MMAP_BASE; /* Current base of mmap'd region */
static caddr_t mbreak = MMAP_BASE; /* Current "break" address */
static caddr_t mtop = MMAP_BASE; /* Current top of mmap'd region */
static int fd = -1; /* Open fd for /dev/zero */
/* Provide a utility routine for other modules to obtain compatible
page alignment. */
PTR
mmap_page_align (addr)
PTR addr;
{
return (PAGE_ALIGN (addr));
}
/* Return the base address of the start of the mmap'd region. Note that
we can find the end of the region at anytime by calling mmap_sbrk(0) */
PTR
mmap_base ()
{
return (mbase);
}
/* Works like sbrk(), but uses mmap to add to or subtract from a
memory region. */
PTR
mmap_sbrk (size)
int size;
{
PTR result = NULL;
int minc;
caddr_t moveto;
if (size == 0)
{
/* Just return the current "break" value. */
result = mbreak;
}
else if (size < 0)
{
/* We are deallocating memory. If the amount requested would cause
us to try to deallocate back past the base of the mmap'd region
then do nothing, and return NULL. Otherwise, deallocate the
memory and return the old break value. */
if (mbreak + size >= mbase)
{
result = (PTR) mbreak;
mbreak += size;
moveto = PAGE_ALIGN (mbreak);
munmap (moveto, (size_t) (mtop - moveto));
mtop = moveto;
}
}
else
{
/* We are allocating memory. Make sure we have an open file
descriptor and then go on to get the memory. */
if ((fd == -1) && (fd = open ("/dev/zero", O_RDONLY)) < 0)
{
result = NULL;
}
else if (mbreak + size > mtop)
{
/* The request would move us past the end of the currently
mapped memory, so map in enough more memory to satisfy
the request. */
moveto = PAGE_ALIGN (mbreak + size);
if (mmap (mtop, moveto - mtop, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_FIXED, fd, 0) == mtop)
{
mtop = moveto;
result = (PTR) mbreak;
mbreak += size;
}
}
else
{
result = (PTR) mbreak;
mbreak += size;
}
}
return (result);
}
PTR
mmap_remap (base, mapsize, fd, foffset)
PTR base;
long mapsize;
int fd;
long foffset;
{
/* FIXME: Quick hack, needs error checking and other attention. */
munmap (mbase, (size_t) (mtop - mbase));
mbase = base;
mtop = mbase + mapsize;
base = mmap (base, mapsize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_FIXED, dup (fd), foffset);
return (base);
}
#endif /* HAVE_MMAP */

View File

@ -38,7 +38,7 @@ nindy_frame_chain_valid (chain, curframe)
FRAME curframe;
{
struct symbol *sym;
int i;
struct minimal_symbol *msymbol;
/* crtnindy.o is an assembler module that is assumed to be linked
* first in an i80960 executable. It contains the true entry point;
@ -64,10 +64,10 @@ nindy_frame_chain_valid (chain, curframe)
if ( sym != 0 ){
a = sym->value.value;
} else {
i = lookup_misc_func (sf);
if (i < 0)
msymbol = lookup_minimal_symbol (sf, (struct objfile *) NULL);
if (msymbol == NULL)
return 0;
a = misc_function_vector[i].address;
a = msymbol -> address;
}
return ( chain != read_memory_integer(a,4) );

326
gdb/objfiles.c Normal file
View File

@ -0,0 +1,326 @@
/* GDB routines for manipulating objfiles.
Copyright 1992 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This file contains support routines for creating, manipulating, and
destroying objfile structures. */
#include <stdio.h>
#include "defs.h"
#include "bfd.h" /* Binary File Description */
#include "symtab.h"
#include "symfile.h"
#include <obstack.h>
/* Externally visible variables that are owned by this module. */
struct objfile *object_files; /* Linked list of all objfiles */
/* Allocate a new objfile struct, fill it in as best we can, and return it.
It is also linked into the list of all known object files. */
struct objfile *
allocate_objfile (abfd, filename, dumpable)
bfd *abfd;
char *filename;
int dumpable;
{
struct objfile *objfile;
/* First, if the objfile is to be dumpable, we must malloc the structure
itself using the mmap version, and arrange that all memory allocation
for the objfile uses the mmap routines. Otherwise, just use the
old sbrk'd malloc routines. */
if (dumpable)
{
objfile = (struct objfile *) mmap_xmalloc (sizeof (struct objfile));
(void) memset (objfile, 0, sizeof (struct objfile));
objfile -> malloc = mmap_malloc;
objfile -> realloc = mmap_realloc;
objfile -> xmalloc = mmap_xmalloc;
objfile -> xrealloc = mmap_xrealloc;
objfile -> free = mmap_free;
objfile -> flags |= OBJF_DUMPABLE;
}
else
{
objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
(void) memset (objfile, 0, sizeof (struct objfile));
objfile -> malloc = malloc;
objfile -> realloc = realloc;
objfile -> xmalloc = xmalloc;
objfile -> xrealloc = xrealloc;
objfile -> free = free;
}
/* Now, malloc a fresh copy of the filename string using the malloc
specified as appropriate for the objfile. */
objfile -> name = (*objfile -> xmalloc) (strlen (filename) + 1);
strcpy (objfile -> name, filename);
objfile -> obfd = abfd;
objfile -> mtime = bfd_get_mtime (abfd);
/* Set up the various obstacks to use the memory allocation/free
functions that are appropriate for this objfile. */
obstack_full_begin (&objfile -> psymbol_obstack, 0, 0,
objfile -> xmalloc, objfile -> free);
obstack_full_begin (&objfile -> symbol_obstack, 0, 0,
objfile -> xmalloc, objfile -> free);
obstack_full_begin (&objfile -> type_obstack, 0, 0,
objfile -> xmalloc, objfile -> free);
/* Push this file onto the head of the linked list of other such files. */
objfile -> next = object_files;
object_files = objfile;
return (objfile);
}
/* Destroy an objfile and all the symtabs and psymtabs under it. Note
that as much as possible is allocated on the symbol_obstack and
psymbol_obstack, so that the memory can be efficiently freed. */
void
free_objfile (objfile)
struct objfile *objfile;
{
struct objfile *ofp;
if (objfile -> name)
{
(*objfile -> free) (objfile -> name);
}
if (objfile -> obfd)
{
bfd_close (objfile -> obfd);
}
/* Remove it from the chain of all objfiles. */
if (object_files == objfile)
{
object_files = objfile -> next;
}
else
{
for (ofp = object_files; ofp; ofp = ofp -> next)
{
if (ofp -> next == objfile)
{
ofp -> next = objfile -> next;
}
}
}
obstack_free (&objfile -> psymbol_obstack, 0);
obstack_free (&objfile -> symbol_obstack, 0);
obstack_free (&objfile -> type_obstack, 0);
#if 0 /* FIXME!! */
/* Before the symbol table code was redone to make it easier to
selectively load and remove information particular to a specific
linkage unit, gdb used to do these things whenever the monolithic
symbol table was blown away. How much still needs to be done
is unknown, but we play it safe for now and keep each action until
it is shown to be no longer needed. */
clear_symtab_users_once ();
#if defined (CLEAR_SOLIB)
CLEAR_SOLIB ();
#endif
clear_pc_function_cache ();
#endif
/* The last thing we do is free the objfile struct itself, using the
free() that is appropriate for the objfile. */
(*objfile -> free) (objfile);
}
/* Many places in gdb want to test just to see if we have any partial
symbols available. This function returns zero if none are currently
available, nonzero otherwise. */
int
have_partial_symbols ()
{
struct objfile *ofp;
int havethem = 0;
for (ofp = object_files; ofp; ofp = ofp -> next)
{
if (ofp -> psymtabs != NULL)
{
havethem++;
break;
}
}
return (havethem);
}
/* Many places in gdb want to test just to see if we have any full
symbols available. This function returns zero if none are currently
available, nonzero otherwise. */
int
have_full_symbols ()
{
struct objfile *ofp;
int havethem = 0;
for (ofp = object_files; ofp; ofp = ofp -> next)
{
if (ofp -> symtabs != NULL)
{
havethem++;
break;
}
}
return (havethem);
}
/* Many places in gdb want to test just to see if we have any minimal
symbols available. This function returns zero if none are currently
available, nonzero otherwise. */
int
have_minimal_symbols ()
{
struct objfile *ofp;
int havethem = 0;
for (ofp = object_files; ofp; ofp = ofp -> next)
{
if (ofp -> msymbols != NULL)
{
havethem++;
break;
}
}
return (havethem);
}
/* Call the function specified by FUNC for each currently available objfile,
for as long as this function continues to return NULL. If the function
ever returns non-NULL, then the iteration over the objfiles is terminated,
and the result is returned to the caller. The function called has full
control over the form and content of the information returned via the
non-NULL result, which may be as simple as a pointer to the objfile that
the iteration terminated on, or as complex as a pointer to a private
structure containing multiple results. */
PTR
iterate_over_objfiles (func, arg1, arg2, arg3)
PTR (*func) PARAMS ((struct objfile *, PTR, PTR, PTR));
PTR arg1;
PTR arg2;
PTR arg3;
{
register struct objfile *objfile;
PTR result = NULL;
for (objfile = object_files;
objfile != NULL && result == NULL;
objfile = objfile -> next)
{
result = (*func)(objfile, arg1, arg2, arg3);
}
return (result);
}
/* Call the function specified by FUNC for each currently available symbol
table, for as long as this function continues to return NULL. If the
function ever returns non-NULL, then the iteration over the symbol tables
is terminated, and the result is returned to the caller. The function
called has full control over the form and content of the information
returned via the non-NULL result, which may be as simple as a pointer
to the symtab that the iteration terminated on, or as complex as a
pointer to a private structure containing multiple results. */
PTR
iterate_over_symtabs (func, arg1, arg2, arg3)
PTR (*func) PARAMS ((struct objfile *, struct symtab *, PTR, PTR, PTR));
PTR arg1;
PTR arg2;
PTR arg3;
{
register struct objfile *objfile;
register struct symtab *symtab;
PTR result = NULL;
for (objfile = object_files;
objfile != NULL && result == NULL;
objfile = objfile -> next)
{
for (symtab = objfile -> symtabs;
symtab != NULL && result == NULL;
symtab = symtab -> next)
{
result = (*func)(objfile, symtab, arg1, arg2, arg3);
}
}
return (result);
}
/* Call the function specified by FUNC for each currently available partial
symbol table, for as long as this function continues to return NULL. If
the function ever returns non-NULL, then the iteration over the partial
symbol tables is terminated, and the result is returned to the caller.
The function called has full control over the form and content of the
information returned via the non-NULL result, which may be as simple as a
pointer to the partial symbol table that the iteration terminated on, or
as complex as a pointer to a private structure containing multiple
results. */
PTR
iterate_over_psymtabs (func, arg1, arg2, arg3)
PTR (*func) PARAMS ((struct objfile *, struct partial_symtab *,
PTR, PTR, PTR));
PTR arg1;
PTR arg2;
PTR arg3;
{
register struct objfile *objfile;
register struct partial_symtab *psymtab;
PTR result = NULL;
for (objfile = object_files;
objfile != NULL && result == NULL;
objfile = objfile -> next)
{
for (psymtab = objfile -> psymtabs;
psymtab != NULL && result == NULL;
psymtab = psymtab -> next)
{
result = (*func)(objfile, psymtab, arg1, arg2, arg3);
}
}
return (result);
}

View File

@ -31,6 +31,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "frame.h"
#include "expression.h"
#include "value.h"
@ -38,6 +39,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "language.h"
#include "parser-defs.h"
static void
prefixify_expression PARAMS ((struct expression *));
static int
length_of_subexp PARAMS ((struct expression *, int));
static void
prefixify_subexp PARAMS ((struct expression *, struct expression *, int, int));
/* Assign machine-independent names to certain registers
(unless overridden by the REGISTER_NAMES table) */
@ -117,7 +127,7 @@ write_exp_elt (expelt)
if (expout_ptr >= expout_size)
{
expout_size *= 2;
expout = (struct expression *) xrealloc (expout,
expout = (struct expression *) xrealloc ((char *) expout,
sizeof (struct expression)
+ expout_size * sizeof (union exp_element));
}
@ -207,7 +217,7 @@ write_exp_string (str)
{
expout_size = max (expout_size * 2, expout_ptr + 10);
expout = (struct expression *)
xrealloc (expout, (sizeof (struct expression)
xrealloc ((char *) expout, (sizeof (struct expression)
+ (expout_size * sizeof (union exp_element))));
}
bcopy (str.ptr, (char *) &expout->elts[expout_ptr - lenelt], len);
@ -230,9 +240,7 @@ copy_name (token)
/* Reverse an expression from suffix form (in which it is constructed)
to prefix form (in which we can conveniently print or execute it). */
static void prefixify_subexp ();
void
static void
prefixify_expression (expr)
register struct expression *expr;
{
@ -252,7 +260,7 @@ prefixify_expression (expr)
/* Return the number of exp_elements in the subexpression of EXPR
whose last exp_element is at index ENDPOS - 1 in EXPR. */
int
static int
length_of_subexp (expr, endpos)
register struct expression *expr;
register int endpos;
@ -552,7 +560,7 @@ parse_exp_1 (stringptr, block, comma)
discard_cleanups (old_chain);
expout->nelts = expout_ptr;
expout = (struct expression *)
xrealloc (expout,
xrealloc ((char *) expout,
sizeof (struct expression)
+ expout_ptr * sizeof (union exp_element));
prefixify_expression (expout);
@ -582,7 +590,7 @@ push_type (tp)
{
type_stack_size *= 2;
type_stack = (union type_stack_elt *)
xrealloc (type_stack, type_stack_size * sizeof (*type_stack));
xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack));
}
type_stack[type_stack_depth++].piece = tp;
}
@ -595,7 +603,7 @@ push_type_int (n)
{
type_stack_size *= 2;
type_stack = (union type_stack_elt *)
xrealloc (type_stack, type_stack_size * sizeof (*type_stack));
xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack));
}
type_stack[type_stack_depth++].int_val = n;
}

View File

@ -19,6 +19,9 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (PARSER_DEFS_H)
#define PARSER_DEFS_H 1
struct std_regs {
char *name;
int regnum;
@ -31,21 +34,6 @@ struct expression *expout;
int expout_size;
int expout_ptr;
extern struct type *init_type ();
void write_exp_elt ();
void write_exp_elt_opcode ();
void write_exp_elt_sym ();
void write_exp_elt_longcst ();
void write_exp_elt_dblcst ();
void write_exp_elt_type ();
void write_exp_elt_intern ();
void write_exp_string ();
void start_arglist ();
int end_arglist ();
void free_funcalls ();
char *copy_name ();
/* If this is nonzero, this block is used as the lexical context
for symbol names. */
@ -106,10 +94,53 @@ union type_stack_elt {
union type_stack_elt *type_stack;
int type_stack_depth, type_stack_size;
void push_type ();
void push_type_int ();
enum type_pieces pop_type ();
int pop_type_int ();
extern void
write_exp_elt PARAMS ((union exp_element));
extern void
write_exp_elt_opcode PARAMS ((enum exp_opcode));
extern void
write_exp_elt_sym PARAMS ((struct symbol *));
extern void
write_exp_elt_longcst PARAMS ((LONGEST));
extern void
write_exp_elt_dblcst PARAMS ((double));
extern void
write_exp_elt_type PARAMS ((struct type *));
extern void
write_exp_elt_intern PARAMS ((struct internalvar *));
extern void
write_exp_string PARAMS ((struct stoken));
extern void
start_arglist PARAMS ((void));
extern int
end_arglist PARAMS ((void));
extern void
free_funcalls PARAMS ((void));
extern char *
copy_name PARAMS ((struct stoken));
extern void
push_type PARAMS ((enum type_pieces));
extern void
push_type_int PARAMS ((int));
extern enum type_pieces
pop_type PARAMS ((void));
extern int
pop_type_int PARAMS ((void));
/* During parsing of a C expression, the pointer to the next character
is in this variable. */
@ -160,3 +191,5 @@ struct op_print
enum precedence precedence;
int right_assoc;
};
#endif /* PARSER_DEFS_H */

View File

@ -47,8 +47,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
SET_NAMESTRING();
bss_ext_symbol:
record_misc_function (namestring, CUR_SYMBOL_VALUE,
CUR_SYMBOL_TYPE); /* Always */
record_minimal_symbol (namestring, CUR_SYMBOL_VALUE,
CUR_SYMBOL_TYPE, objfile); /* Always */
#endif /* DBXREAD_ONLY */
continue;
@ -108,8 +108,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|| VTBL_PREFIX_P ((namestring+HASH_OFFSET)))
{
/* Not really a function here, but... */
record_misc_function (namestring, CUR_SYMBOL_VALUE,
CUR_SYMBOL_TYPE); /* Always */
record_minimal_symbol (namestring, CUR_SYMBOL_VALUE,
CUR_SYMBOL_TYPE, objfile); /* Always */
}
#endif /* DBXREAD_ONLY */
continue;
@ -182,15 +182,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
The first one is a directory name; the second the file name.
If pst exists, is empty, and has a filename ending in '/',
we assume the previous N_SO was a directory name. */
if (global_psymbols.next
== (global_psymbols.list + pst->globals_offset)
&& static_psymbols.next
== (static_psymbols.list + pst->statics_offset)
if (pst -> objfile -> global_psymbols.next
== (pst -> objfile -> global_psymbols.list + pst->globals_offset)
&& pst -> objfile -> static_psymbols.next
== (pst -> objfile -> static_psymbols.list + pst->statics_offset)
&& pst->filename && pst->filename[0]
&& pst->filename[strlen(pst->filename)-1] == '/') {
/* Just replace the directory name with the real filename. */
pst->filename =
(char *) obstack_alloc (psymbol_obstack,
(char *) obstack_alloc (&pst->objfile->psymbol_obstack,
strlen (namestring) + 1);
strcpy (pst->filename, namestring);
continue;
@ -208,7 +208,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
pst = START_PSYMTAB (objfile, addr,
namestring, valu,
first_symnum * symbol_size,
global_psymbols.next, static_psymbols.next);
objfile -> global_psymbols.next,
objfile -> static_psymbols.next);
continue;
}
@ -299,20 +300,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
case 'T':
ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
STRUCT_NAMESPACE, LOC_TYPEDEF,
static_psymbols, CUR_SYMBOL_VALUE);
objfile->static_psymbols, CUR_SYMBOL_VALUE);
if (p[2] == 't')
{
/* Also a typedef with the same name. */
ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
VAR_NAMESPACE, LOC_TYPEDEF,
static_psymbols, CUR_SYMBOL_VALUE);
objfile->static_psymbols, CUR_SYMBOL_VALUE);
p += 1;
}
goto check_enum;
case 't':
ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
VAR_NAMESPACE, LOC_TYPEDEF,
static_psymbols, CUR_SYMBOL_VALUE);
objfile->static_psymbols, CUR_SYMBOL_VALUE);
check_enum:
/* If this is an enumerated type, we need to
add all the enum constants to the partial symbol
@ -361,7 +362,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
enum constants in psymtabs, just in symtabs. */
ADD_PSYMBOL_TO_LIST (p, q - p,
VAR_NAMESPACE, LOC_CONST,
static_psymbols, 0);
objfile->static_psymbols, 0);
/* Point past the name. */
p = q;
/* Skip over the value. */
@ -377,7 +378,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Constant, e.g. from "const" in Pascal. */
ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
VAR_NAMESPACE, LOC_CONST,
static_psymbols, CUR_SYMBOL_VALUE);
objfile->static_psymbols, CUR_SYMBOL_VALUE);
continue;
default:
/* Skip if the thing following the : is
@ -418,13 +419,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
case 'c':
ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
VAR_NAMESPACE, LOC_CONST,
static_psymbols, CUR_SYMBOL_VALUE);
objfile->static_psymbols, CUR_SYMBOL_VALUE);
continue;
case 'S':
CUR_SYMBOL_VALUE += addr; /* Relocate */
ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring,
VAR_NAMESPACE, LOC_STATIC,
static_psymbols, CUR_SYMBOL_VALUE);
objfile->static_psymbols, CUR_SYMBOL_VALUE);
continue;
case 'G':
CUR_SYMBOL_VALUE += addr; /* Relocate */
@ -432,19 +433,19 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
wrong. See the code that reads 'G's for symtabs. */
ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring,
VAR_NAMESPACE, LOC_STATIC,
global_psymbols, CUR_SYMBOL_VALUE);
objfile->global_psymbols, CUR_SYMBOL_VALUE);
continue;
case 't':
ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
VAR_NAMESPACE, LOC_TYPEDEF,
static_psymbols, CUR_SYMBOL_VALUE);
objfile->static_psymbols, CUR_SYMBOL_VALUE);
continue;
case 'f':
ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
VAR_NAMESPACE, LOC_BLOCK,
static_psymbols, CUR_SYMBOL_VALUE);
objfile->static_psymbols, CUR_SYMBOL_VALUE);
continue;
/* Global functions were ignored here, but now they
@ -455,7 +456,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
case 'F':
ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
VAR_NAMESPACE, LOC_BLOCK,
global_psymbols, CUR_SYMBOL_VALUE);
objfile->global_psymbols, CUR_SYMBOL_VALUE);
continue;
/* Two things show up here (hopefully); static symbols of

View File

@ -32,6 +32,7 @@ regardless of whether or not the actual target has floating point hardware.
*/
#include <stdio.h>
#include "defs.h"
@ -42,7 +43,6 @@ regardless of whether or not the actual target has floating point hardware.
#include <fcntl.h>
#include <errno.h>
#include "ansidecl.h"
#include "inferior.h"
#include "target.h"
@ -50,14 +50,6 @@ regardless of whether or not the actual target has floating point hardware.
#define PROC_NAME_FMT "/proc/%d"
#endif
extern void EXFUN(supply_gregset, (gregset_t *gregsetp));
extern void EXFUN(fill_gregset, (gregset_t *gresetp, int regno));
#if defined (FP0_REGNUM)
extern void EXFUN(supply_fpregset, (fpregset_t *fpregsetp));
extern void EXFUN(fill_fpregset, (fpregset_t *fpresetp, int regno));
#endif
#if 1 /* FIXME: Gross and ugly hack to resolve coredep.c global */
CORE_ADDR kernel_u_addr;
#endif
@ -89,16 +81,47 @@ struct procinfo {
static struct procinfo pi; /* Inferior's process information */
/* Forward declarations of static functions so we don't have to worry
about ordering within this file. The EXFUN macro may be slightly
misleading. Should probably be called DCLFUN instead, or something
more intuitive, since it can be used for both static and external
definitions. */
/* Prototypes for local functions */
static int
proc_address_to_fd PARAMS ((CORE_ADDR, int));
static int
open_proc_file PARAMS ((int, struct procinfo *));
static void
close_proc_file PARAMS ((struct procinfo *));
static void
unconditionally_kill_inferior PARAMS ((void));
static void
proc_init_failed PARAMS ((char *));
static void
proc_info PARAMS ((char *, int));
static void
proc_info_address_map PARAMS ((struct procinfo *, int));
static char *
mappingflags PARAMS ((long));
/* External function prototypes that can't be easily included in any
header file because the args are typedefs in system include files. */
extern void
supply_gregset PARAMS ((gregset_t *));
extern void
fill_gregset PARAMS ((gregset_t *, int));
extern void
supply_fpregset PARAMS ((fpregset_t *));
extern void
fill_fpregset PARAMS ((fpregset_t *, int));
static void EXFUN(proc_init_failed, (char *why));
static int EXFUN(open_proc_file, (int pid, struct procinfo *pip));
static void EXFUN(close_proc_file, (struct procinfo *pip));
static void EXFUN(unconditionally_kill_inferior, (void));
/*
@ -120,11 +143,11 @@ DESCRIPTION
*/
int
DEFUN(ptrace, (request, pid, arg3, arg4),
int request AND
int pid AND
int arg3 AND
int arg4)
ptrace (request, pid, arg3, arg4)
int request;
int pid;
int arg3;
int arg4;
{
error ("internal error - there is a call to ptrace() somewhere");
/*NOTREACHED*/
@ -155,7 +178,7 @@ NOTES
*/
void
DEFUN_VOID(kill_inferior_fast)
kill_inferior_fast ()
{
if (inferior_pid != 0 && !attach_flag)
{
@ -186,7 +209,7 @@ NOTES
*/
void
DEFUN_VOID(kill_inferior)
kill_inferior ()
{
if (inferior_pid != 0)
{
@ -219,7 +242,7 @@ NOTE
*/
static void
DEFUN_VOID(unconditionally_kill_inferior)
unconditionally_kill_inferior ()
{
int signo;
@ -258,12 +281,12 @@ NOTES
int
DEFUN(child_xfer_memory, (memaddr, myaddr, len, dowrite, target),
CORE_ADDR memaddr AND
char *myaddr AND
int len AND
int dowrite AND
struct target_ops *target /* ignored */)
child_xfer_memory (memaddr, myaddr, len, dowrite, target)
CORE_ADDR memaddr;
char *myaddr;
int len;
int dowrite;
struct target_ops *target; /* ignored */
{
int nbytes = 0;
@ -324,8 +347,8 @@ NOTES
*/
void
DEFUN(store_inferior_registers, (regno),
int regno)
store_inferior_registers (regno)
int regno;
{
if (regno != -1)
{
@ -376,8 +399,8 @@ NOTES
*/
void
DEFUN(inferior_proc_init, (pid),
int pid)
inferior_proc_init (pid)
int pid;
{
if (!open_proc_file (pid, &pi))
{
@ -432,7 +455,7 @@ NOTE
*/
void
DEFUN_VOID(proc_set_exec_trap)
proc_set_exec_trap ()
{
sysset_t exitset;
auto char procname[32];
@ -476,8 +499,8 @@ DESCRIPTION
*/
int
DEFUN(proc_iterate_over_mappings, (func),
int (*func)())
proc_iterate_over_mappings (func)
int (*func) PARAMS ((int, CORE_ADDR));
{
int nmap;
int fd;
@ -488,13 +511,13 @@ DEFUN(proc_iterate_over_mappings, (func),
if (pi.valid && (ioctl (pi.fd, PIOCNMAP, &nmap) == 0))
{
prmaps = alloca ((nmap + 1) * sizeof (*prmaps));
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
if (ioctl (pi.fd, PIOCMAP, prmaps) == 0)
{
for (prmap = prmaps; prmap -> pr_size && funcstat == 0; ++prmap)
{
fd = proc_address_to_fd (prmap -> pr_vaddr, 0);
funcstat = (*func) (fd, prmap -> pr_vaddr);
fd = proc_address_to_fd ((CORE_ADDR) prmap -> pr_vaddr, 0);
funcstat = (*func) (fd, (CORE_ADDR) prmap -> pr_vaddr);
close (fd);
}
}
@ -524,9 +547,11 @@ DESCRIPTION
*/
#if 0 /* Currently unused */
CORE_ADDR
DEFUN(proc_base_address, (addr),
CORE_ADDR addr)
proc_base_address (addr)
CORE_ADDR addr;
{
int nmap;
struct prmap *prmaps;
@ -535,7 +560,7 @@ DEFUN(proc_base_address, (addr),
if (pi.valid && (ioctl (pi.fd, PIOCNMAP, &nmap) == 0))
{
prmaps = alloca ((nmap + 1) * sizeof (*prmaps));
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
if (ioctl (pi.fd, PIOCMAP, prmaps) == 0)
{
for (prmap = prmaps; prmap -> pr_size; ++prmap)
@ -552,6 +577,8 @@ DEFUN(proc_base_address, (addr),
return (baseaddr);
}
#endif /* 0 */
/*
GLOBAL_FUNCTION
@ -572,10 +599,10 @@ DESCRIPTION
*/
int
DEFUN(proc_address_to_fd, (addr, complain),
CORE_ADDR addr AND
int complain)
static int
proc_address_to_fd (addr, complain)
CORE_ADDR addr;
int complain;
{
int fd = -1;
@ -621,8 +648,8 @@ NOTES
*/
int
DEFUN(attach, (pid),
int pid)
attach (pid)
int pid;
{
if (!open_proc_file (pid, &pi))
{
@ -714,8 +741,8 @@ DESCRIPTION
*/
void
DEFUN(detach, (signal),
int signal)
detach (signal)
int signal;
{
if (signal)
{
@ -815,8 +842,8 @@ NOTES
*/
int
DEFUN(proc_wait, (statloc),
int *statloc)
proc_wait (statloc)
int *statloc;
{
short what;
short why;
@ -950,9 +977,9 @@ NOTE
*/
void
DEFUN(child_resume, (step, signal),
int step AND
int signal)
child_resume (step, signal)
int step;
int signal;
{
errno = 0;
pi.prrun.pr_flags = PRSVADDR | PRSTRACE | PRSFAULT | PRCFAULT;
@ -991,7 +1018,7 @@ GLOBAL FUNCTION
SYNOPSIS
void fetch_inferior_registers (void)
void fetch_inferior_registers (int regno)
DESCRIPTION
@ -1002,7 +1029,8 @@ DESCRIPTION
*/
void
DEFUN_VOID(fetch_inferior_registers)
fetch_inferior_registers (regno)
int regno;
{
if (ioctl (pi.fd, PIOCGREG, &pi.gregset) != -1)
{
@ -1025,7 +1053,7 @@ GLOBAL FUNCTION
SYNOPSIS
void fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
int which)
int which, unsigned in reg_addr)
DESCRIPTION
@ -1041,10 +1069,11 @@ NOTES
*/
void
fetch_core_registers (core_reg_sect, core_reg_size, which)
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
unsigned int reg_addr; /* Unused in this version */
{
if (which == 0)
@ -1096,8 +1125,8 @@ DESCRIPTION
*/
static void
DEFUN(proc_init_failed, (why),
char *why)
proc_init_failed (why)
char *why;
{
print_sys_errmsg (pi.pathname, errno);
(void) kill (pi.pid, SIGKILL);
@ -1126,8 +1155,8 @@ DESCRIPTION
*/
static void
DEFUN(close_proc_file, (pip),
struct procinfo *pip)
close_proc_file (pip)
struct procinfo *pip;
{
pip -> pid = 0;
if (pip -> valid)
@ -1167,9 +1196,9 @@ DESCRIPTION
*/
static int
DEFUN(open_proc_file, (pid, pip),
int pid AND
struct procinfo *pip)
open_proc_file (pid, pip)
int pid;
struct procinfo *pip;
{
pip -> valid = 0;
if (pip -> valid)
@ -1190,8 +1219,8 @@ DEFUN(open_proc_file, (pid, pip),
}
static char *
DEFUN (mappingflags, (flags),
long flags)
mappingflags (flags)
long flags;
{
static char asciiflags[7];
@ -1206,9 +1235,9 @@ DEFUN (mappingflags, (flags),
}
static void
DEFUN(proc_info_address_map, (pip, verbose),
struct procinfo *pip AND
int verbose)
proc_info_address_map (pip, verbose)
struct procinfo *pip;
int verbose;
{
int nmap;
struct prmap *prmaps;
@ -1223,7 +1252,7 @@ DEFUN(proc_info_address_map, (pip, verbose),
"Flags");
if (ioctl (pip -> fd, PIOCNMAP, &nmap) == 0)
{
prmaps = alloca ((nmap + 1) * sizeof (*prmaps));
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
if (ioctl (pip -> fd, PIOCMAP, prmaps) == 0)
{
for (prmap = prmaps; prmap -> pr_size; ++prmap)
@ -1265,9 +1294,9 @@ DESCRIPTION
*/
static void
DEFUN(proc_info, (args, from_tty),
char *args AND
int from_tty)
proc_info (args, from_tty)
char *args;
int from_tty;
{
int verbose = 0;
int pid;
@ -1275,7 +1304,6 @@ DEFUN(proc_info, (args, from_tty),
struct procinfo *pip;
struct cleanup *old_chain;
char *nexttok;
extern char *strtok ();
old_chain = make_cleanup (null_cleanup, 0);

View File

@ -32,11 +32,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/user.h> /* After a.out.h */
#include <sys/file.h>
#include <sys/stat.h>
void
fetch_inferior_registers ()
fetch_inferior_registers (regno)
int regno;
{
register int regno, datum;
register int datum;
register unsigned int regaddr;
int reg_buf[NUM_REGS+1];
struct user u;
@ -124,6 +126,7 @@ fetch_inferior_registers ()
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
store_inferior_registers (regno)
int regno;
{

View File

@ -1083,7 +1083,7 @@ int from_tty;
/* You may need to do an init_target_mm() */
/* init_target_mm(?,?,?,?,?,?,?,?); */
immediate_quit--;
/* symbol_file_add (arg_string, from_tty, text_addr, 0); */
/* (void) symbol_file_add (arg_string, from_tty, text_addr, 0); */
#endif
}

View File

@ -301,7 +301,7 @@ nindy_load( filename, from_tty )
tmpfile = coffstrip(scratch_pathname);
if ( tmpfile ){
old_chain = make_cleanup(unlink,tmpfile);
old_chain = make_cleanup (unlink,tmpfile);
immediate_quit++;
ninDownload( tmpfile, !from_tty );
/* FIXME, don't we want this merged in here? */

View File

@ -47,10 +47,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "xdr_rdb.h"
#include "dbgRpcLib.h"
/* get rid of value.h if possible */
#include <value.h>
#include <symtab.h>
extern void symbol_file_command ();
extern int stop_soon_quietly; /* for wait_for_inferior */
@ -718,7 +716,7 @@ vx_load_command (arg_string, from_tty)
immediate_quit--;
/* FIXME, for now we ignore data_addr and bss_addr. */
symbol_file_add (arg_string, from_tty, text_addr, 0);
(void) symbol_file_add (arg_string, from_tty, text_addr, 0);
}
#ifdef FIXME /* Not ready for prime time */
@ -1041,7 +1039,7 @@ add_symbol_stub (arg)
struct ldfile *pLoadFile = (struct ldfile *)arg;
printf("\t%s: ", pLoadFile->name);
symbol_file_add (pLoadFile->name, 0, pLoadFile->txt_addr, 0);
(void) symbol_file_add (pLoadFile->name, 0, pLoadFile->txt_addr, 0);
printf ("ok\n");
return 1;
}

View File

@ -60,7 +60,8 @@ static int special_regs[] = {
extern int one_stepped;
fetch_inferior_registers ()
fetch_inferior_registers (regno)
int regno;
{
int ii;
extern char registers[];
@ -87,6 +88,7 @@ fetch_inferior_registers ()
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
store_inferior_registers (regno)
int regno;
{
@ -156,16 +158,15 @@ store_inferior_registers (regno)
if ( errno ) {
perror ("ptrace write"); errno = 0;
return -1;
}
return 0;
}
void
fetch_core_registers (core_reg_sect, core_reg_size, which)
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
unsigned int reg_addr; /* Unused in this version */
{
/* fetch GPRs and special registers from the first register section
in core bfd. */
@ -230,7 +231,6 @@ unsigned int pid;
{
#define MAX_LOAD_SEGS 64 /* maximum number of load segments */
extern int compare_misc_functions ();
struct ld_info *ldi;
int temp;
@ -256,7 +256,7 @@ unsigned int pid;
&& (ldi = (void *) (ldi->ldinfo_next + (char *) ldi)));
/* Now that we've jumbled things around, re-sort them. */
sort_misc_function_vector ();
sort_minimal_symbols ();
/* relocate the exec and core sections as well. */
vmap_exec ();

777
gdb/state.c Normal file
View File

@ -0,0 +1,777 @@
/* Support for dumping and reloading various pieces of GDB's internal state.
Copyright 1992 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This file provides support for dumping and then later reloading various
portions of gdb's internal state. It was originally implemented to
support a need for mapping in an image of gdb's symbol table from an
external file, where this image was created by an external program, such
as an incremental linker. However, it was generalized to enable future
support for dumping and reloading various other useful pieces of gdb's
internal state.
State files have a fairly simple form which is intended to be easily
extensible. The basic format is:
<file-header> <state-data> <form-tree>
Where:
file-header A simple file-header containing a magic number
so that gdb (and other readers) can quickly
determine what kind of file this is, and a file
offset to the root of the form-tree.
state-data The "raw" state-data that is referenced by nodes
in the form-tree.
form-tree A tree of arbitrarily sized nodes containing
information about gdb's internal state, and
possibly referencing data in the state-data section
of the file. Resembles DWARF in some respects.
When writing a state file, a hole is left for the file-header at the
beginning of the file, the state data is written immediately after the
file header (while storing the file offsets and sizes back into the
internal form-tree along the way), the form-tree itself is written
at the end of the file, and then the file header is written by seeking
back to the beginning of the file. This order is required because
the form tree contains file offsets and sizes in the state data portion
of the file, and the file header contains the file offset to the start
of the form tree.
Readers simply open the file, validate the magic number, seek to the
root of the form-tree, and walk the tree looking for the information that
they are interested in (and ignoring things that they aren't, or don't
understand).
*/
#include <stdio.h>
#include "defs.h"
#include "symtab.h"
#include "bfd.h"
#include "symfile.h"
#include "state.h"
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif
/* Inside the state file, the form-tree consists of a series of
form-tree entries (FTE's). The parent/child/sibling relationships
are implied by the ordering and by an explicit sibling reference
in FTE's that have siblings.
Specifically, given two sequential FTE's, say A and B, if B immediately
follows A, and A does not have a sibling reference to B, then B is
the first child of A. Otherwise B must be a sibling of A and A must
have a sibling reference for it.
Each FTE is simply an array of long integers, with at least three
members. This form was chosen over a packed data form for simplicity
in access, not having to worry about the relative sizes of the different
integers (short, int, long), and not having to worry about alignment
constraints. Also in the name of simplicity, every FTE has a sibling
reference slot reserved for it, even if there are no siblings.
The first value in an FTE is the size of the FTE in bytes, including
the size value itself. The second entry contains a tag which indicates
the type of the FTE. The third entry is a sibling reference, which either
refers to a valid sibling node or is zero. Following is zero or more
attributes, each of which consists of one or more long values. */
/* Tag names and codes. */
#define TAG_padding 0x0000 /* Padding */
#define TAG_objfile 0x0001 /* Dumped objfile */
/* Form names, codes, and macros. */
#define FORM_ABSREF 0x01 /* Next long is absolute file offset */
#define FORM_RELREF 0x02 /* Next long is relative file offset */
#define FORM_IVAL 0x03 /* Next long is int value */
#define FORM_ADDR 0x04 /* Next long is mem addr */
#define FORM_MASK 0xFF
#define FORM_X(atr) ((atr) & FORM_MASK)
/* Attribute names and codes. */
#define AT_sibling (0x0100 | FORM_RELREF) /* Reference to sibling node */
#define AT_name (0x0200 | FORM_ABSREF) /* Reference to a string */
#define AT_offset (0x0300 | FORM_ABSREF) /* Reference to generic data */
#define AT_size (0x0400 | FORM_IVAL)
#define AT_addr (0x0500 | FORM_ADDR)
#define AT_aux_addr (0x0600 | FORM_ADDR)
/* */
static void
load_symbols PARAMS ((FILE *));
static void
dump_state_command PARAMS ((char *, int));
static void
load_state_command PARAMS ((char *, int));
#ifdef HAVE_MMAP
static void
write_header PARAMS ((sfd *));
static void
write_formtree PARAMS ((sfd *));
static void
write_objfile_state PARAMS ((sfd *));
static void
free_subtree PARAMS ((struct formnode *));
static void
size_subtree PARAMS ((struct formnode *));
#endif
struct formnode *formtree = NULL;
/* ARGSUSED */
static void
load_symbols (statefile)
FILE *statefile;
{
#if 0
/* Discard old symbols. FIXME: This is essentially symbol_file_command's
body when there is no name. Make it a common function that is
called from each place. */
if (symfile_objfile)
{
free_objfile (symfile_objfile);
}
symfile_objfile = NULL;
#endif
#if 0 && defined (HAVE_MMAP)
if (mtop > mbase)
{
warning ("internal error: mbase (%08x) != mtop (%08x)",
mbase, mtop);
munmap (mbase, mtop - mbase);
}
#endif /* HAVE_MMAP */
/* Getting new symbols may change our opinion about what is frameless. */
reinit_frame_cache ();
}
#ifdef HAVE_MMAP
/* Allocate a form node */
static struct formnode *
alloc_formnode ()
{
struct formnode *fnp;
fnp = (struct formnode *) xmalloc (sizeof (struct formnode));
(void) memset (fnp, 0, sizeof (struct formnode));
fnp -> sibling = formtree;
formtree = fnp;
return (fnp);
}
/* Recursively walk a form-tree from the specified node, freeing
nodes from the bottom up. The concept is pretty simple, just free
all the child nodes, then all the sibling nodes, then the node
itself. */
static void
free_subtree (fnp)
struct formnode *fnp;
{
if (fnp != NULL)
{
free_subtree (fnp -> child);
free_subtree (fnp -> sibling);
if (fnp -> nodedata != NULL)
{
free (fnp -> nodedata);
}
free (fnp);
}
}
/* Recursively walk a form-tree from the specified node, computing the
size of each subtree from the bottom up.
At each node, the file space that will be consumed by the subtree
rooted in that node is the sum of all the subtrees rooted in each
child node plus the size of the node itself.
Thus for each node, we size the child subtrees, add to that our
size, contribute this size towards the size of any parent node, and
then ask any of our siblings to do the same.
Also, once we know the size of any subtree rooted at this node, we
can initialize the offset to the sibling node (if any).
Since every form-tree node must have valid nodedata at this point,
we detect and report a warning for any node that doesn't. */
static void
size_subtree (fnp)
struct formnode *fnp;
{
long *lp;
if (fnp != NULL)
{
if (fnp -> nodedata == NULL)
{
warning ("internal error -- empty form node");
}
else
{
size_subtree (fnp -> child);
fnp -> treesize += *(long *) fnp -> nodedata;
if (fnp -> parent != NULL)
{
fnp -> parent -> treesize += fnp -> treesize;
}
if (fnp -> sibling)
{
size_subtree (fnp -> sibling);
lp = (long *) (fnp -> nodedata + 2 * sizeof (long));
*lp = fnp -> treesize;
}
}
}
}
/* Recursively walk a form-tree from the specified node, writing
nodes from the top down. */
static void
write_subtree (fnp, asfd)
struct formnode *fnp;
sfd *asfd;
{
if (fnp != NULL)
{
if (fnp -> nodedata != NULL)
{
fwrite (fnp -> nodedata, *(long *) fnp -> nodedata, 1, asfd -> fp);
}
write_subtree (fnp -> child, asfd);
write_subtree (fnp -> sibling, asfd);
}
}
/* Free the entire current formtree. Called via do_cleanups, regardless
of whether there is an error or not. */
static void
free_formtree ()
{
free_subtree (formtree);
formtree = NULL;
}
/* Write out the file header. Generally this is done last, even though
it is located at the start of the file, since we need to have file
offset to where the annotated form tree was written, and it's size. */
static void
write_header (asfd)
sfd *asfd;
{
fseek (asfd -> fp, 0L, SEEK_SET);
fwrite ((char *) &asfd -> hdr, sizeof (asfd -> hdr), 1, asfd -> fp);
}
/* Write out the annotated form tree. We should already have written out
the state data, and noted the file offsets and sizes in each node of
the form tree that references part of the state data.
The form tree can be written anywhere in the file where there is room
for it. Since there is always room at the end of the file, we write
it there. We also need to record the file offset to the start of the
form tree, and it's size, for future use when writing the file header.
In order to compute the sibling references, we need to know, at
each node, how much space will be consumed when all of that node's
children nodes have been written. Thus we walk the tree, computing
the sizes of the subtrees from the bottom up. At any node, the
offset from the start of that node to the start of the sibling node
is simply the size of the node plus the size of the subtree rooted
in that node. */
static void
write_formtree (asfd)
sfd *asfd;
{
size_subtree (formtree);
fseek (asfd -> fp, 0L, SEEK_END);
asfd -> hdr.sf_ftoff = ftell (asfd -> fp);
write_subtree (formtree, asfd);
asfd -> hdr.sf_ftsize = ftell (asfd -> fp) - asfd -> hdr.sf_ftoff;
}
/* Note that we currently only support having one objfile with dumpable
state. */
static void
write_objfile_state (asfd)
sfd *asfd;
{
struct objfile *objfile;
struct formnode *fnp;
PTR base;
PTR breakval;
long *lp;
unsigned int ftesize;
long ftebuf[64];
long foffset;
/* First walk through the objfile list looking for the first objfile
that is dumpable. */
for (objfile = object_files; objfile != NULL; objfile = objfile -> next)
{
if (objfile -> flags & OBJF_DUMPABLE)
{
break;
}
}
if (objfile == NULL)
{
warning ("no dumpable objfile was found");
}
else
{
fnp = alloc_formnode ();
lp = ftebuf;
lp++; /* Skip FTE size slot, filled in at the end. */
*lp++ = TAG_objfile; /* This is an objfile FTE */
*lp++ = 0; /* Zero the sibling reference slot. */
/* Build an AT_name attribute for the objfile's name, and write
the name into the state data. */
*lp++ = AT_name;
*lp++ = (long) ftell (asfd -> fp);
fwrite (objfile -> name, strlen (objfile -> name) + 1, 1, asfd -> fp);
/* Build an AT_addr attribute for the virtual address to which the
objfile data is mapped (and needs to be remapped when read in). */
base = mmap_base ();
*lp++ = AT_addr;
*lp++ = (long) base;
/* Build an AT_aux_addr attribute for the address of the objfile
structure itself, within the dumpable data. When we read the objfile
back in, we use this address as the pointer the "struct objfile". */
*lp++ = AT_aux_addr;
*lp++ = (long) objfile;
/* Reposition in state file to next paging boundry so we can mmap the
dumpable objfile data when we reload it. */
foffset = (long) mmap_page_align ((PTR) ftell (asfd -> fp));
fseek (asfd -> fp, foffset, SEEK_SET);
/* Build an AT_offset attribute for the offset in the state file to
the start of the dumped objfile data. */
*lp++ = AT_offset;
*lp++ = (long) ftell (asfd -> fp);
/* Build an AT_size attribute for the size of the dumped objfile data. */
breakval = mmap_sbrk (0);
*lp++ = AT_size;
*lp++ = breakval - base;
/* Write the dumpable data. */
fwrite ((char *) base, breakval - base, 1, asfd -> fp);
/* Now finish up the FTE by filling in the size slot based on
how much of the ftebuf we have used, allocate some memory for
it hung off the form tree node, and copy it there. */
ftebuf[0] = (lp - ftebuf) * sizeof (ftebuf[0]);
fnp -> nodedata = (char *) xmalloc (ftebuf[0]);
memcpy (fnp -> nodedata, ftebuf, ftebuf[0]);
}
}
static void
load_state_command (arg_string, from_tty)
char *arg_string;
int from_tty;
{
char *filename;
char **argv;
FILE *fp;
struct cleanup *cleanups;
dont_repeat ();
if (arg_string == NULL)
{
error ("load-state takes a file name and optional state specifiers");
}
else if ((argv = buildargv (arg_string)) == NULL)
{
fatal ("virtual memory exhausted.", 0);
}
cleanups = make_cleanup (freeargv, argv);
filename = tilde_expand (*argv);
make_cleanup (free, filename);
if ((fp = fopen (filename, "r")) == NULL)
{
perror_with_name (filename);
}
make_cleanup (fclose, fp);
immediate_quit++;
while (*++argv != NULL)
{
if (strcmp (*argv, "symbols") == 0)
{
if (from_tty
&& !query ("load symbol table state from file \"%s\"? ",
filename))
{
error ("Not confirmed.");
}
load_symbols (fp);
}
else
{
error ("unknown state specifier '%s'", *argv);
}
}
immediate_quit--;
do_cleanups (cleanups);
}
/* ARGSUSED */
static void
dump_state_command (arg_string, from_tty)
char *arg_string;
int from_tty;
{
char *filename;
char **argv;
sfd *asfd;
struct cleanup *cleanups;
dont_repeat ();
if (arg_string == NULL)
{
error ("dump-state takes a file name and state specifiers");
}
else if ((argv = buildargv (arg_string)) == NULL)
{
fatal ("virtual memory exhausted.", 0);
}
cleanups = make_cleanup (freeargv, argv);
filename = tilde_expand (*argv);
make_cleanup (free, filename);
/* Now attempt to create a fresh state file. */
if ((asfd = sfd_fopen (filename, "w")) == NULL)
{
perror_with_name (filename);
}
make_cleanup (sfd_fclose, asfd);
make_cleanup (free_formtree, NULL);
immediate_quit++;
/* Now that we have an open and initialized state file, seek to the
proper offset to start writing state data and the process the
arguments. For each argument, write the state data and initialize
a form-tree node for each piece of state data. */
fseek (asfd -> fp, sizeof (sf_hdr), SEEK_SET);
while (*++argv != NULL)
{
if (strcmp (*argv, "objfile") == 0)
{
write_objfile_state (asfd);
}
else
{
error ("unknown state specifier '%s'", *argv);
}
}
/* We have written any state data. All that is left to do now is
write the form-tree and the file header. */
write_formtree (asfd);
write_header (asfd);
immediate_quit--;
do_cleanups (cleanups);
}
static char *
find_fte_by_walk (thisfte, endfte, tag)
char *thisfte;
char *endfte;
long tag;
{
char *found = NULL;
char *nextfte;
long thistag;
long thissize;
long siboffset;
while (thisfte < endfte)
{
if ((thistag = *(long *)(thisfte + sizeof (long))) == tag)
{
found = thisfte;
break;
}
else
{
thissize = *(long *)(thisfte);
siboffset = *(long *)(thisfte + (2 * sizeof (long)));
nextfte = thisfte + (siboffset != 0 ? siboffset : thissize);
found = find_fte_by_walk (thisfte + thissize, nextfte, tag);
thisfte = nextfte;
}
}
return (found);
}
/* Walk the form-tree looking for a specific FTE type. Returns the first
one found that matches the specified tag. */
static char *
find_fte (asfd, tag)
sfd *asfd;
long tag;
{
char *ftbase;
char *ftend;
char *ftep;
char *found = NULL;
if (fseek (asfd -> fp, asfd -> hdr.sf_ftoff, SEEK_SET) == 0)
{
ftbase = xmalloc (asfd -> hdr.sf_ftsize);
ftend = ftbase + asfd -> hdr.sf_ftsize;
if (fread (ftbase, asfd -> hdr.sf_ftsize, 1, asfd -> fp) == 1)
{
ftep = find_fte_by_walk (ftbase, ftend, tag);
if (ftep != NULL)
{
found = xmalloc (*(long *)ftep);
memcpy (found, ftep, (int) *(long *)ftep);
}
}
free (ftbase);
}
return (found);
}
struct objfile *
objfile_from_statefile (asfd)
sfd *asfd;
{
struct objfile *objfile = NULL;
char *ftep;
long *thisattr;
long *endattr;
PTR base;
long foffset;
long mapsize;
ftep = find_fte (asfd, TAG_objfile);
thisattr = (long *) (ftep + 3 * sizeof (long));
endattr = (long *) (ftep + *(long *)ftep);
while (thisattr < endattr)
{
switch (*thisattr++)
{
case AT_name:
/* Ignore for now */
thisattr++;
break;
case AT_addr:
base = (PTR) *thisattr++;
break;
case AT_aux_addr:
objfile = (struct objfile *) *thisattr++;
break;
case AT_offset:
foffset = *thisattr++;
break;
case AT_size:
mapsize = *thisattr++;
break;
}
}
if (mmap_remap (base, mapsize, (int) fileno (asfd -> fp), foffset) != base)
{
print_sys_errmsg (asfd -> filename, errno);
error ("mapping failed");
}
return (objfile);
}
#else
struct objfile *
objfile_from_statefile (asfd)
sfd *asfd;
{
error ("this version of gdb doesn't support reloading symtabs from state files");
}
#endif /* HAVE_MMAP */
/* Close a state file, freeing all memory that was used by the state
file descriptor, closing the raw file pointer, etc. */
void
sfd_fclose (asfd)
sfd *asfd;
{
if (asfd != NULL)
{
if (asfd -> fp != NULL)
{
fclose (asfd -> fp);
}
if (asfd -> filename != NULL)
{
free (asfd -> filename);
}
free (asfd);
}
}
/* Given the name of a possible statefile, and flags to use to open it,
try to open the file and prepare it for use.
If the flags contain 'r', then we want to read an existing state
file, so attempt to read in the state file header and determine if this
is a valid state file. If not, return NULL.
Returns a pointer to a properly initialized state file descriptor if
successful. */
sfd *
sfd_fopen (name, flags)
char *name;
char *flags;
{
int success = 0;
sfd *asfd;
asfd = (sfd *) xmalloc (sizeof (sfd));
(void) memset (asfd, 0, sizeof (sfd));
asfd -> filename = xmalloc (strlen (name) + 1);
(void) strcpy (asfd -> filename, name);
if ((asfd -> fp = fopen (asfd -> filename, flags)) != NULL)
{
/* We have the file, now see if we are reading an existing file
or writing to a new file. We don't currently support "rw". */
if (strchr (flags, 'r') != NULL)
{
if (fread ((char *) &asfd -> hdr, sizeof (asfd -> hdr), 1,
asfd -> fp) == 1)
{
if (SF_GOOD_MAGIC (asfd))
{
success = 1;
}
}
}
else
{
/* This is a new state file. Initialize various things. */
asfd -> hdr.sf_mag0 = SF_MAG0;
asfd -> hdr.sf_mag1 = SF_MAG1;
asfd -> hdr.sf_mag2 = SF_MAG2;
asfd -> hdr.sf_mag3 = SF_MAG3;
success = 1;
}
}
if (!success)
{
sfd_fclose (asfd);
asfd = NULL;
}
return (asfd);
}
void
_initialize_state ()
{
#ifdef HAVE_MMAP
add_com ("load-state", class_support, load_state_command,
"Load some saved gdb state from FILE.\n\
Select and load some portion of gdb's saved state from the specified file.\n\
The dump-state command may be used to save various portions of gdb's\n\
internal state.");
add_com ("dump-state", class_support, dump_state_command,
"Dump some of gdb's state to FILE.\n\
Select and dump some portion of gdb's internal state to the specified file.\n\
The load-state command may be used to reload various portions of gdb's\n\
internal state from the file.");
#endif /* HAVE_MMAP */
}

85
gdb/state.h Normal file
View File

@ -0,0 +1,85 @@
/* Support for dumping and reloading various pieces of GDB's internal state.
Copyright 1992 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This file provides definitions used for reading and writing gdb
state files. State files have a fairly simple form which is intended
to be easily extensible. See state.c for further documentation. */
#if !defined (_STATE_H)
#define _STATE_H
/* State file-header */
typedef struct {
unsigned char sf_mag0; /* Magic number byte 0 */
unsigned char sf_mag1; /* Magic number byte 1 */
unsigned char sf_mag2; /* Magic number byte 2 */
unsigned char sf_mag3; /* Magic number byte 3 */
unsigned long sf_ftoff; /* File offset to start of form-tree */
unsigned long sf_ftsize; /* Size of the form-tree, in bytes */
} sf_hdr;
#define SF_MAG0 'g' /* Magic number byte 0 value */
#define SF_MAG1 'd' /* Magic number byte 1 value */
#define SF_MAG2 'b' /* Magic number byte 2 value */
#define SF_MAG3 '\000' /* Magic number byte 3 value */
#define SF_GOOD_MAGIC(asfd) ((asfd) -> hdr.sf_mag0 == SF_MAG0 && \
(asfd) -> hdr.sf_mag1 == SF_MAG1 && \
(asfd) -> hdr.sf_mag2 == SF_MAG2 && \
(asfd) -> hdr.sf_mag3 == SF_MAG3)
/* The internal form-tree is formed from nodes that contain pointers
to the first sibling, the first child, a backpointer to the parent,
and a pointer to the actual data for the node. This allows all
tree nodes to have the same sized structure, but support variable
numbers of child nodes per parent node. The backpointer for the
parent is required for simplier tree walks. */
struct formnode
{
struct formnode *sibling; /* Pointer to first sibling */
struct formnode *child; /* Pointer to first child */
struct formnode *parent; /* Backpointer to parent */
char *nodedata; /* Pointer to the nodes data */
unsigned long treesize; /* Size of subtree rooted here */
};
/* A state file descriptor is defined by the following structure. */
typedef struct
{
char *filename; /* Full pathname of the state file */
FILE *fp; /* Open file pointer for the state file */
sf_hdr hdr; /* Copy of the state file-header */
char *formtree; /* Pointer to in-memory copy of form-tree */
} sfd;
extern sfd *
sfd_fopen PARAMS ((char *, char *));
extern void
sfd_fclose PARAMS ((sfd *));
extern struct objfile *
objfile_from_statefile PARAMS ((sfd *));
#endif /* !defined (_STATE_H) */

View File

@ -444,15 +444,12 @@ symmetry_extract_return_value(type, regbuf, valbuf)
double d;
int l[2];
} xd;
int i;
struct minimal_symbol *msymbol;
float f;
if (TYPE_CODE_FLT == TYPE_CODE(type)) {
for (i = 0; i < misc_function_count; i++) {
if (!strcmp(misc_function_vector[i].name, "1167_flt"))
break;
}
if (i < misc_function_count) {
msymbol = lookup_minimal_symbol ("1167_flt", (struct objfile *) NULL);
if (msymbol != NULL) {
/* found "1167_flt" means 1167, %fp2-%fp3 */
/* float & double; 19= %fp2, 20= %fp3 */
/* no single precision on 1167 */

View File

@ -18,16 +18,4 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This is for SunOS version 4, not for earlier versions. */
#define CLEAR_SOLIB clear_solib
extern void clear_solib ();
#define SOLIB_ADD(filename, from_tty, targ) solib_add (filename, from_tty, targ)
extern void solib_add ();
#define SOLIB_CREATE_INFERIOR_HOOK solib_create_inferior_hook
extern void solib_create_inferior_hook();
/* If we can't set a breakpoint, and it's in a shared library, just
disable it. */
#define DISABLE_UNSETTABLE_BREAK(addr) solib_address(addr)
extern int solib_address (); /* solib.c */
#include "solib.h" /* Support for shared libraries. */

View File

@ -21,13 +21,23 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <string.h>
#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "gdbcore.h"
#include "frame.h"
#include "command.h"
#include "gdbcmd.h"
extern char *cplus_demangle ();
/* Local function prototypes. */
static value
value_headof PARAMS ((value, struct type *, struct type *));
static void
show_values PARAMS ((char *, int));
static void
show_convenience PARAMS ((void));
/* The value-history records all the values printed
by print commands during this session. Each chunk
@ -1002,6 +1012,8 @@ value_headof (arg, btype, dtype)
struct symbol *sym;
CORE_ADDR pc_for_sym;
char *demangled_name;
struct minimal_symbol *msymbol;
btype = TYPE_VPTR_BASETYPE (dtype);
check_stub_type (btype);
if (btype != dtype)
@ -1011,8 +1023,9 @@ value_headof (arg, btype, dtype)
vtbl = value_ind (value_field (value_ind (vtbl), TYPE_VPTR_FIELDNO (btype)));
/* Check that VTBL looks like it points to a virtual function table. */
i = find_pc_misc_function (VALUE_ADDRESS (vtbl));
if (i < 0 || ! VTBL_PREFIX_P (demangled_name = misc_function_vector[i].name))
msymbol = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtbl));
if (msymbol == NULL
|| !VTBL_PREFIX_P (demangled_name = msymbol -> name))
{
/* If we expected to find a vtable, but did not, let the user
know that we aren't happy, but don't throw an error.
@ -1249,7 +1262,7 @@ unpack_field_as_long (type, valaddr, fieldno)
char *valaddr;
int fieldno;
{
long val;
unsigned long val;
int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);

View File

@ -40,6 +40,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "libbfd.h" /* BFD internals (sigh!) FIXME */
/* Prototypes for local functions */
static void
add_to_section_table PARAMS ((bfd *, sec_ptr, PTR));
static void
file_command PARAMS ((char *, int));
static void
exec_close PARAMS ((int));
struct section_table *exec_sections, *exec_sections_end;
#define eq(s0, s1) !strcmp(s0, s1)
@ -90,7 +101,7 @@ extern struct target_ops exec_ops;
/* exec_close - done with exec file, clean up all resources. */
void
static void
exec_close(quitting) {
register struct vmap *vp, *nxt;
@ -124,7 +135,7 @@ char *filename;
int scratch_chan;
filename = tilde_expand(filename);
make_cleanup(free, filename);
make_cleanup (free, filename);
scratch_chan = openp(getenv("PATH"), 1, filename, O_RDONLY, 0
, &scratch_pathname);
@ -177,7 +188,7 @@ char *filename;
* novelty. Why did GDB go through four major releases before this
* command was added?
*/
void
static void
file_command(arg, from_tty)
char *arg; {
@ -189,7 +200,7 @@ char *arg; {
table_pp_char is a char * to get it through bfd_map_over_sections;
we cast it back to its proper type. */
void
static void
add_to_section_table (abfd, asect, table_pp_char)
bfd *abfd;
sec_ptr asect;
@ -283,7 +294,6 @@ map_vmap (bfd *bf, bfd *arch)
struct vmap_and_bfd vmap_bfd;
struct vmap *vp, **vpp;
struct objfile *obj;
char *name;
vp = (void*) xmalloc (sizeof (*vp));
vp->nxt = 0;
@ -297,8 +307,7 @@ map_vmap (bfd *bf, bfd *arch)
obj = lookup_objfile_bfd (bf);
if (exec_bfd && !obj) {
name = savestring (bfd_get_filename (bf), strlen (bfd_get_filename (bf)));
obj = allocate_objfile (bf, name);
obj = allocate_objfile (bf, bfd_get_filename (bf), 0);
syms_from_objfile (obj, 0, 0, 0);
}
@ -308,8 +317,20 @@ map_vmap (bfd *bf, bfd *arch)
*vpp = vp;
}
/* Called via iterate_over_msymbols to relocate minimal symbols */
/* true, if symbol table and misc_function_vector is relocated. */
static void
relocate_minimal_symbol (objfile, msymbol, arg1, arg2, arg3)
struct objfile *objfile;
struct minimal_symbol *msymbol;
PTR arg1;
PTR arg2;
PTR arg3;
{
msymbol -> address += (int) arg1;
}
/* true, if symbol table and minimal symbol table are relocated. */
int symtab_relocated = 0;
@ -321,56 +342,61 @@ register struct vmap *vp;
CORE_ADDR old_start;
struct stat *vip;
{
register struct symtab *s;
/*
* for each symbol table generated from the vp->bfd
*/
for (s = symtab_list; s; s = s->next) {
/* skip over if this is not relocatable and doesn't have a line table */
if (s->nonreloc && !LINETABLE (s))
register struct symtab *s;
register struct objfile *objfile;
/*
* for each symbol table generated from the vp->bfd
*/
for (objfile = object_files; objfile != NULL; objfile = objfile -> next)
{
for (s = objfile -> symtabs; s != NULL; s = s -> next) {
/* skip over if this is not relocatable and doesn't have a line table */
if (s->nonreloc && !LINETABLE (s))
continue;
/* matching the symbol table's BFD and the *vp's BFD is hairy.
exec_file creates a seperate BFD for possibly the
same file as symbol_file.FIXME ALL THIS MUST BE RECTIFIED. */
if (objfile->obfd == vp->bfd) {
/* if they match, we luck out. */
;
} else if (vp->member[0]) {
/* no match, and member present, not this one. */
continue;
} else {
struct stat si;
FILE *io;
/*
* no match, and no member. need to be sure.
*/
io = bfd_cache_lookup(objfile->obfd);
if (!io)
fatal("cannot find BFD's iostream for sym");
/*
* see if we are referring to the same file
*/
if (fstat(fileno(io), &si) < 0)
fatal("cannot fstat BFD for sym");
if (si.st_dev != vip->st_dev
|| si.st_ino != vip->st_ino)
continue;
/* matching the symbol table's BFD and the *vp's BFD is hairy.
exec_file creates a seperate BFD for possibly the
same file as symbol_file.FIXME ALL THIS MUST BE RECTIFIED. */
if (s->objfile->obfd == vp->bfd) {
/* if they match, we luck out. */
;
} else if (vp->member[0]) {
/* no match, and member present, not this one. */
continue;
} else {
struct stat si;
FILE *io;
/*
* no match, and no member. need to be sure.
*/
io = bfd_cache_lookup(s->objfile->obfd);
if (!io)
fatal("cannot find BFD's iostream for sym");
/*
* see if we are referring to the same file
*/
if (fstat(fileno(io), &si) < 0)
fatal("cannot fstat BFD for sym");
if (si.st_dev != vip->st_dev
|| si.st_ino != vip->st_ino)
continue;
}
if (vp->tstart != old_start)
vmap_symtab_1(s, vp, old_start);
}
if (vp->tstart != old_start)
fixup_misc_vector (vp->tstart - old_start);
symtab_relocated = 1;
vmap_symtab_1(s, vp, old_start);
}
}
if (vp->tstart != old_start)
iterate_over_msymbols (relocate_minimal_symbol,
(PTR) (vp->tstart - old_start),
(PTR) NULL, (PTR) NULL);
symtab_relocated = 1;
}

View File

@ -38,6 +38,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/stat.h>
#include "symtab.h"
#include "gdbtypes.h"
#include "symfile.h"
#include "buildsym.h"
@ -45,14 +46,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "libcoff.h" /* FIXME, internal data from BFD */
#include "coff/rs6000.h" /* FIXME, raw file-format guts of xcoff */
extern char *index();
static void enter_line_range ();
static struct symbol *process_xcoff_symbol ();
static int read_symbol_nvalue ();
static int read_symbol_lineno ();
/* Simplified internal version of coff symbol table information */
struct coff_symbol {
@ -151,14 +144,106 @@ struct coff_symfile_info {
};
static void
enter_line_range PARAMS ((struct subfile *, unsigned, unsigned, CORE_ADDR,
unsigned *));
static void
aixcoff_symfile_read PARAMS ((struct sym_fns *, CORE_ADDR, int));
static void
free_debugsection PARAMS ((void));
static int
init_debugsection PARAMS ((bfd *));
static int
init_stringtab PARAMS ((bfd *, long, struct objfile *));
static void
aixcoff_symfile_init PARAMS ((struct sym_fns *));
static void
aixcoff_new_init PARAMS ((void));
static void
dump_minimal_symbols PARAMS ((struct objfile *));
static void
dump_symtab_lines PARAMS ((struct symtab *));
static void
dump_symtabs PARAMS ((struct symtab *));
static void
dump_last_symtab PARAMS ((struct symtab *));
static void
dump_blockvector PARAMS ((struct blockvector *));
static void
dump_block PARAMS ((struct block *));
static char *
dump_addrclass PARAMS ((int));
static char *
dump_namespace PARAMS ((int));
static void
dump_symbol PARAMS ((struct symbol *));
static void
dump_type PARAMS ((struct type *));
static void
dump_linetable PARAMS ((struct linetable *));
static void
dump_strtbl PARAMS ((void));
static int
init_lineno PARAMS ((bfd *, long, int));
static void
find_linenos PARAMS ((bfd *, sec_ptr, PTR));
static int
read_symbol_lineno PARAMS ((char *, int));
static int
read_symbol_nvalue PARAMS ((char *, int));
static struct symbol *
process_xcoff_symbol PARAMS ((struct coff_symbol *, struct objfile *));
static void
read_xcoff_symtab PARAMS ((struct objfile *, int));
static void
enter_line_range PARAMS ((struct subfile *, unsigned, unsigned, CORE_ADDR,
unsigned *));
static void
add_stab_to_list PARAMS ((char *, struct pending_stabs **));
static void
sort_syms PARAMS ((void));
static int
compare_symbols PARAMS ((const void *, const void *));
/* Call sort_syms to sort alphabetically
the symbols of each block of each symtab. */
static int
compare_symbols (s1, s2)
struct symbol **s1, **s2;
compare_symbols (s1p, s2p)
const PTR s1p;
const PTR s2p;
{
/* Names that are less should come first. */
register struct symbol **s1 = (struct symbol **) s1p;
register struct symbol **s2 = (struct symbol **) s2p;
register int namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2));
if (namediff != 0)
return namediff;
@ -175,22 +260,28 @@ static void
sort_syms ()
{
register struct symtab *s;
register struct objfile *objfile;
register int i, nbl;
register struct blockvector *bv;
register struct block *b;
for (s = symtab_list; s; s = s->next)
{
bv = BLOCKVECTOR (s);
nbl = BLOCKVECTOR_NBLOCKS (bv);
for (i = 0; i < nbl; i++)
for (objfile = object_files; objfile != NULL; objfile = objfile -> next)
{
b = BLOCKVECTOR_BLOCK (bv, i);
if (BLOCK_SHOULD_SORT (b))
qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
sizeof (struct symbol *), compare_symbols);
for (s = objfile -> symtabs; s != NULL; s = s -> next)
{
bv = BLOCKVECTOR (s);
nbl = BLOCKVECTOR_NBLOCKS (bv);
for (i = 0; i < nbl; i++)
{
b = BLOCKVECTOR_BLOCK (bv, i);
if (BLOCK_SHOULD_SORT (b))
{
qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
sizeof (struct symbol *), compare_symbols);
}
}
}
}
}
}
@ -211,47 +302,13 @@ struct pending_stabs **stabvector;
else if ((*stabvector)->count >= (*stabvector)->length) {
(*stabvector)->length += INITIAL_STABVECTOR_LENGTH;
*stabvector = (struct pending_stabs *)
xrealloc (*stabvector, sizeof (struct pending_stabs) +
xrealloc ((char *) *stabvector, sizeof (struct pending_stabs) +
(*stabvector)->length * sizeof (char*));
}
(*stabvector)->stab [(*stabvector)->count++] = stabname;
}
/* for all the stabs in a given stab vector, build appropriate types
and fix their symbols in given symbol vector. */
void
patch_block_stabs (symbols, stabs)
struct pending *symbols;
struct pending_stabs *stabs;
{
int ii;
if (!stabs)
return;
/* for all the stab entries, find their corresponding symbols and
patch their types! */
for (ii=0; ii < stabs->count; ++ii) {
char *name = stabs->stab[ii];
char *pp = (char*) index (name, ':');
struct symbol *sym = find_symbol_in_list (symbols, name, pp-name);
if (!sym) {
printf ("ERROR! stab symbol not found!\n"); /* FIXME */
}
else {
pp += 2;
if (*(pp-1) == 'F' || *(pp-1) == 'f')
SYMBOL_TYPE (sym) = lookup_function_type (read_type (&pp));
else
SYMBOL_TYPE (sym) = read_type (&pp);
}
}
}
/* Enter a given range of lines into the line vector.
can be called in the following two ways:
enter_line_range (subfile, beginoffset, endoffset, 0, firstLine) or
@ -316,16 +373,16 @@ enter_line_range (subfile, beginoffset, endoffset, endaddr, firstLine)
/* Reading symbol table has to be fast! Keep the followings as macros, rather
than functions. */
#define RECORD_MISC_FUNCTION(NAME, ADDR, TYPE, ALLOCED) \
#define RECORD_MINIMAL_SYMBOL(NAME, ADDR, TYPE, ALLOCED) \
{ \
char *namestr; \
if (ALLOCED) \
namestr = (NAME) + 1; \
else { \
namestr = obstack_copy0 (symbol_obstack, (NAME) + 1, strlen ((NAME)+1)); \
namestr = obstack_copy0 (&objfile->symbol_obstack, (NAME) + 1, strlen ((NAME)+1)); \
(ALLOCED) = 1; \
} \
prim_record_misc_function (namestr, (ADDR), (TYPE)); \
prim_record_minimal_symbol (namestr, (ADDR), (TYPE)); \
last_recorded_fun = (ADDR); \
}
@ -343,7 +400,7 @@ static int symname_alloced = 0;
/* read the whole symbol table of a given bfd. */
void
static void
read_xcoff_symtab (objfile, nsyms)
struct objfile *objfile; /* Object file we're reading from */
int nsyms; /* # of symbols */
@ -376,6 +433,8 @@ read_xcoff_symtab (objfile, nsyms)
char *last_seen_csect;
int last_recorded_fun = 0; /* last recorded fun. value */
current_objfile = objfile;
/* Get the appropriate COFF "constants" related to the file we're handling. */
N_TMASK = coff_data (abfd)->local_n_tmask;
N_BTSHFT = coff_data (abfd)->local_n_btshft;
@ -522,7 +581,7 @@ read_xcoff_symtab (objfile, nsyms)
if (cs->c_name && cs->c_name[0] == '.') {
last_seen_csect = cs->c_name;
RECORD_MISC_FUNCTION (cs->c_name, cs->c_value, mf_text, symname_alloced);
RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_text, symname_alloced);
}
}
continue;
@ -553,7 +612,7 @@ read_xcoff_symtab (objfile, nsyms)
function_entry_point:
if (cs->c_value != last_recorded_fun)
RECORD_MISC_FUNCTION (cs->c_name, cs->c_value, mf_text,
RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_text,
symname_alloced);
fcn_line_offset = main_aux->x_sym.x_fcnary.x_fcn.x_lnnoptr;
@ -569,7 +628,7 @@ function_entry_point:
/* shared library function entry point. */
else if (CSECT_SCLAS (main_aux) == XMC_GL) {
if (last_recorded_fun != cs->c_value)
RECORD_MISC_FUNCTION (cs->c_name, cs->c_value, mf_text,
RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_text,
symname_alloced);
continue;
}
@ -627,7 +686,7 @@ function_entry_point:
/* mark_first_line (fcn_line_offset, cs->c_symnum); */
new = push_context (0, fcn_start_addr);
new->name = process_xcoff_symbol (&fcn_cs_saved);
new->name = process_xcoff_symbol (&fcn_cs_saved, objfile);
}
else if (strcmp (cs->c_name, ".ef") == 0) {
@ -653,7 +712,7 @@ function_entry_point:
finish_block (new->name, &local_symbols, new->old_blocks,
new->start_addr,
fcn_cs_saved.c_value +
fcn_aux_saved.x_sym.x_misc.x_fsize);
fcn_aux_saved.x_sym.x_misc.x_fsize, objfile);
within_function = 0;
}
break;
@ -690,7 +749,7 @@ function_entry_point:
fcn_last_line = cs->c_value; /* Offset to last line number */
{ long dummy = 0;
enter_line_range (current_subfile, fcn_first_line, cs->c_value, 0,
&dummy);
(unsigned *) &dummy);
}
start_subfile (pop_subfile (), (char *)0);
break;
@ -710,14 +769,14 @@ function_entry_point:
if (local_symbols && context_stack_depth > 0) {
/* Make a block for the local symbols within. */
finish_block (new->name, &local_symbols, new->old_blocks,
new->start_addr, cs->c_value);
new->start_addr, cs->c_value, objfile);
}
local_symbols = new->locals;
}
break;
default :
(void) process_xcoff_symbol (cs);
(void) process_xcoff_symbol (cs, objfile);
break;
}
@ -727,24 +786,26 @@ function_entry_point:
end_symtab (cur_src_end_addr, 1, 1, objfile);
free (symtbl);
current_objfile = NULL;
}
#define SYMBOL_DUP(SYMBOL1, SYMBOL2) \
(SYMBOL2) = (struct symbol *) \
obstack_alloc (symbol_obstack, sizeof (struct symbol)); \
obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); \
*(SYMBOL2) = *(SYMBOL1);
#define SYMNAME_ALLOC(NAME, ALLOCED) \
(ALLOCED) ? (NAME) : obstack_copy0 (symbol_obstack, (NAME), strlen (NAME));
(ALLOCED) ? (NAME) : obstack_copy0 (&objfile->symbol_obstack, (NAME), strlen (NAME));
/* process one xcoff symbol. */
static struct symbol *
process_xcoff_symbol (cs)
process_xcoff_symbol (cs, objfile)
register struct coff_symbol *cs;
struct objfile *objfile;
{
struct symbol onesymbol;
register struct symbol *sym = &onesymbol;
@ -769,7 +830,7 @@ process_xcoff_symbol (cs)
on in patch_block_stabs () */
SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced);
SYMBOL_TYPE (sym) = lookup_function_type (builtin_type_int);
SYMBOL_TYPE (sym) = lookup_function_type (lookup_fundamental_type (current_objfile, FT_INTEGER));
SYMBOL_CLASS (sym) = LOC_BLOCK;
SYMBOL_DUP (sym, sym2);
@ -783,7 +844,7 @@ process_xcoff_symbol (cs)
else {
/* in case we can't figure out the type, default is `int'. */
SYMBOL_TYPE (sym) = builtin_type_int;
SYMBOL_TYPE (sym) = lookup_fundamental_type (current_objfile, FT_INTEGER);
switch (cs->c_sclass)
{
@ -795,12 +856,12 @@ process_xcoff_symbol (cs)
break;
case C_DECL: /* a type decleration?? */
qq = (char*) index (name, ':');
qq = (char*) strchr (name, ':');
if (!qq) /* skip if there is no ':' */
return NULL;
pp = qq + 2;
ttype = SYMBOL_TYPE (sym) = read_type (&pp);
ttype = SYMBOL_TYPE (sym) = read_type (&pp, objfile);
/* read_type() will return null if type (or tag) definition was
unnnecessarily duplicated. Also, if the symbol doesn't have a name,
@ -819,7 +880,7 @@ process_xcoff_symbol (cs)
}
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_NAME (sym) = obsavestring (name, qq-name);
SYMBOL_NAME (sym) = obsavestring (name, qq-name, &objfile->symbol_obstack);
if (SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE)
TYPE_NAME (ttype) = concat (
@ -840,36 +901,36 @@ process_xcoff_symbol (cs)
break;
case C_PSYM:
if (*name == ':' || (pp = (char *) index (name, ':')) == NULL)
if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL)
return NULL;
SYMBOL_NAME (sym) = obsavestring (name, pp-name);
SYMBOL_NAME (sym) = obsavestring (name, pp-name, &objfile -> symbol_obstack);
SYMBOL_CLASS (sym) = LOC_ARG;
pp += 2;
SYMBOL_TYPE (sym) = read_type (&pp);
SYMBOL_TYPE (sym) = read_type (&pp, objfile);
SYMBOL_DUP (sym, sym2);
add_symbol_to_list (sym2, &local_symbols);
break;
case C_STSYM:
if (*name == ':' || (pp = (char *) index (name, ':')) == NULL)
if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL)
return NULL;
SYMBOL_NAME (sym) = obsavestring (name, pp-name);
SYMBOL_NAME (sym) = obsavestring (name, pp-name, &objfile -> symbol_obstack);
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE (sym) += static_block_base;
pp += 2;
SYMBOL_TYPE (sym) = read_type (&pp);
SYMBOL_TYPE (sym) = read_type (&pp, objfile);
SYMBOL_DUP (sym, sym2);
add_symbol_to_list
(sym2, within_function ? &local_symbols : &file_symbols);
break;
case C_LSYM:
if (*name == ':' || (pp = (char *) index (name, ':')) == NULL)
if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL)
return NULL;
SYMBOL_NAME (sym) = obsavestring (name, pp-name);
SYMBOL_NAME (sym) = obsavestring (name, pp-name, &objfile -> symbol_obstack);
SYMBOL_CLASS (sym) = LOC_LOCAL;
pp += 1;
SYMBOL_TYPE (sym) = read_type (&pp);
SYMBOL_TYPE (sym) = read_type (&pp, objfile);
SYMBOL_DUP (sym, sym2);
add_symbol_to_list (sym2, &local_symbols);
break;
@ -905,21 +966,22 @@ process_xcoff_symbol (cs)
break;
case C_RSYM:
pp = (char*) index (name, ':');
pp = (char*) strchr (name, ':');
SYMBOL_CLASS (sym) = LOC_REGISTER;
SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (cs->c_value);
if (pp) {
SYMBOL_NAME (sym) = obsavestring (name, pp-name);
SYMBOL_NAME (sym) = obsavestring (name, pp-name, &objfile -> symbol_obstack);
pp += 2;
if (*pp)
SYMBOL_TYPE (sym) = read_type (&pp);
SYMBOL_TYPE (sym) = read_type (&pp, objfile);
}
else
/* else this is not a stab entry, suppose the type is either
`int' or `float', depending on the register class. */
SYMBOL_TYPE (sym) = (SYMBOL_VALUE (sym) < 32) ?
builtin_type_int : builtin_type_float;
SYMBOL_TYPE (sym) = (SYMBOL_VALUE (sym) < 32)
? lookup_fundamental_type (current_objfile, FT_INTEGER)
: lookup_fundamental_type (current_objfile, FT_FLOAT);
SYMBOL_DUP (sym, sym2);
add_symbol_to_list (sym2, &local_symbols);
@ -986,7 +1048,7 @@ static void
find_linenos(abfd, asect, vpinfo)
bfd *abfd;
sec_ptr asect;
void *vpinfo;
PTR vpinfo;
{
struct coff_symfile_info *info;
int size, count;
@ -1033,12 +1095,12 @@ init_lineno (abfd, offset, size)
linetab_offset = offset;
linetab_size = size;
make_cleanup(free, linetab); /* Be sure it gets de-allocated. */
make_cleanup (free, linetab); /* Be sure it gets de-allocated. */
return 0;
}
void
static void
dump_strtbl ()
{
int ii;
@ -1048,7 +1110,7 @@ dump_strtbl ()
printf ("\n");
}
void
static void
dump_linetable (ltb)
struct linetable *ltb;
{
@ -1057,17 +1119,14 @@ dump_linetable (ltb)
printf ("line: %d, addr: 0x%x\n", ltb->item[ii].line, ltb->item[ii].pc);
}
void
static void
dump_type (typeP)
struct type *typeP;
{
printf ("0x%x: name: %s\n", typeP, typeP->name ? typeP->name : "(nil)");
}
char *dump_namespace ();
char *dump_addrclass ();
void
static void
dump_symbol (pp)
struct symbol *pp;
{
@ -1079,8 +1138,7 @@ dump_symbol (pp)
SYMBOL_CLASS(pp) == LOC_BLOCK ? BLOCK_END(SYMBOL_BLOCK_VALUE(pp)) : 0);
}
char *
static char *
dump_namespace (ns)
int ns;
{
@ -1098,8 +1156,7 @@ int ns;
return "***ERROR***";
}
char *
static char *
dump_addrclass (ac)
int ac; /* address class */
{
@ -1137,7 +1194,7 @@ int ac; /* address class */
return "***ERROR***";
}
void
static void
dump_block (pp)
struct block *pp;
{
@ -1147,7 +1204,7 @@ dump_block (pp)
dump_symbol (pp->sym[ii]);
}
void
static void
dump_blockvector (pp)
struct blockvector *pp;
{
@ -1156,8 +1213,7 @@ dump_blockvector (pp)
dump_block (pp->block [ii]);
}
void
static void
dump_last_symtab (pp)
struct symtab *pp;
{
@ -1169,7 +1225,7 @@ dump_last_symtab (pp)
}
}
void
static void
dump_symtabs (pp)
struct symtab *pp;
{
@ -1181,7 +1237,7 @@ dump_symtabs (pp)
}
}
void
static void
dump_symtab_lines (pp)
struct symtab *pp;
{
@ -1193,14 +1249,16 @@ dump_symtab_lines (pp)
}
}
void
dump_misc_funcs ()
static void
dump_minimal_symbols (objfile)
struct objfile *objfile;
{
int ii;
for (ii=0; ii < misc_function_count; ++ii)
printf ("name: %s, addr: 0x%x\n",
misc_function_vector[ii].name,
misc_function_vector[ii].address);
struct minimal_symbol *msymbol;
for (msymbol = objfile -> msymbols; msymbol -> name != NULL; msymbol++)
{
printf ("name: %s, addr: 0x%x\n", msymbol -> name, msymbol -> address);
}
}
@ -1235,77 +1293,85 @@ char **pp;
/* default types are defined in dbxstclass.h. */
switch ( typenums[1] ) {
case 1:
return builtin_type_int;
return lookup_fundamental_type (current_objfile, FT_INTEGER);
case 2:
return builtin_type_char;
return lookup_fundamental_type (current_objfile, FT_CHAR);
case 3:
return builtin_type_short;
return lookup_fundamental_type (current_objfile, FT_SHORT);
case 4:
return builtin_type_long;
return lookup_fundamental_type (current_objfile, FT_LONG);
case 5:
return builtin_type_unsigned_char;
return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
case 6:
return builtin_type_char; /* requires a builtin `signed char' */
return lookup_fundamental_type (current_objfile, FT_SIGNED_CHAR);
case 7:
return builtin_type_unsigned_short;
return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
case 8:
return builtin_type_unsigned_int;
return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
case 9:
return builtin_type_unsigned_int;
return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
case 10:
return builtin_type_unsigned_long;
return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
case 11:
return builtin_type_void;
return lookup_fundamental_type (current_objfile, FT_VOID);
case 12:
return builtin_type_float;
return lookup_fundamental_type (current_objfile, FT_FLOAT);
case 13:
return builtin_type_double;
return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
case 14:
return builtin_type_double; /* requires a builtin `long double' */
return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
case 15:
return builtin_type_int; /* requires a builtin `integer' */
/* requires a builtin `integer' */
return lookup_fundamental_type (current_objfile, FT_INTEGER);
case 16:
return builtin_type_int; /* requires builtin `boolean' */
return lookup_fundamental_type (current_objfile, FT_BOOLEAN);
case 17:
return builtin_type_float; /* requires builtin `short real' */
/* requires builtin `short real' */
return lookup_fundamental_type (current_objfile, FT_FLOAT);
case 18:
return builtin_type_float; /* requires builtin `real' */
/* requires builtin `real' */
return lookup_fundamental_type (current_objfile, FT_FLOAT);
default :
printf ("ERROR! Unknown builtin type -%d\n", typenums[1]);
return NULL;
}
}
#if 0 /* Seems to be unused, don't bother converting from old misc function
vector usage to new minimal symbol tables. FIXME: Delete this? */
/* if we now nothing about a function but its address, make a function symbol
out of it with the limited knowladge you have. This will be used when
somebody refers to a function, which doesn't exist in the symbol table,
but in misc_function_vector. */
but is in the minimal symbol table. */
struct symbol *
build_function_symbol (ind)
build_function_symbol (ind, objfile)
int ind;
struct objfile *objfile;
{
struct symbol *sym =
(struct symbol *) obstack_alloc (symbol_obstack, sizeof (struct symbol));
(struct symbol *) obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
SYMBOL_NAME (sym) = misc_function_vector[ind].name;
/* SYMBOL_VALUE (sym) = misc_function_vector[ind].address; */
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
SYMBOL_CLASS (sym) = LOC_BLOCK;
SYMBOL_TYPE (sym) = lookup_function_type (builtin_type_int);
SYMBOL_TYPE (sym) = lookup_function_type (lookup_fundamental_type (current_objfile, FT_INTEGER));
SYMBOL_BLOCK_VALUE (sym) = (struct block *)
obstack_alloc (symbol_obstack, sizeof (struct block));
obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) = misc_function_vector[ind].address;
return sym;
}
#endif
void
static void
aixcoff_new_init ()
{
/* Nothin' to do. */
}
void
static void
aixcoff_symfile_init (sf)
struct sym_fns *sf;
{
@ -1331,9 +1397,10 @@ struct sym_fns *sf;
static int
init_stringtab(abfd, offset)
init_stringtab(abfd, offset, objfile)
bfd *abfd;
long offset;
struct objfile *objfile;
{
long length;
int val;
@ -1354,7 +1421,7 @@ init_stringtab(abfd, offset)
/* Allocate string table from symbol_obstack. We will need this table
as long as we have its symbol table around. */
strtbl = (char*) obstack_alloc (symbol_obstack, length);
strtbl = (char*) obstack_alloc (&objfile->symbol_obstack, length);
if (strtbl == NULL)
return -1;
@ -1389,7 +1456,7 @@ init_debugsection(abfd)
if (!(length = bfd_section_size(abfd, secp)))
return 0;
debugsec = (void *) xmalloc ((unsigned)length);
debugsec = (char *) xmalloc ((unsigned)length);
if (debugsec == NULL)
return -1;
@ -1411,7 +1478,7 @@ free_debugsection()
/* aixcoff version of symbol file read. */
void
static void
aixcoff_symfile_read (sf, addr, mainline)
struct sym_fns *sf;
CORE_ADDR addr;
@ -1449,7 +1516,7 @@ aixcoff_symfile_read (sf, addr, mainline)
error("\"%s\": error reading line numbers\n", name);
}
val = init_stringtab(abfd, stringtab_offset);
val = init_stringtab(abfd, stringtab_offset, sf->objfile);
if (val < 0) {
error ("\"%s\": can't get string table", name);
}
@ -1466,8 +1533,8 @@ aixcoff_symfile_read (sf, addr, mainline)
if (bfd_tell(abfd) != symtab_offset)
fatal("bfd? BFD!");
init_misc_bunches ();
make_cleanup(discard_misc_bunches, 0);
init_minimal_symbol_collection ();
make_cleanup (discard_minimal_symbols, 0);
#ifdef XCOFF_INIT_LOADINFO
if (mainline)
@ -1479,13 +1546,15 @@ aixcoff_symfile_read (sf, addr, mainline)
read_xcoff_symtab(sf->objfile, num_symbols);
make_cleanup(free_debugsection, 0);
make_cleanup (free_debugsection, 0);
/* Sort symbols alphabetically within each block. */
sort_syms ();
/* Go over the misc functions and install them in vector. */
condense_misc_bunches (!mainline);
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
install_minimal_symbols (!mainline, sf -> objfile);
/* Make a default for file to list. */
select_source_symtab (0);