mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-02-17 17:19:35 +08:00
RDOFF patch from Yuri Zaporogets:
- Panos Minos's LDRDF fix (correct export of relocation records); - Panos Minos's symtab.c verbose dump fix; - Librarian (rdflib) now puts a signature block when creating a library (instead of creating an empty file). In theory it doesn't break binary compatibility, but due to a bug in the original 'rdlib.c' you can't use old LDRDF with new libraries. Fix this bug as well. - Other minor changes in LDRDF.
This commit is contained in:
parent
87242df32d
commit
27cf503e03
@ -7,13 +7,9 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: actually get this new version working!
|
||||
* - finish off write_output() - appears to be done
|
||||
* - implement library searching - appears to be done
|
||||
* - maybe we only want to do one pass, for performance reasons?
|
||||
* this makes things a little harder, but unix 'ld' copes...
|
||||
* - implement command line options - appears to be done
|
||||
* - improve symbol table implementation - done, thanks to Graeme Defty
|
||||
* TODO:
|
||||
* 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
|
||||
* - general performance improvements
|
||||
@ -21,11 +17,8 @@
|
||||
* BUGS & LIMITATIONS: this program doesn't support multiple code, data
|
||||
* or bss segments, therefore for 16 bit programs whose code, data or BSS
|
||||
* segment exceeds 64K in size, it will not work. This program probably
|
||||
* wont work if compiled by a 16 bit compiler. Try DJGPP if you're running
|
||||
* won't work if compiled by a 16 bit compiler. Try DJGPP if you're running
|
||||
* under DOS. '#define STINGY_MEMORY' may help a little.
|
||||
*
|
||||
* TO FIX: enhance search of required export symbols in libraries (now depends
|
||||
* on modules order in library).
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -39,7 +32,7 @@
|
||||
#include "rdlib.h"
|
||||
#include "segtab.h"
|
||||
|
||||
#define LDRDF_VERSION "1.03"
|
||||
#define LDRDF_VERSION "1.04"
|
||||
|
||||
#define RDF_MAXSEGS 64
|
||||
/* #define STINGY_MEMORY */
|
||||
@ -104,35 +97,6 @@ char * libpath = NULL;
|
||||
/* error file */
|
||||
static FILE * error_file;
|
||||
|
||||
#ifdef _MULTBOOT_H
|
||||
|
||||
/* loading address for multiboot header */
|
||||
unsigned MBHloadAddr;
|
||||
|
||||
/*
|
||||
* Tiny code that moves RDF loader to its working memory region:
|
||||
* mov esi,SOURCE_ADDR ; BE xx xx xx xx
|
||||
* mov edi,DEST_ADDR ; BF xx xx xx xx
|
||||
* mov esp,edi ; 89 FC
|
||||
* push edi ; 57
|
||||
* mov ecx,RDFLDR_LENGTH/4 ; B9 xx xx xx xx
|
||||
* cld ; FC
|
||||
* rep movsd ; F3 A5
|
||||
* ret ; C3
|
||||
*/
|
||||
|
||||
#define RDFLDR_LENGTH 4096 /* Loader will be moved to unused */
|
||||
#define RDFLDR_DESTLOC 0xBF000 /* video page */
|
||||
|
||||
unsigned char RDFloaderMover[]={
|
||||
0xBE, 0, 0, 0, 0, 0xBF, 0, 0xF0, 0xB, 0,
|
||||
0x89, 0xFC, 0x57,
|
||||
0xB9, 0, 4, 0, 0,
|
||||
0xFC, 0xF3, 0xA5, 0xC3
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* the header of the output file, built up stage by stage */
|
||||
rdf_headerbuf * newheader = NULL;
|
||||
|
||||
@ -160,6 +124,29 @@ struct ldrdfoptions {
|
||||
|
||||
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
|
||||
*/
|
||||
@ -736,7 +723,7 @@ void write_output(const char * filename)
|
||||
|
||||
hr = (rdfheaderrec *) malloc(sizeof(struct MultiBootHdrRec));
|
||||
hr->mbh.type = 9;
|
||||
hr->mbh.reclen = sizeof(struct tMultiBootHeader)+RDFLDRMOVER_SIZE;
|
||||
hr->mbh.reclen = sizeof(struct tMultiBootHeader)+TRAMPOLINESIZE;
|
||||
|
||||
hr->mbh.mb.Magic = MB_MAGIC;
|
||||
hr->mbh.mb.Flags = MB_FL_KLUDGE;
|
||||
@ -745,7 +732,7 @@ void write_output(const char * filename)
|
||||
hr->mbh.mb.LoadAddr = MBHloadAddr;
|
||||
hr->mbh.mb.Entry = MBHloadAddr+16+sizeof(struct tMultiBootHeader);
|
||||
|
||||
memcpy(hr->mbh.mover,RDFloaderMover,RDFLDRMOVER_SIZE);
|
||||
memcpy(hr->mbh.trampoline,trampoline_code,TRAMPOLINESIZE);
|
||||
|
||||
rdfaddheader(rdfheader,hr);
|
||||
free(hr);
|
||||
@ -931,8 +918,17 @@ 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+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;
|
||||
@ -1094,11 +1090,14 @@ void write_output(const char * filename)
|
||||
struct MultiBootHdrRec *mbhrec = (struct MultiBootHdrRec *)(rdfheader->buf->buffer);
|
||||
unsigned l = membuflength(rdfheader->buf) + 14 +
|
||||
10*rdfheader->nsegments + rdfheader->seglength;
|
||||
unsigned *ldraddr = (unsigned *)(mbhrec->mover+1);
|
||||
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);
|
||||
|
@ -3,7 +3,13 @@
|
||||
/*
|
||||
* an rdoff library is simply a sequence of RDOFF object files, each
|
||||
* preceded by the name of the module, an ASCII string of up to 255
|
||||
* characters, terminated by a zero.
|
||||
* characters, terminated by a zero.
|
||||
*
|
||||
* When a library is being created, special signature block is placed
|
||||
* in the beginning of the file. It is a string 'RDLIB' followed by a
|
||||
* version number, then long content size and a long time stamp.
|
||||
* The module name of the signature block is '.sig'.
|
||||
*
|
||||
*
|
||||
* There may be an optional directory placed on the end of the file.
|
||||
* The format of the directory will be 'RDLDD' followed by a version
|
||||
@ -11,16 +17,17 @@
|
||||
* directory, the format of which has not yet been designed.
|
||||
* The module name of the directory must be '.dir'.
|
||||
*
|
||||
* All module names beginning with '.' are reserved
|
||||
* for possible future extensions. The linker ignores all such modules,
|
||||
* assuming they have the format of a six byte type & version identifier
|
||||
* followed by long content size, followed by data.
|
||||
* All module names beginning with '.' are reserved for possible future
|
||||
* extensions. The linker ignores all such modules, assuming they have
|
||||
* the format of a six byte type & version identifier followed by long
|
||||
* content size, followed by data.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
/* functions supported:
|
||||
* create a library (no extra operands required)
|
||||
@ -41,6 +48,9 @@ const char *usage =
|
||||
" r - replace (module-name filename)\n"
|
||||
" d - delete (module-name)\n"
|
||||
" t - list\n";
|
||||
|
||||
/* Library signature */
|
||||
const char *rdl_signature = "RDLIB2", *sig_modname = ".sig";
|
||||
|
||||
char **_argv;
|
||||
|
||||
@ -114,10 +124,11 @@ long copylong(FILE *fp, FILE *fp2)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *fp, *fp2, *fptmp;
|
||||
FILE *fp, *fp2 = NULL, *fptmp;
|
||||
char *p, buf[256], c;
|
||||
int i;
|
||||
long l;
|
||||
time_t t;
|
||||
char tmptempl[L_tmpnam], rdbuf[10];
|
||||
|
||||
_argv = argv;
|
||||
@ -137,6 +148,11 @@ int main(int argc, char **argv)
|
||||
perror("rdflib");
|
||||
exit(1);
|
||||
}
|
||||
fwrite(sig_modname, 1, strlen(sig_modname)+1, fp);
|
||||
fwrite(rdl_signature, 1, strlen(rdl_signature), fp);
|
||||
l = sizeof(t = time(NULL));
|
||||
fwrite(&l, sizeof(l), 1, fp);
|
||||
fwrite(&t, 1, l, fp);
|
||||
fclose(fp);
|
||||
break;
|
||||
|
||||
|
@ -6,11 +6,13 @@
|
||||
#include "rdlib.h"
|
||||
|
||||
/*
|
||||
* format of rdoff library files:
|
||||
* format of RDOFF library files:
|
||||
* optional signature ('.sig')
|
||||
* repeat
|
||||
* null terminated module name (max 255 chars)
|
||||
* RDOFF module
|
||||
* until eof
|
||||
* optional directory ('.dir')
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -54,26 +56,27 @@ int rdl_verify(const char * filename)
|
||||
i++;
|
||||
if (feof(fp)) break;
|
||||
|
||||
fread(buf, 6, 1, fp);
|
||||
buf[6] = 0;
|
||||
if (buf[0] == '.') {
|
||||
/*
|
||||
* a special module, eg a directory.
|
||||
* A special module, eg a signature block or a directory.
|
||||
* Format of such a module is defined to be:
|
||||
* six char type identifier (which we've already read)
|
||||
* six char type identifier
|
||||
* long count bytes content
|
||||
* content
|
||||
* so we can handle it uniformaly with RDOFF2 modules...
|
||||
* do nothing here. :-)
|
||||
* so we can handle it uniformaly with RDOFF2 modules.
|
||||
*/
|
||||
fread(buf, 6, 1, fp);
|
||||
buf[6] = 0;
|
||||
/* Currently, nothing useful to do with signature block.. */
|
||||
} else {
|
||||
fread(buf, 6, 1, fp);
|
||||
buf[6] = 0;
|
||||
if (strncmp(buf, "RDOFF", 5)) {
|
||||
return rdl_error = lastresult = 2;
|
||||
} else if (buf[5] != '2') {
|
||||
return rdl_error = lastresult = 3;
|
||||
}
|
||||
}
|
||||
else if (strncmp(buf, "RDOFF", 5)) {
|
||||
return rdl_error = lastresult = 2;
|
||||
}
|
||||
else if (buf[5] != '2') {
|
||||
return rdl_error = lastresult = 3;
|
||||
}
|
||||
|
||||
fread(&length, 4, 1, fp);
|
||||
fseek(fp, length, SEEK_CUR); /* skip over the module */
|
||||
}
|
||||
|
@ -481,7 +481,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r)
|
||||
|
||||
#ifdef _MULTBOOT_H
|
||||
case 9: /* MultiBoot header */
|
||||
membufwrite(h->buf,&r->mbh.mb,sizeof(struct tMultiBootHeader)+RDFLDRMOVER_SIZE);
|
||||
membufwrite(h->buf,&r->mbh.mb,sizeof(struct tMultiBootHeader)+TRAMPOLINESIZE);
|
||||
break ;
|
||||
#endif
|
||||
|
||||
|
@ -77,9 +77,11 @@ struct ModRec {
|
||||
#define SYM_FUNCTION 0x02
|
||||
#define SYM_GLOBAL 0x04
|
||||
|
||||
/* Multiboot record */
|
||||
|
||||
#ifdef _MULTBOOT_H
|
||||
|
||||
#define RDFLDRMOVER_SIZE 22
|
||||
#define TRAMPOLINESIZE 22
|
||||
|
||||
struct MultiBootHdrRec {
|
||||
byte type; /* must be 9 */
|
||||
@ -88,9 +90,10 @@ struct MultiBootHdrRec {
|
||||
struct tMultiBootHeader mb __attribute__ ((packed)); /* MultiBoot header */
|
||||
#else
|
||||
struct tMultiBootHeader mb;
|
||||
#endif
|
||||
byte mover[RDFLDRMOVER_SIZE]; /* Mover of RDF loader */
|
||||
#endif
|
||||
byte trampoline[TRAMPOLINESIZE];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* GenericRec - contains the type and length field, plus a 128 byte
|
||||
|
@ -117,10 +117,14 @@ symtabDump(void *stab, FILE* of)
|
||||
fprintf(of, " ... slot %d ...\n", i);
|
||||
}
|
||||
while(l) {
|
||||
fprintf(of, "%-32s %s:%08lx (%ld)\n",l->ent.name,
|
||||
SegNames[l->ent.segment],
|
||||
l->ent.offset, l->ent.flags);
|
||||
l = l->next;
|
||||
if ((l->ent.segment) == -1) {
|
||||
fprintf(of,"%-32s Unresolved reference\n",l->ent.name);
|
||||
} else {
|
||||
fprintf(of, "%-32s %s:%08lx (%ld)\n",l->ent.name,
|
||||
SegNames[l->ent.segment],
|
||||
l->ent.offset, l->ent.flags);
|
||||
}
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
fprintf(of, "........... end of Symbol table.\n");
|
||||
|
@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
|
||||
|
||||
[ $1 ] || {
|
||||
echo "Usage: $0 <library name> <module> [...]"
|
||||
exit 1
|
||||
|
Loading…
Reference in New Issue
Block a user