mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-21 03:14:19 +08:00
outrdf2.c now uses the same definitions of RDOFF2 format that RDOFF utils.
Export/import/common label size is increased from 33 to 64. Fixed the bug that caused wrong behavior of rdfgetheaderrec() if label length was 32. Changed error codes from numeric values to symbolic constants. Moved some routines from rdfdump.c to rdoff.c. They will be utilized also by rdfdisasm, which is being developed.
This commit is contained in:
parent
7549d14998
commit
e0c059ab4e
446
output/outrdf2.c
446
output/outrdf2.c
@ -1,10 +1,9 @@
|
||||
/* outrdf2.c output routines for the Netwide Assembler to produce
|
||||
* RDOFF version 2 format object files (which are intended
|
||||
* mainly for use in proprietary projects, as the code to
|
||||
* load and execute them is very simple). They will also be
|
||||
* used for device drivers and possibly some executable files
|
||||
* in the MOSCOW operating system. See Rdoff.txt for
|
||||
* details.
|
||||
/*
|
||||
* outrdf2.c output routines for the Netwide Assembler to produce
|
||||
* RDOFF version 2 format object files, which is used as a
|
||||
* main binary format in the RadiOS (http://radios.sf.net).
|
||||
* Originally Julian planned to use it in his MOSCOW
|
||||
* operating system.
|
||||
*
|
||||
* The Netwide Assembler is copyright (C) 1996-1998 Simon Tatham and
|
||||
* Julian Hall. All rights reserved. The software is
|
||||
@ -23,19 +22,15 @@
|
||||
#include "outform.h"
|
||||
|
||||
/* VERBOSE_WARNINGS: define this to add some extra warnings... */
|
||||
#define VERBOSE_WARNINGS
|
||||
#define VERBOSE_WARNINGS
|
||||
|
||||
#ifdef OF_RDF2
|
||||
|
||||
#define RDF_MAXSEGS 64 /* maximum number of segments - user configurable */
|
||||
#include "rdoff/rdoff.h"
|
||||
|
||||
typedef unsigned short int16;
|
||||
typedef unsigned char byte;
|
||||
/* This signature is written to start of RDOFF files */
|
||||
static const char *RDOFF2Id = RDOFF2_SIGNATURE;
|
||||
|
||||
static const char *RDOFF2Id = "RDOFF2"; /* written to start of RDOFF files */
|
||||
|
||||
|
||||
/* the records that can be found in the RDOFF header */
|
||||
|
||||
/* Note that whenever a segment is referred to in the RDOFF file, its number
|
||||
* is always half of the segment number that NASM uses to refer to it; this
|
||||
@ -44,86 +39,16 @@ static const char *RDOFF2Id = "RDOFF2"; /* written to start of RDOFF files */
|
||||
* allows up to 65533 external labels to be defined; otherwise it would be
|
||||
* 32764. */
|
||||
|
||||
#define RDFREC_RELOC 1
|
||||
#define RDFREC_IMPORT 2
|
||||
#define RDFREC_GLOBAL 3
|
||||
#define RDFREC_DLL 4
|
||||
#define RDFREC_BSS 5
|
||||
#define RDFREC_SEGRELOC 6
|
||||
#define RDFREC_FARIMPORT 7
|
||||
#define RDFREC_MODNAME 8
|
||||
#define RDFREC_COMMON 10
|
||||
#define RDFREC_GENERIC 0
|
||||
|
||||
|
||||
struct RelocRec {
|
||||
byte type; /* must be 1, or 6 for segment base ref */
|
||||
byte reclen; /* set to 8 */
|
||||
byte segment; /* only 0 for code, or 1 for data supported,
|
||||
* but add 64 for relative refs (ie do not require
|
||||
* reloc @ loadtime, only linkage) */
|
||||
long offset; /* from start of segment in which reference is loc'd */
|
||||
byte length; /* 1 2 or 4 bytes */
|
||||
int16 refseg; /* segment to which reference refers to */
|
||||
};
|
||||
|
||||
struct ImportRec {
|
||||
byte type; /* must be 2, or 7 for FAR import */
|
||||
byte reclen; /* equals 3+label length */
|
||||
byte flags; /* SYM_* flags (see below) */
|
||||
int16 segment; /* segment number allocated to the label for reloc
|
||||
* records - label is assumed to be at offset zero
|
||||
* in this segment, so linker must fix up with offset
|
||||
* of segment and of offset within segment */
|
||||
char label[33]; /* zero terminated... should be written to file until
|
||||
* the zero, but not after it - max len = 32 chars */
|
||||
};
|
||||
|
||||
struct ExportRec {
|
||||
byte type; /* must be 3 */
|
||||
byte reclen; /* equals 7+label length */
|
||||
byte flags; /* SYM_* flags (see below) */
|
||||
byte segment; /* segment referred to (0/1) */
|
||||
long offset; /* offset within segment */
|
||||
char label[33]; /* zero terminated as above. max len = 32 chars */
|
||||
};
|
||||
|
||||
struct BSSRec {
|
||||
byte type; /* must be 5 */
|
||||
byte reclen; /* equals 4 */
|
||||
long amount; /* number of bytes BSS to reserve */
|
||||
};
|
||||
|
||||
struct DLLModRec {
|
||||
byte type; /* 4 for DLLRec, 8 for ModRec */
|
||||
byte reclen; /* 1+lib name length for DLLRec, 1+mod name length */
|
||||
char name[128]; /* library to link at load time or module name */
|
||||
};
|
||||
|
||||
struct CommonRec {
|
||||
byte type; /* must be 10 */
|
||||
byte reclen; /* equals 9+label length */
|
||||
int16 segment; /* segment number */
|
||||
long size; /* size of common variable */
|
||||
int16 align; /* alignment (power of two) */
|
||||
char label[33]; /* zero terminated as above. max len = 32 chars */
|
||||
};
|
||||
|
||||
/* Flags for ExportRec */
|
||||
#define SYM_DATA 1
|
||||
#define SYM_FUNCTION 2
|
||||
#define SYM_GLOBAL 4
|
||||
#define SYM_IMPORT 8
|
||||
|
||||
#define COUNT_SEGTYPES 9
|
||||
|
||||
static char * segmenttypes[COUNT_SEGTYPES] = {
|
||||
"null", "text", "code", "data", "comment", "lcomment", "pcomment",
|
||||
"symdebug", "linedebug"
|
||||
"null", "text", "code", "data",
|
||||
"comment", "lcomment", "pcomment",
|
||||
"symdebug", "linedebug"
|
||||
};
|
||||
|
||||
static int segmenttypenumbers[COUNT_SEGTYPES] = {
|
||||
0, 1, 1, 2, 3, 4, 5, 6, 7
|
||||
0, 1, 1, 2, 3, 4, 5, 6, 7
|
||||
};
|
||||
|
||||
/* code for managing buffers needed to separate code and data into individual
|
||||
@ -147,11 +72,11 @@ static FILE *ofile;
|
||||
static efunc error;
|
||||
|
||||
static struct seginfo {
|
||||
char *segname;
|
||||
int segnumber;
|
||||
int16 segtype;
|
||||
int16 segreserved;
|
||||
long seglength;
|
||||
char *segname;
|
||||
int segnumber;
|
||||
uint16 segtype;
|
||||
uint16 segreserved;
|
||||
long seglength;
|
||||
} segments[RDF_MAXSEGS];
|
||||
|
||||
static int nsegments;
|
||||
@ -290,11 +215,15 @@ static long rdf2_section_names(char *name, int pass, int *bits)
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write relocation record
|
||||
*/
|
||||
static void write_reloc_rec(struct RelocRec *r)
|
||||
{
|
||||
char buf[4],*b;
|
||||
|
||||
if (r->refseg != (int16)NO_SEG && (r->refseg & 1)) /* segment base ref */
|
||||
if (r->refseg != (uint16)NO_SEG && (r->refseg & 1)) /* segment base ref */
|
||||
r->type = RDFREC_SEGRELOC;
|
||||
|
||||
r->refseg >>= 1; /* adjust segment nos to RDF rather than NASM */
|
||||
@ -310,37 +239,45 @@ static void write_reloc_rec(struct RelocRec *r)
|
||||
headerlength += r->reclen + 2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write export record
|
||||
*/
|
||||
static void write_export_rec(struct ExportRec *r)
|
||||
{
|
||||
char buf[4], *b;
|
||||
char buf[4], *b;
|
||||
|
||||
r->segment >>= 1;
|
||||
r->segment >>= 1;
|
||||
|
||||
saa_wbytes(header,&r->type,1);
|
||||
saa_wbytes(header,&r->reclen,1);
|
||||
saa_wbytes(header,&r->flags,1);
|
||||
saa_wbytes(header,&r->segment,1);
|
||||
b = buf; WRITELONG(b,r->offset);
|
||||
saa_wbytes(header,buf,4);
|
||||
saa_wbytes(header,r->label,strlen(r->label) + 1);
|
||||
headerlength += r->reclen + 2;
|
||||
saa_wbytes(header, &r->type, 1);
|
||||
saa_wbytes(header, &r->reclen, 1);
|
||||
saa_wbytes(header, &r->flags, 1);
|
||||
saa_wbytes(header, &r->segment, 1);
|
||||
b = buf; WRITELONG(b, r->offset);
|
||||
saa_wbytes(header, buf, 4);
|
||||
saa_wbytes(header, r->label, strlen(r->label) + 1);
|
||||
headerlength += r->reclen + 2;
|
||||
}
|
||||
|
||||
static void write_import_rec(struct ImportRec *r)
|
||||
{
|
||||
char buf[4], *b;
|
||||
char buf[4], *b;
|
||||
|
||||
r->segment >>= 1;
|
||||
r->segment >>= 1;
|
||||
|
||||
saa_wbytes(header,&r->type,1);
|
||||
saa_wbytes(header,&r->reclen,1);
|
||||
saa_wbytes(header,&r->flags,1);
|
||||
b = buf; WRITESHORT(b,r->segment);
|
||||
saa_wbytes(header,buf,2);
|
||||
saa_wbytes(header,r->label,strlen(r->label) + 1);
|
||||
headerlength += r->reclen + 2;
|
||||
saa_wbytes(header, &r->type, 1);
|
||||
saa_wbytes(header, &r->reclen, 1);
|
||||
saa_wbytes(header, &r->flags, 1);
|
||||
b = buf; WRITESHORT(b,r->segment);
|
||||
saa_wbytes(header, buf, 2);
|
||||
saa_wbytes(header, r->label, strlen(r->label) + 1);
|
||||
headerlength += r->reclen + 2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write BSS record
|
||||
*/
|
||||
static void write_bss_rec(struct BSSRec *r)
|
||||
{
|
||||
char buf[4], *b;
|
||||
@ -353,139 +290,160 @@ static void write_bss_rec(struct BSSRec *r)
|
||||
}
|
||||
|
||||
/*
|
||||
* Write common variable record.
|
||||
* Write common variable record
|
||||
*/
|
||||
static void write_common_rec(struct CommonRec *r)
|
||||
{
|
||||
char buf[4], *b;
|
||||
char buf[4], *b;
|
||||
|
||||
r->segment >>= 1;
|
||||
r->segment >>= 1;
|
||||
|
||||
saa_wbytes(header,&r->type,1);
|
||||
saa_wbytes(header,&r->reclen,1);
|
||||
b = buf; WRITESHORT(b,r->segment);
|
||||
saa_wbytes(header,buf,2);
|
||||
b = buf; WRITELONG(b,r->size);
|
||||
saa_wbytes(header,buf,4);
|
||||
b = buf; WRITESHORT(b,r->align);
|
||||
saa_wbytes(header,buf,2);
|
||||
saa_wbytes(header,r->label,strlen(r->label) + 1);
|
||||
headerlength += r->reclen + 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write library record. Also used for module name records.
|
||||
*/
|
||||
static void write_dllmod_rec(struct DLLModRec *r)
|
||||
{
|
||||
saa_wbytes(header,&r->type,1);
|
||||
saa_wbytes(header,&r->reclen,1);
|
||||
saa_wbytes(header,r->name,strlen(r->name) + 1);
|
||||
saa_wbytes(header, &r->type, 1);
|
||||
saa_wbytes(header, &r->reclen, 1);
|
||||
b = buf; WRITESHORT(b,r->segment);
|
||||
saa_wbytes(header, buf, 2);
|
||||
b = buf; WRITELONG(b, r->size);
|
||||
saa_wbytes(header,buf,4);
|
||||
b = buf; WRITESHORT(b, r->align);
|
||||
saa_wbytes(header, buf, 2);
|
||||
saa_wbytes(header, r->label, strlen(r->label) + 1);
|
||||
headerlength += r->reclen + 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write library record
|
||||
*/
|
||||
static void write_dll_rec(struct DLLRec *r)
|
||||
{
|
||||
saa_wbytes(header,&r->type,1);
|
||||
saa_wbytes(header,&r->reclen,1);
|
||||
saa_wbytes(header, r->libname, strlen(r->libname) + 1);
|
||||
headerlength += r->reclen + 2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write module name record
|
||||
*/
|
||||
static void write_modname_rec(struct ModRec *r)
|
||||
{
|
||||
saa_wbytes(header,&r->type,1);
|
||||
saa_wbytes(header,&r->reclen,1);
|
||||
saa_wbytes(header, r->modname, strlen(r->modname) + 1);
|
||||
headerlength += r->reclen + 2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle export, import and common records.
|
||||
*/
|
||||
static void rdf2_deflabel(char *name, long segment, long offset,
|
||||
int is_global, char *special)
|
||||
{
|
||||
struct ExportRec r;
|
||||
struct ImportRec ri;
|
||||
struct CommonRec ci;
|
||||
static int farsym = 0;
|
||||
static int i;
|
||||
byte symflags = 0;
|
||||
struct ExportRec r;
|
||||
struct ImportRec ri;
|
||||
struct CommonRec ci;
|
||||
static int farsym = 0;
|
||||
static int i;
|
||||
byte symflags = 0;
|
||||
int len;
|
||||
|
||||
if (is_global == 2) {
|
||||
/* Common variable */
|
||||
ci.type = RDFREC_COMMON;
|
||||
ci.size = offset;
|
||||
ci.segment = segment;
|
||||
strncpy(ci.label, name, 32);
|
||||
ci.label[32] = 0;
|
||||
ci.reclen = 9 + strlen(ci.label);
|
||||
ci.align = 0;
|
||||
/* Check if the label length is OK */
|
||||
if ((len = strlen(name)) >= EXIM_LABEL_MAX) {
|
||||
error(ERR_NONFATAL, "label size exceeds %d bytes", EXIM_LABEL_MAX);
|
||||
return;
|
||||
}
|
||||
if (!len) {
|
||||
error(ERR_NONFATAL, "zero-length label");
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_global == 2) {
|
||||
/* Common variable */
|
||||
ci.type = RDFREC_COMMON;
|
||||
ci.size = offset;
|
||||
ci.segment = segment;
|
||||
strcpy(ci.label, name);
|
||||
ci.reclen = 9 + len;
|
||||
ci.align = 0;
|
||||
|
||||
/*
|
||||
* Check the special text to see if it's a valid number and power
|
||||
* of two; if so, store it as the alignment for the common variable.
|
||||
*/
|
||||
/*
|
||||
* Check the special text to see if it's a valid number and power
|
||||
* of two; if so, store it as the alignment for the common variable.
|
||||
*/
|
||||
if (special) {
|
||||
int err;
|
||||
ci.align = readnum(special, &err);
|
||||
if (err)
|
||||
error(ERR_NONFATAL, "alignment constraint `%s' is not a"
|
||||
" valid number", special);
|
||||
else if ( (ci.align | (ci.align-1)) != 2*ci.align - 1)
|
||||
error(ERR_NONFATAL, "alignment constraint `%s' is not a"
|
||||
" power of two", special);
|
||||
}
|
||||
write_common_rec(&ci);
|
||||
}
|
||||
|
||||
/* We don't care about local labels or fix-up hints */
|
||||
if (is_global != 1) return;
|
||||
|
||||
if (special) {
|
||||
int err;
|
||||
ci.align = readnum(special, &err);
|
||||
if (err) error(ERR_NONFATAL, "alignment constraint `%s' is not a"
|
||||
" valid number", special);
|
||||
else if ( (ci.align | (ci.align-1)) != 2*ci.align - 1)
|
||||
error(ERR_NONFATAL, "alignment constraint `%s' is not a"
|
||||
" power of two", special);
|
||||
}
|
||||
write_common_rec(&ci);
|
||||
}
|
||||
|
||||
/* We don't care about local labels or fix-up hints */
|
||||
if (is_global != 1) return;
|
||||
|
||||
if (special) {
|
||||
while(*special == ' ' || *special == '\t') special++;
|
||||
while(*special == ' ' || *special == '\t') special++;
|
||||
|
||||
if (!nasm_strnicmp(special, "export", 6)) {
|
||||
special += 6;
|
||||
symflags |= SYM_GLOBAL;
|
||||
}
|
||||
else if (!nasm_strnicmp(special, "import", 6)) {
|
||||
special += 6;
|
||||
symflags |= SYM_IMPORT;
|
||||
if (!nasm_strnicmp(special, "export", 6)) {
|
||||
special += 6;
|
||||
symflags |= SYM_GLOBAL;
|
||||
} else if (!nasm_strnicmp(special, "import", 6)) {
|
||||
special += 6;
|
||||
symflags |= SYM_IMPORT;
|
||||
}
|
||||
|
||||
if (*special) {
|
||||
while (isspace(*special)) special++;
|
||||
if (!nasm_stricmp(special, "far")) {
|
||||
farsym = 1;
|
||||
} else if (!nasm_stricmp(special, "near")) {
|
||||
farsym = 0;
|
||||
} else if (!nasm_stricmp(special, "proc") ||
|
||||
!nasm_stricmp(special, "function")) {
|
||||
symflags |= SYM_FUNCTION;
|
||||
} else if (!nasm_stricmp(special, "data") ||
|
||||
!nasm_stricmp(special, "object")) {
|
||||
symflags |= SYM_DATA;
|
||||
} else
|
||||
error(ERR_NONFATAL, "unrecognised symbol type `%s'", special);
|
||||
}
|
||||
}
|
||||
|
||||
if (*special) {
|
||||
while(isspace(*special)) special++;
|
||||
if (!nasm_stricmp(special, "far")) {
|
||||
farsym = 1;
|
||||
}
|
||||
else if (!nasm_stricmp(special, "near")) {
|
||||
farsym = 0;
|
||||
}
|
||||
else if (!nasm_stricmp(special, "proc") ||
|
||||
!nasm_stricmp(special, "function")) {
|
||||
symflags |= SYM_FUNCTION;
|
||||
}
|
||||
else if (!nasm_stricmp(special, "data") ||
|
||||
!nasm_stricmp(special, "object")) {
|
||||
symflags |= SYM_DATA;
|
||||
}
|
||||
else
|
||||
error(ERR_NONFATAL, "unrecognised symbol type `%s'", special);
|
||||
}
|
||||
}
|
||||
if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
|
||||
error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
|
||||
error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < nsegments; i++) {
|
||||
if (segments[i].segnumber == segment>>1) break;
|
||||
}
|
||||
|
||||
for (i = 0; i < nsegments; i++) {
|
||||
if (segments[i].segnumber == segment>>1) break;
|
||||
}
|
||||
if (i >= nsegments) { /* EXTERN declaration */
|
||||
ri.type = farsym ? RDFREC_FARIMPORT : RDFREC_IMPORT;
|
||||
if (symflags & SYM_GLOBAL)
|
||||
error(ERR_NONFATAL, "symbol type conflict - EXTERN cannot be EXPORT");
|
||||
ri.flags = symflags;
|
||||
ri.segment = segment;
|
||||
strncpy(ri.label,name,32);
|
||||
ri.label[32] = 0;
|
||||
ri.reclen = 4 + strlen(ri.label);
|
||||
write_import_rec(&ri);
|
||||
} else if (is_global) {
|
||||
r.type = RDFREC_GLOBAL;
|
||||
if (symflags & SYM_IMPORT)
|
||||
error(ERR_NONFATAL, "symbol type conflict - GLOBAL cannot be IMPORT");
|
||||
r.flags = symflags;
|
||||
r.segment = segment;
|
||||
r.offset = offset;
|
||||
strncpy(r.label,name,32);
|
||||
r.label[32] = 0;
|
||||
r.reclen = 7 + strlen(r.label);
|
||||
write_export_rec(&r);
|
||||
}
|
||||
if (i >= nsegments) { /* EXTERN declaration */
|
||||
ri.type = farsym ? RDFREC_FARIMPORT : RDFREC_IMPORT;
|
||||
if (symflags & SYM_GLOBAL)
|
||||
error(ERR_NONFATAL, "symbol type conflict - EXTERN cannot be EXPORT");
|
||||
ri.flags = symflags;
|
||||
ri.segment = segment;
|
||||
strcpy(ri.label, name);
|
||||
ri.reclen = 4 + len;
|
||||
write_import_rec(&ri);
|
||||
} else if (is_global) {
|
||||
r.type = RDFREC_GLOBAL; /* GLOBAL declaration */
|
||||
if (symflags & SYM_IMPORT)
|
||||
error(ERR_NONFATAL, "symbol type conflict - GLOBAL cannot be IMPORT");
|
||||
r.flags = symflags;
|
||||
r.segment = segment;
|
||||
r.offset = offset;
|
||||
strcpy(r.label, name);
|
||||
r.reclen = 7 + len;
|
||||
write_export_rec(&r);
|
||||
}
|
||||
}
|
||||
|
||||
static void membufwrite(int segment, const void * data, int bytes)
|
||||
@ -681,8 +639,7 @@ static void rdf2_cleanup (int debuginfo) {
|
||||
/* generate the output file... */
|
||||
fwrite(RDOFF2Id,6,1,ofile); /* file type magic number */
|
||||
|
||||
if (bsslength != 0) /* reserve BSS */
|
||||
{
|
||||
if (bsslength != 0) { /* reserve BSS */
|
||||
bs.type = RDFREC_BSS;
|
||||
bs.amount = bsslength;
|
||||
bs.reclen = 4;
|
||||
@ -730,25 +687,38 @@ static long rdf2_segbase (long segment) {
|
||||
return segment;
|
||||
}
|
||||
|
||||
static int rdf2_directive (char *directive, char *value, int pass) {
|
||||
struct DLLModRec r;
|
||||
|
||||
/*
|
||||
* Handle RDOFF2 specific directives
|
||||
*/
|
||||
static int rdf2_directive (char *directive, char *value, int pass)
|
||||
{
|
||||
int n;
|
||||
|
||||
/* Check if the name length is OK */
|
||||
if ((n = strlen(value)) >= MODLIB_NAME_MAX) {
|
||||
error(ERR_NONFATAL, "name size exceeds %d bytes", MODLIB_NAME_MAX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! strcmp(directive, "library")) {
|
||||
if (pass == 1) {
|
||||
struct DLLRec r;
|
||||
r.type = RDFREC_DLL;
|
||||
r.reclen=strlen(value)+1;
|
||||
strcpy(r.name, value);
|
||||
write_dllmod_rec(&r);
|
||||
r.reclen = n+1;
|
||||
strcpy(r.libname, value);
|
||||
write_dll_rec(&r);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (! strcmp(directive, "module")) {
|
||||
if (pass == 1) {
|
||||
struct ModRec r;
|
||||
r.type = RDFREC_MODNAME;
|
||||
r.reclen=strlen(value)+1;
|
||||
strcpy(r.name, value);
|
||||
write_dllmod_rec(&r);
|
||||
r.reclen = n+1;
|
||||
strcpy(r.modname, value);
|
||||
write_modname_rec(&r);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -42,8 +42,8 @@ PROGRAMS = rdfdump$(X) ldrdf$(X) rdx$(X) rdflib$(X) \
|
||||
|
||||
all: $(PROGRAMS)
|
||||
|
||||
rdfdump$(X): rdfdump.$(O)
|
||||
$(CC) $(LDFLAGS) -o rdfdump$(X) rdfdump.$(O)
|
||||
rdfdump$(X): rdfdump.$(O) rdoff.$(O)
|
||||
$(CC) $(LDFLAGS) -o rdfdump$(X) rdfdump.$(O) rdoff.$(O)
|
||||
ldrdf$(X): ldrdf.$(O) $(LDRDFLIBS)
|
||||
$(CC) $(LDFLAGS) -o ldrdf$(X) ldrdf.$(O) $(LDRDFLIBS)
|
||||
rdx$(X): rdx.$(O) $(RDXLIBS)
|
||||
|
@ -33,8 +33,8 @@ RDXLIBS = rdoff.o rdfload.o symtab.o hash.o collectn.o
|
||||
|
||||
all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com
|
||||
|
||||
rdfdump: rdfdump.o
|
||||
$(CC) -o rdfdump rdfdump.o
|
||||
rdfdump: rdfdump.o rdoff.o
|
||||
$(CC) -o rdfdump rdfdump.o rdoff.o
|
||||
|
||||
ldrdf: ldrdf.o $(LDRDFLIBS)
|
||||
$(CC) -o ldrdf ldrdf.o $(LDRDFLIBS)
|
||||
|
@ -33,8 +33,8 @@ RDXLIBS = rdoff.o rdfload.o symtab.o collectn.o hash.o
|
||||
|
||||
all: rdfdump ldrdf rdx rdflib rdf2bin
|
||||
|
||||
rdfdump: rdfdump.o
|
||||
$(CC) $(LDFLAGS) -o rdfdump rdfdump.o $(LIBS)
|
||||
rdfdump: rdfdump.o rdoff.o
|
||||
$(CC) $(LDFLAGS) -o rdfdump rdfdump.o rdoff.o $(LIBS)
|
||||
ldrdf: ldrdf.o $(LDRDFLIBS)
|
||||
$(CC) $(LDFLAGS) -o ldrdf ldrdf.o $(LDRDFLIBS) $(LIBS)
|
||||
rdx: rdx.o $(RDXLIBS)
|
||||
|
@ -33,8 +33,8 @@ RDXLIBS = rdoff.o rdfload.o symtab.o hash.o collectn.o
|
||||
|
||||
all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com
|
||||
|
||||
rdfdump: rdfdump.o
|
||||
$(CC) -o rdfdump rdfdump.o
|
||||
rdfdump: rdfdump.o rdoff.o
|
||||
$(CC) -o rdfdump rdfdump.o rdoff.o
|
||||
|
||||
ldrdf: ldrdf.o $(LDRDFLIBS)
|
||||
$(CC) -o ldrdf ldrdf.o $(LDRDFLIBS)
|
||||
|
@ -181,5 +181,5 @@ file for a comment containing the word 'TODO'. A brief list is given here:
|
||||
MAINTAINERS
|
||||
===========
|
||||
|
||||
Yuri Zaporogets <yuriz@ukr.net> - primary maintainer
|
||||
Yuri Zaporogets <yuriz@users.sf.net> - primary maintainer
|
||||
Julian Hall <jules@dsf.org.uk> - original designer and author
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* collectn.c Implements variable length pointer arrays [collections]
|
||||
/*
|
||||
* collectn.c - implements variable length pointer arrays [collections].
|
||||
*
|
||||
* This file is public domain.
|
||||
*/
|
||||
@ -8,33 +9,36 @@
|
||||
|
||||
void collection_init(Collection * c)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++) c->p[i] = NULL;
|
||||
c->next = NULL;
|
||||
for (i = 0; i < 32; i++)
|
||||
c->p[i] = NULL;
|
||||
c->next = NULL;
|
||||
}
|
||||
|
||||
void ** colln(Collection * c, int index)
|
||||
void **colln(Collection * c, int index)
|
||||
{
|
||||
while (index >= 32) {
|
||||
index -= 32;
|
||||
if (c->next == NULL) {
|
||||
c->next = malloc(sizeof(Collection));
|
||||
collection_init(c->next);
|
||||
while (index >= 32) {
|
||||
index -= 32;
|
||||
if (c->next == NULL) {
|
||||
c->next = malloc(sizeof(Collection));
|
||||
collection_init(c->next);
|
||||
}
|
||||
c = c->next;
|
||||
}
|
||||
c = c->next;
|
||||
}
|
||||
return &(c->p[index]);
|
||||
return &(c->p[index]);
|
||||
}
|
||||
|
||||
void collection_reset(Collection *c)
|
||||
void collection_reset(Collection * c)
|
||||
{
|
||||
int i;
|
||||
if (c->next) {
|
||||
collection_reset(c->next);
|
||||
free(c->next);
|
||||
}
|
||||
int i;
|
||||
|
||||
c->next = NULL;
|
||||
for (i = 0; i < 32; i++) c->p[i] = NULL;
|
||||
if (c->next) {
|
||||
collection_reset(c->next);
|
||||
free(c->next);
|
||||
}
|
||||
|
||||
c->next = NULL;
|
||||
for (i = 0; i < 32; i++)
|
||||
c->p[i] = NULL;
|
||||
}
|
||||
|
@ -1,17 +1,18 @@
|
||||
/* collectn.h Header file for 'collection' abstract data type
|
||||
/*
|
||||
* collectn.h - header file for 'collection' abstract data type.
|
||||
*
|
||||
* This file is public domain, and does not come under the NASM license.
|
||||
* It, along with 'collectn.c' implements what is basically a variable
|
||||
* length array (of pointers)
|
||||
* length array (of pointers).
|
||||
*/
|
||||
|
||||
#ifndef _COLLECTN_H
|
||||
#define _COLLECTN_H
|
||||
|
||||
typedef struct tagCollection {
|
||||
void *p[32]; /* array of pointers to objects */
|
||||
void *p[32]; /* array of pointers to objects */
|
||||
|
||||
struct tagCollection *next;
|
||||
struct tagCollection *next;
|
||||
} Collection;
|
||||
|
||||
void collection_init(Collection * c);
|
||||
@ -19,4 +20,3 @@ void ** colln(Collection * c, int index);
|
||||
void collection_reset(Collection * c);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
Copyright @copyright{} 2002-2003 Netwide Assembler Project.
|
||||
Written by Yuri Zaporogets @email{yuriz@@ukr.net}
|
||||
Copyright @copyright{} 2002-2004 Netwide Assembler Project.
|
||||
Written by Yuri Zaporogets @email{yuriz@@users.sf.net}
|
||||
Based on various sources and notes written by Julian Hall @email{jules@@dsf.org.uk}
|
||||
Distributed under GNU documentation license.
|
||||
@end ifinfo
|
||||
|
@ -92,4 +92,3 @@ hash (const char *name)
|
||||
return (hashval);
|
||||
|
||||
}
|
||||
|
||||
|
113
rdoff/ldrdf.c
113
rdoff/ldrdf.c
@ -2,7 +2,7 @@
|
||||
* ldrdf.c - RDOFF Object File linker/loader main program.
|
||||
*
|
||||
* Copyright (c) 1996,99 Julian Hall. All rights reserved.
|
||||
* Copyright (c) 2000-2003 RET & COM Research.
|
||||
* Improvements and fixes (c) 1999-2004 RET & COM Research.
|
||||
*
|
||||
* This file is distributed under the terms and conditions of the
|
||||
* GNU Lesser Public License (LGPL), version 2.1.
|
||||
@ -28,6 +28,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define RDOFF_UTILS
|
||||
|
||||
#include "rdoff.h"
|
||||
#include "symtab.h"
|
||||
#include "collectn.h"
|
||||
@ -36,7 +38,6 @@
|
||||
|
||||
#define LDRDF_VERSION "1.07"
|
||||
|
||||
#define RDF_MAXSEGS 64
|
||||
/* #define STINGY_MEMORY */
|
||||
|
||||
/* =======================================================================
|
||||
@ -70,8 +71,8 @@ struct modulenode {
|
||||
*/
|
||||
|
||||
void processmodule(const char * filename, struct modulenode * mod);
|
||||
int allocnewseg(int16 type,int16 reserved);
|
||||
int findsegment(int16 type,int16 reserved);
|
||||
int allocnewseg(uint16 type,uint16 reserved);
|
||||
int findsegment(uint16 type,uint16 reserved);
|
||||
void symtab_add(const char * symbol, int segment, long offset);
|
||||
int symtab_get(const char * symbol, int * segment, long * offset);
|
||||
|
||||
@ -219,8 +220,7 @@ void processmodule(const char * filename, struct modulenode * mod)
|
||||
long bssamount = 0;
|
||||
int bss_was_referenced = 0;
|
||||
|
||||
for (seg = 0; seg < mod->f.nsegs; seg++)
|
||||
{
|
||||
for (seg = 0; seg < mod->f.nsegs; seg++) {
|
||||
/*
|
||||
* get the segment configuration for this type from the segment
|
||||
* table. getsegconfig() is a macro, defined in ldsegs.h.
|
||||
@ -418,7 +418,7 @@ int lookformodule(const char *name)
|
||||
* a segment of the type requested, and if one isn't found allocates a
|
||||
* new one.
|
||||
*/
|
||||
int allocnewseg(int16 type,int16 reserved)
|
||||
int allocnewseg(uint16 type,uint16 reserved)
|
||||
{
|
||||
outputseg[nsegs].type = type;
|
||||
outputseg[nsegs].number = nsegs;
|
||||
@ -430,7 +430,7 @@ int allocnewseg(int16 type,int16 reserved)
|
||||
return nsegs++;
|
||||
}
|
||||
|
||||
int findsegment(int16 type,int16 reserved)
|
||||
int findsegment(uint16 type,uint16 reserved)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -463,8 +463,7 @@ void symtab_add(const char * symbol, int segment, long offset)
|
||||
symtabEnt * ste;
|
||||
|
||||
ste = symtabFind(symtab, symbol);
|
||||
if (ste)
|
||||
{
|
||||
if (ste) {
|
||||
if (ste->segment >= 0) {
|
||||
/*
|
||||
* symbol previously defined
|
||||
@ -516,9 +515,7 @@ int symtab_get(const char * symbol, int * segment, long * offset)
|
||||
*segment = -1;
|
||||
*offset = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*segment = ste->segment;
|
||||
*offset = ste->offset;
|
||||
return 1;
|
||||
@ -539,16 +536,13 @@ void add_library(const char * name)
|
||||
errorcount++;
|
||||
return;
|
||||
}
|
||||
if (! libraries)
|
||||
{
|
||||
if (!libraries) {
|
||||
lastlib = libraries = malloc(sizeof(*libraries));
|
||||
if (! libraries) {
|
||||
fprintf(stderr, "ldrdf: out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
lastlib->next = malloc(sizeof(*libraries));
|
||||
if (!lastlib->next) {
|
||||
fprintf(stderr, "ldrdf: out of memory\n");
|
||||
@ -588,13 +582,11 @@ int search_libraries()
|
||||
|
||||
cur = libraries;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
while (cur) {
|
||||
if (options.verbose > 2)
|
||||
printf("scanning library `%s', pass %d...\n", cur->name, pass);
|
||||
|
||||
for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++)
|
||||
{
|
||||
for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++) {
|
||||
if (pass == 2 && lookformodule(f.name)) continue;
|
||||
|
||||
if (options.verbose > 3)
|
||||
@ -613,8 +605,7 @@ int search_libraries()
|
||||
|
||||
keepfile = 0;
|
||||
|
||||
while ((hr = rdfgetheaderrec (&f)))
|
||||
{
|
||||
while ((hr = rdfgetheaderrec (&f))) {
|
||||
/* We're only interested in exports, so skip others */
|
||||
if (hr->type != RDFREC_GLOBAL) continue;
|
||||
|
||||
@ -744,8 +735,7 @@ void write_output(const char * filename)
|
||||
* under 16 bit DOS, but that would be a slower way of doing this.
|
||||
* And you could always use DJGPP...
|
||||
*/
|
||||
for (i = 0; i < nsegs; i++)
|
||||
{
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
outputseg[i].data=NULL;
|
||||
if(!outputseg[i].length) continue;
|
||||
outputseg[i].data = malloc(outputseg[i].length);
|
||||
@ -764,21 +754,18 @@ void write_output(const char * filename)
|
||||
/*
|
||||
* Step through the modules, performing required actions on each one
|
||||
*/
|
||||
for (cur = modules; cur; cur=cur->next)
|
||||
{
|
||||
for (cur = modules; cur; cur=cur->next) {
|
||||
/*
|
||||
* Read the actual segment contents into the correct places in
|
||||
* the newly allocated segments
|
||||
*/
|
||||
|
||||
for (i = 0; i < cur->f.nsegs; i++)
|
||||
{
|
||||
for (i = 0; i < cur->f.nsegs; i++) {
|
||||
int dest = cur->seginfo[i].dest_seg;
|
||||
|
||||
if (dest == -1) continue;
|
||||
if (rdfloadseg(&cur->f, i,
|
||||
outputseg[dest].data + cur->seginfo[i].reloc))
|
||||
{
|
||||
outputseg[dest].data + cur->seginfo[i].reloc)) {
|
||||
rdfperror("ldrdf", cur->name);
|
||||
exit(1);
|
||||
}
|
||||
@ -797,8 +784,7 @@ void write_output(const char * filename)
|
||||
if (cur->f.header_loc)
|
||||
rdfheaderrewind(&cur->f);
|
||||
else
|
||||
if (rdfloadseg(&cur->f, RDOFF_HEADER, header))
|
||||
{
|
||||
if (rdfloadseg(&cur->f, RDOFF_HEADER, header)) {
|
||||
rdfperror("ldrdf", cur->name);
|
||||
exit(1);
|
||||
}
|
||||
@ -808,18 +794,16 @@ void write_output(const char * filename)
|
||||
* table for the segments in this module.
|
||||
*/
|
||||
init_seglocations(&segs);
|
||||
for (i = 0; i < cur->f.nsegs; i++)
|
||||
{
|
||||
for (i = 0; i < cur->f.nsegs; i++) {
|
||||
add_seglocation(&segs, cur->f.seg[i].number,
|
||||
cur->seginfo[i].dest_seg, cur->seginfo[i].reloc);
|
||||
}
|
||||
/*
|
||||
* and the BSS segment (doh!)
|
||||
*/
|
||||
add_seglocation (&segs, 2, 2, cur->bss_reloc);
|
||||
add_seglocation(&segs, 2, 2, cur->bss_reloc);
|
||||
|
||||
while ((hr = rdfgetheaderrec(&cur->f)))
|
||||
{
|
||||
while ((hr = rdfgetheaderrec(&cur->f))) {
|
||||
switch(hr->type) {
|
||||
case RDFREC_RELOC: /* relocation record - need to do a fixup */
|
||||
/*
|
||||
@ -834,21 +818,18 @@ void write_output(const char * filename)
|
||||
* case we have to first subtract the amount we've relocated
|
||||
* the containing segment by.
|
||||
*/
|
||||
|
||||
if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset))
|
||||
{
|
||||
if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) {
|
||||
fprintf(stderr, "%s: reloc to undefined segment %04x\n",
|
||||
cur->name, (int) hr->r.refseg);
|
||||
errorcount++;
|
||||
break;
|
||||
}
|
||||
|
||||
isrelative = (hr->r.segment & 64) == 64;
|
||||
hr->r.segment &= 63;
|
||||
isrelative = (hr->r.segment & RDOFF_RELATIVEMASK) == RDOFF_RELATIVEMASK;
|
||||
hr->r.segment &= (RDOFF_RELATIVEMASK-1);
|
||||
|
||||
if (hr->r.segment == 2 ||
|
||||
(localseg = rdffindsegment(&cur->f, hr->r.segment)) == -1)
|
||||
{
|
||||
(localseg = rdffindsegment(&cur->f, hr->r.segment)) == -1) {
|
||||
fprintf(stderr, "%s: reloc from %s segment (%d)\n",
|
||||
cur->name,
|
||||
hr->r.segment == 2 ? "BSS" : "unknown",
|
||||
@ -857,8 +838,8 @@ void write_output(const char * filename)
|
||||
break;
|
||||
}
|
||||
|
||||
if (hr->r.length != 1 && hr->r.length != 2 && hr->r.length!=4)
|
||||
{
|
||||
if (hr->r.length != 1 && hr->r.length != 2 &&
|
||||
hr->r.length != 4 ) {
|
||||
fprintf(stderr, "%s: nonstandard length reloc "
|
||||
"(%d bytes)\n", cur->name, hr->r.length);
|
||||
errorcount++;
|
||||
@ -883,10 +864,10 @@ void write_output(const char * filename)
|
||||
* Then add 'offset' onto the value at data.
|
||||
*/
|
||||
|
||||
if (isrelative) offset -= cur->seginfo[localseg].reloc;
|
||||
switch (hr->r.length)
|
||||
{
|
||||
case 1:
|
||||
if (isrelative)
|
||||
offset -= cur->seginfo[localseg].reloc;
|
||||
switch (hr->r.length) {
|
||||
case 1:
|
||||
offset += *data;
|
||||
if (offset < -127 || offset > 128)
|
||||
fprintf(error_file, "warning: relocation out of range "
|
||||
@ -894,7 +875,7 @@ void write_output(const char * filename)
|
||||
(int)hr->r.segment, hr->r.offset);
|
||||
*data = (char) offset;
|
||||
break;
|
||||
case 2:
|
||||
case 2:
|
||||
offset += * (short *)data;
|
||||
if (offset < -32767 || offset > 32768)
|
||||
fprintf(error_file, "warning: relocation out of range "
|
||||
@ -902,7 +883,7 @@ void write_output(const char * filename)
|
||||
(int)hr->r.segment, hr->r.offset);
|
||||
* (short *)data = (short) offset;
|
||||
break;
|
||||
case 4:
|
||||
case 4:
|
||||
* (long *)data += offset;
|
||||
/* we can't easily detect overflow on this one */
|
||||
break;
|
||||
@ -915,13 +896,12 @@ void write_output(const char * filename)
|
||||
* Otherwise, we need to output a new relocation record
|
||||
* with the references updated segment and offset...
|
||||
*/
|
||||
if (! isrelative || cur->seginfo[localseg].dest_seg != seg)
|
||||
{
|
||||
if (!isrelative || cur->seginfo[localseg].dest_seg != seg) {
|
||||
hr->r.segment = cur->seginfo[localseg].dest_seg;
|
||||
hr->r.offset += cur->seginfo[localseg].reloc;
|
||||
hr->r.refseg = seg;
|
||||
if (isrelative)
|
||||
hr->r.segment += 64;
|
||||
hr->r.segment += RDOFF_RELATIVEMASK;
|
||||
rdfaddheader(rdfheader, hr);
|
||||
}
|
||||
break;
|
||||
@ -1045,8 +1025,7 @@ void write_output(const char * filename)
|
||||
hr->r.segment = cur->seginfo[localseg].dest_seg;
|
||||
hr->r.offset += cur->seginfo[localseg].reloc;
|
||||
|
||||
if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset))
|
||||
{
|
||||
if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) {
|
||||
fprintf(stderr, "%s: segment fixup to undefined "
|
||||
"segment %04x\n", cur->name, (int)hr->r.refseg);
|
||||
errorcount++;
|
||||
@ -1085,8 +1064,7 @@ void write_output(const char * filename)
|
||||
/*
|
||||
* Write the header
|
||||
*/
|
||||
for (i = 0; i < nsegs; i++)
|
||||
{
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
if (i == 2) continue;
|
||||
rdfaddsegment (rdfheader, outputseg[i].length);
|
||||
}
|
||||
@ -1098,9 +1076,8 @@ void write_output(const char * filename)
|
||||
* Step through the segments, one at a time, writing out into
|
||||
* the output file
|
||||
*/
|
||||
for (i = 0; i < nsegs; i++)
|
||||
{
|
||||
int16 s;
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
uint16 s;
|
||||
long l;
|
||||
|
||||
if (i == 2) continue;
|
||||
@ -1154,14 +1131,13 @@ int main(int argc, char ** argv)
|
||||
|
||||
error_file = stderr;
|
||||
|
||||
argc --, argv ++;
|
||||
argc--, argv++;
|
||||
if (argc == 0) usage();
|
||||
while (argc && *argv && **argv == '-' && argv[0][1] != 'l')
|
||||
{
|
||||
while (argc && *argv && **argv == '-' && argv[0][1] != 'l') {
|
||||
switch(argv[0][1]) {
|
||||
case 'r':
|
||||
printf("ldrdf (linker for RDF files) version " LDRDF_VERSION "\n");
|
||||
printf( _RDOFF_H "\n");
|
||||
printf("RDOFF2 revision %s\n", RDOFF2_REVISION);
|
||||
exit(0);
|
||||
case 'v':
|
||||
if (argv[0][2] == '=') {
|
||||
@ -1318,3 +1294,4 @@ int main(int argc, char ** argv)
|
||||
if (errorcount > 0) exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
/* rdf2bin: convert an RDOFF object file to flat binary */
|
||||
/*
|
||||
* rdf2bin.c - convert an RDOFF object file to flat binary
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rdfload.h"
|
||||
#include "rdoff.h"
|
||||
#include "nasmlib.h"
|
||||
|
||||
long origin = 0;
|
||||
|
@ -1,12 +1,14 @@
|
||||
/* rdf2ihx: convert an RDOFF object file to Intel Hex format. This is based
|
||||
on rdf2bin. Note that this program only writes 16-bit HEX. */
|
||||
/*
|
||||
* rdf2ihx.c - convert an RDOFF object file to Intel Hex format.
|
||||
* This is based on rdf2bin.
|
||||
* Note that this program only writes 16-bit HEX.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rdfload.h"
|
||||
#include "rdoff.h"
|
||||
#include "nasmlib.h"
|
||||
#include "symtab.h"
|
||||
|
||||
@ -186,4 +188,3 @@ int main(int argc, char **argv)
|
||||
fclose(of);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
447
rdoff/rdfdump.c
447
rdoff/rdfdump.c
@ -6,74 +6,52 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define RDOFF_UTILS
|
||||
|
||||
#include "rdoff.h"
|
||||
|
||||
#define PROGRAM_VERSION "2.3"
|
||||
|
||||
FILE *infile;
|
||||
|
||||
/* Translate from little endian to local representation */
|
||||
long translatelong(long in)
|
||||
{
|
||||
long r;
|
||||
unsigned char *i;
|
||||
|
||||
i = (unsigned char *)∈
|
||||
r = i[3];
|
||||
r = (r << 8) + i[2];
|
||||
r = (r << 8) + i[1];
|
||||
r = (r << 8) + *i;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int16 translateshort(int16 in)
|
||||
{
|
||||
int r;
|
||||
unsigned char *i;
|
||||
|
||||
i = (unsigned char *)∈
|
||||
r = (i[1] << 8) + *i;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void print_header(long length, int rdf_version)
|
||||
{
|
||||
char buf[129],t,l,s,flags;
|
||||
char buf[129], t, l, s, flags;
|
||||
unsigned char reclen;
|
||||
long o,ll;
|
||||
int16 rs;
|
||||
long o, ll;
|
||||
uint16 rs;
|
||||
|
||||
while (length > 0) {
|
||||
fread(&t,1,1,infile);
|
||||
fread(&t, 1, 1, infile);
|
||||
if (rdf_version >= 2) {
|
||||
fread(&reclen,1,1,infile);
|
||||
fread(&reclen, 1, 1, infile);
|
||||
}
|
||||
switch(t) {
|
||||
case RDFREC_GENERIC: /* generic record */
|
||||
printf(" generic record (length=%d)\n", (int)reclen);
|
||||
switch (t) {
|
||||
case RDFREC_GENERIC: /* generic record */
|
||||
printf(" generic record (length=%d)\n", (int) reclen);
|
||||
fseek(infile, reclen, SEEK_CUR);
|
||||
break;
|
||||
|
||||
case RDFREC_RELOC: /* relocation record */
|
||||
case RDFREC_SEGRELOC: /* segment relocation */
|
||||
fread(&s,1,1,infile);
|
||||
fread(&o,4,1,infile);
|
||||
fread(&l,1,1,infile);
|
||||
fread(&rs,2,1,infile);
|
||||
|
||||
case RDFREC_RELOC: /* relocation record */
|
||||
case RDFREC_SEGRELOC: /* segment relocation */
|
||||
fread(&s, 1, 1, infile);
|
||||
fread(&o, 4, 1, infile);
|
||||
fread(&l, 1, 1, infile);
|
||||
fread(&rs, 2, 1, infile);
|
||||
printf(" %s: location (%04x:%08lx), length %d, "
|
||||
"referred seg %04x\n", t == 1 ? "relocation" : "seg relocation",
|
||||
(int)s,translatelong(o),(int)l,
|
||||
translateshort(rs));
|
||||
if (rdf_version >= 2 && reclen != 8)
|
||||
"referred seg %04x\n", t == 1 ? "relocation" : "seg relocation",
|
||||
(int) s, translatelong(o), (int) l, translateshort(rs));
|
||||
if (rdf_version >= 2 && reclen != 8)
|
||||
printf(" warning: reclen != 8\n");
|
||||
if (rdf_version == 1) length -= 9;
|
||||
if (rdf_version == 1)
|
||||
length -= 9;
|
||||
if (rdf_version == 1 && t == 6)
|
||||
printf(" warning: seg relocation not supported in RDOFF1\n");
|
||||
break;
|
||||
|
||||
case RDFREC_IMPORT: /* import record */
|
||||
case RDFREC_FARIMPORT: /* import far symbol */
|
||||
fread(&flags, 1, 1, infile);
|
||||
break;
|
||||
|
||||
case RDFREC_IMPORT: /* import record */
|
||||
case RDFREC_FARIMPORT: /* import far symbol */
|
||||
fread(&flags, 1, 1, infile);
|
||||
fread(&rs, 2, 1, infile);
|
||||
ll = 0;
|
||||
|
||||
@ -82,22 +60,25 @@ void print_header(long length, int rdf_version)
|
||||
fread(&buf[ll], 1, 1, infile);
|
||||
} while (buf[ll++]);
|
||||
} else {
|
||||
for (;ll < reclen - 3; ll++)
|
||||
for (; ll < reclen - 3; ll++)
|
||||
fread(&buf[ll], 1, 1, infile);
|
||||
}
|
||||
}
|
||||
|
||||
if (t == 7)
|
||||
printf("far ");
|
||||
printf((flags & SYM_IMPORT) ? " import" : " extern");
|
||||
if (flags & SYM_FUNCTION) printf(" proc");
|
||||
if (flags & SYM_DATA) printf(" data");
|
||||
if (flags & SYM_FUNCTION)
|
||||
printf(" proc");
|
||||
if (flags & SYM_DATA)
|
||||
printf(" data");
|
||||
printf(": segment %04x = %s\n", translateshort(rs), buf);
|
||||
if (rdf_version == 1) length -= ll + 3;
|
||||
if (rdf_version == 1)
|
||||
length -= ll + 3;
|
||||
if (rdf_version == 1 && t == 7)
|
||||
printf (" warning: far import not supported in RDOFF1\n");
|
||||
break;
|
||||
|
||||
case RDFREC_GLOBAL: /* export record */
|
||||
printf(" warning: far import not supported in RDOFF1\n");
|
||||
break;
|
||||
|
||||
case RDFREC_GLOBAL: /* export record */
|
||||
fread(&flags, 1, 1, infile);
|
||||
fread(&s, 1, 1, infile);
|
||||
fread(&o, 4, 1, infile);
|
||||
@ -105,228 +86,218 @@ void print_header(long length, int rdf_version)
|
||||
|
||||
if (rdf_version == 1) {
|
||||
do {
|
||||
fread(&buf[ll], 1, 1, infile);
|
||||
fread(&buf[ll], 1, 1, infile);
|
||||
} while (buf[ll++]);
|
||||
} else {
|
||||
for (; ll < reclen - 6; ll ++)
|
||||
fread(&buf[ll], 1, 1, infile);
|
||||
}
|
||||
printf((flags & SYM_GLOBAL) ? " export" : " public");
|
||||
if (flags & SYM_FUNCTION) printf(" proc");
|
||||
if (flags & SYM_DATA) printf(" data");
|
||||
printf(": (%04x:%08lx) = %s\n", (int)s, translatelong(o), buf);
|
||||
if (rdf_version == 1) length -= ll + 6;
|
||||
for (; ll < reclen - 6; ll++)
|
||||
fread(&buf[ll], 1, 1, infile);
|
||||
}
|
||||
printf((flags & SYM_GLOBAL) ? " export" : " public");
|
||||
if (flags & SYM_FUNCTION)
|
||||
printf(" proc");
|
||||
if (flags & SYM_DATA)
|
||||
printf(" data");
|
||||
printf(": (%04x:%08lx) = %s\n", (int) s, translatelong(o), buf);
|
||||
if (rdf_version == 1)
|
||||
length -= ll + 6;
|
||||
break;
|
||||
|
||||
case RDFREC_DLL: /* DLL and Module records */
|
||||
|
||||
case RDFREC_DLL: /* DLL and Module records */
|
||||
case RDFREC_MODNAME:
|
||||
ll = 0;
|
||||
if (rdf_version == 1) {
|
||||
do {
|
||||
fread(&buf[ll],1,1,infile);
|
||||
fread(&buf[ll], 1, 1, infile);
|
||||
} while (buf[ll++]);
|
||||
} else {
|
||||
for (; ll < reclen; ll++)
|
||||
fread(&buf[ll], 1, 1, infile);
|
||||
}
|
||||
if (t==4) printf(" dll: %s\n",buf);
|
||||
else printf(" module: %s\n",buf);
|
||||
}
|
||||
if (t == 4)
|
||||
printf(" dll: %s\n", buf);
|
||||
else
|
||||
printf(" module: %s\n", buf);
|
||||
if (rdf_version == 1)
|
||||
length -= ll + 1;
|
||||
break;
|
||||
|
||||
case RDFREC_BSS: /* BSS reservation */
|
||||
fread(&ll,4,1,infile);
|
||||
printf(" bss reservation: %08lx bytes\n",translatelong(ll));
|
||||
if (rdf_version == 1) length -= 5;
|
||||
break;
|
||||
|
||||
case RDFREC_BSS: /* BSS reservation */
|
||||
fread(&ll, 4, 1, infile);
|
||||
printf(" bss reservation: %08lx bytes\n", translatelong(ll));
|
||||
if (rdf_version == 1)
|
||||
length -= 5;
|
||||
if (rdf_version > 1 && reclen != 4)
|
||||
printf(" warning: reclen != 4\n");
|
||||
break;
|
||||
|
||||
case RDFREC_COMMON: {
|
||||
|
||||
case RDFREC_COMMON: {
|
||||
unsigned short seg, align;
|
||||
unsigned long size;
|
||||
|
||||
|
||||
fread(&seg, 2, 1, infile);
|
||||
fread(&size, 4, 1, infile);
|
||||
fread(&align, 2, 1, infile);
|
||||
for (ll = 0; ll < reclen - 8; ll++)
|
||||
fread(buf+ll, 1, 1, infile);
|
||||
fread(buf + ll, 1, 1, infile);
|
||||
printf(" common: segment %04x = %s, %ld:%d\n", translateshort(seg),
|
||||
buf, translatelong(size), translateshort(align));
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf(" unrecognized record (type %d", (int)t);
|
||||
printf(" unrecognized record (type %d", (int) t);
|
||||
if (rdf_version > 1) {
|
||||
printf(", length %d",(int)reclen);
|
||||
fseek(infile,reclen,SEEK_CUR);
|
||||
} else length --;
|
||||
printf(")\n");
|
||||
printf(", length %d", (int) reclen);
|
||||
fseek(infile, reclen, SEEK_CUR);
|
||||
} else
|
||||
length--;
|
||||
printf(")\n");
|
||||
}
|
||||
if (rdf_version != 1) length -= 2 + reclen;
|
||||
if (rdf_version != 1)
|
||||
length -= 2 + reclen;
|
||||
}
|
||||
}
|
||||
|
||||
char * knowntypes[8] = {"NULL", "text", "data", "object comment",
|
||||
"linked comment", "loader comment",
|
||||
"symbolic debug", "line number debug"};
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char id[7];
|
||||
long l;
|
||||
uint16 s;
|
||||
int verbose = 0;
|
||||
long offset;
|
||||
int foundnullsegment = 0;
|
||||
int version;
|
||||
long segmentcontentlength = 0;
|
||||
int nsegments = 0;
|
||||
long headerlength = 0;
|
||||
long objectlength = 0;
|
||||
|
||||
char * translatesegmenttype(int16 type) {
|
||||
if (type < 8) return knowntypes[type];
|
||||
if (type < 0x0020) return "reserved";
|
||||
if (type < 0x1000) return "reserved - moscow";
|
||||
if (type < 0x8000) return "reserved - system dependant";
|
||||
if (type < 0xFFFF) return "reserved - other";
|
||||
if (type == 0xFFFF) return "invalid type code";
|
||||
return "type code out of range";
|
||||
}
|
||||
printf("RDOFF dump utility, version %s\n", PROGRAM_VERSION);
|
||||
printf("RDOFF2 revision %s\n", RDOFF2_REVISION);
|
||||
puts("Copyright (c) 1996,99 Julian R Hall\n"
|
||||
"Improvements and fixes (c) 2002-2004 RET & COM Research.");
|
||||
|
||||
int main(int argc,char **argv) {
|
||||
char id[7];
|
||||
long l;
|
||||
int16 s;
|
||||
int verbose = 0;
|
||||
long offset;
|
||||
int foundnullsegment = 0;
|
||||
int version;
|
||||
long segmentcontentlength = 0;
|
||||
int nsegments = 0;
|
||||
long headerlength = 0;
|
||||
long objectlength = 0;
|
||||
|
||||
puts("RDOFF Dump utility v2.2\n"\
|
||||
"Copyright (c) 1996,99 Julian R Hall\n"
|
||||
"Copyright (c) 2000-2002 RET & COM Research.");
|
||||
|
||||
if (argc < 2) {
|
||||
fputs("Usage: rdfdump [-v] <filename>\n",stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (! strcmp (argv[1], "-v") )
|
||||
{
|
||||
verbose = 1;
|
||||
if (argc < 3)
|
||||
{
|
||||
fputs("required parameter missing\n",stderr);
|
||||
exit(1);
|
||||
if (argc < 2) {
|
||||
fputs("Usage: rdfdump [-v] <filename>\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
|
||||
infile = fopen(argv[1],"rb");
|
||||
if (! infile) {
|
||||
fprintf(stderr,"rdfdump: Could not open %s\n",argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
if (!strcmp(argv[1], "-v")) {
|
||||
verbose = 1;
|
||||
if (argc < 3) {
|
||||
fputs("required parameter missing\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
|
||||
fread(id,6,1,infile);
|
||||
if (strncmp(id,"RDOFF",5)) {
|
||||
fputs("rdfdump: File does not contain valid RDOFF header\n",stderr);
|
||||
exit(1);
|
||||
}
|
||||
infile = fopen(argv[1], "rb");
|
||||
if (!infile) {
|
||||
fprintf(stderr, "rdfdump: Could not open %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("File %s: RDOFF version %c\n\n",argv[1],id[5]);
|
||||
if (id[5] < '1' || id[5] > '2') {
|
||||
fprintf(stderr,"rdfdump: unknown RDOFF version '%c'\n",id[5]);
|
||||
exit(1);
|
||||
}
|
||||
version = id[5] - '0';
|
||||
fread(id, 6, 1, infile);
|
||||
if (strncmp(id, "RDOFF", 5)) {
|
||||
fputs("rdfdump: File does not contain valid RDOFF header\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (version > 1) {
|
||||
fread(&l, 4, 1, infile);
|
||||
objectlength = translatelong(l);
|
||||
printf("Object content size: %ld bytes\n", objectlength);
|
||||
}
|
||||
printf("File %s: RDOFF version %c\n\n", argv[1], id[5]);
|
||||
if (id[5] < '1' || id[5] > '2') {
|
||||
fprintf(stderr, "rdfdump: unknown RDOFF version '%c'\n", id[5]);
|
||||
exit(1);
|
||||
}
|
||||
version = id[5] - '0';
|
||||
|
||||
fread(&l,4,1,infile);
|
||||
headerlength = translatelong(l);
|
||||
printf("Header (%ld bytes):\n",headerlength);
|
||||
print_header(headerlength, version);
|
||||
if (version > 1) {
|
||||
fread(&l, 4, 1, infile);
|
||||
objectlength = translatelong(l);
|
||||
printf("Object content size: %ld bytes\n", objectlength);
|
||||
}
|
||||
|
||||
if (version == 1) {
|
||||
fread(&l,4,1,infile);
|
||||
l = translatelong(l);
|
||||
printf("\nText segment length = %ld bytes\n",l);
|
||||
offset = 0;
|
||||
while(l--) {
|
||||
fread(id,1,1,infile);
|
||||
if (verbose) {
|
||||
if (offset % 16 == 0)
|
||||
printf("\n%08lx ", offset);
|
||||
printf(" %02x",(int) (unsigned char)id[0]);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
if (verbose) printf("\n\n");
|
||||
|
||||
fread(&l,4,1,infile);
|
||||
l = translatelong(l);
|
||||
printf("Data segment length = %ld bytes\n",l);
|
||||
fread(&l, 4, 1, infile);
|
||||
headerlength = translatelong(l);
|
||||
printf("Header (%ld bytes):\n", headerlength);
|
||||
print_header(headerlength, version);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
offset = 0;
|
||||
while (l--) {
|
||||
fread(id,1,1,infile);
|
||||
if (offset % 16 == 0)
|
||||
printf("\n%08lx ", offset);
|
||||
printf(" %02x",(int) (unsigned char) id[0]);
|
||||
offset++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do {
|
||||
fread(&s,2,1,infile);
|
||||
s = translateshort(s);
|
||||
if (!s) {
|
||||
printf("\nNULL segment\n");
|
||||
foundnullsegment = 1;
|
||||
break;
|
||||
}
|
||||
printf("\nSegment:\n Type = %04X (%s)\n",(int)s,
|
||||
translatesegmenttype(s));
|
||||
nsegments++;
|
||||
if (version == 1) {
|
||||
fread(&l, 4, 1, infile);
|
||||
l = translatelong(l);
|
||||
printf("\nText segment length = %ld bytes\n", l);
|
||||
offset = 0;
|
||||
while (l--) {
|
||||
fread(id, 1, 1, infile);
|
||||
if (verbose) {
|
||||
if (offset % 16 == 0)
|
||||
printf("\n%08lx ", offset);
|
||||
printf(" %02x", (int) (unsigned char) id[0]);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
if (verbose)
|
||||
printf("\n\n");
|
||||
|
||||
fread(&s,2,1,infile);
|
||||
printf(" Number = %04X\n",(int)translateshort(s));
|
||||
fread(&s,2,1,infile);
|
||||
printf(" Resrvd = %04X\n",(int)translateshort(s));
|
||||
fread(&l,4,1,infile);
|
||||
l = translatelong(l);
|
||||
printf(" Length = %ld bytes\n",l);
|
||||
segmentcontentlength += l;
|
||||
fread(&l, 4, 1, infile);
|
||||
l = translatelong(l);
|
||||
printf("Data segment length = %ld bytes\n", l);
|
||||
|
||||
offset = 0;
|
||||
while(l--) {
|
||||
fread(id,1,1,infile);
|
||||
if (verbose) {
|
||||
if (offset % 16 == 0)
|
||||
printf("\n%08lx ", offset);
|
||||
printf(" %02x",(int) (unsigned char)id[0]);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
if (verbose) printf("\n");
|
||||
} while (!feof(infile));
|
||||
if (! foundnullsegment)
|
||||
printf("\nWarning: unexpected end of file - "
|
||||
"NULL segment not found\n");
|
||||
if (verbose) {
|
||||
offset = 0;
|
||||
while (l--) {
|
||||
fread(id, 1, 1, infile);
|
||||
if (offset % 16 == 0)
|
||||
printf("\n%08lx ", offset);
|
||||
printf(" %02x", (int) (unsigned char) id[0]);
|
||||
offset++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
fread(&s, 2, 1, infile);
|
||||
s = translateshort(s);
|
||||
if (!s) {
|
||||
printf("\nNULL segment\n");
|
||||
foundnullsegment = 1;
|
||||
break;
|
||||
}
|
||||
printf("\nSegment:\n Type = %04X (%s)\n", (int) s, translatesegmenttype(s));
|
||||
nsegments++;
|
||||
|
||||
printf("\nTotal number of segments: %d\n", nsegments);
|
||||
printf("Total segment content length: %ld bytes\n",segmentcontentlength);
|
||||
fread(&s, 2, 1, infile);
|
||||
printf(" Number = %04X\n", (int) translateshort(s));
|
||||
fread(&s, 2, 1, infile);
|
||||
printf(" Resrvd = %04X\n", (int) translateshort(s));
|
||||
fread(&l, 4, 1, infile);
|
||||
l = translatelong(l);
|
||||
printf(" Length = %ld bytes\n", l);
|
||||
segmentcontentlength += l;
|
||||
|
||||
/* calculate what the total object content length should have been */
|
||||
l = segmentcontentlength + 10 * (nsegments+1) + headerlength + 4;
|
||||
if (l != objectlength)
|
||||
printf("Warning: actual object length (%ld) != "
|
||||
"stored object length (%ld)\n", l, objectlength);
|
||||
}
|
||||
fclose(infile);
|
||||
return 0;
|
||||
offset = 0;
|
||||
while (l--) {
|
||||
fread(id, 1, 1, infile);
|
||||
if (verbose) {
|
||||
if (offset % 16 == 0)
|
||||
printf("\n%08lx ", offset);
|
||||
printf(" %02x", (int) (unsigned char) id[0]);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
if (verbose)
|
||||
printf("\n");
|
||||
} while (!feof(infile));
|
||||
if (!foundnullsegment)
|
||||
printf("\nWarning: unexpected end of file - " "NULL segment not found\n");
|
||||
|
||||
printf("\nTotal number of segments: %d\n", nsegments);
|
||||
printf("Total segment content length: %ld bytes\n", segmentcontentlength);
|
||||
|
||||
/* calculate what the total object content length should have been */
|
||||
l = segmentcontentlength + 10 * (nsegments + 1) + headerlength + 4;
|
||||
if (l != objectlength)
|
||||
printf("Warning: actual object length (%ld) != " "stored object length (%ld)\n", l, objectlength);
|
||||
}
|
||||
fclose(infile);
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
#include "rdfload.h"
|
||||
#include "symtab.h"
|
||||
#include "rdoff.h"
|
||||
#include "collectn.h"
|
||||
|
||||
extern int rdf_errno;
|
||||
@ -36,17 +35,15 @@ rdfmodule * rdfload(const char *filename)
|
||||
rdfheaderrec *r;
|
||||
|
||||
f = malloc(sizeof(rdfmodule));
|
||||
if (f == NULL)
|
||||
{
|
||||
rdf_errno = 6; /* out of memory */
|
||||
if (f == NULL) {
|
||||
rdf_errno = RDF_ERR_NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f->symtab = symtabNew();
|
||||
if (!f->symtab)
|
||||
{
|
||||
if (!f->symtab) {
|
||||
free(f);
|
||||
rdf_errno = 6;
|
||||
rdf_errno = RDF_ERR_NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -63,7 +60,7 @@ rdfmodule * rdfload(const char *filename)
|
||||
hdr = malloc (f->f.header_len);
|
||||
|
||||
if (! f->t || ! f->d || !hdr) {
|
||||
rdf_errno = 6;
|
||||
rdf_errno = RDF_ERR_NOMEM;
|
||||
rdfclose(&f->f);
|
||||
if (f->t) free(f->t);
|
||||
if (f->d) free(f->d);
|
||||
@ -87,20 +84,18 @@ rdfmodule * rdfload(const char *filename)
|
||||
|
||||
/* Allocate BSS segment; step through header and count BSS records */
|
||||
|
||||
while ( ( r = rdfgetheaderrec (&f->f) ) )
|
||||
{
|
||||
while ((r = rdfgetheaderrec(&f->f))) {
|
||||
if (r->type == 5)
|
||||
bsslength += r->b.amount;
|
||||
}
|
||||
|
||||
f->b = malloc ( bsslength );
|
||||
if (bsslength && (!f->b))
|
||||
{
|
||||
if (bsslength && (!f->b)) {
|
||||
free(f->t);
|
||||
free(f->d);
|
||||
free(f);
|
||||
free(hdr);
|
||||
rdf_errno = 6;
|
||||
rdf_errno = RDF_ERR_NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -121,13 +116,11 @@ int rdf_relocate(rdfmodule * m)
|
||||
long rel;
|
||||
unsigned char * seg;
|
||||
|
||||
rdfheaderrewind ( & m->f );
|
||||
rdfheaderrewind (&m->f);
|
||||
collection_init(&imports);
|
||||
|
||||
while ( (r = rdfgetheaderrec ( & m->f ) ) )
|
||||
{
|
||||
switch (r->type)
|
||||
{
|
||||
while ((r = rdfgetheaderrec(&m->f))) {
|
||||
switch (r->type) {
|
||||
case 1: /* Relocation record */
|
||||
|
||||
/* calculate relocation factor */
|
||||
@ -154,7 +147,7 @@ int rdf_relocate(rdfmodule * m)
|
||||
seg[r->r.offset] += (char) rel;
|
||||
break;
|
||||
case 2:
|
||||
*(int16 *)(seg + r->r.offset) += (int16) rel;
|
||||
*(uint16 *)(seg + r->r.offset) += (uint16) rel;
|
||||
break;
|
||||
case 4:
|
||||
*(long *)(seg + r->r.offset) += rel;
|
||||
|
@ -12,6 +12,8 @@
|
||||
#ifndef _RDFLOAD_H
|
||||
#define _RDFLOAD_H
|
||||
|
||||
#define RDOFF_UTILS
|
||||
|
||||
#include "rdoff.h"
|
||||
|
||||
typedef struct RDFModuleStruct {
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define RDOFF_UTILS
|
||||
|
||||
#include "rdoff.h"
|
||||
#include "rdlib.h"
|
||||
#include "rdlar.h"
|
||||
@ -264,6 +266,3 @@ void rdl_perror(const char *apname, const char *filename)
|
||||
else
|
||||
fprintf(stderr,"%s:%s:%s\n",apname,filename,rdl_errors[rdl_error]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
/* rdlib.h Functions for manipulating librarys of RDOFF object files */
|
||||
/*
|
||||
* rdlib.h Functions for manipulating libraries of RDOFF object files.
|
||||
*/
|
||||
|
||||
|
||||
struct librarynode {
|
||||
@ -23,5 +25,3 @@ int rdl_searchlib (struct librarynode * lib,
|
||||
int rdl_openmodule (struct librarynode * lib, int module, rdffile * f);
|
||||
|
||||
void rdl_perror(const char *apname, const char *filename);
|
||||
|
||||
|
||||
|
403
rdoff/rdoff.c
403
rdoff/rdoff.c
@ -19,6 +19,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define RDOFF_UTILS
|
||||
|
||||
#include "rdoff.h"
|
||||
|
||||
#define newstr(str) strcpy(malloc(strlen(str) + 1),str)
|
||||
@ -53,7 +56,7 @@ memorybuffer * newmembuf()
|
||||
|
||||
void membufwrite(memorybuffer *const b, void *data, int bytes)
|
||||
{
|
||||
int16 w;
|
||||
uint16 w;
|
||||
long l;
|
||||
|
||||
if (b->next) { /* memory buffer full - use next buffer */
|
||||
@ -85,7 +88,7 @@ void membufwrite(memorybuffer *const b, void *data, int bytes)
|
||||
break;
|
||||
|
||||
case -2:
|
||||
w = * (int16 *) data ;
|
||||
w = * (uint16 *) data ;
|
||||
b->buffer[b->length++] = w & 0xFF;
|
||||
w >>= 8 ;
|
||||
b->buffer[b->length++] = w & 0xFF;
|
||||
@ -146,9 +149,9 @@ long translatelong(long in)
|
||||
return r;
|
||||
}
|
||||
|
||||
int16 translateshort(int16 in)
|
||||
uint16 translateshort(uint16 in)
|
||||
{
|
||||
int16 r;
|
||||
uint16 r;
|
||||
unsigned char * i;
|
||||
|
||||
i = (unsigned char *)∈
|
||||
@ -157,15 +160,48 @@ int16 translateshort(int16 in)
|
||||
return r;
|
||||
}
|
||||
|
||||
const char *RDOFFId = "RDOFF2"; /* written to the start of RDOFF files */
|
||||
/* Segment types */
|
||||
static char *knownsegtypes[8] = {
|
||||
"NULL", "text", "data", "object comment",
|
||||
"linked comment", "loader comment",
|
||||
"symbolic debug", "line number debug"
|
||||
};
|
||||
|
||||
/* Get a textual string describing the segment type */
|
||||
char *translatesegmenttype(uint16 type)
|
||||
{
|
||||
if (type < 8)
|
||||
return knownsegtypes[type];
|
||||
if (type < 0x0020)
|
||||
return "reserved";
|
||||
if (type < 0x1000)
|
||||
return "reserved - Moscow";
|
||||
if (type < 0x8000)
|
||||
return "reserved - system dependant";
|
||||
if (type < 0xFFFF)
|
||||
return "reserved - other";
|
||||
if (type == 0xFFFF)
|
||||
return "invalid type code";
|
||||
return "type code out of range";
|
||||
}
|
||||
|
||||
/* This signature is written to the start of RDOFF files */
|
||||
const char *RDOFFId = RDOFF2_SIGNATURE;
|
||||
|
||||
/* Error messages. Must correspond to the codes defined in rdoff.h */
|
||||
const char *rdf_errors[11] = {
|
||||
"no error occurred","could not open file","invalid file format",
|
||||
"error reading file","unknown error","header not read",
|
||||
"out of memory", "RDOFF v1 not supported",
|
||||
"unknown extended header record",
|
||||
"header record of known type but unknown length",
|
||||
"no such segment"};
|
||||
/* 0 */ "no error occurred",
|
||||
/* 1 */ "could not open file",
|
||||
/* 2 */ "invalid file format",
|
||||
/* 3 */ "error reading file",
|
||||
/* 4 */ "unknown error",
|
||||
/* 5 */ "header not read",
|
||||
/* 6 */ "out of memory",
|
||||
/* 7 */ "RDOFF v1 not supported",
|
||||
/* 8 */ "unknown extended header record",
|
||||
/* 9 */ "header record of known type but unknown length",
|
||||
/* 10 */ "no such segment"
|
||||
};
|
||||
|
||||
int rdf_errno = 0;
|
||||
|
||||
@ -178,119 +214,120 @@ int rdfopen(rdffile *f, const char *name)
|
||||
FILE * fp;
|
||||
|
||||
fp = fopen(name,"rb");
|
||||
if (!fp) return rdf_errno = 1; /* error 1: file open error */
|
||||
if (!fp)
|
||||
return rdf_errno = RDF_ERR_OPEN;
|
||||
|
||||
return rdfopenhere(f,fp,NULL,name);
|
||||
}
|
||||
|
||||
int rdfopenhere(rdffile *f, FILE *fp, int *refcount, const char *name)
|
||||
{
|
||||
char buf[8];
|
||||
long initpos;
|
||||
long l;
|
||||
int16 s;
|
||||
char buf[8];
|
||||
long initpos;
|
||||
long l;
|
||||
uint16 s;
|
||||
|
||||
if (translatelong(0x01020304) != 0x01020304)
|
||||
{ /* fix this to be portable! */
|
||||
fputs("*** this program requires a little endian machine\n",stderr);
|
||||
fprintf(stderr,"01020304h = %08lxh\n",translatelong(0x01020304));
|
||||
exit(3);
|
||||
}
|
||||
if (translatelong(0x01020304) != 0x01020304) {
|
||||
/* fix this to be portable! */
|
||||
fputs("*** this program requires a little endian machine\n",stderr);
|
||||
fprintf(stderr,"01020304h = %08lxh\n",translatelong(0x01020304));
|
||||
exit(3);
|
||||
}
|
||||
|
||||
f->fp = fp;
|
||||
initpos = ftell(fp);
|
||||
f->fp = fp;
|
||||
initpos = ftell(fp);
|
||||
|
||||
fread(buf,6,1,f->fp); /* read header */
|
||||
buf[6] = 0;
|
||||
fread(buf,6,1,f->fp); /* read header */
|
||||
buf[6] = 0;
|
||||
|
||||
if (strcmp(buf,RDOFFId)) {
|
||||
fclose(f->fp);
|
||||
if (!strcmp(buf,"RDOFF1"))
|
||||
return rdf_errno = 7; /* error 7: RDOFF 1 not supported */
|
||||
return rdf_errno = 2; /* error 2: invalid file format */
|
||||
}
|
||||
if (strcmp(buf,RDOFFId)) {
|
||||
fclose(f->fp);
|
||||
if (!strcmp(buf,"RDOFF1"))
|
||||
return rdf_errno = RDF_ERR_VER;
|
||||
return rdf_errno = RDF_ERR_FORMAT;
|
||||
}
|
||||
|
||||
if (fread(&l,1,4,f->fp) != 4 ||
|
||||
fread(&f->header_len,1,4,f->fp) != 4) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = 3; /* error 3: file read error */
|
||||
}
|
||||
if (fread(&l,1,4,f->fp) != 4 || fread(&f->header_len,1,4,f->fp) != 4) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = RDF_ERR_READ;
|
||||
}
|
||||
|
||||
f->header_ofs = ftell(f->fp);
|
||||
f->eof_offset = f->header_ofs + translatelong(l) - 4;
|
||||
f->header_ofs = ftell(f->fp);
|
||||
f->eof_offset = f->header_ofs + translatelong(l) - 4;
|
||||
|
||||
if (fseek(f->fp,f->header_len,SEEK_CUR)) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = 2; /* seek past end of file...? */
|
||||
}
|
||||
if (fseek(f->fp,f->header_len,SEEK_CUR)) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = RDF_ERR_FORMAT; /* seek past end of file...? */
|
||||
}
|
||||
|
||||
if (fread(&s,1,2,f->fp) != 2) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = 3;
|
||||
}
|
||||
if (fread(&s,1,2,f->fp) != 2) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = RDF_ERR_READ;
|
||||
}
|
||||
|
||||
f->nsegs = 0;
|
||||
f->nsegs = 0;
|
||||
|
||||
while (s != 0)
|
||||
{
|
||||
f->seg[f->nsegs].type = s;
|
||||
if (fread(&f->seg[f->nsegs].number,1,2,f->fp) != 2 ||
|
||||
fread(&f->seg[f->nsegs].reserved,1,2,f->fp) != 2 ||
|
||||
fread(&f->seg[f->nsegs].length,1,4,f->fp) != 4)
|
||||
{
|
||||
fclose(f->fp);
|
||||
return rdf_errno = 3;
|
||||
}
|
||||
while (s != 0) {
|
||||
f->seg[f->nsegs].type = s;
|
||||
if (fread(&f->seg[f->nsegs].number,1,2,f->fp) != 2 ||
|
||||
fread(&f->seg[f->nsegs].reserved,1,2,f->fp) != 2 ||
|
||||
fread(&f->seg[f->nsegs].length,1,4,f->fp) != 4) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = RDF_ERR_READ;
|
||||
}
|
||||
|
||||
f->seg[f->nsegs].offset = ftell(f->fp);
|
||||
if (fseek(f->fp,f->seg[f->nsegs].length,SEEK_CUR)) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = 2;
|
||||
}
|
||||
f->nsegs++;
|
||||
f->seg[f->nsegs].offset = ftell(f->fp);
|
||||
if (fseek(f->fp,f->seg[f->nsegs].length,SEEK_CUR)) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = RDF_ERR_FORMAT;
|
||||
}
|
||||
f->nsegs++;
|
||||
|
||||
if (fread(&s,1,2,f->fp) != 2) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = 3;
|
||||
}
|
||||
}
|
||||
if (fread(&s,1,2,f->fp) != 2) {
|
||||
fclose(f->fp);
|
||||
return rdf_errno = RDF_ERR_READ;
|
||||
}
|
||||
}
|
||||
|
||||
if (f->eof_offset != ftell(f->fp) + 8) /* +8 = skip null segment header */
|
||||
{
|
||||
fprintf(stderr, "warning: eof_offset [%ld] and actual eof offset "
|
||||
if (f->eof_offset != ftell(f->fp) + 8) { /* +8 = skip null segment header */
|
||||
fprintf(stderr, "warning: eof_offset [%ld] and actual eof offset "
|
||||
"[%ld] don't match\n", f->eof_offset, ftell(f->fp) + 8);
|
||||
}
|
||||
fseek(f->fp,initpos,SEEK_SET);
|
||||
f->header_loc = NULL;
|
||||
}
|
||||
fseek(f->fp,initpos,SEEK_SET);
|
||||
f->header_loc = NULL;
|
||||
|
||||
f->name = newstr(name);
|
||||
f->refcount = refcount;
|
||||
if (refcount) (*refcount)++;
|
||||
return 0;
|
||||
f->name = newstr(name);
|
||||
f->refcount = refcount;
|
||||
if (refcount) (*refcount)++;
|
||||
return RDF_OK;
|
||||
}
|
||||
|
||||
int rdfclose(rdffile *f)
|
||||
{
|
||||
if (! f->refcount || ! --(*f->refcount))
|
||||
{
|
||||
fclose(f->fp);
|
||||
f->fp = NULL;
|
||||
}
|
||||
if (! f->refcount || ! --(*f->refcount)) {
|
||||
fclose(f->fp);
|
||||
f->fp = NULL;
|
||||
}
|
||||
free(f->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rdfperror(const char *app,const char *name)
|
||||
/*
|
||||
* Print the message for last error (from rdf_errno)
|
||||
*/
|
||||
void rdfperror(const char *app, const char *name)
|
||||
{
|
||||
fprintf(stderr,"%s:%s: %s\n",app,name,rdf_errors[rdf_errno]);
|
||||
if (rdf_errno == 1 || rdf_errno == 3)
|
||||
{
|
||||
perror(app);
|
||||
}
|
||||
|
||||
fprintf(stderr,"%s:%s: %s\n",app,name,rdf_errors[rdf_errno]);
|
||||
if (rdf_errno == RDF_ERR_OPEN || rdf_errno == RDF_ERR_READ) {
|
||||
perror(app);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the segment by its number.
|
||||
* Returns segment array index, or -1 if segment with such number was not found.
|
||||
*/
|
||||
int rdffindsegment(rdffile * f, int segno)
|
||||
{
|
||||
int i;
|
||||
@ -299,36 +336,37 @@ int rdffindsegment(rdffile * f, int segno)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the segment. Returns status.
|
||||
*/
|
||||
int rdfloadseg(rdffile *f,int segment,void *buffer)
|
||||
{
|
||||
long fpos;
|
||||
long slen;
|
||||
long fpos, slen;
|
||||
|
||||
switch(segment) {
|
||||
case RDOFF_HEADER:
|
||||
fpos = f->header_ofs;
|
||||
slen = f->header_len;
|
||||
f->header_loc = (byte *)buffer;
|
||||
f->header_fp = 0;
|
||||
break;
|
||||
default:
|
||||
if (segment < f->nsegs) {
|
||||
fpos = f->seg[segment].offset;
|
||||
slen = f->seg[segment].length;
|
||||
f->seg[segment].data = (byte *)buffer;
|
||||
}
|
||||
else {
|
||||
return rdf_errno = 10; /* no such segment */
|
||||
}
|
||||
}
|
||||
switch(segment) {
|
||||
case RDOFF_HEADER:
|
||||
fpos = f->header_ofs;
|
||||
slen = f->header_len;
|
||||
f->header_loc = (byte *)buffer;
|
||||
f->header_fp = 0;
|
||||
break;
|
||||
default:
|
||||
if (segment < f->nsegs) {
|
||||
fpos = f->seg[segment].offset;
|
||||
slen = f->seg[segment].length;
|
||||
f->seg[segment].data = (byte *)buffer;
|
||||
} else {
|
||||
return rdf_errno = RDF_ERR_SEGMENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (fseek(f->fp,fpos,SEEK_SET))
|
||||
return rdf_errno = 4;
|
||||
if (fseek(f->fp,fpos,SEEK_SET))
|
||||
return rdf_errno = RDF_ERR_UNKNOWN;
|
||||
|
||||
if (fread(buffer,1,slen,f->fp) != slen)
|
||||
return rdf_errno = 3;
|
||||
if (fread(buffer,1,slen,f->fp) != slen)
|
||||
return rdf_errno = RDF_ERR_READ;
|
||||
|
||||
return 0;
|
||||
return RDF_OK;
|
||||
}
|
||||
|
||||
/* Macros for reading integers from header in memory */
|
||||
@ -347,86 +385,93 @@ int rdfloadseg(rdffile *f,int segment,void *buffer)
|
||||
#define RS(str,max) { for(i=0;i<max;i++){\
|
||||
RI8(str[i]); if (!str[i]) break;} str[i]=0; }
|
||||
|
||||
/*
|
||||
* Read a header record.
|
||||
* Returns the address of record, or NULL in case of error.
|
||||
*/
|
||||
rdfheaderrec *rdfgetheaderrec(rdffile *f)
|
||||
{
|
||||
static rdfheaderrec r;
|
||||
int i;
|
||||
static rdfheaderrec r;
|
||||
int i;
|
||||
|
||||
if (!f->header_loc) {
|
||||
rdf_errno = 5;
|
||||
return NULL;
|
||||
}
|
||||
if (!f->header_loc) {
|
||||
rdf_errno = RDF_ERR_HEADER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (f->header_fp >= f->header_len) return 0;
|
||||
if (f->header_fp >= f->header_len) return 0;
|
||||
|
||||
RI8(r.type);
|
||||
RI8(r.g.reclen);
|
||||
RI8(r.type);
|
||||
RI8(r.g.reclen);
|
||||
|
||||
switch(r.type) {
|
||||
case RDFREC_RELOC: /* Relocation record */
|
||||
case RDFREC_SEGRELOC:
|
||||
if (r.r.reclen != 8) {
|
||||
rdf_errno = 9;
|
||||
return NULL;
|
||||
}
|
||||
RI8(r.r.segment);
|
||||
RI32(r.r.offset);
|
||||
RI8(r.r.length);
|
||||
RI16(r.r.refseg);
|
||||
break;
|
||||
switch(r.type) {
|
||||
case RDFREC_RELOC: /* Relocation record */
|
||||
case RDFREC_SEGRELOC:
|
||||
if (r.r.reclen != 8) {
|
||||
rdf_errno = RDF_ERR_RECLEN;
|
||||
return NULL;
|
||||
}
|
||||
RI8(r.r.segment);
|
||||
RI32(r.r.offset);
|
||||
RI8(r.r.length);
|
||||
RI16(r.r.refseg);
|
||||
break;
|
||||
|
||||
case RDFREC_IMPORT: /* Imported symbol record */
|
||||
case RDFREC_FARIMPORT:
|
||||
RI8(r.i.flags);
|
||||
RI16(r.i.segment);
|
||||
RS(r.i.label,32);
|
||||
break;
|
||||
case RDFREC_IMPORT: /* Imported symbol record */
|
||||
case RDFREC_FARIMPORT:
|
||||
RI8(r.i.flags);
|
||||
RI16(r.i.segment);
|
||||
RS(r.i.label, EXIM_LABEL_MAX);
|
||||
break;
|
||||
|
||||
case RDFREC_GLOBAL: /* Exported symbol record */
|
||||
RI8(r.e.flags);
|
||||
RI8(r.e.segment);
|
||||
RI32(r.e.offset);
|
||||
RS(r.e.label,32);
|
||||
break;
|
||||
case RDFREC_GLOBAL: /* Exported symbol record */
|
||||
RI8(r.e.flags);
|
||||
RI8(r.e.segment);
|
||||
RI32(r.e.offset);
|
||||
RS(r.e.label, EXIM_LABEL_MAX);
|
||||
break;
|
||||
|
||||
case RDFREC_DLL: /* DLL record */
|
||||
RS(r.d.libname,127);
|
||||
break;
|
||||
case RDFREC_DLL: /* DLL record */
|
||||
RS(r.d.libname, MODLIB_NAME_MAX);
|
||||
break;
|
||||
|
||||
case RDFREC_BSS: /* BSS reservation record */
|
||||
if (r.r.reclen != 4) {
|
||||
rdf_errno = 9;
|
||||
return NULL;
|
||||
}
|
||||
RI32(r.b.amount);
|
||||
break;
|
||||
case RDFREC_BSS: /* BSS reservation record */
|
||||
if (r.r.reclen != 4) {
|
||||
rdf_errno = RDF_ERR_RECLEN;
|
||||
return NULL;
|
||||
}
|
||||
RI32(r.b.amount);
|
||||
break;
|
||||
|
||||
case RDFREC_MODNAME: /* Module name record */
|
||||
RS(r.m.modname,127);
|
||||
break;
|
||||
case RDFREC_MODNAME: /* Module name record */
|
||||
RS(r.m.modname, MODLIB_NAME_MAX);
|
||||
break;
|
||||
|
||||
case RDFREC_COMMON: /* Common variable */
|
||||
RI16(r.c.segment);
|
||||
RI32(r.c.size);
|
||||
RI16(r.c.align);
|
||||
RS(r.c.label,32);
|
||||
break;
|
||||
case RDFREC_COMMON: /* Common variable */
|
||||
RI16(r.c.segment);
|
||||
RI32(r.c.size);
|
||||
RI16(r.c.align);
|
||||
RS(r.c.label, EXIM_LABEL_MAX);
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
#ifdef STRICT_ERRORS
|
||||
rdf_errno = 8; /* unknown header record */
|
||||
return NULL;
|
||||
rdf_errno = RDF_ERR_RECTYPE; /* unknown header record */
|
||||
return NULL;
|
||||
#else
|
||||
for (i = 0; i < r.g.reclen; i++)
|
||||
RI8(r.g.data[i]);
|
||||
for (i = 0; i < r.g.reclen; i++)
|
||||
RI8(r.g.data[i]);
|
||||
#endif
|
||||
}
|
||||
return &r;
|
||||
}
|
||||
return &r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Rewind to the beginning of the file
|
||||
*/
|
||||
void rdfheaderrewind(rdffile *f)
|
||||
{
|
||||
f->header_fp = 0;
|
||||
f->header_fp = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -450,8 +495,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r)
|
||||
membufwrite(h->buf,&r->type,1);
|
||||
membufwrite(h->buf,&r->g.reclen,1);
|
||||
|
||||
switch (r->type)
|
||||
{
|
||||
switch (r->type) {
|
||||
case RDFREC_GENERIC: /* generic */
|
||||
membufwrite(h->buf, &r->g.data, r->g.reclen);
|
||||
break;
|
||||
@ -491,7 +535,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r)
|
||||
|
||||
default:
|
||||
#ifdef STRICT_ERRORS
|
||||
return (rdf_errno = 8);
|
||||
return rdf_errno = RDF_ERR_RECTYPE;
|
||||
#else
|
||||
for (i = 0; i < r->g.reclen; i++)
|
||||
membufwrite(h->buf, r->g.data[i], 1);
|
||||
@ -530,4 +574,3 @@ void rdfdoneheader(rdf_headerbuf * h)
|
||||
freemembuf(h->buf);
|
||||
free(h);
|
||||
}
|
||||
|
||||
|
166
rdoff/rdoff.h
166
rdoff/rdoff.h
@ -1,4 +1,5 @@
|
||||
/* rdoff.h RDOFF Object File manipulation routines header file
|
||||
/*
|
||||
* rdoff.h RDOFF Object File manipulation routines header file
|
||||
*
|
||||
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
|
||||
* Julian Hall. All rights reserved. The software is
|
||||
@ -11,17 +12,37 @@
|
||||
*/
|
||||
|
||||
#ifndef _RDOFF_H
|
||||
#define _RDOFF_H "RDOFF2 support routines v0.3"
|
||||
#define _RDOFF_H
|
||||
|
||||
/* Some systems don't define this automatically */
|
||||
extern char *strdup(const char *);
|
||||
/*
|
||||
* RDOFF definitions. They are used by RDOFF utilities and by NASM's
|
||||
* 'outrdf2.c' output module.
|
||||
*/
|
||||
|
||||
typedef unsigned short int16;
|
||||
/* Type definitions */
|
||||
typedef unsigned long uint32;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned int bool;
|
||||
|
||||
#define RDF_MAXSEGS 64
|
||||
/* RDOFF format revision (currently used only when printing the version) */
|
||||
#define RDOFF2_REVISION "0.6.1"
|
||||
|
||||
/* the records that can be found in the RDOFF header */
|
||||
/* RDOFF2 file signature */
|
||||
#define RDOFF2_SIGNATURE "RDOFF2"
|
||||
|
||||
/* Maximum size of an import/export label (including trailing zero) */
|
||||
#define EXIM_LABEL_MAX 64
|
||||
|
||||
/* Maximum size of library or module name (including trailing zero) */
|
||||
#define MODLIB_NAME_MAX 128
|
||||
|
||||
/* Maximum number of segments that we can handle in one file */
|
||||
#define RDF_MAXSEGS 64
|
||||
|
||||
|
||||
/* Record types that may present the RDOFF header */
|
||||
#define RDFREC_GENERIC 0
|
||||
#define RDFREC_RELOC 1
|
||||
#define RDFREC_IMPORT 2
|
||||
#define RDFREC_GLOBAL 3
|
||||
@ -31,8 +52,21 @@ typedef unsigned char byte;
|
||||
#define RDFREC_FARIMPORT 7
|
||||
#define RDFREC_MODNAME 8
|
||||
#define RDFREC_COMMON 10
|
||||
#define RDFREC_GENERIC 0
|
||||
|
||||
|
||||
/*
|
||||
* Generic record - contains the type and length field, plus a 128 byte
|
||||
* char array 'data'
|
||||
*/
|
||||
struct GenericRec {
|
||||
byte type;
|
||||
byte reclen;
|
||||
char data[128];
|
||||
};
|
||||
|
||||
/*
|
||||
* Relocation record
|
||||
*/
|
||||
struct RelocRec {
|
||||
byte type; /* must be 1 */
|
||||
byte reclen; /* content length */
|
||||
@ -41,55 +75,73 @@ struct RelocRec {
|
||||
reloc @ loadtime, only linkage) */
|
||||
long offset; /* from start of segment in which reference is loc'd */
|
||||
byte length; /* 1 2 or 4 bytes */
|
||||
int16 refseg; /* segment to which reference refers to */
|
||||
uint16 refseg; /* segment to which reference refers to */
|
||||
};
|
||||
|
||||
/*
|
||||
* Extern/import record
|
||||
*/
|
||||
struct ImportRec {
|
||||
byte type; /* must be 2 */
|
||||
byte reclen; /* content length */
|
||||
byte flags; /* SYM_* flags (see below) */
|
||||
int16 segment; /* segment number allocated to the label for reloc
|
||||
uint16 segment; /* segment number allocated to the label for reloc
|
||||
records - label is assumed to be at offset zero
|
||||
in this segment, so linker must fix up with offset
|
||||
of segment and of offset within segment */
|
||||
char label[33]; /* zero terminated... should be written to file until
|
||||
the zero, but not after it - max len = 32 chars */
|
||||
char label[EXIM_LABEL_MAX]; /* zero terminated, should be written to file
|
||||
until the zero, but not after it */
|
||||
};
|
||||
|
||||
/*
|
||||
* Public/export record
|
||||
*/
|
||||
struct ExportRec {
|
||||
byte type; /* must be 3 */
|
||||
byte reclen; /* content length */
|
||||
byte flags; /* SYM_* flags (see below) */
|
||||
byte segment; /* segment referred to (0/1/2) */
|
||||
long offset; /* offset within segment */
|
||||
char label[33]; /* zero terminated as above. max len = 32 chars */
|
||||
char label[EXIM_LABEL_MAX]; /* zero terminated as in import */
|
||||
};
|
||||
|
||||
/*
|
||||
* DLL record
|
||||
*/
|
||||
struct DLLRec {
|
||||
byte type; /* must be 4 */
|
||||
byte reclen; /* content length */
|
||||
char libname[128]; /* name of library to link with at load time */
|
||||
char libname[MODLIB_NAME_MAX]; /* name of library to link with at load time */
|
||||
};
|
||||
|
||||
/*
|
||||
* BSS record
|
||||
*/
|
||||
struct BSSRec {
|
||||
byte type; /* must be 5 */
|
||||
byte reclen; /* content length */
|
||||
byte reclen; /* content length */
|
||||
long amount; /* number of bytes BSS to reserve */
|
||||
};
|
||||
|
||||
/*
|
||||
* Module name record
|
||||
*/
|
||||
struct ModRec {
|
||||
byte type; /* must be 8 */
|
||||
byte reclen; /* content length */
|
||||
char modname[128]; /* module name */
|
||||
char modname[MODLIB_NAME_MAX]; /* module name */
|
||||
};
|
||||
|
||||
/*
|
||||
* Common variable record
|
||||
*/
|
||||
struct CommonRec {
|
||||
byte type; /* must be 10 */
|
||||
byte reclen; /* equals 7+label length */
|
||||
int16 segment; /* segment number */
|
||||
uint16 segment; /* segment number */
|
||||
long size; /* size of common variable */
|
||||
int16 align; /* alignment (power of two) */
|
||||
char label[33]; /* zero terminated as above. max len = 32 chars */
|
||||
uint16 align; /* alignment (power of two) */
|
||||
char label[EXIM_LABEL_MAX]; /* zero terminated as in import */
|
||||
};
|
||||
|
||||
/* Flags for ExportRec */
|
||||
@ -98,15 +150,13 @@ struct CommonRec {
|
||||
#define SYM_GLOBAL 4
|
||||
#define SYM_IMPORT 8
|
||||
|
||||
/*
|
||||
* GenericRec - contains the type and length field, plus a 128 byte
|
||||
* char array 'data'
|
||||
*/
|
||||
struct GenericRec {
|
||||
byte type;
|
||||
byte reclen;
|
||||
char data[128];
|
||||
};
|
||||
|
||||
/*** The following part is used only by the utilities *************************/
|
||||
|
||||
#ifdef RDOFF_UTILS
|
||||
|
||||
/* Some systems don't define this automatically */
|
||||
extern char *strdup(const char *);
|
||||
|
||||
typedef union RDFHeaderRec {
|
||||
char type; /* invariant throughout all below */
|
||||
@ -122,9 +172,9 @@ typedef union RDFHeaderRec {
|
||||
|
||||
struct SegmentHeaderRec {
|
||||
/* information from file */
|
||||
int16 type;
|
||||
int16 number;
|
||||
int16 reserved;
|
||||
uint16 type;
|
||||
uint16 number;
|
||||
uint16 reserved;
|
||||
long length;
|
||||
|
||||
/* information built up here */
|
||||
@ -133,30 +183,30 @@ struct SegmentHeaderRec {
|
||||
};
|
||||
|
||||
typedef struct RDFFileInfo {
|
||||
FILE *fp; /* file descriptor; must be open to use this struct */
|
||||
int rdoff_ver; /* should be 1; any higher => not guaranteed to work */
|
||||
long header_len;
|
||||
long header_ofs;
|
||||
FILE *fp; /* file descriptor; must be open to use this struct */
|
||||
int rdoff_ver; /* should be 1; any higher => not guaranteed to work */
|
||||
long header_len;
|
||||
long header_ofs;
|
||||
|
||||
byte *header_loc; /* keep location of header */
|
||||
long header_fp; /* current location within header for reading */
|
||||
byte *header_loc; /* keep location of header */
|
||||
long header_fp; /* current location within header for reading */
|
||||
|
||||
struct SegmentHeaderRec seg[RDF_MAXSEGS];
|
||||
int nsegs;
|
||||
struct SegmentHeaderRec seg[RDF_MAXSEGS];
|
||||
int nsegs;
|
||||
|
||||
long eof_offset; /* offset of the first byte beyond the end of this
|
||||
long eof_offset; /* offset of the first byte beyond the end of this
|
||||
module */
|
||||
|
||||
char *name; /* name of module in libraries */
|
||||
int *refcount; /* pointer to reference count on file, or NULL */
|
||||
char *name; /* name of module in libraries */
|
||||
int *refcount; /* pointer to reference count on file, or NULL */
|
||||
} rdffile;
|
||||
|
||||
#define BUF_BLOCK_LEN 4088 /* selected to match page size (4096)
|
||||
* on 80x86 machines for efficiency */
|
||||
typedef struct memorybuffer {
|
||||
int length;
|
||||
byte buffer[BUF_BLOCK_LEN];
|
||||
struct memorybuffer *next;
|
||||
int length;
|
||||
byte buffer[BUF_BLOCK_LEN];
|
||||
struct memorybuffer *next;
|
||||
} memorybuffer;
|
||||
|
||||
typedef struct {
|
||||
@ -166,9 +216,9 @@ typedef struct {
|
||||
} rdf_headerbuf;
|
||||
|
||||
/* segments used by RDOFF, understood by rdoffloadseg */
|
||||
#define RDOFF_CODE 0
|
||||
#define RDOFF_DATA 1
|
||||
#define RDOFF_HEADER -1
|
||||
#define RDOFF_CODE 0
|
||||
#define RDOFF_DATA 1
|
||||
#define RDOFF_HEADER -1
|
||||
/* mask for 'segment' in relocation records to find if relative relocation */
|
||||
#define RDOFF_RELATIVEMASK 64
|
||||
/* mask to find actual segment value in relocation records */
|
||||
@ -176,9 +226,25 @@ typedef struct {
|
||||
|
||||
extern int rdf_errno;
|
||||
|
||||
/* rdf_errno can hold these error codes */
|
||||
enum {
|
||||
/* 0 */ RDF_OK,
|
||||
/* 1 */ RDF_ERR_OPEN,
|
||||
/* 2 */ RDF_ERR_FORMAT,
|
||||
/* 3 */ RDF_ERR_READ,
|
||||
/* 4 */ RDF_ERR_UNKNOWN,
|
||||
/* 5 */ RDF_ERR_HEADER,
|
||||
/* 6 */ RDF_ERR_NOMEM,
|
||||
/* 7 */ RDF_ERR_VER,
|
||||
/* 8 */ RDF_ERR_RECTYPE,
|
||||
/* 9 */ RDF_ERR_RECLEN,
|
||||
/* 10 */ RDF_ERR_SEGMENT
|
||||
};
|
||||
|
||||
/* utility functions */
|
||||
int16 translateshort(int16 in);
|
||||
long translatelong(long in);
|
||||
uint16 translateshort(uint16 in);
|
||||
char *translatesegmenttype(uint16 type);
|
||||
|
||||
/* RDOFF file manipulation functions */
|
||||
int rdfopen(rdffile *f,const char *name);
|
||||
@ -203,4 +269,6 @@ int rdfaddsegment(rdf_headerbuf *h, long seglength);
|
||||
int rdfwriteheader(FILE *fp,rdf_headerbuf *h);
|
||||
void rdfdoneheader(rdf_headerbuf *h);
|
||||
|
||||
#endif /* RDOFF_UTILS */
|
||||
|
||||
#endif /* _RDOFF_H */
|
||||
|
11
rdoff/rdx.c
11
rdoff/rdx.c
@ -16,7 +16,6 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "rdfload.h"
|
||||
#include "rdoff.h"
|
||||
#include "symtab.h"
|
||||
|
||||
typedef int (*main_fn) (int,char**); /* Main function prototype */
|
||||
@ -27,16 +26,14 @@ int main(int argc, char **argv)
|
||||
main_fn code;
|
||||
symtabEnt * s;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
if (argc < 2) {
|
||||
puts("usage: rdx <rdoff-executable> [params]\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
m = rdfload(argv[1]);
|
||||
|
||||
if (! m)
|
||||
{
|
||||
if (! m) {
|
||||
rdfperror("rdx",argv[1]);
|
||||
exit(255);
|
||||
}
|
||||
@ -46,8 +43,7 @@ int main(int argc, char **argv)
|
||||
in other cases... */
|
||||
|
||||
s = symtabFind(m->symtab, "_main");
|
||||
if (! s)
|
||||
{
|
||||
if (! s) {
|
||||
fprintf(stderr,"rdx: could not find symbol '_main' in '%s'\n",argv[1]);
|
||||
exit(255);
|
||||
}
|
||||
@ -58,4 +54,3 @@ int main(int argc, char **argv)
|
||||
|
||||
return code(argc,argv); /* execute */
|
||||
}
|
||||
|
||||
|
@ -4,4 +4,3 @@ void init_seglocations(segtab * r);
|
||||
void add_seglocation(segtab * r, int localseg, int destseg, long offset);
|
||||
int get_seglocation(segtab * r, int localseg, int * destseg, long * offset);
|
||||
void done_seglocations(segtab * r);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user