jejones@ea.UUCP (11/17/84)
The following (not a shell archive, since it's only one file) is a program that does for Microware C relocatable and library files what lorder(1) does for Unix .o files. The following brash one-liner makes fun of condescending Unix documentation: "Take my wife--please!" In conjunction with previously posted stuff (LibSplit), I'm going to use this to shuffle the Microware C library, clib.l, to see if it makes any difference in speed of compilation. If it helps, I'll let you know. BTW--I know I took the sleazy way out on looking for duplications in ShowDep(). I probably should have kept a high-water mark on ECount and allocated that much (it's just a one-shot anyway). Sigh... James Jones ------------------------------TARE HEAR------------------------------ /* * LOrder -- display dependencies among pieces of relocatable and * library files * * usage: LOrder <pathname> [<pathname> ...] * * semantics: LOrder reads the specified files and looks at the * global symbols used and defined by the parts thereof. It * then writes to standard output a sequence of lines of the * form "m1 m2," where m1 is the name of a "module" that refers * to a global symbol defined in the "module" m2. */ #include <stdio.h> #define ROFSYNC 0x62cd2387 /* ROF "sync bytes" */ /* ("magic number" to Unixoids) */ #define SYMLEN 9 /* maximum symbol length */ #define MAXNAME 16 /* maximum "module" name length */ #define HASHSIZE 151 /* size of symbol hash table */ #define MODULE 1 /* tag for "modules" */ #define GLOBAL 0 /* and for globals */ #define MAXREFS 40 /* arbitrary bound on external references */ /* definition/reference */ typedef struct { char r_flag; /* type/location */ unsigned r_offset; } def_ref; /* "module" header structure */ typedef struct { long h_sync; /* should == ROFSYNC */ unsigned h_tylan; /* type/language/attr/revision */ char h_valid; /* asm valid? */ char h_date[5]; /* creation date */ char h_edit; /* edition # */ char h_spare; /* next, sizes of: */ unsigned h_glbl, /* globals */ h_dglbl, /* direct page globals */ h_data, /* data */ h_ddata, /* direct page data */ h_ocode; /* code */ unsigned h_stack, h_entry; } binhead; /* what we keep track of for symbols */ typedef struct module { char m_name[MAXNAME]; struct global **ref_list; struct module *m_next; } Module; typedef struct global { char s_name[MAXNAME]; struct module *def_by; struct global *s_next; } Global; binhead header; FILE *LibFP; Global *HashTable[HASHSIZE]; Module *MList; main(argc, argv) int argc; char *argv[]; { int i; if (argc < 2) { fprintf(stderr, "usage: LOrder pathname [pathname ...]\n"); exit(1); } MList = NULL; for (i = 0; i < HASHSIZE; i++) HashTable[i] = NULL; for (i = 1; i < argc; i++) DoLibFile(argv[i]); ShowDep(); } DoLibFile(LibPath) char *LibPath; { Module *NewMod, *GetModule(); if ((LibFP = fopen(LibPath, "r")) == NULL) { fprintf(stderr, "LOrder: can't open %s\n", LibPath); exit(1); } while (fread(&header, sizeof(header), 1, LibFP) > 0) { if (header.h_sync != ROFSYNC) { fprintf(stderr, "%s is not a library file\n", LibPath); exit(1); } NewMod = GetModule(); DoGlobalDefs(NewMod); fseek(LibFP, (long) header.h_ocode + header.h_ddata + header.h_data, 1); DoExtRefs(NewMod); SkipRefs(); /* local references */ } fclose(LibFP); } DoGlobalDefs(Mod) Module *Mod; { int GCount; Global *GSym, *GetGlobal(); GCount = getw(LibFP); for (; GCount > 0; GCount--) { GSym = GetGlobal(); GSym->def_by = Mod; fseek(LibFP, (long)(sizeof(char) + sizeof(int)), 1); } } DoExtRefs(Mod) Module *Mod; { int i, ECount; Global *GetGlobal(), **rlist; ECount = getw(LibFP); rlist = calloc(ECount + 1, sizeof(Global *)); if (rlist == NULL) { exit(1); } Mod->ref_list = rlist; for (i = 0; i < ECount; i++) { rlist[i] = GetGlobal(); SkipRefs(); } } SkipRefs() { int RCount; RCount = getw(LibFP); fseek(LibFP, (long) (RCount * sizeof(def_ref)), 1); } Global * GetGlobal() { char NameIn[MAXNAME]; Global *NewGlob; int i, hash; for (i = 0; NameIn[i] = getc(LibFP); i++) ; for (hash = i = 0; NameIn[i]; i++) hash ^= NameIn[i] << (i & 7); hash = hash % HASHSIZE; for (NewGlob = HashTable[hash]; NewGlob != NULL; ) { if (strcmp(NameIn, NewGlob->s_name) == 0) { return(NewGlob); } NewGlob = NewGlob->s_next; } if ((NewGlob = malloc(sizeof(Global))) == NULL) { fprintf(stderr, "LOrder: out of memory\n"); exit(1); } strcpy(NewGlob->s_name, NameIn); NewGlob->def_by = NULL; NewGlob->s_next = HashTable[hash]; HashTable[hash] = NewGlob; return(NewGlob); } Module * GetModule() { Module *NewMod; char *scan; if ((NewMod = malloc(sizeof(Module))) == NULL) { fprintf(stderr, "LOrder: out of memory\n"); exit(1); } for (scan = NewMod->m_name; *scan = getc(LibFP); scan++) ; NewMod->ref_list = NULL; NewMod->m_next = MList; MList = NewMod; return(NewMod); } ShowDep() { int i, j, rcount; Global **rlist; Module *scan, *deplist[MAXREFS]; for (scan = MList; scan != NULL; scan = scan->m_next) { rcount = 0; rlist = scan->ref_list; for (i = 0; rlist[i] != NULL; i++) { if ((rlist[i])->def_by == NULL) fprintf(stderr, "LOrder: %s is not defined\n", (rlist[i])->s_name); else { deplist[rcount] = (rlist[i])->def_by; for (j = 0; deplist[j] != deplist[rcount]; j++) ; if (j >= rcount) rcount++; } } for (j = 0; j < rcount; j++) printf("%s %s\n", scan->m_name, deplist[j]->m_name); } }