This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[rfa:symtab] SYMBOL_LOCATION_FUNCS -> SYMBOL_OPS
- From: Andrew Cagney <cagney at gnu dot org>
- To: gdb-patches at sources dot redhat dot com
- Date: Sat, 08 Nov 2003 15:35:57 -0500
- Subject: [rfa:symtab] SYMBOL_LOCATION_FUNCS -> SYMBOL_OPS
Hello,
This patch generalizes the per-symbol location_funcs, replacing them
with a symbol_ops vector (the contents are unchanged). The patch
doesn't change the size of the symbol.
As the comment hints:
+ /* NOTE: cagney/2003-11-02: The fields "aclass" and "ops" contain
+ overlaping information. Since GDB has only a small finite number
+ of symbol classes it should be possible to merge the two fields
+ into a single ops-table "index". Each entry providing both the
+ "ops" and the "aclass" values. Doing that would shave 32 bits
+ off every symbol. */
The patch sets us up for a more significant change - merge "ops" and
"aclass" - and hence eliminates 32 bits (or 20%) of each symbol. I
should note that right now the details of the merge are "left as an
exercise for the reader".
ok?
Andrew
PS: Hmm, better make certain I tested this on a dwarf2 system.
? diffs
Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.4988
diff -u -r1.4988 ChangeLog
--- ChangeLog 8 Nov 2003 00:13:02 -0000 1.4988
+++ ChangeLog 8 Nov 2003 20:18:41 -0000
@@ -1,3 +1,26 @@
+2003-11-08 Andrew Cagney <cagney@redhat.com>
+
+ * dwarf2loc.c (dwarf_expr_frame_base): Use SYMBOL_OPS instead of
+ SYMBOL_LOCATION_FUNCS
+ (dwarf2_loclist_funcs, dwarf2_locexpr_funcs): Change type to
+ "struct symbol_ops".
+ * dwarf2loc.h (dwarf2_locexpr_funcs, dwarf2_loclist_funcs): Change
+ type to "struct symbol_ops".
+ * dwarf2read.c (dwarf2_symbol_mark_computed): Set SYMBOL_OPS
+ intead of SYMBOL_LOCATION_FUNCS.
+ * ax-gdb.c (gen_var_ref): Ditto for "tracepoint_var_ref".
+ * printcmd.c (address_info): Ditto for "describe_location".
+ * findvar.c (symbol_read_needs_frame): Call "read_needs_frame"
+ when available. Assert requirement when LOC_COMPUTED or
+ LOC_COMPUTED_ARG.
+ (read_var_value): Ditto for "read_variable".
+ * symtab.h (struct symbol_ops): Rename "struct location_funcs".
+ (struct symbol): Replace ".aux_value.loc.funcs" and
+ ".aux_value.loc.baton" with ".ops" and ".aux_value.ptr".
+ (SYMBOL_OBJFILE): Delete macro.
+ (SYMBOL_LOCATION_FUNCS): Delete macro.
+ (SYMBOL_LOCATION_BATON): Update.
+
2003-11-07 Andrew Cagney <cagney@redhat.com>
* top.c (print_gdb_version): Replace STREQ with strcmp.
Index: ax-gdb.c
===================================================================
RCS file: /cvs/src/src/gdb/ax-gdb.c,v
retrieving revision 1.22
diff -u -r1.22 ax-gdb.c
--- ax-gdb.c 1 Mar 2003 17:03:19 -0000 1.22
+++ ax-gdb.c 8 Nov 2003 20:18:47 -0000
@@ -525,6 +525,13 @@
/* Dereference any typedefs. */
value->type = check_typedef (SYMBOL_TYPE (var));
+ /* Prefer tracepoint_var_ref over everything else. */
+ if (SYMBOL_OPS (var) != NULL && SYMBOL_OPS (var)->tracepoint_var_ref != NULL)
+ {
+ SYMBOL_OPS (var)->tracepoint_var_ref (var, ax, value);
+ return;
+ }
+
/* I'm imitating the code in read_var_value. */
switch (SYMBOL_CLASS (var))
{
@@ -621,7 +628,7 @@
case LOC_COMPUTED:
case LOC_COMPUTED_ARG:
- (*SYMBOL_LOCATION_FUNCS (var)->tracepoint_var_ref) (var, ax, value);
+ internal_error (__FILE__, __LINE__, "Method tracepoint_var_ref missing");
break;
case LOC_OPTIMIZED_OUT:
Index: dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.13
diff -u -r1.13 dwarf2loc.c
--- dwarf2loc.c 11 Sep 2003 15:02:51 -0000 1.13
+++ dwarf2loc.c 8 Nov 2003 20:18:47 -0000
@@ -154,7 +154,7 @@
framefunc = get_frame_function (debaton->frame);
- if (SYMBOL_LOCATION_FUNCS (framefunc) == &dwarf2_loclist_funcs)
+ if (SYMBOL_OPS (framefunc) == &dwarf2_loclist_funcs)
{
struct dwarf2_loclist_baton *symbaton;
symbaton = SYMBOL_LOCATION_BATON (framefunc);
@@ -465,7 +465,7 @@
/* The set of location functions used with the DWARF-2 expression
evaluator. */
-struct location_funcs dwarf2_locexpr_funcs = {
+struct symbol_ops dwarf2_locexpr_funcs = {
locexpr_read_variable,
locexpr_read_needs_frame,
locexpr_describe_location,
@@ -537,7 +537,7 @@
/* The set of location functions used with the DWARF-2 expression
evaluator and location lists. */
-struct location_funcs dwarf2_loclist_funcs = {
+struct symbol_ops dwarf2_loclist_funcs = {
loclist_read_variable,
loclist_read_needs_frame,
loclist_describe_location,
Index: dwarf2loc.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.h,v
retrieving revision 1.3
diff -u -r1.3 dwarf2loc.h
--- dwarf2loc.h 22 Jul 2003 15:41:59 -0000 1.3
+++ dwarf2loc.h 8 Nov 2003 20:18:47 -0000
@@ -21,6 +21,8 @@
#if !defined (DWARF2LOC_H)
#define DWARF2LOC_H
+struct symbol_ops;
+
/* This header is private to the DWARF-2 reader. It is shared between
dwarf2read.c and dwarf2loc.c. */
@@ -62,7 +64,7 @@
struct objfile *objfile;
};
-extern struct location_funcs dwarf2_locexpr_funcs;
-extern struct location_funcs dwarf2_loclist_funcs;
+extern struct symbol_ops dwarf2_locexpr_funcs;
+extern struct symbol_ops dwarf2_loclist_funcs;
#endif
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.111
diff -u -r1.111 dwarf2read.c
--- dwarf2read.c 8 Nov 2003 00:13:02 -0000 1.111
+++ dwarf2read.c 8 Nov 2003 20:19:04 -0000
@@ -7650,7 +7650,7 @@
complaint (&symfile_complaints,
"Location list used without specifying the CU base address.");
- SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_loclist_funcs;
+ SYMBOL_OPS (sym) = &dwarf2_loclist_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
else
@@ -7679,7 +7679,7 @@
baton->data = NULL;
}
- SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs;
+ SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
}
Index: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.67
diff -u -r1.67 findvar.c
--- findvar.c 2 Oct 2003 20:28:29 -0000 1.67
+++ findvar.c 8 Nov 2003 20:19:09 -0000
@@ -340,16 +340,17 @@
int
symbol_read_needs_frame (struct symbol *sym)
{
+ /* If the symbol has a needs_frame method, just use that. */
+ if (SYMBOL_OPS (sym) != NULL && SYMBOL_OPS (sym)->read_needs_frame != NULL)
+ return SYMBOL_OPS (sym)->read_needs_frame (sym);
+
switch (SYMBOL_CLASS (sym))
{
/* All cases listed explicitly so that gcc -Wall will detect it if
we failed to consider one. */
case LOC_COMPUTED:
case LOC_COMPUTED_ARG:
- {
- struct location_funcs *symfuncs = SYMBOL_LOCATION_FUNCS (sym);
- return (symfuncs->read_needs_frame) (sym);
- }
+ internal_error (__FILE__, __LINE__, "Method read_needs_frame missing");
break;
case LOC_REGISTER:
@@ -410,6 +411,14 @@
if (frame == NULL)
frame = deprecated_safe_get_selected_frame ();
+ /* If the symbol has a read variable method, just use that. */
+ if (SYMBOL_OPS (var) != NULL && SYMBOL_OPS (var)->read_variable != NULL)
+ {
+ if (frame == NULL && symbol_read_needs_frame (var))
+ return NULL;
+ return SYMBOL_OPS (var)->read_variable (var, frame);
+ }
+
switch (SYMBOL_CLASS (var))
{
case LOC_CONST:
@@ -564,15 +573,7 @@
case LOC_COMPUTED:
case LOC_COMPUTED_ARG:
- {
- struct location_funcs *funcs = SYMBOL_LOCATION_FUNCS (var);
-
- if (frame == 0 && (funcs->read_needs_frame) (var))
- return 0;
- return (funcs->read_variable) (var, frame);
-
- }
- break;
+ internal_error (__FILE__, __LINE__, "Method read_variable missing");
case LOC_UNRESOLVED:
{
Index: printcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/printcmd.c,v
retrieving revision 1.69
diff -u -r1.69 printcmd.c
--- printcmd.c 21 Sep 2003 01:26:45 -0000 1.69
+++ printcmd.c 8 Nov 2003 20:19:14 -0000
@@ -1119,150 +1119,153 @@
basereg = SYMBOL_BASEREG (sym);
section = SYMBOL_BFD_SECTION (sym);
- switch (SYMBOL_CLASS (sym))
+ if (sym->ops != NULL && sym->ops->describe_location != NULL)
+ sym->ops->describe_location (sym, gdb_stdout);
+ else
{
- case LOC_CONST:
- case LOC_CONST_BYTES:
- printf_filtered ("constant");
- break;
-
- case LOC_LABEL:
- printf_filtered ("a label at address ");
- print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
- 1, gdb_stdout);
- if (section_is_overlay (section))
+ switch (SYMBOL_CLASS (sym))
{
- load_addr = overlay_unmapped_address (load_addr, section);
- printf_filtered (",\n -- loaded at ");
- print_address_numeric (load_addr, 1, gdb_stdout);
- printf_filtered (" in overlay section %s", section->name);
- }
- break;
-
- case LOC_COMPUTED:
- case LOC_COMPUTED_ARG:
- (SYMBOL_LOCATION_FUNCS (sym)->describe_location) (sym, gdb_stdout);
- break;
-
- case LOC_REGISTER:
- printf_filtered ("a variable in register %s", REGISTER_NAME (val));
- break;
-
- case LOC_STATIC:
- printf_filtered ("static storage at address ");
- print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
- 1, gdb_stdout);
- if (section_is_overlay (section))
- {
- load_addr = overlay_unmapped_address (load_addr, section);
- printf_filtered (",\n -- loaded at ");
- print_address_numeric (load_addr, 1, gdb_stdout);
- printf_filtered (" in overlay section %s", section->name);
- }
- break;
-
- case LOC_INDIRECT:
- printf_filtered ("external global (indirect addressing), at address *(");
- print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
- 1, gdb_stdout);
- printf_filtered (")");
- if (section_is_overlay (section))
- {
- load_addr = overlay_unmapped_address (load_addr, section);
- printf_filtered (",\n -- loaded at ");
- print_address_numeric (load_addr, 1, gdb_stdout);
- printf_filtered (" in overlay section %s", section->name);
- }
- break;
-
- case LOC_REGPARM:
- printf_filtered ("an argument in register %s", REGISTER_NAME (val));
- break;
-
- case LOC_REGPARM_ADDR:
- printf_filtered ("address of an argument in register %s", REGISTER_NAME (val));
- break;
-
- case LOC_ARG:
- printf_filtered ("an argument at offset %ld", val);
- break;
-
- case LOC_LOCAL_ARG:
- printf_filtered ("an argument at frame offset %ld", val);
- break;
-
- case LOC_LOCAL:
- printf_filtered ("a local variable at frame offset %ld", val);
- break;
-
- case LOC_REF_ARG:
- printf_filtered ("a reference argument at offset %ld", val);
- break;
-
- case LOC_BASEREG:
- printf_filtered ("a variable at offset %ld from register %s",
- val, REGISTER_NAME (basereg));
- break;
-
- case LOC_BASEREG_ARG:
- printf_filtered ("an argument at offset %ld from register %s",
- val, REGISTER_NAME (basereg));
- break;
-
- case LOC_TYPEDEF:
- printf_filtered ("a typedef");
- break;
-
- case LOC_BLOCK:
- printf_filtered ("a function at address ");
- print_address_numeric (load_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
- 1, gdb_stdout);
- if (section_is_overlay (section))
- {
- load_addr = overlay_unmapped_address (load_addr, section);
- printf_filtered (",\n -- loaded at ");
- print_address_numeric (load_addr, 1, gdb_stdout);
- printf_filtered (" in overlay section %s", section->name);
- }
- break;
-
- case LOC_UNRESOLVED:
- {
- struct minimal_symbol *msym;
-
- msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, NULL);
- if (msym == NULL)
- printf_filtered ("unresolved");
- else
+ case LOC_CONST:
+ case LOC_CONST_BYTES:
+ printf_filtered ("constant");
+ break;
+
+ case LOC_LABEL:
+ printf_filtered ("a label at address ");
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
+ 1, gdb_stdout);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ break;
+
+ case LOC_COMPUTED:
+ case LOC_COMPUTED_ARG:
+ internal_error (__FILE__, __LINE__, "Symbol requires symbol_ops.describe_location");
+
+ case LOC_REGISTER:
+ printf_filtered ("a variable in register %s", REGISTER_NAME (val));
+ break;
+
+ case LOC_STATIC:
+ printf_filtered ("static storage at address ");
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
+ 1, gdb_stdout);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ break;
+
+ case LOC_INDIRECT:
+ printf_filtered ("external global (indirect addressing), at address *(");
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
+ 1, gdb_stdout);
+ printf_filtered (")");
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ break;
+
+ case LOC_REGPARM:
+ printf_filtered ("an argument in register %s", REGISTER_NAME (val));
+ break;
+
+ case LOC_REGPARM_ADDR:
+ printf_filtered ("address of an argument in register %s", REGISTER_NAME (val));
+ break;
+
+ case LOC_ARG:
+ printf_filtered ("an argument at offset %ld", val);
+ break;
+
+ case LOC_LOCAL_ARG:
+ printf_filtered ("an argument at frame offset %ld", val);
+ break;
+
+ case LOC_LOCAL:
+ printf_filtered ("a local variable at frame offset %ld", val);
+ break;
+
+ case LOC_REF_ARG:
+ printf_filtered ("a reference argument at offset %ld", val);
+ break;
+
+ case LOC_BASEREG:
+ printf_filtered ("a variable at offset %ld from register %s",
+ val, REGISTER_NAME (basereg));
+ break;
+
+ case LOC_BASEREG_ARG:
+ printf_filtered ("an argument at offset %ld from register %s",
+ val, REGISTER_NAME (basereg));
+ break;
+
+ case LOC_TYPEDEF:
+ printf_filtered ("a typedef");
+ break;
+
+ case LOC_BLOCK:
+ printf_filtered ("a function at address ");
+ print_address_numeric (load_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
+ 1, gdb_stdout);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ break;
+
+ case LOC_UNRESOLVED:
{
- section = SYMBOL_BFD_SECTION (msym);
- printf_filtered ("static storage at address ");
- print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (msym),
- 1, gdb_stdout);
- if (section_is_overlay (section))
+ struct minimal_symbol *msym;
+
+ msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, NULL);
+ if (msym == NULL)
+ printf_filtered ("unresolved");
+ else
{
- load_addr = overlay_unmapped_address (load_addr, section);
- printf_filtered (",\n -- loaded at ");
- print_address_numeric (load_addr, 1, gdb_stdout);
- printf_filtered (" in overlay section %s", section->name);
+ section = SYMBOL_BFD_SECTION (msym);
+ printf_filtered ("static storage at address ");
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (msym),
+ 1, gdb_stdout);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
}
}
- }
- break;
-
- case LOC_HP_THREAD_LOCAL_STATIC:
- printf_filtered (
- "a thread-local variable at offset %ld from the thread base register %s",
- val, REGISTER_NAME (basereg));
- break;
-
- case LOC_OPTIMIZED_OUT:
- printf_filtered ("optimized out");
- break;
-
- default:
- printf_filtered ("of unknown (botched) type");
- break;
+ break;
+
+ case LOC_HP_THREAD_LOCAL_STATIC:
+ printf_filtered ("a thread-local variable at offset %ld from the thread "
+ "base register %s", val, REGISTER_NAME (basereg));
+ break;
+
+ case LOC_OPTIMIZED_OUT:
+ printf_filtered ("optimized out");
+ break;
+
+ default:
+ printf_filtered ("of unknown (botched) type");
+ break;
+ }
}
printf_filtered (".\n");
}
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.82
diff -u -r1.82 symtab.h
--- symtab.h 4 Nov 2003 22:22:31 -0000 1.82
+++ symtab.h 8 Nov 2003 20:19:19 -0000
@@ -539,21 +539,12 @@
LOC_COMPUTED_ARG
};
-/* A structure of function pointers describing the location of a
- variable, structure member, or structure base class.
+/* The methods needed to implement a symbol class. These methods can
+ use the symbol's .aux_value for additional per-symbol information.
- These functions' BATON arguments are generic data pointers, holding
- whatever data the functions need --- the code which provides this
- structure also provides the actual contents of the baton, and
- decides its form. However, there may be other rules about where
- the baton data must be allocated; whoever is pointing to this
- `struct location_funcs' object will know the rules. For example,
- when a symbol S's location is LOC_COMPUTED, then
- SYMBOL_LOCATION_FUNCS(S) is pointing to a location_funcs structure,
- and SYMBOL_LOCATION_BATON(S) is the baton, which must be allocated
- on the same obstack as the symbol itself. */
+ At present this is only used to implement location expressions. */
-struct location_funcs
+struct symbol_ops
{
/* Return the value of the variable SYMBOL, relative to the stack
@@ -601,6 +592,12 @@
ENUM_BITFIELD(domain_enum_tag) domain : 6;
/* Address class */
+ /* NOTE: cagney/2003-11-02: The fields "aclass" and "ops" contain
+ overlaping information. Since GDB has only a small finite number
+ of symbol classes it should be possible to merge the two fields
+ into a single ops-table "index". Each entry providing both the
+ "ops" and the "aclass" values. Doing that would shave 32 bits
+ off every symbol. */
ENUM_BITFIELD(address_class) aclass : 6;
@@ -610,28 +607,35 @@
unsigned short line;
- /* Some symbols require an additional value to be recorded on a per-
- symbol basis. Stash those values here. */
+ /* Method's for symbol's of this class. */
+ /* NOTE: cagney/2003-11-02: The fields "aclass" and "ops" contain
+ overlaping information. Since GDB has only a small finite number
+ of symbol classes it should be possible to merge the two fields
+ into a single ops-table "index". Each entry providing both the
+ "ops" and the "aclass" values. Doing that would shave 32 bits
+ off every symbol. */
+
+ const struct symbol_ops *ops;
+
+ /* Some symbols require additional information to be recorded on a
+ per- symbol basis. Stash those values here. */
union
{
/* Used by LOC_BASEREG and LOC_BASEREG_ARG. */
short basereg;
-
- /* For a LOC_COMPUTED or LOC_COMPUTED_ARG symbol, this is the
- baton and location_funcs structure to find its location. For a
- LOC_BLOCK symbol for a function in a compilation unit compiled
- with DWARF 2 information, this is information used internally
- by the DWARF 2 code --- specifically, the location expression
- for the frame base for this function. */
+ /* An arbitrary data pointer. Note that this data must be
+ allocated using the same obstack as the symbol itself. */
+ /* So far it is only used by LOC_COMPUTED and LOC_COMPUTED_ARG to
+ find the location location information. For a LOC_BLOCK symbol
+ for a function in a compilation unit compiled with DWARF 2
+ information, this is information used internally by the DWARF 2
+ code --- specifically, the location expression for the frame
+ base for this function. */
/* FIXME drow/2003-02-21: For the LOC_BLOCK case, it might be better
to add a magic symbol to the block containing this information,
or to have a generic debug info annotation slot for symbols. */
- struct
- {
- void *baton;
- struct location_funcs *funcs;
- } loc;
+ void *ptr;
}
aux_value;
@@ -645,8 +649,8 @@
#define SYMBOL_LINE(symbol) (symbol)->line
#define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg
#define SYMBOL_OBJFILE(symbol) (symbol)->aux_value.objfile
-#define SYMBOL_LOCATION_BATON(symbol) (symbol)->aux_value.loc.baton
-#define SYMBOL_LOCATION_FUNCS(symbol) (symbol)->aux_value.loc.funcs
+#define SYMBOL_OPS(symbol) (symbol)->ops
+#define SYMBOL_LOCATION_BATON(symbol) (symbol)->aux_value.ptr
/* A partial_symbol records the name, domain, and address class of
symbols whose types we have not parsed yet. For functions, it also