Yuri's 12/3/2002 rdoff patches-

This commit is contained in:
Frank Kotler 2002-12-04 00:49:37 +00:00
parent 0bfed6cfdb
commit f17039406f
10 changed files with 317 additions and 275 deletions

View File

@ -52,7 +52,7 @@ static const char *RDOFF2Id = "RDOFF2"; /* written to start of RDOFF files */
#define RDFREC_SEGRELOC 6
#define RDFREC_FARIMPORT 7
#define RDFREC_MODNAME 8
#define RDFREC_MULTIBOOTHDR 9
#define RDFREC_COMMON 10
#define RDFREC_GENERIC 0
@ -99,6 +99,15 @@ struct DLLModRec {
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 0x01
#define SYM_FUNCTION 0x02
@ -340,6 +349,27 @@ static void write_bss_rec(struct BSSRec *r)
headerlength += r->reclen + 2;
}
/*
* Write common variable record.
*/
static void write_common_rec(struct CommonRec *r)
{
char buf[4], *b;
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.
*/
@ -356,10 +386,38 @@ static void rdf2_deflabel(char *name, long segment, long offset,
{
struct ExportRec r;
struct ImportRec ri;
struct CommonRec ci;
static int farsym = 0;
static int i;
byte export_flags = 0;
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 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) {

View File

@ -1,5 +1,11 @@
RDOFF Utilities, version 0.3
============================
*******
This file is getting obsolete. RDOFF documentation is written in Texinfo now.
Directory doc/ contains Texinfo source (rdoff.texi) and makefile for creating
different output formats (info, HTML, PostScript and PDF).
*******
RDOFF Utilities, version 0.3.2
==============================
The files contained in this directory are the C source code of a set
of tools (and general purpose library files) for the manipulation of
@ -8,8 +14,8 @@ exception of 'rdfdump') will NOT work with version 1 object files.
Version 1 of RDOFF is no longer supported.
There is also a 'doc' directory with 'v1-v2' file, which documents the
differences between RDOFF 1 and 2, and an 'rdoff2.txt' file, with
complete documentation for the new format.
differences between RDOFF 1 and 2, and an 'rdoff2.texi' (texinfo source),
with complete documentation for the new format.
Here is a brief summary of the programs' usage:
@ -64,7 +70,7 @@ Most of its options are not implemented, but those that are are listed here:
16, 32 or 256. Default is 16).
-s strip exported symbols from output file. Symbols marked as
SYM_GLOBAL (see rdoff2.txt) are never stripped.
SYM_GLOBAL are never stripped.
-x warn about unresolved symbols.
@ -79,8 +85,7 @@ Most of its options are not implemented, but those that are are listed here:
-L path specify search path for libraries. Default path is a
current directory.
-mbh [addr] add a Multiboot header to output file. If addr is not
specified, default loading address is 0x110000.
-g file embed 'file' as a first header record with type 'generic'.
rdx
@ -176,5 +181,5 @@ file for a comment containing the word 'TODO'. A brief list is given here:
MAINTAINERS
===========
Yuri Zaporogets <yuriz@teraflops.com> - primary maintainer
Yuri Zaporogets <yuriz@ukr.net> - primary maintainer
Julian Hall <jules@dsf.org.uk> - original designer and author

View File

@ -8,7 +8,7 @@
/*
* TODO:
* enhance search of required export symbols in libraries (now depends
* - enhance search of required export symbols in libraries (now depends
* on modules order in library)
* - keep a cache of symbol names in each library module so
* we don't have to constantly recheck the file
@ -25,14 +25,13 @@
#include <stdlib.h>
#include <string.h>
#include "multboot.h"
#include "rdoff.h"
#include "symtab.h"
#include "collectn.h"
#include "rdlib.h"
#include "segtab.h"
#define LDRDF_VERSION "1.04"
#define LDRDF_VERSION "1.05"
#define RDF_MAXSEGS 64
/* #define STINGY_MEMORY */
@ -94,6 +93,9 @@ char * objpath = NULL;
/* libraries search path */
char * libpath = NULL;
/* file to embed as a generic record */
char * generic_rec_file = NULL;
/* error file */
static FILE * error_file;
@ -113,39 +115,15 @@ struct ldrdfoptions {
int verbose;
int align;
int warnUnresolved;
int errorUnresolved;
int strip;
int respfile;
int stderr_redir;
int objpath;
int libpath;
int addMBheader;
} options;
int errorcount = 0; /* determines main program exit status */
/*
* Multiboot header support.
*/
/* loading address for multiboot header */
unsigned MBHloadAddr;
#define RDFLDR_LENGTH 4096 /* Loader size is 4K */
#define RDFLDR_DESTLOC 0x100000 /* and its absolute address */
/*
* Tiny code that moves RDF setup code to its working memory region
*/
unsigned char trampoline_code[] = {
0xBE, 0, 0, 0, 0, /* mov esi,SOURCE_ADDR */
0xBF, 0, 0, 0, 0, /* mov edi,DEST_ADDR */
0x89, 0xFA, /* mov edx,edi */
0xB9, 0, 4, 0, 0, /* mov ecx,RDFLDR_LENGTH/4 */
0xFC, /* cld */
0xF3, 0xA5, /* rep movsd */
0xFF, 0xE2 /* jmp edx */
};
/* =========================================================================
* Utility functions
@ -234,8 +212,8 @@ void loadmodule(const char * filename)
* step through each segment, determine what exactly we're doing with
* it, and if we intend to keep it, determine (a) which segment to
* put it in and (b) whereabouts in that segment it will end up.
* (b) is fairly easy, cos we're now keeping track of how big each segment
* in our output file is...
* (b) is fairly easy, because we're now keeping track of how big each
* segment in our output file is...
*/
void processmodule(const char * filename, struct modulenode * mod)
@ -245,6 +223,7 @@ void processmodule(const char * filename, struct modulenode * mod)
void * header;
rdfheaderrec * hr;
long bssamount = 0;
int bss_was_referenced = 0;
for (seg = 0; seg < mod->f.nsegs; seg++)
{
@ -331,28 +310,25 @@ void processmodule(const char * filename, struct modulenode * mod)
exit(1);
}
while ((hr = rdfgetheaderrec (&mod->f)))
{
while ((hr = rdfgetheaderrec (&mod->f))) {
switch(hr->type) {
case 2: /* imported symbol - define with seg = -1 */
case 7:
case RDFREC_IMPORT: /* imported symbol */
case RDFREC_FARIMPORT:
/* Define with seg = -1 */
symtab_add(hr->i.label, -1, 0);
break;
case 3: /* exported symbol */
{
case RDFREC_GLOBAL: { /* exported symbol */
int destseg;
long destreloc;
if (hr->e.segment == 2)
{
if (hr->e.segment == 2) {
bss_was_referenced = 1;
destreloc = bss_length;
if (destreloc % options.align != 0)
destreloc += options.align - (destreloc % options.align);
destseg = 2;
}
else
{
} else {
if ((destseg = mod->seginfo[(int)hr->e.segment].dest_seg) == -1)
continue;
destreloc = mod->seginfo[(int)hr->e.segment].reloc;
@ -361,18 +337,37 @@ void processmodule(const char * filename, struct modulenode * mod)
break;
}
case 5: /* BSS reservation */
case RDFREC_BSS: /* BSS reservation */
/*
* first, amalgamate all BSS reservations in this module
* into one, because we allow this in the output format.
*/
bssamount += hr->b.amount;
break;
case RDFREC_COMMON: { /* Common variable */
symtabEnt *ste = symtabFind(symtab, hr->c.label);
/* Is the symbol already in the table? */
if (ste) break;
/* Align the variable */
if (bss_length % hr->c.align != 0)
bss_length += hr->c.align - (bss_length % hr->c.align);
if (options.verbose > 1) {
printf ("%s %04x common '%s' => 0002:%08lx (+%04lx)\n",
filename, hr->c.segment, hr->c.label, bss_length, hr->c.size);
}
symtab_add(hr->c.label, 2, bss_length);
mod->bss_reloc = bss_length;
bss_length += hr->c.size;
break;
}
}
}
if (bssamount != 0)
{
if (bssamount != 0 || bss_was_referenced) {
/*
* handle the BSS segment - first pad the existing bss length
* to the correct alignment, then store the length in bss_reloc
@ -405,7 +400,7 @@ void processmodule(const char * filename, struct modulenode * mod)
/*
* Look in list for module by its name.
* Look in the list for module by its name.
*/
int lookformodule(const char *name)
{
@ -627,20 +622,24 @@ int search_libraries()
while ((hr = rdfgetheaderrec (&f)))
{
/* we're only interested in exports, so skip others: */
if (hr->type != 3) continue;
/* We're only interested in exports, so skip others */
if (hr->type != RDFREC_GLOBAL) continue;
/*
* Find the symbol in the symbol table. If the symbol isn't
* defined, we aren't interested, so go on to the next.
* If the symbol is marked as SYM_GLOBAL, somebody will be
* definitely interested in it..
*/
if ((hr->e.flags & SYM_GLOBAL) == 0) {
/*
* otherwise the symbol is just public. Find it in
* the symbol table. If the symbol isn't defined, we
* aren't interested, so go on to the next.
* If it is defined as anything but -1, we're also not
* interested. But if it is defined as -1, insert this
* module into the list of modules to use, and go
* immediately on to the next module...
*/
if (! symtab_get(hr->e.label, &segment, &offset)
|| segment != -1)
{
if (!symtab_get(hr->e.label, &segment, &offset) || segment != -1)
continue;
}
@ -664,8 +663,7 @@ int search_libraries()
processmodule(f.name, lastmodule);
break;
}
if (!keepfile)
{
if (!keepfile) {
free(f.name);
f.name = NULL;
f.fp = NULL;
@ -714,26 +712,31 @@ void write_output(const char * filename)
}
/*
* Add multiboot header if appropriate option is specified.
* Multiboot record *MUST* be the first record in output file.
* If '-g' option was given, first record in output file will be a
* `generic' record, filled with a given file content.
* This can be useful, for example, when constructing multiboot
* compliant kernels.
*/
if (options.addMBheader) {
if (options.verbose)
puts("\nadding multiboot header record");
if (generic_rec_file) {
FILE *ff;
hr = (rdfheaderrec *) malloc(sizeof(struct MultiBootHdrRec));
hr->mbh.type = 9;
hr->mbh.reclen = sizeof(struct tMultiBootHeader)+TRAMPOLINESIZE;
hr->mbh.mb.Magic = MB_MAGIC;
hr->mbh.mb.Flags = MB_FL_KLUDGE;
hr->mbh.mb.Checksum = ~(MB_MAGIC+MB_FL_KLUDGE-1);
hr->mbh.mb.HeaderAddr = MBHloadAddr+16;
hr->mbh.mb.LoadAddr = MBHloadAddr;
hr->mbh.mb.Entry = MBHloadAddr+16+sizeof(struct tMultiBootHeader);
if (options.verbose)
printf("\nadding generic record from binary file %s\n", generic_rec_file);
memcpy(hr->mbh.trampoline,trampoline_code,TRAMPOLINESIZE);
hr = (rdfheaderrec *) malloc(sizeof(struct GenericRec));
if ((ff = fopen(generic_rec_file, "r")) == NULL) {
fprintf(stderr, "ldrdf: couldn't open %s for input\n", generic_rec_file);
exit(1);
}
i = fread(hr->g.data, 1, sizeof(hr->g.data), ff);
fseek(ff, 0, SEEK_END);
if (ftell(ff) > sizeof(hr->g.data)) {
fprintf (error_file, "warning: maximum generic record size is %d, rest of file ignored\n", sizeof(hr->g.data));
}
fclose(ff);
hr->g.type = 0;
hr->g.reclen = i;
rdfaddheader(rdfheader,hr);
free(hr);
}
@ -824,7 +827,7 @@ void write_output(const char * filename)
while ((hr = rdfgetheaderrec(&cur->f)))
{
switch(hr->type) {
case 1: /* relocation record - need to do a fixup */
case RDFREC_RELOC: /* relocation record - need to do a fixup */
/*
* First correct the offset stored in the segment from
* the start of the segment (which may well have changed).
@ -918,27 +921,19 @@ 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)
{
hr->r.segment = cur->seginfo[localseg].dest_seg+64;
hr->r.offset += cur->seginfo[localseg].reloc;
hr->r.refseg = seg;
rdfaddheader(rdfheader, hr);
break;
}
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;
rdfaddheader(rdfheader, hr);
}
break;
case 2: /* import symbol */
case 7:
case RDFREC_IMPORT: /* import symbol */
case RDFREC_FARIMPORT:
/*
* scan the global symbol table for the symbol
* and associate its location with the segment number
@ -947,9 +942,16 @@ void write_output(const char * filename)
se = symtabFind(symtab, hr->i.label);
if (!se || se->segment == -1) {
if (options.warnUnresolved) {
fprintf(error_file, "warning: unresolved reference to `%s'"
switch (options.warnUnresolved) {
case 1:
fprintf(error_file, "warning");
break;
case 2:
fprintf(error_file, "error");
errorcount++;
}
fprintf(error_file, ": unresolved reference to `%s'"
" in module `%s'\n", hr->i.label, cur->name);
if (options.errorUnresolved==1) errorcount++;
}
/*
* we need to allocate a segment number for this
@ -985,7 +987,7 @@ void write_output(const char * filename)
break;
case 3: /* export symbol */
case RDFREC_GLOBAL: /* export symbol */
/*
* need to insert an export for this symbol into the new
* header, unless we're stripping symbols. Even if we're
@ -1016,19 +1018,25 @@ void write_output(const char * filename)
rdfaddheader(rdfheader, hr);
break;
case 8: /* module name */
case RDFREC_MODNAME: /* module name */
/*
* Insert module name record if export symbols
* are not stripped.
* If module name begins with '$' - insert it anyway.
*/
if (options.strip && hr->m.modname[0] != '$') break;
rdfaddheader(rdfheader, hr);
break;
case 6: /* segment fixup */
case RDFREC_DLL: /* DLL name */
/*
* Insert DLL name if it begins with '$'
*/
if (hr->d.libname[0] != '$') break;
rdfaddheader(rdfheader, hr);
break;
case RDFREC_SEGRELOC: /* segment fixup */
/*
* modify the segment numbers if necessary, and
* pass straight through to the output module header
@ -1061,6 +1069,17 @@ void write_output(const char * filename)
hr->r.refseg = seg;
rdfaddheader(rdfheader, hr);
break;
case RDFREC_COMMON: /* Common variable */
/* Is this symbol already in the table? */
se = symtabFind(symtab, hr->c.label);
if (!se) {
printf("%s is not in symtab yet\n", hr->c.label);
break;
}
/* Add segment location */
add_seglocation(&segs, hr->c.segment, se->segment, se->offset);
break;
}
}
@ -1072,7 +1091,7 @@ void write_output(const char * filename)
/*
* combined BSS reservation for the entire results
*/
newrec.type = 5;
newrec.type = RDFREC_BSS;
newrec.b.reclen = 4;
newrec.b.amount = bss_length;
rdfaddheader(rdfheader, &newrec);
@ -1086,27 +1105,13 @@ void write_output(const char * filename)
rdfaddsegment (rdfheader, outputseg[i].length);
}
if (options.addMBheader) {
struct MultiBootHdrRec *mbhrec = (struct MultiBootHdrRec *)(rdfheader->buf->buffer);
unsigned l = membuflength(rdfheader->buf) + 14 +
10*rdfheader->nsegments + rdfheader->seglength;
unsigned *ldraddr = (unsigned *)(mbhrec->trampoline+1);
unsigned *ldrdest = (unsigned *)(mbhrec->trampoline+6);
mbhrec->mb.LoadEndAddr = MBHloadAddr+l+10+RDFLDR_LENGTH;
mbhrec->mb.BSSendAddr = mbhrec->mb.LoadEndAddr;
*ldraddr = MBHloadAddr+l+10;
*ldrdest = RDFLDR_DESTLOC;
}
rdfwriteheader(f, rdfheader);
rdfdoneheader(rdfheader);
/*
* Step through the segments, one at a time, writing out into
* the output file
*/
for (i = 0; i < nsegs; i++)
{
int16 s;
@ -1135,19 +1140,18 @@ void write_output(const char * filename)
void usage()
{
printf("usage:\n");
printf(" ldrdf [options] object modules ... [-llibrary ...]\n");
printf(" ldrdf -r\n");
printf("options:\n");
printf(" -v[=n] increases verbosity by 1, or sets it to n\n");
printf(" -a nn sets segment alignment value (default 16)\n");
printf(" -s strips exported symbols\n");
printf(" -x warn about unresolved symbols\n");
printf(" -o name write output in file 'name'\n");
printf(" -j path specify objects search path\n");
printf(" -L path specify libraries search path\n");
printf(" -mbh [address] add multiboot header to output file. Default\n");
printf(" loading address is 0x110000\n");
printf("usage:\n"
" ldrdf [options] object modules ... [-llibrary ...]\n"
" ldrdf -r\n"
"options:\n"
" -v[=n] increases verbosity by 1, or sets it to n\n"
" -a nn sets segment alignment value (default 16)\n"
" -s strips exported symbols\n"
" -x warn about unresolved symbols\n"
" -o name write output in file 'name'\n"
" -j path specify objects search path\n"
" -L path specify libraries search path\n"
" -g file embed 'file' as a first header record with type 'generic'\n");
exit(0);
}
@ -1166,7 +1170,7 @@ int main(int argc, char ** argv)
argc --, argv ++;
if (argc == 0) usage();
while (argc && **argv == '-' && argv[0][1] != 'l')
while (argc && *argv && **argv == '-' && argv[0][1] != 'l')
{
switch(argv[0][1]) {
case 'r':
@ -1200,35 +1204,29 @@ int main(int argc, char ** argv)
case 'x':
options.warnUnresolved = 1;
if (argv[0][2]=='e')
options.errorUnresolved = 1;
options.warnUnresolved++;
break;
case 'o':
outname = argv[1];
argv++, argc--;
break;
case 'j':
if (!objpath)
{
if (!objpath) {
options.objpath = 1;
objpath = argv[1];
argv++, argc--;
break;
}
else
{
} else {
fprintf(stderr,"ldrdf: more than one objects search path specified\n");
exit(1);
}
case 'L':
if (!libpath)
{
if (!libpath) {
options.libpath = 1;
libpath = argv[1];
argv++, argc--;
break;
}
else
{
} else {
fprintf(stderr,"ldrdf: more than one libraries search path specified\n");
exit(1);
}
@ -1239,70 +1237,58 @@ int main(int argc, char ** argv)
options.respfile = 1;
if (argv[1] != NULL) f = fopen(argv[1],"r");
else
{
else {
fprintf(stderr,"ldrdf: no response file name specified\n");
exit(1);
}
if (f == NULL)
{
if (f == NULL) {
fprintf(stderr,"ldrdf: unable to open response file\n");
exit(1);
}
argc-=2;
while(fgets(buf,sizeof(buf)-1,f)!=NULL)
{
argv++, argc--;
while (fgets(buf, sizeof(buf), f) != NULL) {
char *p;
if (buf[0]=='\n') continue;
if ((p = strchr(buf,'\n')) != 0)
*p=0;
if (i >= 128)
{
if ((p = strchr(buf,'\n')) != NULL) *p = '\0';
if (i >= 128) {
fprintf(stderr,"ldrdf: too many input files\n");
exit(1);
}
*(respstrings+i) = newstr(buf);
argc++, i++;
}
goto done;
break;
}
case '2':
options.stderr_redir = 1;
error_file = stdout;
break;
case 'm':
if (argv[0][2] == 'b' && argv[0][3] == 'h') {
if (argv[1][0] != '-') {
MBHloadAddr = atoi(argv[1]);
} else {
MBHloadAddr = MB_DEFAULTLOADADDR;
}
options.addMBheader = 1;
case 'g':
generic_rec_file = argv[1];
argv++, argc--;
break;
}
default:
usage();
}
argv++, argc--;
}
done:
if (options.verbose > 4) {
printf("ldrdf invoked with options:\n");
printf(" section alignment: %d bytes\n", options.align);
printf(" output name: `%s'\n", outname);
if (options.strip)
printf(" strip symbols\n");
if (options.warnUnresolved)
if (options.warnUnresolved == 1)
printf(" warn about unresolved symbols\n");
if (options.errorUnresolved)
if (options.warnUnresolved == 2)
printf(" error if unresolved symbols\n");
if (options.objpath)
printf(" objects search path: %s\n",objpath);
if (options.libpath)
printf(" libraries search path: %s\n",libpath);
if (options.addMBheader)
printf(" loading address for multiboot header: 0x%X\n",MBHloadAddr);
printf("\n");
}
@ -1314,9 +1300,9 @@ done:
exit(1);
}
if (*respstrings) argv = respstrings;
while (argc)
{
while (argc) {
if (!*argv) argv = respstrings;
if (!*argv) break;
if (!strncmp(*argv, "-l", 2)) /* library */
{
if(libpath) add_library(newstrcat(libpath,*argv + 2));
@ -1335,7 +1321,6 @@ done:
return 0;
}
search_libraries();
if (options.verbose > 2)

View File

@ -38,7 +38,7 @@ int main(int argc, char **argv)
return 1;
}
if (! nasm_strnicmp(getfilename(*argv),"rdf2com",7)) {
if (! nasm_stricmp(getfilename(*argv),"rdf2com")) {
origin = 0x100;
}
argv++, argc--;

View File

@ -1,9 +1,12 @@
/*
* rdfdump.c - dump RDOFF file header.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rdoff.h"
#include "multboot.h"
FILE *infile;
@ -31,12 +34,12 @@ int16 translateshort(int16 in) {
return r;
}
void print_header(long length, int rdf_version) {
char buf[129],t,s,l,flags;
void print_header(long length, int rdf_version)
{
char buf[129],t,l,s,flags;
unsigned char reclen;
long o,ll;
int16 rs;
struct tMultiBootHeader *mb;
while (length > 0) {
fread(&t,1,1,infile);
@ -44,9 +47,13 @@ void print_header(long length, int rdf_version) {
fread(&reclen,1,1,infile);
}
switch(t) {
case RDFREC_GENERIC: /* generic record */
printf(" generic record (length=%d)\n", (int)reclen);
fseek(infile, reclen, SEEK_CUR);
break;
case 1: /* relocation record */
case 6: /* segment relocation */
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);
@ -62,8 +69,8 @@ void print_header(long length, int rdf_version) {
printf(" warning: seg relocation not supported in RDOFF1\n");
break;
case 2: /* import record */
case 7: /* import far symbol */
case RDFREC_IMPORT: /* import record */
case RDFREC_FARIMPORT: /* import far symbol */
fread(&rs,2,1,infile);
ll = 0;
@ -71,9 +78,7 @@ void print_header(long length, int rdf_version) {
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
}
else
{
} else {
for (;ll < reclen - 2; ll++)
fread(&buf[ll],1,1,infile);
}
@ -85,7 +90,7 @@ void print_header(long length, int rdf_version) {
printf (" warning: far import not supported in RDOFF1\n");
break;
case 3: /* export record */
case RDFREC_GLOBAL: /* export record */
fread(&flags,1,1,infile);
fread(&s,1,1,infile);
fread(&o,4,1,infile);
@ -95,9 +100,7 @@ void print_header(long length, int rdf_version) {
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
}
else
{
} else {
for (; ll < reclen - 6; ll ++)
fread(&buf[ll],1,1,infile);
}
@ -111,17 +114,15 @@ void print_header(long length, int rdf_version) {
if (rdf_version == 1) length -= ll + 6;
break;
case 4: /* DLL and Module records */
case 8:
case RDFREC_DLL: /* DLL and Module records */
case RDFREC_MODNAME:
ll = 0;
if (rdf_version == 1) {
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
}
else
{
} else {
for (; ll < reclen; ll++)
fread(&buf[ll],1,1,infile);
}
@ -129,7 +130,8 @@ void print_header(long length, int rdf_version) {
else printf(" module: %s\n",buf);
if (rdf_version == 1) length -= ll + 1;
break;
case 5: /* BSS reservation */
case RDFREC_BSS: /* BSS reservation */
fread(&ll,4,1,infile);
printf(" bss reservation: %08lx bytes\n",translatelong(ll));
if (rdf_version == 1) length -= 5;
@ -137,20 +139,27 @@ void print_header(long length, int rdf_version) {
printf(" warning: reclen != 4\n");
break;
case 9: /* MultiBoot header record */
fread(buf,reclen,1,infile);
mb = (struct tMultiBootHeader *)buf;
printf(" multiboot header: load address=0x%X, size=0x%X, entry=0x%X\n",
mb->LoadAddr, mb->LoadEndAddr - mb->LoadAddr, mb->Entry);
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);
printf(" common: segment %04x = %s, %ld:%d\n", translateshort(seg),
buf, translatelong(size), translateshort(align));
break;
}
default:
printf(" unrecognised 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");
if (rdf_version == 1) length --;
}
if (rdf_version != 1) length -= 2 + reclen;
}

View File

@ -23,7 +23,6 @@
* content size, followed by data.
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
@ -203,7 +202,7 @@ int main(int argc, char **argv)
case 'x':
if (argc < 5) {
fprintf(stderr, "rdflib: required paramenter missing\n");
fprintf(stderr, "rdflib: required parameter missing\n");
exit(1);
}
case 't':
@ -297,7 +296,7 @@ int main(int argc, char **argv)
argc--;
case 'd': /* delete module */
if (argc < 4) {
fprintf(stderr, "rdflib: required paramenter missing\n");
fprintf(stderr, "rdflib: required parameter missing\n");
exit(1);
}
@ -332,7 +331,7 @@ int main(int argc, char **argv)
l = ftell(fp);
fseek(fp, 0, SEEK_SET);
copybytes(fp, fptmp, l);
rewind(fptmp); /* reopen files */
rewind(fptmp);
freopen(argv[2], "wb", fp);
while (! feof(fptmp) ) {

View File

@ -19,7 +19,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "rdfload.h"
#include "symtab.h"

View File

@ -1,28 +1,16 @@
/*
* rdlib.c - routines for manipulating RDOFF libraries (.rdl)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rdoff.h"
#include "rdlib.h"
#include "rdlar.h"
/*
* format of RDOFF library files:
* optional signature ('.sig')
* repeat
* null terminated module name (max 255 chars)
* RDOFF module
* until eof
* optional directory ('.dir')
*/
/*
* TODO
*
* No support exists yet for special modules. But we aren't using
* any special modules yet. They are only defined now so that their
* existance doesn't break older versions of the linker... presently
* anything whose name begins with '.' is ignored.
*/
/* See Texinfo documentation about new RDOFF libraries format */
int rdl_error = 0;
@ -31,6 +19,7 @@ char *rdl_errors[5] = {
"file contains modules of an unsupported RDOFF version",
"module not found"
};
int rdl_verify(const char * filename)
{
FILE * fp = fopen(filename, "rb");

View File

@ -19,8 +19,6 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "multboot.h"
#include "rdoff.h"
#define newstr(str) strcpy(malloc(strlen(str) + 1),str)
@ -365,8 +363,8 @@ rdfheaderrec *rdfgetheaderrec(rdffile *f)
RI8(r.g.reclen);
switch(r.type) {
case 1: /* Relocation record */
case 6:
case RDFREC_RELOC: /* Relocation record */
case RDFREC_SEGRELOC:
if (r.r.reclen != 8) {
rdf_errno = 9;
return NULL;
@ -377,24 +375,24 @@ rdfheaderrec *rdfgetheaderrec(rdffile *f)
RI16(r.r.refseg);
break;
case 2: /* Imported symbol record */
case 7:
case RDFREC_IMPORT: /* Imported symbol record */
case RDFREC_FARIMPORT:
RI16(r.i.segment);
RS(r.i.label,32);
break;
case 3: /* Exported symbol record */
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 4: /* DLL record */
case RDFREC_DLL: /* DLL record */
RS(r.d.libname,127);
break;
case 5: /* BSS reservation record */
case RDFREC_BSS: /* BSS reservation record */
if (r.r.reclen != 4) {
rdf_errno = 9;
return NULL;
@ -402,10 +400,17 @@ rdfheaderrec *rdfgetheaderrec(rdffile *f)
RI32(r.b.amount);
break;
case 8: /* Module name record */
case RDFREC_MODNAME: /* Module name record */
RS(r.m.modname,127);
break;
case RDFREC_COMMON: /* Common variable */
RI16(r.c.segment);
RI32(r.c.size);
RI16(r.c.align);
RS(r.c.label,32);
break;
default:
#ifdef STRICT_ERRORS
rdf_errno = 8; /* unknown header record */
@ -446,45 +451,42 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r)
switch (r->type)
{
case 1:
case 6:
case RDFREC_GENERIC: /* generic */
membufwrite(h->buf, &r->g.data, r->g.reclen);
break;
case RDFREC_RELOC:
case RDFREC_SEGRELOC:
membufwrite(h->buf,&r->r.segment,1);
membufwrite(h->buf,&r->r.offset,-4);
membufwrite(h->buf,&r->r.length,1);
membufwrite(h->buf,&r->r.refseg,-2); /* 9 bytes written */
break;
case 2: /* import */
case 7:
case RDFREC_IMPORT: /* import */
case RDFREC_FARIMPORT:
membufwrite(h->buf,&r->i.segment,-2);
membufwrite(h->buf,&r->i.label,strlen(r->i.label) + 1);
break ;
case 3: /* export */
case RDFREC_GLOBAL: /* export */
membufwrite(h->buf,&r->e.flags,1);
membufwrite(h->buf,&r->e.segment,1);
membufwrite(h->buf,&r->e.offset,-4);
membufwrite(h->buf,&r->e.label,strlen(r->e.label) + 1);
break ;
case 4: /* DLL */
case RDFREC_DLL: /* DLL */
membufwrite(h->buf,&r->d.libname,strlen(r->d.libname) + 1);
break ;
case 5: /* BSS */
case RDFREC_BSS: /* BSS */
membufwrite(h->buf,&r->b.amount,-4);
break ;
case 8: /* Module name */
case RDFREC_MODNAME: /* Module name */
membufwrite(h->buf,&r->m.modname,strlen(r->m.modname) + 1);
break ;
#ifdef _MULTBOOT_H
case 9: /* MultiBoot header */
membufwrite(h->buf,&r->mbh.mb,sizeof(struct tMultiBootHeader)+TRAMPOLINESIZE);
break ;
#endif
default:
#ifdef STRICT_ERRORS
return (rdf_errno = 8);

View File

@ -22,6 +22,16 @@ typedef unsigned char byte;
#define RDF_MAXSEGS 64
/* the records that can be found in the RDOFF header */
#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 */
@ -72,33 +82,24 @@ struct ModRec {
char modname[128]; /* module name */
};
struct CommonRec {
byte type; /* must be 10 */
byte reclen; /* equals 7+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 0x01
#define SYM_FUNCTION 0x02
#define SYM_GLOBAL 0x04
/* Multiboot record */
#ifdef _MULTBOOT_H
#define TRAMPOLINESIZE 22
struct MultiBootHdrRec {
byte type; /* must be 9 */
byte reclen; /* content length */
#ifdef __GNUC__
struct tMultiBootHeader mb __attribute__ ((packed)); /* MultiBoot header */
#else
struct tMultiBootHeader mb;
#endif
byte trampoline[TRAMPOLINESIZE];
};
#endif
/* GenericRec - contains the type and length field, plus a 128 byte
char array 'data', which will probably never be used! */
/*
* GenericRec - contains the type and length field, plus a 128 byte
* char array 'data'
*/
struct GenericRec {
byte type;
byte reclen;
@ -107,16 +108,14 @@ struct GenericRec {
typedef union RDFHeaderRec {
char type; /* invariant throughout all below */
struct GenericRec g;
struct GenericRec g; /* type 0 */
struct RelocRec r; /* type == 1 / 6 */
struct ImportRec i; /* type == 2 / 7 */
struct ExportRec e; /* type == 3 */
struct DLLRec d; /* type == 4 */
struct BSSRec b; /* type == 5 */
struct ModRec m; /* type == 8 */
#ifdef _MULTBOOT_H
struct MultiBootHdrRec mbh; /* type == 9 */
#endif
struct CommonRec c; /* type == 10 */
} rdfheaderrec;
struct SegmentHeaderRec {
@ -202,7 +201,4 @@ int rdfaddsegment(rdf_headerbuf *h, long seglength);
int rdfwriteheader(FILE *fp,rdf_headerbuf *h);
void rdfdoneheader(rdf_headerbuf *h);
/* This is needed by linker to write multiboot header record */
int membuflength(memorybuffer *b);
#endif /* _RDOFF_H */