X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=as%2Fmcs51%2Flklibr.c;h=678eb30301ca9a25e15f59456a62dcb33f7aafc4;hb=4db4740164fed3cb25145cfdaadb986fc0690507;hp=8ca450486b0fa8d4d2bc36f259e2e10fd4ac72e7;hpb=88e560b915dc753c85898e35af1e0a751a4cf723;p=fw%2Fsdcc diff --git a/as/mcs51/lklibr.c b/as/mcs51/lklibr.c index 8ca45048..678eb303 100644 --- a/as/mcs51/lklibr.c +++ b/as/mcs51/lklibr.c @@ -18,15 +18,10 @@ #define EQ(A,B) !strcmp((A),(B)) #define MAXLINE 254 /*when using fgets*/ -#if defined(__APPLE__) && defined(__MACH__) -#include -#include -#else -#include -#endif #include #include #include +#include #include "aslink.h" /*)Module lklibr.c @@ -48,6 +43,35 @@ * */ +#ifdef INDEXLIB +typedef struct slibrarysymbol mlibrarysymbol; +typedef struct slibrarysymbol *pmlibrarysymbol; + +struct slibrarysymbol { + char * name; /*Warning: allocate memory before using*/ + pmlibrarysymbol next; +}; + +typedef struct slibraryfile mlibraryfile; +typedef struct slibraryfile *pmlibraryfile; + +struct slibraryfile { + int loaded; + char * libspc; + char * relfil; /*Warning: allocate memory before using*/ + char * filename; /*Warning: allocate memory before using*/ + long offset; //if > 0, the embedded file offset in the library file libspc + pmlibrarysymbol symbols; + pmlibraryfile next; +}; + +/* First entry in the library object symbol cache */ +pmlibraryfile libr=NULL; + +int buildlibraryindex(); +void freelibraryindex (void); +#endif /* INDEXLIB */ + /*)Function VOID addpath() * * The function addpath() creates a linked structure containing @@ -139,7 +163,7 @@ addlib() } if(foundcount == 0) { - printf("?ASlink-Warning-Couldn't find library '%s'\n", ip); + fprintf(stderr, "?ASlink-Warning-Couldn't find library '%s'\n", ip); } } @@ -356,7 +380,7 @@ search() } /*Load a .rel file embedded in a sdcclib file*/ -void LoadRel(FILE * libfp, char * ModName) +void LoadRel(char * libfname, FILE * libfp, char * ModName) { char str[NINPUT+2]; int state=0; @@ -376,7 +400,8 @@ void LoadRel(FILE * libfp, char * ModName) if(EQ(str, ModName)) state=1; else { - printf("Bad offset in library file str=%s, Modname=%s\n", str, ModName); + fprintf(stderr, "?Aslink-Error-Bad offset in library file %s(%s)\n", + libfname, ModName); lkexit(1); } } @@ -522,7 +547,7 @@ int SdccLib(char * PathLib, FILE * libfp, char * DirLib, char * SymName) /*Jump to where the .rel begins and load it.*/ fseek(libfp, lbfh->offset, SEEK_SET); - LoadRel(libfp, ModName); + LoadRel(PathLib, libfp, ModName); /* if cdb information required & .adb file present */ if (dflag && dfp) @@ -615,6 +640,408 @@ int SdccLib(char * PathLib, FILE * libfp, char * DirLib, char * SymName) * is linked. */ +#ifdef INDEXLIB + +int fndsym( char *name ) +{ + struct lbfile *lbfh, *lbf; + pmlibraryfile ThisLibr; + pmlibrarysymbol ThisSym = NULL; + + pmlibraryfile FirstFound; + int numfound=0; + + /* Build the index if this is the first call to fndsym */ + if (libr==NULL) buildlibraryindex(); + + /* Iterate through all library object files */ + ThisLibr = libr; + FirstFound = libr; /*So gcc stops whining*/ + while (ThisLibr) + { + /* Iterate through all symbols in an object file */ + ThisSym = ThisLibr->symbols; + + while (ThisSym) + { + if (!strcmp(ThisSym->name, name)) + { + if ((!ThisLibr->loaded) && (numfound==0)) + { + /* Object file is not loaded - add it to the list */ + lbfh = (struct lbfile *) new (sizeof(struct lbfile)); + if (lbfhead == NULL) + { + lbfhead = lbfh; + } + else + { + lbf = lbfhead; + while (lbf->next) + lbf = lbf->next; + lbf->next = lbfh; + } + lbfh->libspc = ThisLibr->libspc; + lbfh->filspc = ThisLibr->filename; + lbfh->relfil = (char *) new (strlen(ThisLibr->relfil) + 1); + strcpy(lbfh->relfil, ThisLibr->relfil); + lbfh->offset = ThisLibr->offset; + if(lbfh->offset>0) + { /*For an embedded object file in a library*/ + void loadfile_SdccLib(char * libspc, char * module, long offset); + loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset); + } + else + { /*For a stand alone object file*/ + /* if cdb information required & adb file present */ + if (dflag && dfp) + { + FILE *xfp = afile(lbfh->filspc, "adb",0); + if (xfp) + { + SaveLinkedFilePath(lbfh->filspc); + copyfile(dfp, xfp); + fclose(xfp); + } + } + loadfile(lbfh->filspc); + } + ThisLibr->loaded=1; + } + + if(numfound==0) + { + numfound++; + FirstFound=ThisLibr; + } + else + { + char absPath1[PATH_MAX]; + char absPath2[PATH_MAX]; +#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__) + int j; + + _fullpath(absPath1, FirstFound->libspc, PATH_MAX); + _fullpath(absPath2, ThisLibr->libspc, PATH_MAX); + for(j=0; absPath1[j]!=0; j++) absPath1[j]=tolower(absPath1[j]); + for(j=0; absPath2[j]!=0; j++) absPath2[j]=tolower(absPath2[j]); +#else + realpath(FirstFound->libspc, absPath1); + realpath(ThisLibr->libspc, absPath2); +#endif + if( !( EQ(absPath1, absPath2) && EQ(FirstFound->relfil, ThisLibr->relfil) ) ) + { + if(numfound==1) + { + fprintf(stderr, "?Aslink-Warning-Definition of public symbol '%s'" + " found more than once:\n", name); + fprintf(stderr, " Library: '%s', Module: '%s'\n", + FirstFound->libspc, FirstFound->relfil); + } + fprintf(stderr, " Library: '%s', Module: '%s'\n", + ThisLibr->libspc, ThisLibr->relfil); + numfound++; + } + } + } + ThisSym=ThisSym->next; /* Next sym in library */ + } + ThisLibr=ThisLibr->next; /* Next library in list */ + } + return numfound; +} + +pmlibraryfile buildlibraryindex_SdccLib(char * PathLib, FILE * libfp, char * DirLib, pmlibraryfile This) +{ + char ModName[NCPS]=""; + char FLine[MAXLINE+1]; + char buff[PATH_MAX]; + int state=0; + long IndexOffset=0, FileOffset; + pmlibrarysymbol ThisSym = NULL; + + while(!feof(libfp)) + { + FLine[0]=0; + fgets(FLine, MAXLINE, libfp); + chop_crlf(FLine); + + switch(state) + { + case 0: + if(EQ(FLine, "")) + { + /*The next line has the size of the index*/ + FLine[0]=0; + fgets(FLine, MAXLINE, libfp); + chop_crlf(FLine); + IndexOffset=atol(FLine); + state=1; + } + break; + case 1: + if(EQ(FLine, "")) + { + /*The next line has the name of the module and the offset + of the corresponding embedded file in the library*/ + FLine[0]=0; + fgets(FLine, MAXLINE, libfp); + chop_crlf(FLine); + sscanf(FLine, "%s %ld", ModName, &FileOffset); + state=2; + + /*Create a new libraryfile object for this module*/ + if(libr==NULL) + { + libr=This=(pmlibraryfile)new( sizeof( mlibraryfile )); + } + else + { + This->next=(pmlibraryfile)new( sizeof( mlibraryfile )); + This=This->next; + } + This->next = NULL; + This->loaded=-1; + This->offset=FileOffset+IndexOffset; + This->libspc=PathLib; + + This->relfil=(char *)new(strlen(ModName)+1); + strcpy(This->relfil, ModName); + + sprintf(buff, "%s%s%crel", DirLib, ModName, FSEPX); + This->filename=(char *)new(strlen(buff)+1); + strcpy(This->filename, buff); + + This->symbols=ThisSym=NULL; /*Start a new linked list of symbols*/ + } + else if(EQ(FLine, "")) + { + return This; /*Finish, get out of here*/ + } + break; + case 2: + if(EQ(FLine, "")) + { + This->loaded=0; + /*Create the index for the next module*/ + state=1; + } + else + { + /*Add the symbols*/ + if(ThisSym==NULL) /*First symbol of the current module*/ + { + ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol)); + } + else + { + ThisSym->next = (pmlibrarysymbol)new(sizeof(mlibrarysymbol)); + ThisSym=ThisSym->next; + } + ThisSym->next=NULL; + ThisSym->name=(char *)new(strlen(FLine)+1); + strcpy(ThisSym->name, FLine); + } + break; + + default: + return This; /*State machine should never reach this point, but just in case...*/ + break; + } + } + + return This; /*State machine should never reach this point, but just in case...*/ +} + + +/* buildlibraryindex - build an in-memory cache of the symbols contained in + * the libraries + */ +int buildlibraryindex(void) +{ + FILE *libfp, *fp; + struct lbname *lbnh; + char relfil[NINPUT+2], str[PATH_MAX], *path; + char buf[NINPUT+2], c; + char symname[NINPUT+2]; + pmlibraryfile This=NULL; + pmlibrarysymbol ThisSym; + + /* + * Search through every library in the linked list "lbnhead". + */ + + for (lbnh=lbnhead; lbnh; lbnh=lbnh->next) + { + if ((libfp = fopen(lbnh->libspc, "r")) == NULL) + { + fprintf(stderr, "?Aslink-Error-Cannot open library file %s\n", + lbnh->libspc); + lkexit(1); + } + path = lbnh->path; + + /* + * Read in a line from the library file. + * This is the relative file specification + * for a .REL file in this library. + */ + + while (fgets(relfil, NINPUT, libfp) != NULL) + { + relfil[NINPUT+1] = '\0'; + chop_crlf(relfil); + if (path != NULL) + { + strcpy(str, path); +#ifdef OTHERSYSTEM + if (str[strlen(str)-1] != '/') + { + strcat(str,"/"); + } +#endif + } + else + { + strcpy(str, ""); + } + + if(strcmp(relfil, "")==0) + { + /*Get the built in index of this library*/ + This=buildlibraryindex_SdccLib(lbnh->libspc, libfp, str, This); + break; /*get the index for next library*/ + } + + /*From here down, build the index for the original library format*/ + + if (relfil[0] == '\\') + { + strcat(str,relfil+1); + } + else + { + strcat(str,relfil); + } + + if(strchr(relfil, FSEPX) == NULL) + { + sprintf(&str[strlen(str)], "%crel", FSEPX); + } + + if ((fp = fopen(str, "r")) != NULL) + { + /* Opened OK - create a new libraryfile object for it */ + if(libr==NULL) + { + libr=This=(pmlibraryfile)new( sizeof( mlibraryfile )); + } + else + { + This->next=(pmlibraryfile)new( sizeof( mlibraryfile )); + This=This->next; + } + This->next = NULL; + This->loaded=-1; + This->offset=-1; /*We have a stand alone .rel file*/ + This->libspc = lbnh->libspc; + + This->relfil=(char *)new(strlen(relfil)+1); + strcpy(This->relfil, relfil); + + This->filename=(char *)new(strlen(str)+1); + strcpy(This->filename, str); + + /*Start a new linked list of symbols for this module:*/ + This->symbols=ThisSym=NULL; + + /* + * Read in the object file. Look for lines that + * begin with "S" and end with "D". These are + * symbol table definitions. If we find one, see + * if it is our symbol. Make sure we only read in + * our object file and don't go into the next one. + */ + + while (fgets(buf, NINPUT, fp) != NULL) + { + buf[NINPUT+1] = '\0'; + buf[strlen(buf) - 1] = '\0'; + + /* + * Skip everything that's not a symbol record. + */ + if (buf[0] != 'S') continue; + + /* + * When a 'T line' is found terminate file scan. + * All 'S line's preceed 'T line's in .REL files. + */ + if (buf[0] == 'T') break; + + sscanf(buf, "S %s %c", symname, &c); + + /* If it's an actual symbol, record it */ + if (c == 'D') + { + if(ThisSym==NULL) + { + ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol)); + } + else + { + ThisSym->next=(pmlibrarysymbol)new(sizeof(mlibrarysymbol)); + ThisSym=ThisSym->next; + } + This->loaded=0; + ThisSym->next=NULL; + ThisSym->name=(char *)new(strlen(symname)+1); + strcpy(ThisSym->name, symname); + } + } /* Closes while - read object file */ + fclose(fp); + } /* Closes if object file opened OK */ + else + { + fprintf(stderr, "?Aslink-Warning-Cannot open library module %s\n", str); + } + } /* Ends while - processing all in libr */ + fclose(libfp); + } /* Ends good open of libr file */ + return 0; +} + +/*Release all memory allocated for the in-memory library index*/ +void freelibraryindex (void) +{ + pmlibraryfile ThisLibr, ThisLibr2Free; + pmlibrarysymbol ThisSym, ThisSym2Free; + + ThisLibr = libr; + + while (ThisLibr) + { + ThisSym = ThisLibr->symbols; + + while (ThisSym) + { + free(ThisSym->name); + ThisSym2Free=ThisSym; + ThisSym=ThisSym->next; + free(ThisSym2Free); + } + free(ThisLibr->filename); + free(ThisLibr->relfil); + ThisLibr2Free=ThisLibr; + ThisLibr=ThisLibr->next; + free(ThisLibr2Free); + } + + libr=NULL; +} + +#else /* INDEXLIB */ + int fndsym(name) char *name; @@ -637,7 +1064,7 @@ char *name; { if ((libfp = fopen(lbnh->libspc, "r")) == NULL) { - fprintf(stderr, "Cannot open library file %s\n", + fprintf(stderr, "?Aslink-Error-Cannot open library file %s\n", lbnh->libspc); lkexit(1); } @@ -672,7 +1099,6 @@ char *name; if(strcmp(relfil, "")==0) { result=SdccLib(lbnh->libspc, libfp, str, name); - fclose(libfp); if(result) return(1); /*Found the symbol*/ free(str); /*The symbol is not in the current library, @@ -776,6 +1202,8 @@ char *name; return(0); } +#endif /*INDEXLIB*/ + void loadfile_SdccLib(char * libspc, char * module, long offset) { FILE *fp; @@ -783,7 +1211,7 @@ void loadfile_SdccLib(char * libspc, char * module, long offset) if ((fp = fopen(libspc,"r")) != NULL) { fseek(fp, offset, SEEK_SET); - LoadRel(fp, module); + LoadRel(libspc, fp, module); fclose(fp); } } @@ -824,6 +1252,9 @@ library() loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset); } } +#ifdef INDEXLIB + freelibraryindex(); +#endif } /*)Function VOID loadfile(filspc) @@ -868,3 +1299,4 @@ char *filspc; fclose(fp); } } +