Re: Run time access to symbol tables

bliss@sp64.csrd.uiuc.edu (Brian Bliss)
Wed, 20 Jan 1993 20:46:08 GMT

          From comp.compilers

Related articles
Run time access to symbol tables bar@advtech.uswest.com (1993-01-19)
Re: Run time access to symbol tables bliss@sp64.csrd.uiuc.edu (1993-01-20)
| List of all articles for this month |

Newsgroups: comp.compilers
From: bliss@sp64.csrd.uiuc.edu (Brian Bliss)
Organization: UIUC Center for Supercomputing Research and Development
Date: Wed, 20 Jan 1993 20:46:08 GMT
References: 93-01-138
Keywords: C++, debug

> I am developing a utility to print the contents of a C++ object based on
> its datatype.
>
> I would like to know if it is possible/easy to access the symbol tables
> from the executable (a.out) for the above purpose, assuming that the
> corresponding .o files have been compiled with the '-g' option. ...
> when the function 'LogTheObject' is executed, at run time, it must access
> the symbol tables from the a.out file (just as the way a debugger loads up
> the symbol tables on startup) and print the contents similar to the
> 'print' statement in 'dbx'. This function 'LogTheObject' will be in a
> runtime library linked with the application.


Yes, you can access the dbx symbol table of the executable file, parse in
into an internal format, and then call your pretty print routine which
traverses the type descriptor and the object at the same time. I have
done this with standard C (not C++) on sparcs & alliants. Anonymous ftp
to sp2.csrd.uiuc.edu to retreive the source: /pub/bliss/ae.tar.Z
documentation is included.


AT&T's cfront translator does include a few symbols directly into the
preprocessed source in the form of asm's. After compilation, you must
merge the cfront generated stabs with those generated by the standard C
compiler. A small example is in order:


consider:




class foo {
      int val;
public:
      foo () { val = 0; }
      void setval (int x) { val = x; }
      int getval () { return val; }
};




this is translated by cfront into:




struct foo { /* sizeof foo == 4 */
int val__3foo ;
};
asm(".stabs \"foo:Zcfoo;;__ct__3fooFv setval__3fooFi getval__3fooFv
  ;;;\",0x80,0,0,0");


After compiling, the following can be found in the symbol table of the
a.out file:


foo:T(0,78)=s4val__3foo:(0,1),0,32;;
foo:Zcfoo;;__ct__3fooFv setval__3fooFi getval__3fooFv ;;;


The first string is generated by the c compiler. "foo" is the symbol
name, the colon is a separator, T(0,8) implies that this is tagged type
(as opposed to tyepdef's & regular type named, denoted with a 't') number
8 in file 0 (include files are given unique positive ids). "=" implies
that the type is being defined. "s" stands for struct, since the class
was translated into a structure by cfront. "val" is the name of the
member, which is the appended with "__3foo" by cfront, for some reason.
"(0,1)" indicates that this is type #1 is file #0, which corresponds to
int. "0" is the offset in the structure, and "32" is the size in bits of
the member.


The second line was generated directly by cfront. The "Z" seems to
indicate a class name, and "cfoo" is probably it's superclass (or itself
since it has no superclass). Then follows a list of non-virtual
member functions. The "F" probably indicates that these are functions,
and the "v" or "i" is the return type.


Anyway, you have quite a bit of work cut out for you parsing the stabs and
merging the two, but it is do-able.


bb
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.