{
struct object *o = xmalloc(sizeof(struct object));
o->next = NULL;
+ o->syment = NULL;
+ return o;
+}
+
+static void insert_object(struct object *o)
+{
if (otail)
otail->next = o;
else
otail = o;
}
+static void free_object(struct object *o)
+{
+ if (o->syment)
+ free(o->syment);
+ free(o);
+}
+
struct symbol *new_symbol(char *name, int hash)
{
struct symbol *s = xmalloc(sizeof(struct symbol));
return NULL;
}
+/* Check if a symbol name is known but undefined. We use this to decide
+ whether to incorporate a library module */
+int is_undefined(char *name)
+{
+ int hash = hash_symbol(name);
+ struct symbol *s = find_symbol(name, hash);
+ if (s == NULL || !(s->type & S_UNDEFINED))
+ return 0;
+ /* This is a symbol we need */
+ return 1;
+}
+
struct symbol *find_alloc_symbol(struct object *o, uint8_t type, char *id, uint16_t value)
{
uint8_t hash = hash_symbol(id);
}
/* Two definitions.. usually bad but allow duplicate absolutes */
if ((s->type|type) & S_SEGMENT != ABSOLUTE ||
- s->value |= value)
+ s->value != value)
/* FIXME: expand to report files somehow ? */
printf("%s: multiply defined.\n", id);
}
return s;
}
-struct object *load_object(FILE *fp, off_t base)
+struct object *load_object(FILE *fp, off_t base, int lib)
{
int i;
uint8_t type;
if (fread(&o->oh, sizeof(o->oh), 1, &fp) != 1 || o->o.oh_magic != MAGIC_OBJ ||
o->oh.o_symbase == 0)
error("bad object file");
- /* Make sure all the files are the same architeture */
- if (arch) {
- if (o->oh.o_arch != arch)
- error("wrong architecture");
- } else
- arch = o->oh.o_arch;
- /* The CPU features required is the sum of all the flags in the objects */
- arch_flags |= o->oh.o_cpuflags;
-
/* Load up the symbols */
- fseek(fp, base + o->oh.o_symbase, SEEK_SET);
nsym = (o->oh.o_dbgbase - o->oh.o_symbase) / S_SIZE:
if (nsym < 0)
error("bad object file");
+ /* Allocate the symbol entries */
o->syment = (struct symbol **)xmalloc(sizeof(struct symbol *) * nsym);
o->nsym = nsym;
+restart:
+ fseek(fp, base + o->oh.o_symbase, SEEK_SET);
sp = o->syment;
for (i = 0; i < nsym; i++) {
type = fgetc(fp);
read(name. 16, 1, fp);
name[16] = 0;
value = fgetc(fp) + (fgetc(fp) << 8);
- *sp++ = find_alloc_symbol(o, type, name, value);
+ /* In library mode we look for a symbol that means we will load
+ this object - and then restart wih lib = 0 */
+ if (lib) {
+ if (is_undefined(name)) {
+ lib = 0;
+ goto restart;
+ } else
+ *sp++ = find_alloc_symbol(o, type, name, value);
}
+ /* If we get here with lib set then this was a library module we didn't
+ in fact require */
+ if (lib) {
+ free_object(o);
+ return NULL;
+ }
+ insert_object(o);
+ /* Make sure all the files are the same architeture */
+ if (arch) {
+ if (o->oh.o_arch != arch)
+ error("wrong architecture");
+ } else
+ arch = o->oh.o_arch;
+ /* The CPU features required is the sum of all the flags in the objects */
+ arch_flags |= o->oh.o_cpuflags;
return o;
}
error("image too large");
/* Whoopee it fits */
/* Insert the linker symbols */
- insert_internal_symbol("__code", base[0]);
- insert_internal_symbol("__data", base[1]);
- insert_internal_symbol("__bss", base[2]);
- insert_internal_symbol("__end", bas[2] + size[2]);
+ insert_internal_symbol("__code", base[1]);
+ insert_internal_symbol("__data", base[2]);
+ insert_internal_symbol("__bss", base[3]);
+ insert_internal_symbol("__end", bas[3] + size[3]);
/* Now set the base of each object appropriately */
memcpy(&pos, &base, sizeof(pos));
for (o = objects; o != NULL; o = o->next) {
s = s->next;
}
}
- /* We now know all the base addresses and all the symbolv values are
+ /* We now know all the base addresses and all the symbol values are
corrected. Everything needed for relocation is present */
}