jejones@ea.UUCP (10/28/84)
[If people can post hex dumps of Macintosh programs to net.sources, ...?]
The following program lets one split a Microware C library file into its
component pieces. This has various uses, and in particular lets one insert
one's own versions of functions. (The header file at the beginning is one
that I use continually, out of revulsion at the thought of using ints for
boolean quantities. At least I can hide the fact...)
Down with Funky Stuff,
James Jones
------------------------------TEAR HERE------------------------------
# This is a shell archive. Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file". (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# bool.h LibSplit.c
echo x - bool.h
sed 's/^ //' > "bool.h" << '//E*O*F bool.h//'
/*
* bool.h -- a header for those of us who think that C really
* should have a Boolean type...
*/
typedef int bool;
#define TRUE 1
#define FALSE 0
//E*O*F bool.h//
echo x - LibSplit.c
sed 's/^ //' > "LibSplit.c" << '//E*O*F LibSplit.c//'
/*
* LibSplit -- split library files into their component "modules"
*
* usage: LibSplit libfile [module ...]
*
* semantics: LibSplit will read the specified library file and
* split out its component "modules." If "module" names are
* explicitly given on the command line, then only those "modules"
* will be extracted; otherwise, all "modules" from the library
* file will be extracted. Each selected "module" is written into
* a separate file named after the "module."
*/
#include <stdio.h>
#include <bool.h>
/*
* We are only concerned with library file structure inasmuch as it
* permits us to chop a file into its components. Thus you will not
* see here as much detail as in, say, rdump; only the needed stuff.
*/
#define ROFSYNC 0x62cd2387 /* ROF "sync bytes" */
/* ("magic number" to Unixoids) */
#define SYMLEN 9 /* maximum symbol length */
#define MAXNAME 16 /* maximum "module" name length */
/* 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;
binhead header;
FILE *LibFP, *ModFP;
bool GetCurr;
main(argc, argv)
int argc;
char *argv[];
{
int i, NMods;
bool GetAll;
char ModName[MAXNAME + 1];
char *LibFName;
if (argc < 2) {
fprintf(stderr, "usage: LibSplit libfile [module ...]\n");
exit(1);
}
if (GetAll = (argc == 2))
NMods = 30000;
else
NMods = argc - 2;
LibFName = argv[1];
if ((LibFP = fopen(LibFName, "r")) == NULL) {
fprintf(stderr, "LibSplit: can't open %s\n", LibFName);
exit(1);
}
while (NMods > 0) {
if (fread(&header, sizeof(header), 1, LibFP) < 1)
break;
if (header.h_sync != ROFSYNC) {
fprintf(stderr, "%s is not a library file\n", LibFName);
exit(1);
}
GetName(ModName);
if (GetAll)
GetCurr = TRUE;
else {
GetCurr = FALSE;
for (i = 2; i < argc; i++) {
if (strcmp(ModName, argv[i]) == 0) {
GetCurr = TRUE;
break;
}
}
}
if (GetCurr) {
NMods--;
if ((ModFP = fopen(ModName, "w")) == NULL) {
fprintf(stderr, "LibSplit: can't create %s\n",
ModName);
exit(1);
}
fwrite(&header, sizeof(header), 1, ModFP);
PutName(ModName);
}
CopyGlobalDefs();
CopyCode();
CopyExtRefs();
CopyRefs(); /* local references */
if (GetCurr)
fclose(ModFP);
}
fclose(LibFP);
}
CopyGlobalDefs()
{
int GCount, Offset;
char GSym[SYMLEN + 1], flag;
GCount = getw(LibFP);
if (GetCurr)
putw(GCount, ModFP);
for (; GCount > 0; GCount--) {
GetName(GSym);
if (GetCurr) {
PutName(GSym);
putc((flag = getc(LibFP)), ModFP);
putw((Offset = getw(LibFP)), ModFP);
} else
fseek(LibFP, (long)(sizeof(char) + sizeof(int)), 1);
}
}
CopyCode()
{
int HowMuch;
char buffer[BUFSIZ];
HowMuch = header.h_ocode + header.h_ddata + header.h_data;
if (GetCurr) {
for (; HowMuch >= BUFSIZ; HowMuch -= BUFSIZ) {
fread(buffer, 1, BUFSIZ, LibFP);
fwrite(buffer, 1, BUFSIZ, ModFP);
}
if (HowMuch > 0) {
fread(buffer, 1, HowMuch, LibFP);
fwrite(buffer, 1, HowMuch, ModFP);
}
} else
fseek(LibFP, (long) HowMuch, 1);
}
CopyExtRefs()
{
int ECount;
char ESym[SYMLEN + 1];
putw((ECount = getw(LibFP)), ModFP);
for (; ECount > 0; ECount--) {
GetName(ESym);
if (GetCurr)
PutName(ESym);
CopyRefs();
}
}
CopyRefs()
{
int RCount;
def_ref ref;
RCount = getw(LibFP);
if (GetCurr) {
putw(RCount, ModFP);
for (; RCount > 0; RCount--) {
fread(&ref, sizeof(ref), 1, LibFP);
fwrite(&ref, sizeof(ref), 1, ModFP);
}
} else
fseek(LibFP, (long) (RCount * sizeof(ref)), 1);
}
GetName(s)
char *s;
{
while (*(s++) = getc(LibFP))
;
}
PutName(s)
char *s;
{
fputs(s, ModFP);
putc('\0', ModFP);
}
//E*O*F LibSplit.c//
exit 0