X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=as%2Fmcs51%2Flklibr.c;h=808dfc64c4682b51366ccb77d10fa43ed492f90f;hb=30357bade4ba51536bdf52d60db2a3c96251a1ff;hp=a6a549a78d201287d229ccb94a745a653c172972;hpb=2437a0a93a6a08861709777666895991e4fbd99b;p=fw%2Fsdcc diff --git a/as/mcs51/lklibr.c b/as/mcs51/lklibr.c index a6a549a7..808dfc64 100644 --- a/as/mcs51/lklibr.c +++ b/as/mcs51/lklibr.c @@ -15,9 +15,19 @@ * */ +#define EQ(A,B) !strcmp((A),(B)) +#define MAXLINE 254 /*when using fgets*/ + +#if defined(__APPLE__) && defined(__MACH__) +#include +#include +#elseif !defined(__FreeBSD__) +#include +#endif #include +#include #include -#include +#include #include "aslink.h" /*)Module lklibr.c @@ -39,6 +49,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 @@ -97,6 +136,7 @@ addpath() * global variables: * lbpath *lbphead The pointer to the first * path structure + * ip a pointer to the library name * * functions called: * VOID addfile() lklibr.c @@ -112,19 +152,28 @@ VOID addlib() { struct lbpath *lbph; + int foundcount=0; unget(getnb()); - if (lbphead == NULL) { - addfile(NULL,ip); - return; - } - for (lbph=lbphead; lbph; lbph=lbph->next) { - addfile(lbph->path,ip); + if (lbphead == NULL) + { + foundcount=addfile(NULL, ip); } + else + { + for (lbph=lbphead; lbph; lbph=lbph->next) + { + foundcount+=addfile(lbph->path, ip); + } + } + if(foundcount == 0) + { + fprintf(stderr, "?ASlink-Warning-Couldn't find library '%s'\n", ip); + } } -/*)Function VOID addfile(path,libfil) +/*)Function int addfile(path,libfil) * * char *path library path specification * char *libfil library file specification @@ -156,55 +205,114 @@ addlib() * * side effects: * An lbname structure may be created. + * + * return: + * 1: the library was found + * 0: the library was not found */ -VOID -addfile(path,libfil) -char *path; -char *libfil; +int addfile(char * path, char * libfil) { FILE *fp; char *str; struct lbname *lbnh, *lbn; +#ifdef OTHERSYSTEM + int libfilinc=0; +#endif - if ((path != NULL) && (strchr(libfil,':') == NULL)){ + if (path != NULL) + { str = (char *) new (strlen(path) + strlen(libfil) + 6); strcpy(str,path); #ifdef OTHERSYSTEM - if (str[strlen(str)-1] != '/') { + if (str[strlen(str)-1] != '/') + { strcat(str,"/"); } #endif - } else { + } + else + { str = (char *) new (strlen(libfil) + 5); } + #ifdef OTHERSYSTEM - if (libfil[0] == '/') { libfil++; } + if (libfil[0] == '/') + { + libfil++; + libfilinc=1; + } #endif - strcat(str,libfil); - if(strchr(str,FSEPX) == NULL) { + + strcat(str, libfil); + if(strchr(libfil, FSEPX) == NULL) + { sprintf(&str[strlen(str)], "%clib", FSEPX); } - if ((fp = fopen(str, "r")) != NULL) { + + fp=fopen(str, "r"); + if(fp == NULL) + { + /*Ok, that didn't work. Try with the 'libfil' name only*/ +#ifdef OTHERSYSTEM + if(libfilinc) libfil--; +#endif + fp=fopen(libfil, "r"); + if(fp != NULL) + { + /*Bingo! 'libfil' is the absolute path of the library*/ + strcpy(str, libfil); + path=NULL;/*This way 'libfil' and 'path' will be rebuilt from 'str'*/ + } + } + + if(path==NULL) + { + /*'path' can not be null since it is needed to find the '.rel' files associated with + the library. So, get 'path' from 'str' and then chop it off and recreate 'libfil'. + That way putting 'path' and 'libfil' together will result into the original filepath + as contained in 'str'.*/ + int j; + path = (char *) new (strlen(str)); + strcpy(path, str); + for(j=strlen(path)-1; j>=0; j--) + { + if((path[j]=='\\')||(path[j]=='/')) + { + strcpy(libfil, &path[j+1]); + path[j+1]=0; + break; + } + } + if(j<=0) path[0]=0; + } + + if (fp != NULL) + { fclose(fp); lbnh = (struct lbname *) new (sizeof(struct lbname)); - if (lbnhead == NULL) { + if (lbnhead == NULL) + { lbnhead = lbnh; - } else { + } + else + { lbn = lbnhead; while (lbn->next) lbn = lbn->next; lbn->next = lbnh; } - if ((path != NULL) && (strchr(libfil,':') == NULL)){ - lbnh->path = path; - } + + lbnh->path = path; lbnh->libfil = (char *) new (strlen(libfil) + 1); strcpy(lbnh->libfil,libfil); lbnh->libspc = str; - fprintf(stderr,"library file %s\n",str); - } else { + return 1; + } + else + { free(str); + return 0; } } @@ -277,6 +385,196 @@ search() } } +/*Load a .rel file embedded in a sdcclib file*/ +void LoadRel(char * libfname, FILE * libfp, char * ModName) +{ + char str[NINPUT+2]; + int state=0; + + while (fgets(str, NINPUT, libfp) != NULL) + { + str[NINPUT+1] = '\0'; + chop_crlf(str); + switch(state) + { + case 0: + if(EQ(str, "")) + { + fgets(str, NINPUT, libfp); + str[NINPUT+1] = '\0'; + chop_crlf(str); + if(EQ(str, ModName)) state=1; + else + { + fprintf(stderr, "?Aslink-Error-Bad offset in library file %s(%s)\n", + libfname, ModName); + lkexit(1); + } + } + break; + case 1: + if(EQ(str, "")) state=2; + break; + case 2: + if(EQ(str, "")) return; + ip = str; + link_main(); + break; + } + } +} + +/*Load an .adb file embedded in a sdcclib file. If there is +something between and returns 1, otherwise returns 0. +This way the aomf51 will not have uselless empty modules. */ + +int LoadAdb(FILE * libfp) +{ + char str[MAXLINE+1]; + int state=0; + int ToReturn=0; + + while (fgets(str, MAXLINE, libfp) != NULL) + { + str[NINPUT+1] = '\0'; + chop_crlf(str); + switch(state) + { + case 0: + if(EQ(str, "")) state=1; + break; + case 1: + if(EQ(str, "")) return ToReturn; + fprintf(dfp, "%s\n", str); + ToReturn=1; + break; + } + } + return ToReturn; +} + +/*Check for a symbol in a SDCC library. If found, add the embedded .rel and +.adb files from the library. The library must be created with the SDCC +librarian 'sdcclib' since the linking process depends on the correct file offsets +embedded in the library file.*/ + +int SdccLib(char * PathLib, FILE * libfp, char * DirLib, char * SymName) +{ + struct lbfile *lbfh, *lbf; + char ModName[NCPS]=""; + char FLine[MAXLINE+1]; + int state=0; + long IndexOffset=0, FileOffset; + + 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; + } + else if(EQ(FLine, "")) + { + /*Reached the end of the index. The symbol is not in this library.*/ + return 0; + } + break; + case 2: + if(EQ(FLine, "")) + { + /*The symbol is not in this module, try the next one*/ + state=1; + } + else + { + /*Check if this is the symbol we are looking for.*/ + if (strncmp(SymName, FLine, NCPS)==0) + { + /*The symbol is in this module.*/ + + /*As in the original library format, it is assumed that the .rel + files reside in the same directory as the lib files.*/ + strcat(DirLib, ModName); + sprintf(&DirLib[strlen(DirLib)], "%crel", FSEPX); + + /*If this module has been loaded already don't load it again.*/ + lbf = lbfhead; + while (lbf) + { + if(EQ(DirLib, lbf->filspc)) return 1;/*Already loaded*/ + lbf=lbf->next; + } + + /*Add the embedded file to the list of files to be loaded in + the second pass. That is performed latter by the function + library() below.*/ + 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 = PathLib; + lbfh->filspc = DirLib; + lbfh->relfil = (char *) new (strlen(ModName) + 1); + strcpy(lbfh->relfil, ModName); + /*Library embedded file, so lbfh->offset must be >=0*/ + lbfh->offset = IndexOffset+FileOffset; + + /*Jump to where the .rel begins and load it.*/ + fseek(libfp, lbfh->offset, SEEK_SET); + LoadRel(PathLib, libfp, ModName); + + /* if cdb information required & .adb file present */ + if (dflag && dfp) + { + if(LoadAdb(libfp)) + SaveLinkedFilePath(DirLib); + } + return 1; /*Found the symbol, so success!*/ + } + } + break; + + default: + return 0; /*It should never reach this point, but just in case...*/ + break; + } + } + + return 0; /*The symbol is not in this library*/ +} + /*)Function VOID fndsym(name) * * char *name symbol name to find @@ -348,6 +646,408 @@ search() * 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; @@ -360,14 +1060,17 @@ char *name; char symname[NINPUT]; char *path,*str; char c; + int result; /* * Search through every library in the linked list "lbnhead". */ -/*1*/ for (lbnh=lbnhead; lbnh; lbnh=lbnh->next) { - if ((libfp = fopen(lbnh->libspc, "r")) == NULL) { - fprintf(stderr, "Cannot open library file %s\n", + 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); } @@ -379,105 +1082,146 @@ char *name; * for a .REL file in this library. */ -/*2*/ while (fgets(relfil, NINPUT, libfp) != NULL) { + while (fgets(relfil, NINPUT, libfp) != NULL) + { relfil[NINPUT+1] = '\0'; - relfil[strlen(relfil) - 1] = '\0'; - if (path != NULL) { - str = (char *) new (strlen(path)+strlen(relfil)+6); - strcpy(str,path); + chop_crlf(relfil); + if (path != NULL) + { + str = (char *) new (strlen(path)+strlen(relfil)+6); + strcpy(str,path); #ifdef OTHERSYSTEM - if (str[strlen(str)-1] != '/') { - strcat(str,"/"); - } + if (str[strlen(str)-1] != '/') + { + strcat(str,"/"); + } #endif - } else { - str = (char *) new (strlen(relfil) + 5); } - if (relfil[0] == '\\') { - strcat(str,relfil+1); - } else { - strcat(str,relfil); + else + { + str = (char *) new (strlen(relfil) + 5); + } + + if(strcmp(relfil, "")==0) + { + result=SdccLib(lbnh->libspc, libfp, str, name); + if(result) return(1); /*Found the symbol*/ + free(str); + /*The symbol is not in the current library, + check the next library in the list*/ + break; + } + + /*From here down is the support for libraries in the original format*/ + if (relfil[0] == '\\') + { + strcat(str,relfil+1); + } + else + { + strcat(str,relfil); } - if(strchr(str,FSEPX) == NULL) { - sprintf(&str[strlen(str)], "%crel", FSEPX); + + if(strchr(relfil, FSEPX) == NULL) + { + sprintf(&str[strlen(str)], "%crel", FSEPX); } -/*3*/ if ((fp = fopen(str, "r")) != 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. - */ + + if ((fp = fopen(str, "r")) != 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. + */ -/*4*/ 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 we find a symbol definition for the - * symbol we're looking for, load in the - * file and add it to lbfhead so it gets - * loaded on pass number 2. - */ -/*5*/ if (strncmp(symname, name, NCPS) == 0 && c == 'D') { - - 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 = lbnh->libspc; - lbfh->filspc = str; - lbfh->relfil = (char *) new (strlen(relfil) + 1); - strcpy(lbfh->relfil,relfil); - fclose(fp); - fclose(libfp); - /* if cdb information required & cdb file present */ - if (dflag && dfp) { - FILE *xfp = afile(str,"cdb",0); - if (xfp) { - copyfile(dfp,xfp); - fclose(xfp); - } - } - loadfile(str); - return (1); + while (fgets(buf, NINPUT, fp) != NULL) + { + buf[NINPUT+1] = '\0'; + chop_crlf(buf); + /* + * 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; -/*5*/ } + sscanf(buf, "S %s %c", symname, &c); -/*4*/ } - fclose(fp); -/*3*/ } + /* + * If we find a symbol definition for the + * symbol we're looking for, load in the + * file and add it to lbfhead so it gets + * loaded on pass number 2. + */ + if (strncmp(symname, name, NCPS) == 0 && c == 'D') + { + lbfh = (struct lbfile *) new (sizeof(struct lbfile)); + if (lbfhead == NULL) + { + lbfhead = lbfh; + } + else + { + lbf = lbfhead; + while (lbf->next) + lbf = lbf->next; + lbf->next = lbfh; + } - free(str); -/*2*/ } + lbfh->libspc = lbnh->libspc; + lbfh->filspc = str; + lbfh->relfil = (char *) new (strlen(relfil) + 1); + lbfh->offset = -1; /*Stand alone rel file*/ + strcpy(lbfh->relfil,relfil); + fclose(fp); + fclose(libfp); + + /* if cdb information required & adb file present */ + if (dflag && dfp) + { + FILE *xfp = afile(str,"adb",0); //JCF: Nov 30, 2002 + if (xfp) + { + SaveLinkedFilePath(str); + copyfile(dfp,xfp); + fclose(xfp); + } + } + loadfile(str); + return (1); + } + } + fclose(fp); + } + free(str); + } fclose(libfp); -/*1*/ } + } return(0); } +#endif /*INDEXLIB*/ + +void loadfile_SdccLib(char * libspc, char * module, long offset) +{ + FILE *fp; + + if ((fp = fopen(libspc,"r")) != NULL) + { + fseek(fp, offset, SEEK_SET); + LoadRel(libspc, fp, module); + fclose(fp); + } +} + /*)Function VOID library() * * The function library() links all the library object files @@ -501,9 +1245,22 @@ library() { struct lbfile *lbfh; - for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { - loadfile(lbfh->filspc); + for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) + { + if(lbfh->offset<0) + { + /*Stand alone rel file (original lib format)*/ + loadfile(lbfh->filspc); + } + else + { + /*rel file embedded in lib (new lib format)*/ + loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset); + } } +#ifdef INDEXLIB + freelibraryindex(); +#endif } /*)Function VOID loadfile(filspc) @@ -537,17 +1294,15 @@ char *filspc; { FILE *fp; char str[NINPUT+2]; - int i; if ((fp = fopen(filspc,"r")) != NULL) { while (fgets(str, NINPUT, fp) != NULL) { str[NINPUT+1] = '\0'; - i = strlen(str) - 1; - if (str[i] == '\n') - str[i] = '\0'; + chop_crlf(str); ip = str; link_main(); } fclose(fp); } } +