home *** CD-ROM | disk | FTP | other *** search
- From: mauro@netcom.COM (Mauro DePalma)
- Newsgroups: comp.sources.misc
- Subject: v18i018: cdl - COFF Dynamic Loader, Part02/02
- Message-ID: <1991Apr13.212620.15975@sparky.IMD.Sterling.COM>
- Date: 13 Apr 91 21:26:20 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: b9b54dac fd95c06f eb5c16ad 90a27ccb
-
- Submitted-by: Mauro DePalma <mauro@netcom.COM>
- Posting-number: Volume 18, Issue 18
- Archive-name: cdl/part02
-
- #!/bin/sh
- # This is part 02 of CDL-1.2
- if touch 2>&1 | fgrep '[-amc]' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= loader.c ==============
- echo "x - extracting loader.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > loader.c &&
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) loader.c 1.5 1/18/91 by DePalma SoftCraft";
- X#endif
- X
- X/* UNIX System V/386 COFF Dynamic Loader (CDL).
- X*/
- X#ifndef PORTAR
- X# define PORTAR yes
- X#endif
- X
- X#include <errno.h>
- X#include <stdio.h>
- X#include <sys/stat.h>
- X#include <sys/fcntl.h>
- X#include <a.out.h>
- X#include <ldfcn.h>
- X
- X#include "craft.h"
- X#include "loader.h"
- X
- X
- X/*
- X NAME
- X assort(CDL) -- adjust and sort out symbols.
- X
- X SYNOPSIS
- X*/
- X int assort(source, seed, name, symndx, dynamic)
- X buffer_t source;
- X caddr_t * seed;
- X char * name;
- X int symndx;
- X loader_t dynamic;
- X/*
- X DESCRIPTION
- X The goal here is to provide correct values for symbols and
- X and place those which are defined in the 'seed' structure.
- X*/
- X{
- X SYMENT * symbol = (SYMENT *) (dynamic->table + symndx * SYMESZ);
- X caddr_t item;
- X
- X/* object archive support
- X*/
- X if (AVLsearch(*seed, (caddr_t) name, &item, strcmp) == SUCCESS)
- X {
- X collect_t parcel = (collect_t) item;
- X
- X if (symbol->n_scnum || (symbol->n_scnum == N_UNDEF && symbol->n_value))
- X {
- X if (symbol->n_scnum == N_UNDEF && symbol->n_value)
- X {
- X if (symbol->n_value = (long) allocate(NIL, symbol->n_value))
- X symbol->n_sclass = (char) 0;
- X else
- X return ELDNOMEM;
- X }
- X
- X parcel->sector = sectarian(symbol->n_scnum);
- X parcel->segment = source->base;
- X parcel->site = symbol->n_value;
- X }
- X
- X return SUCCESS;
- X }
- X
- X/* see if it's a global symbol
- X*/
- X if (AVLsearch(Global, (caddr_t) name, &item, strcmp) == SUCCESS)
- X if (symbol->n_scnum == N_UNDEF)
- X {
- X collect_t parcel = (collect_t) item;
- X
- X symbol->n_value = parcel->site;
- X
- X if (parcel->sector == N_DATA || parcel->sector == N_BSS)
- X symbol->n_sclass = (char) 0;
- X
- X return SUCCESS;
- X }
- X
- X/* see if it's uninitialized data
- X*/
- X if (symbol->n_scnum == N_UNDEF && symbol->n_value)
- X {
- X if (symbol->n_value = (long) allocate(NIL, symbol->n_value))
- X symbol->n_sclass = (char) 0;
- X else
- X return ELDNOMEM;
- X }
- X
- X return collect(source, seed, name, symbol, dynamic);
- X} /* assort */
- X
- X
- X
- X/*
- X NAME
- X collect(CDL) -- collect symbols.
- X
- X SYNOPSIS
- X*/
- X static int collect(source, seed, name, symbol, dynamic)
- X buffer_t source;
- X caddr_t * seed;
- X char * name;
- X SYMENT * symbol;
- X loader_t dynamic;
- X/*
- X DESCRIPTION
- X*/
- X{
- X collect_t parcel = (collect_t) 0;
- X int status;
- X
- X if (! (parcel = (collect_t) allocate(NIL, sizeof(struct _collect))))
- X return ELDNOMEM;
- X
- X if (symbol)
- X {
- X parcel->sector = sectarian(symbol->n_scnum);
- X parcel->segment = source->base;
- X parcel->site = symbol->n_value;
- X }
- X else
- X {
- X parcel->sector = N_FILE;
- X parcel->segment = (dynamic) ? dynamic->segment : (char *) 0;
- X parcel->site = source->mark;
- X }
- X
- X status = AVLinsert(seed, (caddr_t) name, (caddr_t) parcel, strcmp);
- X
- X if (status != SUCCESS)
- X {
- X deallocate((caddr_t) parcel);
- X status = DUBIOUS(status);
- X }
- X
- X return status;
- X} /* collect */
- X
- X
- X
- X/*
- X NAME
- X destruct(CDL) -- dispose of a single stored symbol.
- X
- X SYNOPSIS
- X*/
- X static int destruct(key, item)
- X caddr_t key;
- X caddr_t item;
- X/*
- X DESCRIPTION
- X*/
- X{
- X deallocate(item);
- X deallocate(key);
- X
- X return SUCCESS;
- X} /* destruct */
- X
- X
- X
- X/*
- X NAME
- X initialize(CDL) -- dynamic loader initialization.
- X
- X SYNOPSIS
- X*/
- X static int initialize(pid)
- X int pid;
- X/*
- X DESCRIPTION
- X Initialization consists on a "ps -fp `echo $$`" using the 8th
- X field of the last line of output from that command.
- X*/
- X{
- X if (Global == (caddr_t) 0) /* initialization required */
- X {
- X FILE * stream;
- X LDFILE * ldptr;
- X char line[BUFSIZ];
- X char * image;
- X int status;
- X short scan;
- X
- X (void) sprintf(line, "ps -fp %d", pid);
- X
- X if (stream = popen(line, "r"))
- X while (fgets(line, BUFSIZ, stream))
- X ;
- X
- X for (scan = 0; scan < 8; scan++) /* 'image' is the 8th field */
- X image = strtok((scan) ? NULL : line, " ");
- X
- X ldptr = ldopen(image = which(image), NULL);
- X status = (ldptr) ? SUCCESS : ERROR(sys_errlist, errno);
- X
- X if (status == SUCCESS)
- X {
- X struct _buffer record;
- X struct _buffer * source = &record;
- X
- X if ((status = quantum(ldptr, source, image)) == SUCCESS)
- X status = prospect(ldptr, source, &Global, NIL);
- X
- X (void) ldclose(ldptr);
- X }
- X
- X return status;
- X }
- X
- X return SUCCESS;
- X} /* initialize */
- X
- X
- X
- X/*
- X NAME
- X process(CDL) -- driver for loading a module.
- X
- X SYNOPSIS
- X*/
- X static int process(ldptr, source, seed, card)
- X LDFILE * ldptr;
- X buffer_t source;
- X caddr_t * seed;
- X caddr_t * card;
- X/*
- X DESCRIPTION
- X*/
- X{
- X int status;
- X loader_t dynamic;
- X
- X if (! (dynamic = (loader_t) allocate(NIL, sizeof(struct _loader))))
- X return ELDNOMEM;
- X
- X if ((status = profile(ldptr, dynamic)) == SUCCESS)
- X if ((status = prospect(ldptr, source, seed, dynamic)) == SUCCESS)
- X if (Stack(card, (caddr_t) dynamic) == (caddr_t) 0)
- X status = ELDNOMEM;
- X
- X if (status != SUCCESS)
- X {
- X deallocate((caddr_t) dynamic->reloc.base);
- X deallocate((caddr_t) dynamic->segment);
- X deallocate((caddr_t) dynamic->table);
- X deallocate((caddr_t) dynamic);
- X }
- X
- X return status;
- X} /* process */
- X
- X
- X
- X/*
- X NAME
- X profile(CDL) -- read relevant information.
- X
- X SYNOPSIS
- X*/
- X static int profile(ldptr, dynamic)
- X LDFILE * ldptr;
- X loader_t dynamic;
- X/*
- X DESCRIPTION
- X Sufficient memory is allocated for combined section data,
- X relocation information, and symbol table; each of these parts
- X are read from the LDFILE* 'ldptr' into their respective
- X loader_t (see, loader.h) 'dynamic' component.
- X*/
- X{
- X FILHDR * header = &HEADER(ldptr);
- X SCNHDR scnhdr;
- X SCNHDR * section = &scnhdr;
- X long region = (long) 0;
- X ushort nreloc = (ushort) 0;
- X ushort scnum;
- X
- X if (! ISCOFF(header->f_magic))
- X return ELDBADHDR;
- X
- X/* read section headers and track size of combined section data
- X along with the number of relocation entries
- X*/
- X for (scnum = 1; scnum <= header->f_nscns; scnum++)
- X {
- X if (ldshread(ldptr, scnum, section) == FAILURE)
- X return ELDSCNHDR;
- X
- X nreloc += section->s_nreloc;
- X region += section->s_size;
- X }
- X
- X/* allocate and read combined section data
- X*/
- X if (! (dynamic->segment = (char *) allocate(NIL, region)))
- X return ELDNOMEM;
- X
- X if (ldsseek(ldptr, N_TEXT) == FAILURE && errno > 0)
- X return ERROR(sys_errlist, errno);
- X
- X if (FREAD(dynamic->segment, sizeof(char), region, ldptr) != region)
- X return ELDSECTION;
- X
- X/* allocate and read combined relocation entries
- X*/
- X region = (long) nreloc * RELSZ;
- X
- X if (! (dynamic->reloc.base = (char *) allocate(NIL, region)))
- X return ELDNOMEM;
- X
- X dynamic->reloc.mark = (long) nreloc;
- X
- X if (FREAD(dynamic->reloc.base, sizeof(char), region, ldptr) != region)
- X return ELDRELOC;
- X
- X/* allocate and read the symbol table (assume: AUXESZ == SYMESZ)
- X*/
- X region = header->f_nsyms * SYMESZ;
- X
- X if (! (dynamic->table = (char *) allocate(NIL, region)))
- X return ELDNOMEM;
- X
- X if (ldtbseek(ldptr) == FAILURE)
- X return ERROR(sys_errlist, errno);
- X
- X if (FREAD(dynamic->table, sizeof(char), region, ldptr) != region)
- X return ELDSYMBOL;
- X
- X return SUCCESS;
- X} /* profile */
- X
- X
- X
- X/*
- X NAME
- X prospect(CDL) -- store global symbols.
- X
- X SYNOPSIS
- X*/
- X static int prospect(ldptr, source, seed, dynamic)
- X LDFILE * ldptr;
- X buffer_t source;
- X caddr_t * seed;
- X loader_t dynamic;
- X/*
- X DESCRIPTION
- X*/
- X{
- X SYMENT syment;
- X SYMENT * symbol = &syment;
- X int status = SUCCESS;
- X ushort symndx;
- X ushort nsyms;
- X
- X for (nsyms = HEADER(ldptr).f_nsyms, symndx = 0; symndx < nsyms; )
- X {
- X if (ldtbread(ldptr, symndx, symbol) == FAILURE)
- X break;
- X
- X if (symbol->n_sclass == C_EXT && symbol->n_scnum >= 0)
- X {
- X char * name = strdup(ldgetname(ldptr, symbol));
- X
- X if (dynamic)
- X status = assort(source, seed, name, symndx, dynamic);
- X else
- X status = collect(source, seed, name, symbol, dynamic);
- X
- X if (status != SUCCESS)
- X break;
- X }
- X
- X symndx += symbol->n_numaux + 1;
- X }
- X
- X if (status == SUCCESS)
- X status = collect(source, seed, source->base, NULL, dynamic);
- X
- X return status;
- X} /* prospect */
- X
- X
- X
- X/*
- X NAME
- X quantum(CDL) -- identify module.
- X
- X SYNOPSIS
- X*/
- X static int quantum(ldptr, source, module)
- X LDFILE * ldptr;
- X buffer_t source;
- X char * module;
- X/*
- X DESCRIPTION
- X Here we determine whether what is being processed is an object
- X file or an archive. The buffer_t (see, craft.h) 'source' fields
- X in either case are set to the module name and its modification
- X date/time.
- X
- X BUGS
- X Although, there may be other reasons, ldahread(3X) failure is
- X taken as proof that we're dealing with and object file.
- X*/
- X{
- X ARCHDR archdr;
- X char buffer[BLOCK];
- X
- X if (ldahread(ldptr, &archdr) == SUCCESS)
- X {
- X (void) sprintf(buffer, "%s[%s]", module, archdr.ar_name);
- X
- X source->base = strdup(buffer);
- X source->mark = archdr.ar_date;
- X }
- X else
- X {
- X struct stat info;
- X
- X if (stat(module, &info) == -1)
- X return ERROR(sys_errlist, errno);
- X
- X source->base = strdup(module);
- X source->mark = info.st_mtime;
- X }
- X
- X return SUCCESS;
- X} /* quantum */
- X
- X
- X
- X/*
- X NAME
- X realize(CDL) -- realize a newly loaded file.
- X
- X SYNOPSIS
- X*/
- X static int realize(symtab, card)
- X caddr_t symtab;
- X caddr_t * card;
- X/*
- X DESCRIPTION
- X*/
- X{
- X int status = SUCCESS;
- X loader_t dynamic;
- X
- X AVLwalk(symtab, shepherd, (caddr_t) &status);
- X
- X if (status == SUCCESS)
- X {
- X AVLwalk(symtab, sloven, (caddr_t) &status);
- X
- X while (status == SUCCESS && (dynamic = (loader_t) Stack(card, NIL)))
- X {
- X status = resolve(dynamic);
- X
- X if (status == SUCCESS)
- X {
- X struct _assoc vehicle;
- X struct _assoc * shuttle = &vehicle;
- X
- X shuttle->key = (caddr_t) dynamic->segment;
- X shuttle->item = (caddr_t) &status;
- X
- X AVLwalk(symtab, solder, (caddr_t) shuttle);
- X }
- X
- X if (status != SUCCESS)
- X deallocate((caddr_t) dynamic->segment);
- X
- X deallocate((caddr_t) dynamic->reloc.base);
- X deallocate((caddr_t) dynamic->table);
- X deallocate((caddr_t) dynamic);
- X }
- X }
- X
- X/* always: completely discard 'card' stack and contents
- X*/
- X while (dynamic = (loader_t) Stack(card, NIL))
- X {
- X deallocate((caddr_t) dynamic->reloc.base);
- X deallocate((caddr_t) dynamic->segment);
- X deallocate((caddr_t) dynamic->table);
- X deallocate((caddr_t) dynamic);
- X }
- X
- X return status;
- X} /* realize */
- X
- X
- X
- X/*
- X NAME
- X resolve(CDL) -- resolve relocation entries.
- X
- X SYNOPSIS
- X*/
- X static int resolve(dynamic)
- X loader_t dynamic;
- X/*
- X DESCRIPTION
- X*/
- X{
- X SYMENT * symbol;
- X RELOC * reloc;
- X char * address;
- X long datum;
- X ushort nreloc;
- X ushort count;
- X
- X for (count = 0, nreloc = dynamic->reloc.mark; count < nreloc; count++)
- X {
- X reloc = (RELOC *) (dynamic->reloc.base + count * RELSZ);
- X
- X if (reloc->r_type == R_ABS) /* absolute: no relocation necessary */
- X continue;
- X
- X address = (char *) (reloc->r_vaddr + (long) dynamic->segment);
- X symbol = (SYMENT *) (dynamic->table + reloc->r_symndx * SYMESZ);
- X
- X if (symbol->n_scnum == N_UNDEF || symbol->n_scnum == N_TEXT)
- X datum = symbol->n_value;
- X else
- X datum = (long) 0;
- X
- X if (symbol->n_sclass) /* see, assort(CDL) for details */
- X switch (reloc->r_type)
- X {
- X case R_DIR16:
- X (void) puts(DANGER("relocation type R_DIR16 untested"));
- X datum += *(short *) address + (long) dynamic->segment;
- X break;
- X
- X case R_REL16:
- X (void) puts(DANGER("relocation type R_REL16 untested"));
- X if (datum)
- X datum -= (long) address + sizeof(short);
- X break;
- X
- X case R_DIR32:
- X datum += *(long *) address + (long) dynamic->segment;
- X break;
- X
- X case R_PCRLONG:
- X if (datum)
- X datum -= (long) address + sizeof(long);
- X break;
- X
- X default:
- X return ELDRESOLVE;
- X }
- X
- X switch (reloc->r_type)
- X {
- X case R_DIR16: /* direct, 16-bit reference */
- X case R_REL16: /* PC relative, 16-bit reference */
- X if (datum < -32768 || datum > 32767)
- X return ELDRESOLVE;
- X
- X *(short *) address = datum;
- X break;
- X
- X case R_DIR32: /* direct, 32-bit reference */
- X case R_PCRLONG: /* PC relative, 32-bit reference */
- X if (datum)
- X *(long *) address = datum;
- X break;
- X
- X default:
- X return ELDRESOLVE;
- X }
- X }
- X
- X return SUCCESS;
- X} /* resolve */
- X
- X
- X
- X/*
- X NAME
- X selector(CDL) -- select a global symbol.
- X
- X SYNOPSIS
- X*/
- X static int selector(key, item, ark)
- X caddr_t key;
- X caddr_t item;
- X caddr_t ark;
- X/*
- X DESCRIPTION
- X Selector inserts a global symbol in a 'list' when
- X the symbol belongs to the 'module' given.
- X
- X ark -> +--------+
- X | module |
- X |--------|
- X | list |
- X +--------+
- X*/
- X{
- X assoc_t shuttle = (assoc_t) ark;
- X collect_t parcel = (collect_t) item;
- X int status = SUCCESS;
- X
- X if (parcel->sector != N_FILE)
- X if (strcmp(parcel->segment, (char *) shuttle->key) == 0)
- X status = LLinsert(&(shuttle->item), key, item);
- X
- X return status;
- X} /* selector */
- X
- X
- X
- X/*
- X NAME
- X shepherd(CDL) -- govern a local symbol tree.
- X
- X SYNOPSIS
- X*/
- X static int shepherd(key, item, ark)
- X caddr_t key;
- X caddr_t item;
- X caddr_t ark;
- X/*
- X DESCRIPTION
- X Shepherd flags multiply defined symbols and corrects the
- X address for those which exist.
- X*/
- X{
- X caddr_t store = (caddr_t) 0;
- X
- X if (AVLsearch(Global, key, &store, strcmp) == SUCCESS)
- X {
- X collect_t packet = (collect_t) item;
- X collect_t parcel = (collect_t) store;
- X int * state = (int *) ark;
- X
- X if (*state == SUCCESS)
- X {
- X *state = FAILURE;
- X error(ELDMULDEF);
- X }
- X
- X error(ERRMSG, "%s : '%s' already defined in '%s'",
- X packet->segment, key, parcel->segment);
- X }
- X
- X return SUCCESS;
- X} /* shepherd */
- X
- X
- X
- X/*
- X NAME
- X sloven(CDL) -- flag undefined symbols.
- X
- X SYNOPSIS
- X*/
- X static int sloven(key, item, ark)
- X caddr_t key;
- X caddr_t item;
- X caddr_t ark;
- X/*
- X DESCRIPTION
- X*/
- X{
- X collect_t parcel = (collect_t) item;
- X
- X if (parcel->sector == N_UNDEF && parcel->site == (long) 0)
- X {
- X int * state = (int *) ark;
- X
- X if (*state == SUCCESS)
- X {
- X *state = FAILURE;
- X error(ELDUNDEF);
- X }
- X
- X error(ERRMSG, "'%s' referenced in '%s'", key, parcel->segment);
- X }
- X
- X return SUCCESS;
- X} /* sloven */
- X
- X
- X
- X/*
- X NAME
- X solder(CDL) -- add new symbols to global structure.
- X
- X SYNOPSIS
- X*/
- X static int solder(key, item, ark)
- X caddr_t key;
- X caddr_t item;
- X caddr_t ark;
- X/*
- X DESCRIPTION
- X Solder is an action routine which serves to copy a symbol
- X from a working structure to the global symbols structure.
- X
- X ark -> +--------------------------------+
- X | loader_t record |
- X |--------------------------------|
- X | start of combined section data |
- X +--------------------------------+
- X*/
- X{
- X assoc_t shuttle = (assoc_t) ark;
- X collect_t parcel = (collect_t) item;
- X int * state = (int *) shuttle->item;
- X
- X if (*state == SUCCESS)
- X {
- X collect_t store;
- X
- X if (store = (collect_t) allocate(NIL, sizeof(struct _collect)))
- X {
- X store->sector = parcel->sector;
- X store->segment = parcel->segment;
- X store->site = parcel->site;
- X
- X if (store->sector != N_FILE)
- X store->site += (long) shuttle->key;
- X
- X *state = AVLinsert(&Global, (caddr_t) key, (caddr_t) store, strcmp);
- X }
- X else
- X {
- X *state = ELDNOMEM;
- X }
- X }
- X
- X return SUCCESS;
- X} /* solder */
- X
- X
- X
- X/*
- X NAME
- X solvent(CDL) -- remove a global symbol.
- X
- X SYNOPSIS
- X*/
- X static int solvent(key, item)
- X caddr_t key;
- X caddr_t item;
- X/*
- X DESCRIPTION
- X*/
- X{
- X return AVLremove(&Global, key, strcmp, destruct);
- X} /* solvent */
- X
- X
- X
- X/*
- X NAME
- X load(3L) -- load a common object file.
- X
- X SYNOPSIS
- X*/
- X int load(module)
- X char * module;
- X/*
- X DESCRIPTION
- X If the given 'module' has been loaded already its modification
- X date is compared with the dynamic loading date; when the two dates
- X differ an unload(3L) is performed on the one in memory and dynamic
- X loading is then attempted with the 'module' given.
- X
- X SEE ALSO
- X error(3L), symbol(3L), unload(3L).
- X
- X DIAGNOSTICS
- X Upon successful completion SUCCESS is returned. Otherwise the
- X value of the return status indicates what error was encountered.
- X*/
- X{
- X LDFILE * ldptr = (LDFILE *) 0;
- X caddr_t item;
- X caddr_t symtab = (caddr_t) 0;
- X caddr_t vitals = (caddr_t) 0;
- X int status;
- X long stamp;
- X struct _buffer record;
- X struct _buffer * source = &record;
- X
- X if ((status = initialize(getpid())) == SUCCESS)
- X {
- X do
- X {
- X if (ldptr = ldopen(module, ldptr))
- X {
- X if ((status = quantum(ldptr, source, module)) != SUCCESS)
- X break;
- X
- X if (stamp = (long) symbol(source->base))
- X {
- X if (stamp == source->mark)
- X continue;
- X
- X if ((status = unload(source->base)) != SUCCESS)
- X break;
- X }
- X
- X status = process(ldptr, source, &symtab, &vitals);
- X }
- X } while (ldclose(ldptr) == FAILURE && status == SUCCESS);
- X
- X if (symtab)
- X {
- X if (status == SUCCESS) /* augment global structure */
- X status = realize(symtab, &vitals);
- X
- X AVLdispose(symtab, (agent_t)((status == SUCCESS) ? 0 : destruct));
- X }
- X else
- X {
- X if (errno)
- X status = ERROR(sys_errlist, errno);
- X }
- X }
- X
- X return status;
- X} /* load */
- X
- X
- X
- X/*
- X NAME
- X symbol(3L) -- symbol look up.
- X
- X SYNOPSIS
- X*/
- X void * symbol(name)
- X char * name;
- X/*
- X DESCRIPTION
- X The specified 'name' is looked up and if found its value returned.
- X A value of NIL indicates look up failure.
- X*/
- X{
- X caddr_t item;
- X void * entry = NIL;
- X
- X if (AVLsearch(Global, (caddr_t) name, &item, strcmp) == SUCCESS)
- X {
- X collect_t parcel = (collect_t) item;
- X
- X entry = (void *) parcel->site;
- X }
- X
- X return entry;
- X} /* symbol */
- X
- X
- X
- X/*
- X NAME
- X unload(3L) -- unload all symbols associated with a module.
- X
- X SYNOPSIS
- X*/
- X int unload(module)
- X char * module;
- X/*
- X DESCRIPTION
- X All symbols associated with the given module are indiscriminately
- X removed and any memory allocated is freed.
- X*/
- X{
- X caddr_t item;
- X collect_t parcel;
- X struct _assoc vehicle;
- X struct _assoc * shuttle = &vehicle;
- X
- X if (AVLsearch(Global, (caddr_t) module, &item, strcmp) != SUCCESS)
- X return ELDNOFILE;
- X
- X shuttle->key = (caddr_t) module;
- X shuttle->item = (caddr_t) 0;
- X
- X/* we cannot directly remove symbols
- X*/
- X AVLwalk(Global, selector, (caddr_t) shuttle);
- X
- X LLwalk(shuttle->item, solvent, NIL);
- X LLdispose(shuttle->item, destruct);
- X
- X/* free what we allocated for combined section data
- X*/
- X parcel = (collect_t) item;
- X
- X if (parcel->segment)
- X deallocate(parcel->segment);
- X
- X return DUBIOUS(AVLremove(&Global, (caddr_t) module, strcmp, destruct));
- X} /* unload */
- X
- X
- X
- X#ifdef DEBUG
- X/*
- X NAME
- X display -- display routine for symbols.
- X
- X SYNOPSIS
- X*/
- X static int display(key, item, nest, ark)
- X caddr_t key;
- X caddr_t item;
- X int nest;
- X caddr_t ark;
- X/*
- X DESCRIPTION
- X*/
- X{
- X collect_t parcel = (collect_t) item;
- X int status;
- X
- X if (parcel->sector == N_FILE)
- X status = printf("%19s(%d) : 0x%8.8x\n", (char*) key,
- X parcel->site, (long) parcel->segment);
- X else
- X status = printf("%19s(%s) : 0x%8.8x\n", (char*) key,
- X parcel->segment, parcel->site);
- X
- X return status;
- X} /* display */
- X
- X
- X
- X/*
- X NAME
- X dump -- dump symbol table.
- X
- X SYNOPSIS
- X*/
- X void dump(symtab)
- X caddr_t symtab;
- X/*
- X DESCRIPTION
- X*/
- X{
- X
- X AVLdump(symtab, display, NIL);
- X} /* dump */
- X#endif /* DEBUG */
- SHAR_EOF
- $TOUCH -am 0118122491 loader.c &&
- chmod 0444 loader.c ||
- echo "restore of loader.c failed"
- set `wc -c loader.c`;Wc_c=$1
- if test "$Wc_c" != "21155"; then
- echo original size 21155, current size $Wc_c
- fi
- # ============= loader.h ==============
- echo "x - extracting loader.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > loader.h &&
- X
- X/* UNIX System V/386 COFF Dynamic Loader (CDL) header file.
- X
- X loader.h 1.5 1/18/91 by DePalma SoftCraft
- X*/
- X
- X#ifndef __LOADER_H__ /* guard against multiple includes */
- X#define __LOADER_H__
- X
- X/* mauro@olympus (19910104.1808)
- X
- X The, UNIX System V/386 Programmer's Guide warns that it is a mistake
- X to assume the characteristics of sections in general of a COFF file.
- X
- X Here however the assumption is made that the sections named '.text',
- X '.data', '.bss' appear as the first three sections in a COFF file.
- X*/
- X#define sectarian(x) (x) /* .. only if assumption hold true */
- X
- X#define N_TEXT 1 /* mnemonic for '.text' section */
- X#define N_DATA 2 /* mnemonic for '.data' section */
- X#define N_BSS 3 /* mnemonic for '.bss' section */
- X
- X#define N_FILE 0x1f /* special: file name symbol */
- X
- X
- Xtypedef union /* either symbol or auxiliary entry */
- X {
- X AUXENT auxent; /* .. auxiliary entry */
- X SYMENT syment; /* .. symbol entry */
- X } SYMBOL;
- X
- X
- Xtypedef struct _collect /* Dynamic Loader symbol data */
- X {
- X char sector; /* .. section mnemonic or N_FILE */
- X char * segment; /* .. combined section data or file */
- X long site; /* .. offset in memory or date/time */
- X } *collect_t;
- X
- X
- Xtypedef struct _loader /* Dynamic Loader data structure */
- X {
- X struct _buffer reloc; /* .. relocation entries */
- X char * segment; /* .. start of combined section data */
- X char * table; /* .. symbol table and auxiliary */
- X } *loader_t;
- X
- X
- X/* Dynamic Loader Specific Errors (should be read from a message file)
- X*/
- Xstatic char *ldErrorList[] =
- X {
- X "",
- X "The file doesn't have a COFF header", /* 1 */
- X "Dynamic Loader cannot allocate enough memory", /* 2 */
- X "An error was encountered while reading the file header", /* 3 */
- X "An error was encountered while reading the optional header", /* 4 */
- X "An error was encountered while reading a section header", /* 5 */
- X "An error was encountered while reading section data", /* 6 */
- X "An error was encountered while reading relocation information", /* 7 */
- X "An error was encountered while reading the symbol table", /* 8 */
- X "The following symbols are multiply defined:", /* 9 */
- X "The following symbols remain undefined:", /* 10 */
- X "Dynamic Loader cannot handle a relocation entry", /* 11 */
- X "No such file dynamically loaded", /* 12 */
- X 0
- X };
- X
- X#define ELDBADHDR ERROR(ldErrorList, 1) /* invalid a.out header */
- X#define ELDNOMEM ERROR(ldErrorList, 2) /* can't allocate enough memory */
- X#define ELDFILHDR ERROR(ldErrorList, 3) /* error reading file header */
- X#define ELDOPTHDR ERROR(ldErrorList, 4) /* error reading optional header*/
- X#define ELDSCNHDR ERROR(ldErrorList, 5) /* error reading section header */
- X#define ELDSECTION ERROR(ldErrorList, 6) /* error reading section data */
- X#define ELDRELOC ERROR(ldErrorList, 7) /* error reading reloc. entries */
- X#define ELDSYMBOL ERROR(ldErrorList, 8) /* error reading symbol table */
- X#define ELDMULDEF ERROR(ldErrorList, 9) /* multiply defined symbol(s) */
- X#define ELDUNDEF ERROR(ldErrorList, 10) /* unresolved symbol(s) */
- X#define ELDRESOLVE ERROR(ldErrorList, 11) /* (internal) unable to resolve */
- X#define ELDNOFILE ERROR(ldErrorList, 12) /* file was not loaded */
- X
- X
- X
- X/* Dynamic Loader Private
- X*/
- Xstatic int assort(buffer_t, caddr_t *, char *, int, loader_t);
- Xstatic int collect(buffer_t, caddr_t *, char *, SYMENT *, loader_t);
- Xstatic int destruct(caddr_t, caddr_t);
- X
- Xstatic int initialize(int);
- Xstatic int process(LDFILE *, buffer_t, caddr_t *, caddr_t *);
- Xstatic int profile(LDFILE *, loader_t);
- Xstatic int prospect(LDFILE *, buffer_t, caddr_t *, loader_t);
- Xstatic int quantum(LDFILE *, buffer_t, char *);
- Xstatic int realize(caddr_t, caddr_t *);
- Xstatic int resolve(loader_t);
- X
- Xstatic int selector(caddr_t, caddr_t, caddr_t);
- Xstatic int shepherd(caddr_t, caddr_t, caddr_t);
- Xstatic int sloven(caddr_t, caddr_t, caddr_t);
- Xstatic int solder(caddr_t, caddr_t, caddr_t);
- Xstatic int solvent(caddr_t, caddr_t);
- X
- Xstatic caddr_t Global = (caddr_t) 0; /* symbol table for globals */
- X
- X
- X/* Dynamic Loader Externals
- X*/
- Xextern char * ldgetname(LDFILE *, SYMENT *);
- X#endif /* __LOADER_H__ */
- X
- SHAR_EOF
- $TOUCH -am 0118122491 loader.h &&
- chmod 0444 loader.h ||
- echo "restore of loader.h failed"
- set `wc -c loader.h`;Wc_c=$1
- if test "$Wc_c" != "4799"; then
- echo original size 4799, current size $Wc_c
- fi
- # ============= simple.c ==============
- echo "x - extracting simple.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > simple.c &&
- X
- X#include <stdio.h>
- X
- Xextern char* sys_errlist[];
- X
- Xchar *module = __FILE__;
- Xshort bogus;
- X
- Xvoyage(char* caller)
- X{
- X char* routine = "voyage";
- X
- X (void) printf("<%s line %d> %s: called by, '%s'\n",
- X module, __LINE__, routine, caller);
- X gossip(routine);
- X}
- X
- Xgossip(char* caller)
- X{
- X char* routine = "gossip";
- X
- X (void) printf("<%s line %d> %s: called by, '%s'\n",
- X module, __LINE__, routine, caller);
- X
- X (void) printf("<%s line %d> %s: some extern data, '%s'\n",
- X module, __LINE__, routine, sys_errlist[1]);
- X
- X (void) printf("<%s line %d> %s: some local data, '%d'\n",
- X module, __LINE__, routine, bogus=1234);
- X}
- SHAR_EOF
- $TOUCH -am 0116200491 simple.c &&
- chmod 0644 simple.c ||
- echo "restore of simple.c failed"
- set `wc -c simple.c`;Wc_c=$1
- if test "$Wc_c" != "676"; then
- echo original size 676, current size $Wc_c
- fi
- exit 0
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-