scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

pass1.c (3878B)


      1 #include <stdarg.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 
      6 #include <scc/mach.h>
      7 #include <scc/scc.h>
      8 #include <scc/ar.h>
      9 
     10 #include "ld.h"
     11 
     12 static int bintype = -1;
     13 Objlst *objhead, *objlast;
     14 
     15 static void
     16 addobj(Obj *obj, FILE *fp)
     17 {
     18 	int n;
     19 	Objlst *lst;
     20 	Objsym *sym;
     21 	Objsect *secp;
     22 
     23 	if ((lst = malloc(sizeof(*lst))) == NULL) {
     24 		error("out of memory");
     25 		return;
     26 	}
     27 
     28 	lst->obj = obj;
     29 	lst->next = NULL;
     30 
     31 	if (!objlast)
     32 		objlast = objhead = lst;
     33 	else
     34 		objlast = objlast->next = lst;
     35 
     36 	for (sym = obj->syms; sym; sym = sym->next)
     37 		newsym(sym, obj);
     38 }
     39 
     40 static void
     41 newobject(FILE *fp, int type, int inlib)
     42 {
     43 	Obj *obj;
     44  
     45 	if ((obj = objnew(type)) == NULL) {
     46 		error("out of memory");
     47 		return;
     48 	}
     49  
     50 	if (bintype != -1 && bintype != type) {
     51 		error("not compatible object file");
     52 		goto delete;
     53 	}
     54 	bintype = type;
     55  
     56 	if (objread(obj, fp) < 0) {
     57 		error("object file corrupted");
     58 		goto delete;
     59 	}
     60  
     61 	if (objsyms(obj) < 0 || objsect(obj) < 0) {
     62 		error("object file corrupted");
     63 		goto delete;
     64 	}
     65 
     66 	/*
     67 	 * we add the object to the list of objects
     68 	 * if we are not in a library without index,
     69 	 * or in that case if the library defines
     70 	 * some symbol needed.
     71 	 */
     72 	if (!inlib || defasym(obj)) {
     73 		addobj(obj, fp);
     74 		return;
     75 	}
     76 
     77  delete:
     78 	objdel(obj);
     79 	return;
     80 }
     81 
     82 static void
     83 addlib(FILE *fp)
     84 {
     85 	int t, added;
     86 	long n;
     87 	Objsymdef *def, *dp;
     88 	Symbol *sym;
     89 
     90 	if (getindex(bintype, &n, &def, fp) < 0) {
     91 		error("corrupted index");
     92 		return;
     93 	}
     94 
     95 	added = 1;
     96 	while (moreundef() && added) {
     97 		added = 0;
     98 		for (dp = def; dp; dp = dp->next) {
     99 			sym = lookup(dp->name, NOINSTALL);
    100 			if (!sym || sym->def)
    101 				continue;
    102 
    103 			if (fseek(fp, dp->offset, SEEK_SET) == EOF) {
    104 				error(errstr());
    105 				goto clean;
    106 			}
    107 
    108 			if ((t = objtype(fp, NULL)) == -1) {
    109 				error("library file corrupted");
    110 				goto clean;
    111 			}
    112 
    113 			if (t != bintype) {
    114 				error("incompatible library");
    115 				goto clean;
    116 			}
    117 
    118 			newobject(fp, t, OUTLIB);
    119 			added = 1;
    120 		}
    121 	}
    122 clean:
    123 	free(def);
    124 }
    125 
    126 static int
    127 newmember(FILE *fp, char *name, void *data)
    128 {
    129 	int t;
    130 	int *nmemb = data;
    131 
    132 	if (bintype == -1) {
    133 		error("an object file is needed before any library");
    134 		return 0;
    135 	}
    136 
    137 	if (*nmemb++ == 0) {
    138 		if (!strncmp(name, "/", SARNAM) ||
    139 		    !strncmp(name, "__.SYMDEF", SARNAM)) {
    140 			addlib(fp);
    141 			return 0;
    142 		}
    143 	}
    144 
    145 	membname = name;
    146 	if ((t = objtype(fp, NULL)) == -1)
    147 		return 1;
    148 
    149 	if (bintype != t) {
    150 		error("wrong object file format");
    151 		return 1;
    152 	}
    153 
    154 	newobject(fp, t, INLIB);
    155 	membname = NULL;
    156 
    157 	return 1;
    158 }
    159 
    160 static int
    161 newlibrary(FILE *fp)
    162 {
    163 	int nmemb = 0;
    164 
    165 	return formember(fp, newmember, &nmemb);
    166 }
    167 
    168 static FILE *
    169 openfile(char *name, char *buffer)
    170 {
    171 	size_t pathlen, len;
    172 	FILE *fp;
    173 	char **bp;
    174 	char libname[FILENAME_MAX];
    175 	extern char *syslibs[];
    176 
    177 	filename = name;
    178 	membname = NULL;
    179 	if (name[0] != '-' || name[1] != 'l') {
    180 		if ((fp = fopen(name, "rb")) == NULL)
    181 			error(errstr());
    182 		return fp;
    183 	}
    184 
    185 	len = strlen(name+2) + 3;
    186 	if (len > FILENAME_MAX-1) {
    187 		error("library name too long");
    188 		return NULL;
    189 	}
    190 	strcat(strcpy(buffer, "lib"), name+2);
    191 
    192 	filename = buffer;
    193 	if ((fp = fopen(libname, "rb")) != NULL)
    194 		return fp;
    195 
    196 	for (bp = syslibs; *bp; ++bp) {
    197 		pathlen = strlen(*bp);
    198 		if (pathlen + len > FILENAME_MAX-1)
    199 			continue;
    200 		memcpy(libname, *bp, pathlen);
    201 		memcpy(libname+pathlen+1, buffer, len);
    202 		buffer[pathlen] = '/';
    203 
    204 		if ((fp = fopen(buffer, "rb")) != NULL)
    205 			return fp;
    206 	}
    207 
    208 	error("not found");
    209 	return NULL;
    210 }
    211 
    212 /*
    213  * Get the list of object files that are going to be linked
    214  */
    215 void
    216 pass1(int argc, char *argv[])
    217 {
    218 	int t;
    219 	FILE *fp;
    220 	char buff[FILENAME_MAX];
    221 
    222 	for ( ; *argv; ++argv) {
    223 		if ((fp = openfile(*argv, buff)) == NULL)
    224 			continue;
    225 
    226 		if ((t = objtype(fp, NULL)) != -1)
    227 			newobject(fp, t, OUTLIB);
    228 		else if (archive(fp))
    229 			newlibrary(fp);
    230 		else
    231 			error("bad format");
    232 	}
    233 
    234 	if (moreundef()) {
    235 		listundef();
    236 		exit(EXIT_FAILURE);
    237 	}
    238 }