*/
#define EQ(A,B) !strcmp((A),(B))
-#define MAXLINE 254 /*when using fgets*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <assert.h>
+
#include "aslink.h"
+#include "lkrel.h"
+#include "lklibr.h"
/*)Module lklibr.c
*
*
*/
-#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;
-};
+#define NELEM(x) (sizeof (x) / sizeof (*x))
+#ifdef INDEXLIB
/* First entry in the library object symbol cache */
-pmlibraryfile libr=NULL;
+pmlibraryfile libr = NULL;
-int buildlibraryindex(void);
+int buildlibraryindex (void);
void freelibraryindex (void);
#endif /* INDEXLIB */
+struct aslib_target *aslib_targets[] = {
+ &aslib_target_sdcclib,
+ &aslib_target_lib,
+};
+
/*)Function VOID addpath()
*
* The function addpath() creates a linked structure containing
*/
VOID
-addpath(void)
+addpath (void)
{
- struct lbpath *lbph, *lbp;
-
- lbph = (struct lbpath *) new (sizeof(struct lbpath));
- if (lbphead == NULL) {
- lbphead = lbph;
- } else {
- lbp = lbphead;
- while (lbp->next)
+ struct lbpath *lbph, *lbp;
+
+ lbph = (struct lbpath *) new (sizeof (struct lbpath));
+ if (lbphead == NULL)
+ {
+ lbphead = lbph;
+ }
+ else
+ {
+ lbp = lbphead;
+ while (lbp->next)
{
- lbp = lbp->next;
+ lbp = lbp->next;
}
- lbp->next = lbph;
+ lbp->next = lbph;
}
- unget(getnb());
- lbph->path = (char *) new (strlen(ip)+1);
- strcpy(lbph->path, ip);
+ unget (getnb ());
+ lbph->path = strdup (ip);
}
/*)Function VOID addlib()
*/
VOID
-addlib(void)
+addlib (void)
{
- struct lbpath *lbph;
- int foundcount=0;
+ struct lbpath *lbph;
+ int foundcount = 0;
- unget(getnb());
+ unget (getnb ());
- if (lbphead == NULL)
+ if (lbphead == NULL)
{
- foundcount=addfile(NULL, ip);
+ foundcount = addfile (NULL, ip);
}
- else
+ else
{
- for (lbph=lbphead; lbph; lbph=lbph->next)
+ for (lbph = lbphead; lbph; lbph = lbph->next)
{
- foundcount+=addfile(lbph->path, ip);
+ foundcount += addfile (lbph->path, ip);
}
}
- if(foundcount == 0)
+ if (foundcount == 0)
{
- fprintf(stderr, "?ASlink-Warning-Couldn't find library '%s'\n", ip);
+ fprintf (stderr, "?ASlink-Warning-Couldn't find library '%s'\n", ip);
}
}
* 0: the library was not found
*/
-int addfile(char * path, char * libfil)
+int
+addfile (char *path, char *libfil)
{
- FILE *fp;
- char *str;
- struct lbname *lbnh, *lbn;
+ FILE *fp;
+ char *str;
+ struct lbname *lbnh, *lbn;
#ifdef OTHERSYSTEM
- int libfilinc=0;
+ int libfilinc = 0;
#endif
- if (path != NULL)
+ if (path != NULL)
{
- str = (char *) new (strlen(path) + strlen(libfil) + 6);
- strcpy(str, path);
+ str = (char *) new (strlen (path) + strlen (libfil) + 6);
+ strcpy (str, path);
#ifdef OTHERSYSTEM
- if (strlen(str) && (str[strlen(str)-1] != '/') && (str[strlen(str)-1] != LKDIRSEP))
+ if (strlen (str) && (str[strlen (str) - 1] != '/') && (str[strlen (str) - 1] != LKDIRSEP))
{
- strcat(str, LKDIRSEPSTR);
+ strcat (str, LKDIRSEPSTR);
}
#endif
}
- else
+ else
{
- str = (char *) new (strlen(libfil) + 5);
+ str = (char *) new (strlen (libfil) + 5);
}
#ifdef OTHERSYSTEM
- if ((libfil[0] == '/') || (libfil[0] == LKDIRSEP))
+ if ((libfil[0] == '/') || (libfil[0] == LKDIRSEP))
{
- libfil++;
- libfilinc=1;
+ libfil++;
+ libfilinc = 1;
}
#endif
- strcat(str, libfil);
- if(strchr(libfil, FSEPX) == NULL)
+ strcat (str, libfil);
+ if (strchr (libfil, FSEPX) == NULL)
{
- sprintf(&str[strlen(str)], "%clib", FSEPX);
+ sprintf (&str[strlen (str)], "%clib", FSEPX);
}
- fp=fopen(str, "r");
- if(fp == NULL)
+ fp = fopen (str, "rb");
+ if (fp == NULL)
{
- /*Ok, that didn't work. Try with the 'libfil' name only*/
+ /*Ok, that didn't work. Try with the 'libfil' name only */
#ifdef OTHERSYSTEM
- if(libfilinc) libfil--;
+ if (libfilinc)
+ libfil--;
#endif
- fp=fopen(libfil, "r");
- if(fp != NULL)
+ fp = fopen (libfil, "rb");
+ 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'*/
+ /*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)
+ if (path == NULL)
{
- /*'path' can not be null since it is needed to find the object 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) + 1);
- strcpy(path, str);
- for(j=strlen(path)-1; j>=0; j--)
+ /*'path' can not be null since it is needed to find the object 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 = strdup (str);
+ for (j = strlen (path) - 1; j >= 0; j--)
{
- if((path[j] == '/') || (path[j] == LKDIRSEP))
+ if ((path[j] == '/') || (path[j] == LKDIRSEP))
{
- strcpy(libfil, &path[j+1]);
- path[j+1]=0;
- break;
+ strcpy (libfil, &path[j + 1]);
+ path[j + 1] = 0;
+ break;
}
}
- if(j<=0) path[0]=0;
+ if (j <= 0)
+ path[0] = 0;
}
- if (fp != NULL)
+ if (fp != NULL)
{
- fclose(fp);
- lbnh = (struct lbname *) new (sizeof(struct lbname));
- if (lbnhead == NULL)
+ fclose (fp);
+ lbnh = (struct lbname *) new (sizeof (struct lbname));
+ if (lbnhead == NULL)
{
- lbnhead = lbnh;
+ lbnhead = lbnh;
}
- else
+ else
{
- lbn = lbnhead;
- while (lbn->next)
+ lbn = lbnhead;
+ while (lbn->next)
{
- lbn = lbn->next;
+ lbn = lbn->next;
}
- lbn->next = lbnh;
+ lbn->next = lbnh;
}
- lbnh->path = path;
- lbnh->libfil = (char *) new (strlen(libfil) + 1);
- strcpy(lbnh->libfil, libfil);
- lbnh->libspc = str;
- return 1;
+ lbnh->path = path;
+ lbnh->libfil = strdup (libfil);
+ lbnh->libspc = str;
+ return 1;
}
- else
+ else
{
- free(str);
- return 0;
+ free (str);
+ return 0;
}
}
*/
VOID
-search(void)
-{
- register struct sym *sp;
- register int i, symfnd;
-
- /*
- * Look for undefined symbols. Keep
- * searching until no more symbols are resolved.
- */
- symfnd = 1;
- while (symfnd) {
- symfnd = 0;
- /*
- * Look through all the symbols
- */
- for (i=0; i<NHASH; ++i) {
- sp = symhash[i];
- while (sp) {
- /* If we find an undefined symbol
- * (one where S_DEF is not set), then
- * try looking for it. If we find it
- * in any of the libraries then
- * increment symfnd. This will force
- * another pass of symbol searching and
- * make sure that back references work.
- */
- if ((sp->s_type & S_DEF) == 0) {
- if (fndsym(sp->s_id)) {
- symfnd++;
- }
- }
- sp = sp->s_sp;
- }
- }
- }
-}
-
-/*Load a .rel file embedded in a sdcclib file*/
-void LoadRel(char * libfname, FILE * libfp, char * ModName)
+search (void)
{
- char str[NINPUT+2];
- int state=0;
-
- while (fgets(str, NINPUT, libfp) != NULL)
+ register struct sym *sp;
+ register int i, symfnd;
+
+ /*
+ * Look for undefined symbols. Keep
+ * searching until no more symbols are resolved.
+ */
+ symfnd = 1;
+ while (symfnd)
{
- str[NINPUT+1] = '\0';
- chop_crlf(str);
- switch(state)
+ symfnd = 0;
+ /*
+ * Look through all the symbols
+ */
+ for (i = 0; i < NHASH; ++i)
{
- case 0:
- if(EQ(str, "<FILE>"))
- {
- 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, "<REL>")) state=2;
- break;
- case 2:
- if(EQ(str, "</REL>")) return;
- ip = str;
- link_main();
- break;
- }
- }
-}
-
-/*Load an .adb file embedded in a sdcclib file. If there is
-something between <ADB> and </ADB> returns 1, otherwise returns 0.
-This way the aomf51 will not have useless 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, "<ADB>")) state=1;
- break;
- case 1:
- if(EQ(str, "</ADB>")) 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, "<INDEX>"))
- {
- /*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, "<MODULE>"))
- {
- /*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, "</INDEX>"))
- {
- /*Reached the end of the index. The symbol is not in this library.*/
- return 0;
- }
- break;
- case 2:
- if(EQ(FLine, "</MODULE>"))
- {
- /*The symbol is not in this module, try the next one*/
- state=1;
- }
- else
+ sp = symhash[i];
+ while (sp)
+ {
+ /* If we find an undefined symbol
+ * (one where S_DEF is not set), then
+ * try looking for it. If we find it
+ * in any of the libraries then
+ * increment symfnd. This will force
+ * another pass of symbol searching and
+ * make sure that back references work.
+ */
+ if ((sp->s_type & S_DEF) == 0)
{
- /*Check if this is the symbol we are looking for.*/
- if (strncmp(SymName, FLine, NCPS)==0)
+ if (fndsym (sp->s_id))
{
- /*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)], "%c%s", FSEPX, LKOBJEXT);
-
- /*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!*/
+ symfnd++;
}
}
- break;
-
- default:
- return 0; /*It should never reach this point, but just in case...*/
- break;
+ sp = sp->s_sp;
+ }
}
}
-
- return 0; /*The symbol is not in this library*/
}
/*)Function VOID fndsym(name)
*
* functions called:
* int fclose() c_library
- * int fgets() c_library
* FILE *fopen() c_library
* VOID free() c_library
* char getnb() lklex.c
*/
#ifdef INDEXLIB
-
-int fndsym( char *name )
+int
+fndsym (char *name)
{
- struct lbfile *lbfh, *lbf;
- pmlibraryfile ThisLibr;
- pmlibrarysymbol ThisSym = NULL;
+ struct lbfile *lbfh, *lbf;
+ pmlibraryfile ThisLibr;
+ pmlibrarysymbol ThisSym = NULL;
- pmlibraryfile FirstFound;
- int numfound=0;
+ pmlibraryfile FirstFound;
+ int numfound = 0;
- /* Build the index if this is the first call to fndsym */
- if (libr==NULL) buildlibraryindex();
+ /* 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 library object files */
+ ThisLibr = libr;
+ FirstFound = libr; /*So gcc stops whining */
+ while (ThisLibr)
{
- /* Iterate through all symbols in an object file */
- ThisSym = ThisLibr->symbols;
+ /* Iterate through all symbols in an object file */
+ ThisSym = ThisLibr->symbols;
- while (ThisSym)
+ while (ThisSym)
{
- if (!strcmp(ThisSym->name, name))
+ if (!strcmp (ThisSym->name, name))
{
- if ((!ThisLibr->loaded) && (numfound==0))
+ 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)
+ /* Object file is not loaded - add it to the list */
+ lbfh = (struct lbfile *) new (sizeof (struct lbfile));
+ if (lbfhead == NULL)
{
- lbfhead = lbfh;
+ lbfhead = lbfh;
}
- else
+ 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)
+ lbf = lbfhead;
+ while (lbf->next)
{
- FILE *xfp = afile(lbfh->filspc, "adb",0);
- if (xfp)
- {
- SaveLinkedFilePath(lbfh->filspc);
- copyfile(dfp, xfp);
- fclose(xfp);
- }
+ lbf = lbf->next;
}
- loadfile(lbfh->filspc);
+ lbf->next = lbfh;
}
- ThisLibr->loaded=1;
+ lbfh->libspc = ThisLibr->libspc;
+ lbfh->filspc = ThisLibr->filename;
+ lbfh->relfil = strdup (ThisLibr->relfil);
+ lbfh->offset = ThisLibr->offset;
+ lbfh->type = ThisLibr->type;
+
+ (*aslib_targets[lbfh->type]->loadfile) (lbfh);
+
+ ThisLibr->loaded = 1;
}
- if(numfound==0)
+ if (numfound == 0)
{
- numfound++;
- FirstFound=ThisLibr;
+ numfound++;
+ FirstFound = ThisLibr;
}
- else
+ else
{
- char absPath1[PATH_MAX];
- char absPath2[PATH_MAX];
+ 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((unsigned char)absPath1[j]);
- for(j=0; absPath2[j]!=0; j++) absPath2[j]=tolower((unsigned char)absPath2[j]);
+ int j;
+
+ _fullpath (absPath1, FirstFound->libspc, PATH_MAX);
+ _fullpath (absPath2, ThisLibr->libspc, PATH_MAX);
+ for (j = 0; absPath1[j] != 0; j++)
+ absPath1[j] = tolower ((unsigned char) absPath1[j]);
+ for (j = 0; absPath2[j] != 0; j++)
+ absPath2[j] = tolower ((unsigned char) absPath2[j]);
#else
- realpath(FirstFound->libspc, absPath1);
- realpath(ThisLibr->libspc, absPath2);
+ realpath (FirstFound->libspc, absPath1);
+ realpath (ThisLibr->libspc, absPath2);
#endif
- if( !( EQ(absPath1, absPath2) && EQ(FirstFound->relfil, ThisLibr->relfil) ) )
+ if (!(EQ (absPath1, absPath2) && EQ (FirstFound->relfil, ThisLibr->relfil)))
{
- if(numfound==1)
+ 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, "?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++;
+ fprintf (stderr, " Library: '%s', Module: '%s'\n", ThisLibr->libspc, ThisLibr->relfil);
+ numfound++;
}
}
}
- ThisSym=ThisSym->next; /* Next sym in library */
+ ThisSym = ThisSym->next; /* Next sym in library */
}
- ThisLibr=ThisLibr->next; /* Next library in list */
+ ThisLibr = ThisLibr->next; /* Next library in list */
}
- return numfound;
+ return numfound;
}
-pmlibraryfile buildlibraryindex_SdccLib(char * PathLib, FILE * libfp, char * DirLib, pmlibraryfile This)
+struct add_sym_s
{
- 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, "<INDEX>"))
- {
- /*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, "<MODULE>"))
- {
- /*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;
+ pmlibraryfile plf;
+ pmlibrarysymbol pls;
+};
- This->relfil=(char *)new(strlen(ModName)+1);
- strcpy(This->relfil, ModName);
+static int
+add_sybmol (const char *sym, void *param)
+{
+ struct add_sym_s *as = (struct add_sym_s *) param;
+ pmlibrarysymbol ps = (pmlibrarysymbol) new (sizeof (mlibrarysymbol));
- sprintf(buff, "%s%s%c%s", DirLib, ModName, FSEPX, LKOBJEXT);
- This->filename=(char *)new(strlen(buff)+1);
- strcpy(This->filename, buff);
+ as->plf->loaded = 0;
+ ps->next = NULL;
+ ps->name = strdup (sym);
- This->symbols=ThisSym=NULL; /*Start a new linked list of symbols*/
- }
- else if(EQ(FLine, "</INDEX>"))
- {
- return This; /*Finish, get out of here*/
- }
- break;
- case 2:
- if(EQ(FLine, "</MODULE>"))
- {
- 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;
- }
+ if (as->pls == NULL)
+ {
+ as->pls = as->plf->symbols = ps;
+ }
+ else
+ {
+ as->pls->next = ps;
+ as->pls = as->pls->next;
}
- return This; /*State machine should never reach this point, but just in case...*/
+ return 0;
}
+pmlibrarysymbol
+add_rel_index (FILE * fp, long size, pmlibraryfile This)
+{
+ struct add_sym_s as;
+ as.plf = This;
+ as.pls = This->symbols;
+
+ assert (This->symbols == NULL);
+
+ enum_symbols (fp, size, &add_sybmol, &as);
+
+ return as.pls;
+}
/* buildlibraryindex - build an in-memory cache of the symbols contained in
* the libraries
*/
-int buildlibraryindex(void)
+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)
+ pmlibraryfile This = NULL;
+ struct lbname *lbnh;
+
+ /*
+ * Search through every library in the linked list "lbnhead".
+ */
+ for (lbnh = lbnhead; lbnh; lbnh = lbnh->next)
{
- if ((libfp = fopen(lbnh->libspc, "r")) == NULL)
+ FILE *libfp;
+ int i;
+
+ if ((libfp = fopen (lbnh->libspc, "rb")) == NULL)
{
- fprintf(stderr, "?ASlink-Error-Cannot open library file %s\n",
- lbnh->libspc);
- lkexit(1);
+ 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)
+ for (i = 0; i < NELEM (aslib_targets); ++i)
{
- relfil[NINPUT+1] = '\0';
- chop_crlf(relfil);
- if (path != NULL)
+ if ((*aslib_targets[i]->is_lib) (libfp))
{
- strcpy(str, path);
-#ifdef OTHERSYSTEM
- if (strlen(str) && (str[strlen(str)-1] != '/') && (str[strlen(str)-1] != LKDIRSEP))
- {
- strcat(str, LKDIRSEPSTR);
- }
-#endif
+ This = (*aslib_targets[i]->buildlibraryindex) (lbnh, libfp, This, i);
+ break;
}
- else
- {
- strcpy(str, "");
- }
-
- if(strcmp(relfil, "<SDCCLIB>")==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] == '/') || (relfil[0] == LKDIRSEP))
- {
- strcat(str, relfil+1);
- }
- else
- {
- strcat(str, relfil);
- }
-
- if(strchr(relfil, FSEPX) == NULL)
- {
- sprintf(&str[strlen(str)], "%c%s", FSEPX, LKOBJEXT);
- }
-
- 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;
+ if (i >= NELEM (aslib_targets))
+ fprintf (stderr, "?ASlink-Error-Unknown library file format %s\n", lbnh->libspc);
- sscanf(buf, "S %s %c", symname, &c);
+ fclose (libfp);
+ }
- /* 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;
+ return 0;
}
/*Release all memory allocated for the in-memory library index*/
-void freelibraryindex (void)
+void
+freelibraryindex (void)
{
- pmlibraryfile ThisLibr, ThisLibr2Free;
- pmlibrarysymbol ThisSym, ThisSym2Free;
+ pmlibraryfile ThisLibr, ThisLibr2Free;
+ pmlibrarysymbol ThisSym, ThisSym2Free;
- ThisLibr = libr;
+ ThisLibr = libr;
- while (ThisLibr)
+ while (ThisLibr)
{
- ThisSym = ThisLibr->symbols;
+ ThisSym = ThisLibr->symbols;
- while (ThisSym)
+ while (ThisSym)
{
- free(ThisSym->name);
- ThisSym2Free=ThisSym;
- ThisSym=ThisSym->next;
- free(ThisSym2Free);
+ free (ThisSym->name);
+ ThisSym2Free = ThisSym;
+ ThisSym = ThisSym->next;
+ free (ThisSym2Free);
}
- free(ThisLibr->filename);
- free(ThisLibr->relfil);
- ThisLibr2Free=ThisLibr;
- ThisLibr=ThisLibr->next;
- free(ThisLibr2Free);
+ free (ThisLibr->filename);
+ free (ThisLibr->relfil);
+ ThisLibr2Free = ThisLibr;
+ ThisLibr = ThisLibr->next;
+ free (ThisLibr2Free);
}
- libr=NULL;
+ libr = NULL;
}
#else /* INDEXLIB */
-int
-fndsym(char *name)
+struct load_sym_s
+{
+ const char *name;
+ struct lbname *lbnh;
+ const char *relfil;
+ const char *filspc;
+ int offset;
+ int type;
+};
+
+static int
+load_sybmol (const char *sym, void *params)
{
- FILE *libfp, *fp;
- struct lbname *lbnh;
- struct lbfile *lbfh, *lbf;
- char relfil[NINPUT+2];
- char buf[NINPUT+2];
- char symname[NINPUT];
- char *path,*str;
- char c;
- int result;
-
- /*
- * Search through every library in the linked list "lbnhead".
- */
-
- for (lbnh=lbnhead; lbnh; lbnh=lbnh->next)
+ struct load_sym_s *ls = (struct load_sym_s *) params;
+
+ if (strcmp (ls->name, sym) == 0)
{
- if ((libfp = fopen(lbnh->libspc, "r")) == NULL)
- {
- fprintf(stderr, "?ASlink-Error-Cannot open library file %s\n",
- lbnh->libspc);
- lkexit(1);
- }
- path = lbnh->path;
+ struct lbfile *lbfh, *lbf;
- /*
- * Read in a line from the library file.
- * This is the relative file specification
- * for a .REL file in this library.
- */
+ lbfh = (struct lbfile *) new (sizeof (struct lbfile));
+ lbfh->libspc = ls->lbnh->libspc;
+ lbfh->relfil = strdup (ls->relfil);
+ lbfh->filspc = strdup (ls->filspc);
+ lbfh->offset = ls->offset;
+ lbfh->type = ls->type;
- while (fgets(relfil, NINPUT, libfp) != NULL)
+ if (lbfhead == NULL)
{
- relfil[NINPUT+1] = '\0';
- chop_crlf(relfil);
- if (path != NULL)
- {
- str = (char *) new (strlen(path)+strlen(relfil)+6);
- strcpy(str,path);
-#ifdef OTHERSYSTEM
- if (strlen(str) && (str[strlen(str)-1] != '/') && (str[strlen(str)-1] != LKDIRSEP))
- {
- strcat(str, LKDIRSEPSTR);
- }
-#endif
- }
- else
+ lbfhead = lbfh;
+ }
+ else
+ {
+ lbf = lbfhead;
+ while (lbf->next)
{
- str = (char *) new (strlen(relfil) + 5);
+ lbf = lbf->next;
}
+ lbf->next = lbfh;
+ }
- /*See if this is a library with embedded files*/
- if(strcmp(relfil, "<SDCCLIB>")==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;
- }
+ (*aslib_targets[ls->type]->loadfile) (lbfh);
- /*From here down is the support for libraries in the original format*/
- if ((relfil[0] == '/') || (relfil[0] == LKDIRSEP))
- {
- strcat(str, relfil+1);
- }
- else
- {
- strcat(str, relfil);
- }
+ return 1;
+ }
+ else
+ return 0;
+}
- if(strchr(relfil, FSEPX) == NULL)
- {
- sprintf(&str[strlen(str)], "%c%s", FSEPX, LKOBJEXT);
- }
+int
+add_rel_file (const char *name, struct lbname *lbnh, const char *relfil,
+ const char *filspc, int offset, FILE * fp, long size, int type)
+{
+ struct load_sym_s ls;
+ ls.name = name;
+ ls.lbnh = lbnh;
+ ls.relfil = relfil;
+ ls.filspc = filspc;
+ ls.offset = offset;
+ ls.type = type;
+
+ return enum_symbols (fp, size, &load_sybmol, &ls);
+}
- 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.
- */
-
- 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;
-
- 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.
- */
- 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;
- }
+int
+fndsym (const char *name)
+{
+ FILE *libfp;
+ struct lbname *lbnh;
+ int i;
+
+ /*
+ * Search through every library in the linked list "lbnhead".
+ */
+ for (lbnh = lbnhead; lbnh; lbnh = lbnh->next)
+ {
+ int ret;
- 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 ((libfp = fopen (lbnh->libspc, "rb")) == NULL)
+ {
+ fprintf (stderr, "?ASlink-Error-Cannot open library file %s\n", lbnh->libspc);
+ lkexit (1);
+ }
- /* 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);
- }
- } /* Closes while - read object file */
- fclose(fp);
- } /* Closes if object file opened OK */
- else
+ for (i = 0; i < NELEM (aslib_targets); ++i)
+ {
+ if ((*aslib_targets[i]->is_lib) (libfp))
{
- fprintf(stderr, "?ASlink-Warning-Cannot open library module %s\n", str);
+ ret = (*aslib_targets[i]->fndsym) (name, lbnh, libfp, i);
+ break;
}
- free(str);
- } /* Ends while - processing all in libr */
- fclose(libfp);
- } /* Ends good open of libr file */
- return(0);
-}
+ }
-#endif /* INDEXLIB */
+ if (i >= NELEM (aslib_targets))
+ fprintf (stderr, "?ASlink-Error-Unknown library file format %s\n", lbnh->libspc);
-void loadfile_SdccLib(char * libspc, char * module, long offset)
-{
- FILE *fp;
+ fclose (libfp);
-#ifdef __CYGWIN__
- char posix_path[PATH_MAX];
- void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
- cygwin_conv_to_full_posix_path(libspc, posix_path);
- fp = fopen(posix_path, "r");
-#else
- fp = fopen(libspc,"r");
-#endif
+ if (!ret)
+ break;
- if (fp != NULL)
- {
- fseek(fp, offset, SEEK_SET);
- LoadRel(libspc, fp, module);
- fclose(fp);
- }
- else
- {
- fprintf(stderr, "?ASlink-Error-Opening library '%s'\n", libspc);
- lkexit(1);
- }
+ } /* Ends good open of libr file */
+ return 0;
}
+#endif /* INDEXLIB */
/*)Function VOID library()
*
*/
VOID
-library(void)
+library (void)
{
- struct lbfile *lbfh;
-
- 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
-}
+ struct lbfile *lbfh;
-/*)Function VOID loadfile(filspc)
- *
- * char *filspc library object file specification
- *
- * The function loadfile() links the library object module.
- *
- * local variables:
- * FILE *fp file handle
- * int i input line length
- * char str[] file input line
- *
- * global variables:
- * char *ip pointer to linker input string
- *
- * functions called:
- * int fclose() c_library
- * int fgets() c_library
- * FILE * fopen() c_library
- * VOID link_main() lkmain.c
- * int strlen() c_library
- *
- * side effects:
- * If file exists it is linked.
- */
+ for (lbfh = lbfhead; lbfh; lbfh = lbfh->next)
+ (*aslib_targets[lbfh->type]->loadfile) (lbfh);
-VOID
-loadfile(char *filspc)
-{
- FILE *fp;
- char str[NINPUT+2];
-
-#ifdef __CYGWIN__
- char posix_path[PATH_MAX];
- void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
- cygwin_conv_to_full_posix_path(filspc, posix_path);
- fp = fopen(posix_path, "r");
-#else
- fp = fopen(filspc,"r");
+#ifdef INDEXLIB
+ freelibraryindex ();
#endif
-
- if (fp != NULL)
- {
- while (fgets(str, NINPUT, fp) != NULL)
- {
- str[NINPUT+1] = '\0';
- chop_crlf(str);
- ip = str;
- link_main();
- }
- fclose(fp);
- }
- else
- {
- fprintf(stderr, "?ASlink-Error-Opening library '%s'\n", filspc);
- lkexit(1);
- }
}