From f17039406f097ded4b3b59560f227f0ef69386b4 Mon Sep 17 00:00:00 2001 From: Frank Kotler Date: Wed, 4 Dec 2002 00:49:37 +0000 Subject: [PATCH] Yuri's 12/3/2002 rdoff patches- --- output/outrdf2.c | 60 ++++++++++- rdoff/README | 21 ++-- rdoff/ldrdf.c | 303 ++++++++++++++++++++++++++----------------------------- rdoff/rdf2bin.c | 2 +- rdoff/rdfdump.c | 67 ++++++------ rdoff/rdflib.c | 7 +- rdoff/rdfload.c | 1 - rdoff/rdlib.c | 25 ++--- rdoff/rdoff.c | 50 ++++----- rdoff/rdoff.h | 54 +++++----- 10 files changed, 316 insertions(+), 274 deletions(-) diff --git a/output/outrdf2.c b/output/outrdf2.c index 18d5e85..1dfef93 100644 --- a/output/outrdf2.c +++ b/output/outrdf2.c @@ -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 @@ -341,6 +350,27 @@ static void write_bss_rec(struct BSSRec *r) } /* + * 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. */ static void write_dllmod_rec(struct DLLModRec *r) @@ -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) { diff --git a/rdoff/README b/rdoff/README index 1c59e75..4962b89 100644 --- a/rdoff/README +++ b/rdoff/README @@ -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 - primary maintainer +Yuri Zaporogets - primary maintainer Julian Hall - original designer and author diff --git a/rdoff/ldrdf.c b/rdoff/ldrdf.c index 2226fef..26c991e 100644 --- a/rdoff/ldrdf.c +++ b/rdoff/ldrdf.c @@ -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 #include -#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 RDFREC_DLL: /* DLL name */ + /* + * Insert DLL name if it begins with '$' + */ + if (hr->d.libname[0] != '$') break; rdfaddheader(rdfheader, hr); break; - case 6: /* segment fixup */ + 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) diff --git a/rdoff/rdf2bin.c b/rdoff/rdf2bin.c index 07ad312..938b4a9 100644 --- a/rdoff/rdf2bin.c +++ b/rdoff/rdf2bin.c @@ -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--; diff --git a/rdoff/rdfdump.c b/rdoff/rdfdump.c index 5bf6264..d8690d2 100644 --- a/rdoff/rdfdump.c +++ b/rdoff/rdfdump.c @@ -1,9 +1,12 @@ +/* + * rdfdump.c - dump RDOFF file header. + */ + #include #include #include #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; } diff --git a/rdoff/rdflib.c b/rdoff/rdflib.c index edf4a22..332d699 100644 --- a/rdoff/rdflib.c +++ b/rdoff/rdflib.c @@ -23,7 +23,6 @@ * content size, followed by data. */ -#include #include #include #include @@ -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) ) { diff --git a/rdoff/rdfload.c b/rdoff/rdfload.c index 6928ca2..4737282 100644 --- a/rdoff/rdfload.c +++ b/rdoff/rdfload.c @@ -19,7 +19,6 @@ #include #include -#include #include "rdfload.h" #include "symtab.h" diff --git a/rdoff/rdlib.c b/rdoff/rdlib.c index 6eee5a9..f511c1c 100644 --- a/rdoff/rdlib.c +++ b/rdoff/rdlib.c @@ -1,28 +1,16 @@ +/* + * rdlib.c - routines for manipulating RDOFF libraries (.rdl) + */ + #include #include #include #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"); diff --git a/rdoff/rdoff.c b/rdoff/rdoff.c index 30d2c03..43e3d65 100644 --- a/rdoff/rdoff.c +++ b/rdoff/rdoff.c @@ -19,8 +19,6 @@ #include #include #include - -#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); diff --git a/rdoff/rdoff.h b/rdoff/rdoff.h index e9b9594..ee00c34 100644 --- a/rdoff/rdoff.h +++ b/rdoff/rdoff.h @@ -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 */ -- 2.7.4