X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=symbol.c;h=f2f513cc3671aa0ca652d7be9f300c40fd8281d4;hp=9ba661fc3fa931609a7f34eb1c95c5aa84d33d6c;hb=60f204cb9e3905100da0d89f14bb40db764acd9e;hpb=1feb728a9eb579b6441daf0124d81483f600365c diff --git a/symbol.c b/symbol.c index 9ba661f..f2f513c 100644 --- a/symbol.c +++ b/symbol.c @@ -7,29 +7,31 @@ // #include "symbol.h" +#include "error.h" #include "listing.h" +#include "object.h" #include "procln.h" -#include "error.h" // Macros -#define NBUCKETS 256 // Number of hash buckets (power of 2) - -static SYM * symbolTable[NBUCKETS]; // User symbol-table header -int curenv; // Current enviroment number -static SYM * sorder; // * -> Symbols, in order of reference -static SYM * sordtail; // * -> Last symbol in sorder list -static SYM * sdecl; // * -> Symbols, in order of declaration -static SYM * sdecltail; // * -> Last symbol in sdecl list -static uint32_t currentUID; // Symbol UID tracking (done by NewSymbol()) - -// Tags for marking symbol spaces +#define NBUCKETS 256 // Number of hash buckets (power of 2) + +static SYM * symbolTable[NBUCKETS]; // User symbol-table header +int curenv; // Current enviroment number +static SYM * sorder; // * -> Symbols, in order of reference +static SYM * sordtail; // * -> Last symbol in sorder list +static SYM * sdecl; // * -> Symbols, in order of declaration +static SYM * sdecltail; // * -> Last symbol in sdecl list +static uint32_t currentUID; // Symbol UID tracking (done by NewSymbol()) +uint32_t firstglobal; // Index of the first global symbol in an ELF object. + +// Tags for marking symbol spaces: // a = absolute // t = text // d = data // ! = "impossible!" // b = BSS -static char tdb_text[8] = { +static uint8_t tdb_text[8] = { 'a', 't', 'd', '!', 'b', SPACE, SPACE, SPACE }; @@ -39,9 +41,7 @@ static char tdb_text[8] = { // void InitSymbolTable(void) { - int i; // Iterator - - for(i=0; isname = strdup(name); - symbol->stype = (BYTE)type; - symbol->senv = (WORD)envno; + symbol->stype = (uint8_t)type; + symbol->senv = (uint16_t)envno; + // We don't set this as DEFINED, as it could be a forward reference! symbol->sattr = 0; - // Don't do this, it could be a forward reference! -// symbol->sattr = DEFINED; // We just defined it... - // This is a bad assumption. Not every symbol 1st seen in a RISC section is - // a RISC symbol! -// symbol->sattre = (rgpu || rdsp ? RISCSYM : 0); + // We don't set RISCSYM here as not every symbol first seen in a RISC + // section is a RISC symbol! symbol->sattre = 0; symbol->svalue = 0; symbol->sorder = NULL; symbol->uid = currentUID++; - // Install symbol in symbol table + // Install symbol in the symbol table int hash = HashSymbol(name, envno); symbol->snext = symbolTable[hash]; symbolTable[hash] = symbol; - // Append symbol to symbol-order list + // Append symbol to the symbol-order list if (sorder == NULL) - sorder = symbol; // Add first symbol + sorder = symbol; // Add first symbol else sordtail->sorder = symbol; // Or append to tail of list @@ -121,7 +119,7 @@ SYM * NewSymbol(char * name, int type, int envno) // Look up the symbol name by its UID and return the pointer to the name. // If it's not found, return NULL. // -char * GetSymbolNameByUID(uint32_t uid) +uint8_t * GetSymbolNameByUID(uint32_t uid) { //problem is with string lookup, that's why we're writing this //so once this is written, we can put the uid in the token stream @@ -143,10 +141,10 @@ char * GetSymbolNameByUID(uint32_t uid) // -// Lookup the symbol `name', of the specified type, with the specified +// Lookup the symbol 'name', of the specified type, with the specified // enviroment level // -SYM * lookup(char * name, int type, int envno) +SYM * lookup(uint8_t * name, int type, int envno) { SYM * symbol = symbolTable[HashSymbol(name, envno)]; @@ -182,7 +180,7 @@ void AddToSymbolDeclarationList(SYM * symbol) if (sdecl == NULL) sdecl = symbol; // First on decl-list - else + else sdecltail->sdecl = symbol; // Add to end of list // Fix up list's tail @@ -200,8 +198,8 @@ void ForceUndefinedSymbolsGlobal(void) DEBUG printf("~ForceUndefinedSymbolsGlobal()\n"); - // Scan through all symbols; - // If a symbol is REFERENCED but not DEFINED, then make it global. + // Scan through all symbols; if a symbol is REFERENCED but not DEFINED, + // then make it global. for(sy=sorder; sy!=NULL; sy=sy->sorder) { if (sy->stype == LABEL && sy->senv == 0 @@ -211,58 +209,43 @@ void ForceUndefinedSymbolsGlobal(void) } -// -// Convert string to uppercase -// -int uc_string(char * s) -{ - for(; *s; s++) - { - if (*s >= 'a' && *s <= 'z') - *s -= 32; - } - - return 0; -} - - // // Assign numbers to symbols that are to be exported or imported. The symbol -// number is put in `.senv'. Return the number of symbols that will be in the +// number is put in 'senv'. Returns the number of symbols that will be in the // symbol table. // -int sy_assign(char * buf, char *(* constr)()) +// N.B.: This is usually called twice; first time with NULL parameters and the +// second time with real ones. The first one is typically done to get a +// count of the # of symbols in the symbol table, and the second is to +// actually create it. +// +uint32_t sy_assign(uint8_t * buf, uint8_t *(* construct)()) { - SYM * sy; - int scount = 0; + uint16_t scount = 0; + // Done only on first pass... if (buf == NULL) { // Append all symbols not appearing on the .sdecl list to the end of // the .sdecl list - for(sy=sorder; sy!=NULL; sy=sy->sorder) + for(SYM * sy=sorder; sy!=NULL; sy=sy->sorder) AddToSymbolDeclarationList(sy); } // Run through all symbols (now on the .sdecl list) and assign numbers to // them. We also pick which symbols should be global or not here. - for(sy=sdecl; sy!=NULL; sy=sy->sdecl) + for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl) { - // Don't want register/CC or undefined on our list -//these should already be rejected above... -// if (sy->sattre & (EQUATEDREG | UNDEF_EQUR | EQUATEDCC | UNDEF_CC))) -// continue; - // Export or import external references, and export COMMON blocks. if ((sy->stype == LABEL) && ((sy->sattr & (GLOBAL | DEFINED)) == (GLOBAL | DEFINED) || (sy->sattr & (GLOBAL | REFERENCED)) == (GLOBAL | REFERENCED)) || (sy->sattr & COMMON)) { - sy->senv = (WORD)scount++; + sy->senv = scount++; if (buf != NULL) - buf = (*constr)(buf, sy, 1); + buf = construct(buf, sy, 1); } // Export vanilla labels (but don't make them global). An exception is // made for equates, which are not exported unless they are referenced. @@ -270,49 +253,159 @@ int sy_assign(char * buf, char *(* constr)()) && (sy->sattr & (DEFINED | REFERENCED)) != 0 && (!as68_flag || *sy->sname != 'L')) { - sy->senv = (WORD)scount++; + sy->senv = scount++; if (buf != NULL) - buf = (*constr)(buf, sy, 0); + buf = construct(buf, sy, 0); } } + // For ELF object mode run through all symbols in reference order + // and export all global-referenced labels. Not sure if this is + // required but it's here nonetheless +/* why?? when you have sy_assign_ELF ??? + if (obj_format == ELF) + { + for(sy=sdecl; sy!=NULL; sy=sy->sorder) + { + if ((sy->sattr == (GLOBAL | REFERENCED)) && (buf != NULL)) + { + buf = (*construct)(buf, sy, 0); + scount++; + } + } + }*/ + return scount; } +// +// Custom version of sy_assign for ELF .o files. +// The order that the symbols should be dumped is different. +// (globals must be explicitly at the end of the table) +// +// N.B.: It should be possible to merge this with sy_assign, as there's nothing +// really ELF specific in here, other than the "globals go at the end of +// the queue" thing, which doesn't break the others. :-P +uint32_t sy_assign_ELF(uint8_t * buf, uint8_t *(* construct)()) +{ + uint16_t scount = 0; + +// if (construct == (uint8_t *(*)())constr_elfsymtab) +// if (buf == NULL) + { + // Append all symbols not appearing on the .sdecl list to the end of + // the .sdecl list + for(SYM * sy=sorder; sy!=NULL; sy=sy->sorder) + AddToSymbolDeclarationList(sy); + } + + // Run through all symbols (now on the .sdecl list) and assign numbers to + // them. We also pick which symbols should be global or not here. + for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl) + { + // Export or import external references, and export COMMON blocks. + //if ((sy->stype == LABEL) + // && ((sy->sattr & (GLOBAL | DEFINED)) == (GLOBAL | DEFINED) + // || (sy->sattr & (GLOBAL | REFERENCED)) == (GLOBAL | REFERENCED)) + // || (sy->sattr & COMMON)) + //{ + // sy->senv = (WORD)scount++; + // + // if (buf != NULL) + // buf = (*construct)(buf, sy, 1); + //} + // Export vanilla labels (but don't make them global). An exception is + // made for equates, which are not exported unless they are referenced. + if (sy->stype == LABEL && lsym_flag + && (sy->sattr & (DEFINED | REFERENCED)) != 0 + && (*sy->sname != '.') + && (sy->sattr & GLOBAL) == 0) + //if (sy->stype == 0) + // if (lsym_flag) + // if ((sy->sattr & (DEFINED | REFERENCED)) != 0) + // if ((!as68_flag || *sy->sname != 'L')) + { + sy->senv = scount++; + + if (buf != NULL) + buf = construct(buf, sy, 0); + } + } + + firstglobal = scount; + + // For ELF object mode run through all symbols in reference order + // and export all global-referenced labels. Not sure if this is + // required but it's here nonetheless + + //for(sy=sdecl; sy!=NULL; sy=sy->sorder) + for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl) + { + if ((sy->stype == LABEL) + && ((sy->sattr & (GLOBAL | DEFINED)) == (GLOBAL | DEFINED) + || (sy->sattr & (GLOBAL | REFERENCED)) == (GLOBAL | REFERENCED)) + || (sy->sattr & COMMON)) + { + sy->senv = scount++; + + if (buf != NULL) + buf = construct(buf, sy, 1); + } + else if ((sy->sattr == (GLOBAL | REFERENCED)) && (buf != NULL)) + { + buf = construct(buf, sy, 0); + scount++; + } + } + + return scount; +} + + +// +// Convert string to uppercase +// +void ToUppercase(uint8_t * s) +{ + for(; *s; s++) + { + if (*s >= 'a' && *s <= 'z') + *s -= 0x20; + } +} + + // // Generate symbol table for listing file // int symtable(void) { + extern int pagelen; int i; int j; SYM * q = NULL; SYM * p; SYM * r; SYM * k; - SYM ** sy; SYM * colptr[4]; - char ln[150]; - char ln1[150]; + char ln[200]; + char ln1[200]; char ln2[20]; char c, c1; WORD w; int ww; - int colhei; - extern int pagelen; + int colhei = pagelen - 5; - colhei = pagelen - 5; + // Allocate storage for list headers and partition all labels. Throw away + // macros and macro arguments. + SYM ** sy = (SYM **)malloc(128 * sizeof(uint32_t)); - // Allocate storage for list headers and partition all labels. - // Throw away macros and macro arguments. - sy = (SYM **)malloc(128 * sizeof(LONG)); - - for(i=0; i<128; ++i) + for(i=0; i<128; i++) sy[i] = NULL; - for(i=0; isvalue); - uc_string(ln2); + ToUppercase(ln2); } sprintf(ln1, " %16s %s %c%c%c", q->sname, ln2, (ww & EQUATEDREG) ? 'e' : SPACE, c1, c);