123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- /* $Header$
- Read the symbol table from an ACK a.out format file.
- */
- #include <stb.h>
- #include <alloc.h>
- #include <assert.h>
- #include "position.h"
- #include "file.h"
- #include "symbol.h"
- #include "idf.h"
- #include "scope.h"
- #include "rd.h"
- extern char *Malloc();
- extern char *strindex();
- extern struct outname *DbxString();
- int saw_code = 0;
- static char *AckStrings; /* ACK a.out string table */
- static struct outname *AckNames; /* ACK a.out symbol table entries */
- static unsigned int NAckNames; /* Number of ACK symbol table entries */
- static struct outname *EndAckNames; /* &AckNames[NAckNames] */
- /* Read the symbol table from file 'f', which is supposed to be an
- ACK a.out format file. Offer DBX strings to the DBX string parser.
- */
- int
- DbxRead(f)
- char *f;
- {
- struct outhead h;
- register struct outname *n;
- register struct outname *line_file = 0;
- long OffsetStrings;
- int had_lbrac = 0;
- /* Open file, read header, and check magic word */
- if (! rd_open(f)) {
- fatal("%s: not an ACK object file", f);
- }
- rd_ohead(&h);
- if (BADMAGIC(h) && h.oh_magic != O_CONVERTED) {
- fatal("%s: not an ACK object file", f);
- }
- /* Allocate space for name table and read it */
- AckNames = (struct outname *)
- Malloc((unsigned)(sizeof(struct outname) * h.oh_nname));
- AckStrings = Malloc((unsigned) h.oh_nchar);
- rd_name(AckNames, h.oh_nname);
- rd_string(AckStrings, h.oh_nchar);
- /* Adjust file offsets in name table to point at strings */
- OffsetStrings = OFF_CHAR(h);
- NAckNames = h.oh_nname;
- EndAckNames = &AckNames[h.oh_nname];
- for (n = EndAckNames; --n >= AckNames;) {
- if (n->on_foff) {
- if ((unsigned)(n->on_foff - OffsetStrings) >= h.oh_nchar) {
- fatal("%s: error in object file", f);
- }
- n->on_mptr = AckStrings + (n->on_foff - OffsetStrings);
- }
- else n->on_mptr = 0;
- }
- /* Offer strings to the DBX string parser if they contain a ':'.
- Also offer filename-line number information to add_position_addr().
- Here, the order may be important.
- */
- for (n = &AckNames[0]; n < EndAckNames; n++) {
- int tp = n->on_type >> 8;
- register p_symbol sym;
- if (tp & (S_STB >> 8)) {
- switch(tp) {
- #ifdef N_BINCL
- case N_BINCL:
- n->on_valu = (long) line_file;
- line_file = n;
- break;
- case N_EINCL:
- if (line_file) {
- line_file = (struct outname *) line_file->on_valu;
- }
- break;
- #endif
- case N_SO:
- if (n->on_mptr[strlen(n->on_mptr)-1] == '/') {
- /* another N_SO follows ... */
- break;
- }
- while (CurrentScope != PervasiveScope) {
- close_scope();
- }
- saw_code = 0;
- sym = add_file(n->on_mptr);
- if (! currfile) newfile(sym->sy_idf);
- open_scope(sym, 0);
- sym->sy_file->f_scope = CurrentScope;
- FileScope = CurrentScope;
- clean_tp_tab();
- /* fall through */
- case N_SOL:
- if (! line_file) line_file = n;
- else line_file->on_mptr = n->on_mptr;
- break;
- case N_MAIN:
- newfile(FileScope->sc_definedby->sy_idf);
- break;
- case N_SLINE:
- assert(line_file);
- if (! saw_code && !CurrentScope->sc_bp_opp) {
- CurrentScope->sc_bp_opp = n->on_valu;
- if (! CurrentScope->sc_start) {
- CurrentScope->sc_start = n->on_valu;
- if (CurrentScope->sc_has_activation_record) {
- add_scope_addr(CurrentScope);
- }
- }
- }
- saw_code = 1;
- add_position_addr(line_file->on_mptr, n);
- break;
- case N_LBRAC: /* block, desc = nesting level */
- if (had_lbrac) {
- open_scope((p_symbol) 0, 0);
- saw_code = 0;
- }
- else {
- register p_scope sc =
- get_scope_from_addr(n->on_valu);
- if (!sc || sc->sc_bp_opp) {
- had_lbrac = 1;
- }
- else CurrentScope = sc;
- }
- break;
- #ifdef N_SCOPE
- case N_SCOPE:
- if (n->on_mptr && strindex(n->on_mptr, ':')) {
- n = DbxString(n);
- }
- break;
- #endif
- case N_RBRAC: /* end block, desc = nesting level */
- had_lbrac = 0;
- if (CurrentScope != FileScope) close_scope();
- saw_code = 0;
- break;
- case N_FUN: /* function, value = address */
- case N_GSYM: /* global variable */
- case N_STSYM: /* data, static, value = address */
- case N_LCSYM: /* bss, static, value = address */
- case N_RSYM: /* register var, value = reg number */
- case N_SSYM: /* struct/union el, value = offset */
- case N_PSYM: /* parameter, value = offset from AP */
- case N_LSYM: /* local sym, value = offset from FP */
- if (had_lbrac) {
- open_scope((p_symbol) 0, 0);
- saw_code = 0;
- had_lbrac = 0;
- }
- if (n->on_mptr && strindex(n->on_mptr, ':')) {
- n = DbxString(n);
- }
- break;
- default:
- /*
- if (n->on_mptr && (n->on_type&S_TYP) >= S_MIN) {
- struct idf *id = str2idf(n->on_mptr, 0);
- sym = new_symbol();
- sym->sy_next = id->id_def;
- id->id_def = sym;
- sym->sy_class = SYMENTRY;
- sym->sy_onam = *n;
- sym->sy_idf = id;
- }
- */
- break;
- }
- }
- }
- close_scope();
- add_position_addr((char *) 0, (struct outname *) 0);
- rd_close();
- return (h.oh_magic == O_CONVERTED);
- }
|