mirror of
https://github.com/open-simh/simtools.git
synced 2026-05-05 07:23:31 +00:00
Make RSX MLB parser more resistant to bad files.
This commit is contained in:
4
README
4
README
@@ -110,6 +110,10 @@ Options:
|
|||||||
-m macname Gives a macro library name.
|
-m macname Gives a macro library name.
|
||||||
Up to 32 macro libraries may be specified, one per
|
Up to 32 macro libraries may be specified, one per
|
||||||
-m option.
|
-m option.
|
||||||
|
The current object file format (default, or from
|
||||||
|
-rt11 or -rsx before this option) is used first to
|
||||||
|
read the file; if this fails, the other format is
|
||||||
|
tried.
|
||||||
Note: unlike MACRO.SAV, SYSMAC.SML is not
|
Note: unlike MACRO.SAV, SYSMAC.SML is not
|
||||||
automatically included; you must name it.
|
automatically included; you must name it.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
#define MACRO11__C
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Assembler compatible with MACRO-11.
|
Assembler compatible with MACRO-11.
|
||||||
|
|
||||||
@@ -132,7 +129,7 @@ static void print_help(
|
|||||||
printf(" -l - enables listing to stdout.\n");
|
printf(" -l - enables listing to stdout.\n");
|
||||||
printf("-m load RSX-11 or RT-11 compatible macro library from which\n");
|
printf("-m load RSX-11 or RT-11 compatible macro library from which\n");
|
||||||
printf(" .MCALLed macros can be found.\n");
|
printf(" .MCALLed macros can be found.\n");
|
||||||
printf(" Multiple allowed.\n");
|
printf(" Multiple allowed. Affected by any -rsx or -rt11 which come before.\n");
|
||||||
printf("-o gives the object file name (.OBJ)\n");
|
printf("-o gives the object file name (.OBJ)\n");
|
||||||
printf("-p gives the name of a directory in which .MCALLed macros may be found.\n");
|
printf("-p gives the name of a directory in which .MCALLed macros may be found.\n");
|
||||||
printf(" Sets environment variable \"MCALL\".\n");
|
printf(" Sets environment variable \"MCALL\".\n");
|
||||||
|
|||||||
163
mlb-rsx.c
163
mlb-rsx.c
@@ -156,6 +156,9 @@ DAMAGE.
|
|||||||
#include "mlb.h"
|
#include "mlb.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#define MLBDEBUG_OPEN 0
|
||||||
|
#define MLBDEBUG_ENTRY 0
|
||||||
|
|
||||||
static MLB *mlb_rsx_open(
|
static MLB *mlb_rsx_open(
|
||||||
char *name,
|
char *name,
|
||||||
int allow_object_library);
|
int allow_object_library);
|
||||||
@@ -168,10 +171,11 @@ static void mlb_rsx_extract(
|
|||||||
MLB *mlb);
|
MLB *mlb);
|
||||||
|
|
||||||
struct mlb_vtbl mlb_rsx_vtbl = {
|
struct mlb_vtbl mlb_rsx_vtbl = {
|
||||||
mlb_rsx_open,
|
.mlb_open = mlb_rsx_open,
|
||||||
mlb_rsx_entry,
|
.mlb_entry = mlb_rsx_entry,
|
||||||
mlb_rsx_extract,
|
.mlb_extract = mlb_rsx_extract,
|
||||||
mlb_rsx_close,
|
.mlb_close = mlb_rsx_close,
|
||||||
|
.mlb_is_rt11 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BLOCKSIZE 512
|
#define BLOCKSIZE 512
|
||||||
@@ -201,7 +205,7 @@ MLB *mlb_rsx_open(
|
|||||||
int allow_objlib)
|
int allow_objlib)
|
||||||
{
|
{
|
||||||
MLB *mlb = memcheck(malloc(sizeof(MLB)));
|
MLB *mlb = memcheck(malloc(sizeof(MLB)));
|
||||||
char *buff;
|
char *buff = NULL;
|
||||||
unsigned entsize;
|
unsigned entsize;
|
||||||
unsigned nr_entries;
|
unsigned nr_entries;
|
||||||
unsigned start_block;
|
unsigned start_block;
|
||||||
@@ -210,6 +214,9 @@ MLB *mlb_rsx_open(
|
|||||||
mlb->vtbl = &mlb_rsx_vtbl;
|
mlb->vtbl = &mlb_rsx_vtbl;
|
||||||
mlb->directory = NULL;
|
mlb->directory = NULL;
|
||||||
|
|
||||||
|
#if MLBDEBUG_OPEN
|
||||||
|
fprintf(stderr, "mlb_rsx_open('%s', %d)\n", name, allow_objlib);
|
||||||
|
#endif
|
||||||
mlb->fp = fopen(name, "rb");
|
mlb->fp = fopen(name, "rb");
|
||||||
if (mlb->fp == NULL) {
|
if (mlb->fp == NULL) {
|
||||||
mlb_rsx_close(mlb);
|
mlb_rsx_close(mlb);
|
||||||
@@ -219,20 +226,16 @@ MLB *mlb_rsx_open(
|
|||||||
buff = memcheck(malloc(060)); /* Size of MLB library header */
|
buff = memcheck(malloc(060)); /* Size of MLB library header */
|
||||||
|
|
||||||
if (fread(buff, 1, 060, mlb->fp) < 060) {
|
if (fread(buff, 1, 060, mlb->fp) < 060) {
|
||||||
fprintf(stderr, "error: can't read full header\n");
|
fprintf(stderr, "mlb_rsx_open error: can't read full header\n");
|
||||||
mlb_rsx_close(mlb);
|
goto error;
|
||||||
free(buff);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mlb->is_objlib = 0;
|
mlb->is_objlib = 0;
|
||||||
if (allow_objlib && WORD(buff) == 01000) { /* Is it an object library? */
|
if (allow_objlib && WORD(buff) == 01000) { /* Is it an object library? */
|
||||||
mlb->is_objlib = 1;
|
mlb->is_objlib = 1;
|
||||||
} else if (WORD(buff) != 01001) { /* Is this really a macro library? */
|
} else if (WORD(buff) != 01001) { /* Is this really a macro library? */
|
||||||
/* fprintf(stderr, "error: first word not correct value\n"); */
|
/* fprintf(stderr, "mlb_rsx_open error: first word not correct value\n"); */
|
||||||
mlb_rsx_close(mlb); /* Nope. */
|
goto error;
|
||||||
free(buff);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entsize = buff[032]; /* The size of each macro directory
|
entsize = buff[032]; /* The size of each macro directory
|
||||||
@@ -242,24 +245,33 @@ MLB *mlb_rsx_open(
|
|||||||
directory */
|
directory */
|
||||||
|
|
||||||
if (entsize < 8) { /* Is this really a macro library? */
|
if (entsize < 8) { /* Is this really a macro library? */
|
||||||
mlb_rsx_close(mlb); /* Nope. */
|
fprintf(stderr, "mlb_rsx_open error: entsize too small: %d\n", entsize);
|
||||||
fprintf(stderr, "error: entsize too small: %d\n", entsize);
|
goto error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fprintf(stderr, "entsize=%d, nr_entries=%d, start_block=%d\n",
|
if (start_block < 1) { /* Is this really a macro library? */
|
||||||
// entsize, nr_entries, start_block);
|
fprintf(stderr, "mlb_rsx_open error: start_block too small: %d\n", start_block);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MLBDEBUG_OPEN
|
||||||
|
fprintf(stderr, "entsize=%d, nr_entries=%d, start_block=%d\n",
|
||||||
|
entsize, nr_entries, start_block);
|
||||||
|
#endif
|
||||||
free(buff); /* Done with that header. */
|
free(buff); /* Done with that header. */
|
||||||
|
|
||||||
/* Allocate a buffer for the disk directory */
|
/* Allocate a buffer for the disk directory */
|
||||||
buff = memcheck(malloc(nr_entries * entsize));
|
buff = memcheck(malloc(nr_entries * entsize));
|
||||||
fseek(mlb->fp, start_block * BLOCKSIZE, SEEK_SET); /* Go to the directory */
|
/* Go to the directory */
|
||||||
|
if (fseek(mlb->fp, start_block * BLOCKSIZE, SEEK_SET) == -1) {
|
||||||
|
fprintf(stderr, "mlb_rsx_open error: seek error: %d\n", start_block * BLOCKSIZE);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read the disk directory */
|
/* Read the disk directory */
|
||||||
if (fread(buff, entsize, nr_entries, mlb->fp) < nr_entries) {
|
if (fread(buff, entsize, nr_entries, mlb->fp) < nr_entries) {
|
||||||
mlb_rsx_close(mlb); /* Sorry, read error. */
|
fprintf(stderr, "mlb_rsx_open error: fread: not enough entries\n");
|
||||||
free(buff);
|
goto error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shift occupied directory entries to the front of the array */
|
/* Shift occupied directory entries to the front of the array */
|
||||||
@@ -269,11 +281,15 @@ MLB *mlb_rsx_open(
|
|||||||
for (i = 0, j = nr_entries; i < j; i++) {
|
for (i = 0, j = nr_entries; i < j; i++) {
|
||||||
char *ent1,
|
char *ent1,
|
||||||
*ent2;
|
*ent2;
|
||||||
|
int w1, w2;
|
||||||
|
|
||||||
ent1 = buff + (i * entsize);
|
ent1 = buff + (i * entsize);
|
||||||
/* Unused entries have 0177777 0177777 for the RAD50 name,
|
/* Unused entries have 0177777 0177777 for the RAD50 name,
|
||||||
which is not legal RAD50. */
|
which is not legal RAD50. */
|
||||||
if (WORD(ent1) == 0177777 && WORD(ent1 + 2) == 0177777) {
|
w1 = WORD(ent1);
|
||||||
|
w2 = WORD(ent1 + 2);
|
||||||
|
|
||||||
|
if (w1 == 0177777 && w2 == 0177777) {
|
||||||
while (--j > i
|
while (--j > i
|
||||||
&& (ent2 = buff + (j * entsize), WORD(ent2) == 0177777 && WORD(ent2 + 2) == 0177777)) ;
|
&& (ent2 = buff + (j * entsize), WORD(ent2) == 0177777 && WORD(ent2 + 2) == 0177777)) ;
|
||||||
if (j <= i)
|
if (j <= i)
|
||||||
@@ -283,15 +299,31 @@ MLB *mlb_rsx_open(
|
|||||||
space */
|
space */
|
||||||
memset(ent2, 0377, entsize); /* Mark entry unused */
|
memset(ent2, 0377, entsize); /* Mark entry unused */
|
||||||
} else {
|
} else {
|
||||||
// fprintf(stderr, "entry %d: %02x%02x.%02x%02x\n",
|
#if MLBDEBUG_OPEN
|
||||||
// i, ent1[5] & 0xFF, ent1[4] & 0xFF, ent1[7] & 0xFF, ent1[6] & 0xFF);
|
fprintf(stderr, "entry %d: %02x%02x.%02x%02x\n",
|
||||||
|
i, ent1[5] & 0xFF, ent1[4] & 0xFF, ent1[7] & 0xFF, ent1[6] & 0xFF);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* 00 00 rad50-decodes to spaces, which are not a
|
||||||
|
* valid name for a macro or object file.
|
||||||
|
*/
|
||||||
|
if (w1 == 0000000 && w2 == 0000000) {
|
||||||
|
fprintf(stderr, "mlb_rsx_open error: bad file, null name\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now i contains the actual number of entries. */
|
/* Now i contains the actual number of entries. */
|
||||||
|
|
||||||
mlb->nentries = i;
|
mlb->nentries = i;
|
||||||
// fprintf(stderr, " mlb->nentries=%d\n", mlb->nentries);
|
#if MLBDEBUG_OPEN
|
||||||
|
fprintf(stderr, "mlb->nentries=%d\n", mlb->nentries);
|
||||||
|
#endif
|
||||||
|
if (mlb->nentries == 0) {
|
||||||
|
fprintf(stderr, "mlb_rsx_open error: no entries\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now, allocate my in-memory directory */
|
/* Now, allocate my in-memory directory */
|
||||||
mlb->directory = memcheck(malloc(sizeof(MLBENT) * mlb->nentries));
|
mlb->directory = memcheck(malloc(sizeof(MLBENT) * mlb->nentries));
|
||||||
@@ -308,15 +340,28 @@ MLB *mlb_rsx_open(
|
|||||||
unrad50(WORD(ent + 2), radname + 3);
|
unrad50(WORD(ent + 2), radname + 3);
|
||||||
radname[6] = 0;
|
radname[6] = 0;
|
||||||
|
|
||||||
// fprintf(stderr, "entry %d: \"%s\" %02x%02x.%02x%02x\n",
|
#if MLBDEBUG_OPEN
|
||||||
// j, radname,
|
fprintf(stderr, "entry %d: \"%s\" %02x%02x.%02x%02x\n",
|
||||||
// ent[5] & 0xFF, ent[4] & 0xFF, ent[7] & 0xFF, ent[6] & 0xFF);
|
j, radname,
|
||||||
|
ent[5] & 0xFF, ent[4] & 0xFF, ent[7] & 0xFF, ent[6] & 0xFF);
|
||||||
|
#endif
|
||||||
trim(radname);
|
trim(radname);
|
||||||
|
if (radname[0] == '\0' || strchr(radname, ' ')) {
|
||||||
|
fprintf(stderr, "mlb_rsx_open error: entry with space in name\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
mlb->directory[j].label = memcheck(strdup(radname));
|
mlb->directory[j].label = memcheck(strdup(radname));
|
||||||
mlb->directory[j].position = BYTEPOS(ent);
|
mlb->directory[j].position = BYTEPOS(ent);
|
||||||
// fprintf(stderr, "entry %d: \"%s\" bytepos=%d\n", j, mlb->directory[j].label, mlb->directory[j].position);
|
#if MLBDEBUG_OPEN
|
||||||
|
fprintf(stderr, "entry %d: \"%s\" bytepos=%ld\n", j, mlb->directory[j].label, mlb->directory[j].position);
|
||||||
|
#endif
|
||||||
mlb->directory[j].length = -1;
|
mlb->directory[j].length = -1;
|
||||||
|
|
||||||
|
if (mlb->directory[j].position < BLOCKSIZE) {
|
||||||
|
fprintf(stderr, "mlb_rsx_open error: bad entry: position\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buff);
|
free(buff);
|
||||||
@@ -324,6 +369,14 @@ MLB *mlb_rsx_open(
|
|||||||
|
|
||||||
/* Done. Return the struct that represents the opened MLB. */
|
/* Done. Return the struct that represents the opened MLB. */
|
||||||
return mlb;
|
return mlb;
|
||||||
|
|
||||||
|
error:
|
||||||
|
#if MLBDEBUG_OPEN
|
||||||
|
fprintf(stderr, "(mlb_rsx_open closing '%s' due to errors)\n", name);
|
||||||
|
#endif
|
||||||
|
mlb_rsx_close(mlb); /* Sorry, bad file. */
|
||||||
|
free(buff);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mlb_rsx_close discards MLB and closes the file. */
|
/* mlb_rsx_close discards MLB and closes the file. */
|
||||||
@@ -367,28 +420,38 @@ BUFFER *mlb_rsx_entry(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i >= mlb->nentries) {
|
if (i >= mlb->nentries) {
|
||||||
// fprintf(stderr, "mlb_rsx_entry: %s not found\n", name);
|
#if MLBDEBUG_ENTRY
|
||||||
|
fprintf(stderr, "mlb_rsx_entry: %s not found\n", name);
|
||||||
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(mlb->fp, ent->position, SEEK_SET);
|
fseek(mlb->fp, ent->position, SEEK_SET);
|
||||||
// fprintf(stderr, "mlb_rsx_entry: %s at position %ld\n", name, (long)ent->position);
|
#if MLBDEBUG_ENTRY
|
||||||
|
fprintf(stderr, "mlb_rsx_entry: %s at position %ld\n", name, (long)ent->position);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MODULE_HEADER_SIZE 022
|
#define MODULE_HEADER_SIZE 022
|
||||||
|
|
||||||
if (fread(module_header, MODULE_HEADER_SIZE, 1, mlb->fp) < 1) {
|
if (fread(module_header, MODULE_HEADER_SIZE, 1, mlb->fp) < 1) {
|
||||||
// fprintf(stderr, "mlb_rsx_entry: %s at position %lx can't read 022 bytes\n", name, (long)ent->position);
|
#if MLBDEBUG_ENTRY
|
||||||
|
fprintf(stderr, "mlb_rsx_entry: %s at position %lx can't read 022 bytes\n", name, (long)ent->position);
|
||||||
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (i = 0; i < MODULE_HEADER_SIZE; i++) {
|
#if MLBDEBUG_ENTRY
|
||||||
// fprintf(stderr, "%02x ", module_header[i]);
|
for (i = 0; i < MODULE_HEADER_SIZE; i++) {
|
||||||
// }
|
fprintf(stderr, "%02x ", module_header[i]);
|
||||||
// fprintf(stderr, "\n");
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
#endif
|
||||||
ent->length = (WORD(module_header + 04) << 16) +
|
ent->length = (WORD(module_header + 04) << 16) +
|
||||||
WORD(module_header + 06);
|
WORD(module_header + 06);
|
||||||
ent->length -= MODULE_HEADER_SIZE; /* length is including this header */
|
ent->length -= MODULE_HEADER_SIZE; /* length is including this header */
|
||||||
// fprintf(stderr, "mlb_rsx_entry: %s at position %lx length = %d\n", name, (long)ent->position, ent->length);
|
#if MLBDEBUG_ENTRY
|
||||||
|
fprintf(stderr, "mlb_rsx_entry: %s at position %lx length = %d\n", name, (long)ent->position, ent->length);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (module_header[02] == 1) {
|
if (module_header[02] == 1) {
|
||||||
fprintf(stderr, "mlb_rsx_entry: %s at position %lx deleted entry\n", name, (long)ent->position);
|
fprintf(stderr, "mlb_rsx_entry: %s at position %lx deleted entry\n", name, (long)ent->position);
|
||||||
@@ -418,19 +481,25 @@ BUFFER *mlb_rsx_entry(
|
|||||||
i = fread(bp, 1, ent->length, mlb->fp);
|
i = fread(bp, 1, ent->length, mlb->fp);
|
||||||
bp += i;
|
bp += i;
|
||||||
} else if (module_header[0] & 0x10) {
|
} else if (module_header[0] & 0x10) {
|
||||||
// fprintf(stderr, "mlb_rsx_entry: %s at position %lx variable length records\n", name, (long)ent->position);
|
#if MLBDEBUG_ENTRY
|
||||||
|
fprintf(stderr, "mlb_rsx_entry: %s at position %lx variable length records\n", name, (long)ent->position);
|
||||||
|
#endif
|
||||||
/* Variable length records with size before them */
|
/* Variable length records with size before them */
|
||||||
i = ent->length;
|
i = ent->length;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
// fprintf(stderr, "file offset:$%lx\n", (long)ftell(mlb->fp));
|
#if MLBDEBUG_ENTRY
|
||||||
|
fprintf(stderr, "file offset:$%lx\n", (long)ftell(mlb->fp));
|
||||||
|
#endif
|
||||||
c = fgetc(mlb->fp); /* Get low byte of length */
|
c = fgetc(mlb->fp); /* Get low byte of length */
|
||||||
length = c & 0xFF;
|
length = c & 0xFF;
|
||||||
c = fgetc(mlb->fp); /* Get high byte */
|
c = fgetc(mlb->fp); /* Get high byte */
|
||||||
length += (c & 0xFF) << 8;
|
length += (c & 0xFF) << 8;
|
||||||
i -= 2;
|
i -= 2;
|
||||||
// fprintf(stderr, "line length: %d $%x\n", length, length);
|
#if MLBDEBUG_ENTRY
|
||||||
|
fprintf(stderr, "line length: %d $%x\n", length, length);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Odd lengths are padded with an extra 0 byte */
|
/* Odd lengths are padded with an extra 0 byte */
|
||||||
int padded = length & 1;
|
int padded = length & 1;
|
||||||
@@ -441,7 +510,9 @@ BUFFER *mlb_rsx_entry(
|
|||||||
|
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
c = fgetc(mlb->fp); /* Get macro byte */
|
c = fgetc(mlb->fp); /* Get macro byte */
|
||||||
//fprintf(stderr, "%02x %c length=%d\n", c, c, length);
|
#if MLBDEBUG_ENTRY
|
||||||
|
fprintf(stderr, "%02x %c length=%d\n", c, c, length);
|
||||||
|
#endif
|
||||||
i--;
|
i--;
|
||||||
length--;
|
length--;
|
||||||
if (c == '\r' || c == 0) /* If it's a carriage return or 0,
|
if (c == '\r' || c == 0) /* If it's a carriage return or 0,
|
||||||
@@ -452,12 +523,16 @@ BUFFER *mlb_rsx_entry(
|
|||||||
*bp++ = '\n';
|
*bp++ = '\n';
|
||||||
if (padded) {
|
if (padded) {
|
||||||
c = fgetc(mlb->fp); /* Get pad byte; need not be 0. */
|
c = fgetc(mlb->fp); /* Get pad byte; need not be 0. */
|
||||||
//fprintf(stderr, "pad byte %02x %c length=%d\n", c, c, length);
|
#if MLBDEBUG_ENTRY
|
||||||
|
fprintf(stderr, "pad byte %02x %c length=%d\n", c, c, length);
|
||||||
|
#endif
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// fprintf(stderr, "mlb_rsx_entry: %s at position %lx byte stream records\n", name, (long)ent->position);
|
#if MLBDEBUG_ENTRY
|
||||||
|
fprintf(stderr, "mlb_rsx_entry: %s at position %lx byte stream records\n", name, (long)ent->position);
|
||||||
|
#endif
|
||||||
for (i = 0; i < ent->length; i++) {
|
for (i = 0; i < ent->length; i++) {
|
||||||
c = fgetc(mlb->fp); /* Get macro byte */
|
c = fgetc(mlb->fp); /* Get macro byte */
|
||||||
if (c == '\r' || c == 0) /* If it's a carriage return or 0,
|
if (c == '\r' || c == 0) /* If it's a carriage return or 0,
|
||||||
|
|||||||
16
mlb-rt11.c
16
mlb-rt11.c
@@ -59,12 +59,20 @@ static void mlb_rt11_extract(
|
|||||||
MLB *mlb);
|
MLB *mlb);
|
||||||
|
|
||||||
struct mlb_vtbl mlb_rt11_vtbl = {
|
struct mlb_vtbl mlb_rt11_vtbl = {
|
||||||
mlb_rt11_open,
|
.mlb_open = mlb_rt11_open,
|
||||||
mlb_rt11_entry,
|
.mlb_entry = mlb_rt11_entry,
|
||||||
mlb_rt11_extract,
|
.mlb_extract = mlb_rt11_extract,
|
||||||
mlb_rt11_close,
|
.mlb_close = mlb_rt11_close,
|
||||||
|
.mlb_is_rt11 = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format description:
|
||||||
|
* http://www.bitsavers.org/pdf/dec/pdp11/rt11/v5.6_Aug91/AA-PD6PA-TC_RT-11_Volume_and_File_Formats_Manual_Aug91.pdf
|
||||||
|
* pages 2-27 ff.
|
||||||
|
*
|
||||||
|
* A MLB Macro Library Header differs a lot from an Object Library Header.
|
||||||
|
*/
|
||||||
#define WORD(cp) ((*(cp) & 0xff) + ((*((cp)+1) & 0xff) << 8))
|
#define WORD(cp) ((*(cp) & 0xff) + ((*((cp)+1) & 0xff) << 8))
|
||||||
|
|
||||||
/* BYTEPOS calculates the byte position within the macro libray file.
|
/* BYTEPOS calculates the byte position within the macro libray file.
|
||||||
|
|||||||
1
mlb.h
1
mlb.h
@@ -62,6 +62,7 @@ typedef struct mlb_vtbl {
|
|||||||
BUFFER *(*mlb_entry)(MLB *mlb, char *name);
|
BUFFER *(*mlb_entry)(MLB *mlb, char *name);
|
||||||
void (*mlb_extract)(MLB *mlb);
|
void (*mlb_extract)(MLB *mlb);
|
||||||
void (*mlb_close)(MLB *mlb);
|
void (*mlb_close)(MLB *mlb);
|
||||||
|
int mlb_is_rt11;
|
||||||
} MLB_VTBL;
|
} MLB_VTBL;
|
||||||
|
|
||||||
extern MLB *mlb_open(
|
extern MLB *mlb_open(
|
||||||
|
|||||||
34
mlb2.c
34
mlb2.c
@@ -35,6 +35,7 @@ DAMAGE.
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "mlb.h"
|
#include "mlb.h"
|
||||||
|
#include "object.h"
|
||||||
|
|
||||||
MLB_VTBL *mlb_vtbls[] = {
|
MLB_VTBL *mlb_vtbls[] = {
|
||||||
&mlb_rsx_vtbl,
|
&mlb_rsx_vtbl,
|
||||||
@@ -42,25 +43,46 @@ MLB_VTBL *mlb_vtbls[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
MLB *mlb_open(
|
static MLB *mlb_open_fmt(
|
||||||
char *name,
|
char *name,
|
||||||
int allow_object_library)
|
int allow_object_library,
|
||||||
|
int object_format)
|
||||||
{
|
{
|
||||||
MLB_VTBL *vtbl;
|
MLB_VTBL *vtbl;
|
||||||
MLB *mlb = NULL;
|
MLB *mlb = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; (vtbl = mlb_vtbls[i]); i++) {
|
for (i = 0; (vtbl = mlb_vtbls[i]); i++) {
|
||||||
mlb = vtbl->mlb_open(name, allow_object_library);
|
if (vtbl->mlb_is_rt11 == object_format) {
|
||||||
if (mlb != NULL) {
|
mlb = vtbl->mlb_open(name, allow_object_library);
|
||||||
mlb->name = memcheck(strdup(name));
|
if (mlb != NULL) {
|
||||||
break;
|
mlb->name = memcheck(strdup(name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mlb;
|
return mlb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MLB *mlb_open(
|
||||||
|
char *name,
|
||||||
|
int allow_object_library)
|
||||||
|
{
|
||||||
|
MLB *mlb = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First try the open function for the currently set object format.
|
||||||
|
* If that fails, try the other one.
|
||||||
|
*/
|
||||||
|
mlb = mlb_open_fmt(name, allow_object_library, rt11);
|
||||||
|
if (mlb == NULL) {
|
||||||
|
mlb = mlb_open_fmt(name, allow_object_library, !rt11);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mlb;
|
||||||
|
}
|
||||||
|
|
||||||
BUFFER *mlb_entry(
|
BUFFER *mlb_entry(
|
||||||
MLB *mlb,
|
MLB *mlb,
|
||||||
char *name)
|
char *name)
|
||||||
|
|||||||
Reference in New Issue
Block a user