Update rdoff

This commit is contained in:
Frank Kotler 2003-12-12 06:18:07 +00:00
parent f7956c4072
commit b4a1735c47
9 changed files with 265 additions and 243 deletions

View file

@ -119,6 +119,7 @@ in \c{elf}
\IR{elf shared libraries} ELF, shared libraries
\IR{executable and linkable format} Executable and Linkable Format
\IR{extern, obj extensions to} \c{EXTERN}, \c{obj} extensions to
\IR{extern, rdf extensions to} \c{EXTERN}, \c{rdf} extensions to
\IR{freebsd} FreeBSD
\IR{freelink} FreeLink
\IR{functions, c calling convention} functions, C calling convention
@ -4543,6 +4544,25 @@ or \i\c{object} to the directive:
\c global kernel_ticks:export data
\S{rdfimpt} \c{rdf} Extensions to the \c{EXTERN} directive\I{EXTERN,
rdf extensions to}
By default the \c{EXTERN} directive in \c{RDOFF} declares a "pure external"
symbol (i.e. the static linker will complain if such a symbol is not resolved).
To declare an "imported" symbol, which must be resolved later during a dynamic
linking phase, \c{RDOFF} offers an additional \c{import} modifier. As in
\c{GLOBAL}, you can also specify whether an imported symbol is a procedure
(function) or data object. For example:
\c library $libc
\c extern _open:import
\c extern _printf:import proc
\c extern _errno:import data
Here the directive \c{LIBRARY} is also included, which gives the dynamic linker
a hint as to where to find requested symbols.
\H{dbgfmt} \i\c{dbg}: Debugging Format
The \c{dbg} output format is not built into NASM in the default

View file

@ -70,6 +70,7 @@ struct RelocRec {
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
@ -109,9 +110,10 @@ struct CommonRec {
};
/* Flags for ExportRec */
#define SYM_DATA 0x01
#define SYM_FUNCTION 0x02
#define SYM_GLOBAL 0x04
#define SYM_DATA 1
#define SYM_FUNCTION 2
#define SYM_GLOBAL 4
#define SYM_IMPORT 8
#define COUNT_SEGTYPES 9
@ -124,7 +126,7 @@ static int segmenttypenumbers[COUNT_SEGTYPES] = {
0, 1, 1, 2, 3, 4, 5, 6, 7
};
/* code for managing buffers needed to seperate code and data into individual
/* code for managing buffers needed to separate code and data into individual
* sections until they are ready to be written to the file.
* We'd better hope that it all fits in memory else we're buggered... */
@ -332,6 +334,7 @@ static void write_import_rec(struct ImportRec *r)
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);
@ -389,7 +392,7 @@ static void rdf2_deflabel(char *name, long segment, long offset,
struct CommonRec ci;
static int farsym = 0;
static int i;
byte export_flags = 0;
byte symflags = 0;
if (is_global == 2) {
/* Common variable */
@ -425,7 +428,11 @@ static void rdf2_deflabel(char *name, long segment, long offset,
if (!nasm_strnicmp(special, "export", 6)) {
special += 6;
export_flags |= SYM_GLOBAL;
symflags |= SYM_GLOBAL;
}
else if (!nasm_strnicmp(special, "import", 6)) {
special += 6;
symflags |= SYM_IMPORT;
}
if (*special) {
@ -438,11 +445,11 @@ static void rdf2_deflabel(char *name, long segment, long offset,
}
else if (!nasm_stricmp(special, "proc") ||
!nasm_stricmp(special, "function")) {
export_flags |= SYM_FUNCTION;
symflags |= SYM_FUNCTION;
}
else if (!nasm_stricmp(special, "data") ||
!nasm_stricmp(special, "object")) {
export_flags |= SYM_DATA;
symflags |= SYM_DATA;
}
else
error(ERR_NONFATAL, "unrecognised symbol type `%s'", special);
@ -458,18 +465,20 @@ static void rdf2_deflabel(char *name, long segment, long offset,
if (segments[i].segnumber == segment>>1) break;
}
if (i >= nsegments) { /* EXTERN declaration */
if (farsym)
ri.type = RDFREC_FARIMPORT;
else
ri.type = RDFREC_IMPORT;
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 = 3 + strlen(ri.label);
ri.reclen = 4 + strlen(ri.label);
write_import_rec(&ri);
} else if (is_global) {
r.type = RDFREC_GLOBAL;
r.flags = export_flags;
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);

View file

@ -12,7 +12,7 @@
@end titlepage
@ifinfo
Copyright @copyright{} 2002 Netwide Assembler Project.
Copyright @copyright{} 2002-2003 Netwide Assembler Project.
Written by Yuri Zaporogets @email{yuriz@@ukr.net}
Based on various sources and notes written by Julian Hall @email{jules@@dsf.org.uk}
Distributed under GNU documentation license.
@ -81,7 +81,7 @@ by a section header.
@subsection Relocation records
@node Import
@subsection Declaring external symbols
@subsection Declaring external and imported symbols
@node Export
@subsection Declaring public and exported symbols

View file

@ -1,9 +1,12 @@
/* ldrdf.c RDOFF Object File linker/loader main program
/*
* ldrdf.c - RDOFF Object File linker/loader main program.
*
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
* Julian Hall. All rights reserved. The software is
* redistributable under the licence given in the file "Licence"
* distributed in the NASM archive.
* Copyright (c) 1996,99 Julian Hall. All rights reserved.
* Copyright (c) 2000-2003 RET & COM Research.
*
* This file is distributed under the terms and conditions of the
* GNU Lesser Public License (LGPL), version 2.1.
* See http://www.gnu.org/copyleft/lgpl.html for details.
*/
/*
@ -31,7 +34,7 @@
#include "rdlib.h"
#include "segtab.h"
#define LDRDF_VERSION "1.05"
#define LDRDF_VERSION "1.07"
#define RDF_MAXSEGS 64
/* #define STINGY_MEMORY */
@ -114,7 +117,7 @@ long bss_length;
struct ldrdfoptions {
int verbose;
int align;
int warnUnresolved;
int dynalink;
int strip;
int respfile;
int stderr_redir;
@ -129,13 +132,11 @@ int errorcount = 0; /* determines main program exit status */
* Utility functions
*/
/*
* initsegments()
*
* sets up segments 0, 1, and 2, the initial code data and bss segments
*/
void initsegments()
{
nsegs = 3;
@ -154,6 +155,7 @@ void initsegments()
bss_length = 0;
}
/*
* loadmodule
*
@ -161,34 +163,27 @@ void initsegments()
* each segment it contains (including determining destination segments and
* relocation factors for segments that are kept).
*/
void loadmodule(const char * filename)
{
if (options.verbose)
printf("loading `%s'\n", filename);
/* allocate a new module entry on the end of the modules list */
if (!modules)
{
if (!modules) {
modules = malloc (sizeof(*modules));
lastmodule = modules;
}
else
{
} else {
lastmodule->next = malloc (sizeof(*modules));
lastmodule = lastmodule->next;
}
if ( ! lastmodule)
{
if (!lastmodule) {
fprintf(stderr, "ldrdf: out of memory\n");
exit(1);
}
/* open the file using 'rdfopen', which returns nonzero on error */
if (rdfopen(&lastmodule->f, filename) != 0)
{
if (rdfopen(&lastmodule->f, filename) != 0) {
rdfperror("ldrdf", filename);
exit(1);
}
@ -198,13 +193,13 @@ void loadmodule(const char * filename)
* it contains, and what we should do with them (determine relocation
* factor if we decide to keep them)
*/
lastmodule->header = NULL;
lastmodule->name = strdup(filename);
lastmodule->next = NULL;
processmodule(filename, lastmodule);
}
/*
* processmodule()
@ -215,7 +210,6 @@ void loadmodule(const char * filename)
* (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)
{
struct segconfig sconf;
@ -315,35 +309,35 @@ void processmodule(const char * filename, struct modulenode * mod)
case RDFREC_IMPORT: /* imported symbol */
case RDFREC_FARIMPORT:
/* Define with seg = -1 */
symtab_add(hr->i.label, -1, 0);
break;
symtab_add(hr->i.label, -1, 0);
break;
case RDFREC_GLOBAL: { /* exported symbol */
int destseg;
long destreloc;
int destseg;
long destreloc;
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;
destreloc = bss_length;
if (destreloc % options.align != 0)
destreloc += options.align - (destreloc % options.align);
destseg = 2;
} else {
if ((destseg = mod->seginfo[(int)hr->e.segment].dest_seg) == -1)
continue;
destreloc = mod->seginfo[(int)hr->e.segment].reloc;
}
symtab_add(hr->e.label, destseg, destreloc + hr->e.offset);
break;
}
if ((destseg = mod->seginfo[(int)hr->e.segment].dest_seg) == -1)
continue;
destreloc = mod->seginfo[(int)hr->e.segment].reloc;
}
symtab_add(hr->e.label, destseg, destreloc + hr->e.offset);
break;
}
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;
/*
* 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);
@ -366,7 +360,7 @@ void processmodule(const char * filename, struct modulenode * mod)
}
}
}
if (bssamount != 0 || bss_was_referenced) {
/*
* handle the BSS segment - first pad the existing bss length
@ -375,7 +369,7 @@ void processmodule(const char * filename, struct modulenode * mod)
* bss_length.
*/
if (bss_length % options.align != 0)
bss_length += options.align - (bss_length % options.align);
bss_length += options.align - (bss_length % options.align);
mod->bss_reloc = bss_length;
if (options.verbose > 1) {
@ -400,18 +394,18 @@ void processmodule(const char * filename, struct modulenode * mod)
/*
* Look in the list for module by its name.
* Return 1 if a given module is in the list, 0 otherwise.
*/
int lookformodule(const char *name)
{
struct modulenode *curr=modules;
{
struct modulenode *curr = modules;
while(curr) {
if (!strcmp(name,curr->name)) return 1;
curr = curr->next;
}
return 0;
}
while(curr) {
if (!strcmp(name, curr->name)) return 1;
curr = curr->next;
}
return 0;
}
/*
@ -446,6 +440,7 @@ int findsegment(int16 type,int16 reserved)
return allocnewseg(type,reserved);
}
/*
* symtab_add()
*
@ -463,7 +458,6 @@ int findsegment(int16 type,int16 reserved)
* routine won't change a previously existing symbol. It will change
* to segment = -2 only if the segment was previously < 0.
*/
void symtab_add(const char * symbol, int segment, long offset)
{
symtabEnt * ste;
@ -515,7 +509,6 @@ void symtab_add(const char * symbol, int segment, long offset)
* are assumed to have -1:0 associated. Returns 1 if the symbol was
* successfully located.
*/
int symtab_get(const char * symbol, int * segment, long * offset)
{
symtabEnt * ste = symtabFind(symtab, symbol);
@ -532,13 +525,13 @@ int symtab_get(const char * symbol, int * segment, long * offset)
}
}
/*
* add_library()
*
* checks that a library can be opened and is in the correct format,
* then adds it to the linked list of libraries.
*/
void add_library(const char * name)
{
if (rdl_verify(name)) {
@ -571,6 +564,7 @@ void add_library(const char * name)
}
}
/*
* search_libraries()
*
@ -581,7 +575,6 @@ void add_library(const char * name)
* returns 1 if any extra library modules are included, indicating that
* another pass through the library list should be made (possibly).
*/
int search_libraries()
{
struct librarynode * cur;
@ -634,13 +627,13 @@ int search_libraries()
* 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 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)
continue;
continue;
}
doneanything = 1;
@ -664,10 +657,10 @@ int search_libraries()
break;
}
if (!keepfile) {
free(f.name);
f.name = NULL;
f.fp = NULL;
}
free(f.name);
f.name = NULL;
f.fp = NULL;
}
}
if (rdl_error != 0 && rdl_error != RDL_ENOTFOUND)
rdl_perror("ldrdf", cur->name);
@ -682,6 +675,7 @@ int search_libraries()
return doneanything;
}
/*
* write_output()
*
@ -719,10 +713,10 @@ void write_output(const char * filename)
*/
if (generic_rec_file) {
FILE *ff;
if (options.verbose)
printf("\nadding generic record from binary file %s\n", generic_rec_file);
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);
@ -734,10 +728,10 @@ void write_output(const char * filename)
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);
rdfaddheader(rdfheader, hr);
free(hr);
}
@ -941,17 +935,10 @@ void write_output(const char * filename)
*/
se = symtabFind(symtab, hr->i.label);
if (!se || se->segment == -1) {
if (options.warnUnresolved) {
switch (options.warnUnresolved) {
case 1:
fprintf(error_file, "warning");
break;
case 2:
fprintf(error_file, "error");
errorcount++;
}
fprintf(error_file, ": unresolved reference to `%s'"
if (!options.dynalink && !(hr->i.flags & SYM_IMPORT)) {
fprintf(error_file, "error: unresolved reference to `%s'"
" in module `%s'\n", hr->i.label, cur->name);
errorcount++;
}
/*
* we need to allocate a segment number for this
@ -984,7 +971,6 @@ void write_output(const char * filename)
}
add_seglocation(&segs, hr->i.segment, se->segment, se->offset);
break;
case RDFREC_GLOBAL: /* export symbol */
@ -1023,7 +1009,7 @@ void write_output(const char * filename)
* 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;
@ -1144,10 +1130,10 @@ void usage()
" 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"
" -v[=n] increase verbosity by 1, or set it to n\n"
" -a nn set segment alignment value (default 16)\n"
" -s strip public symbols\n"
" -dy Unix-style dynamic linking\n"
" -o name write output in file 'name'\n"
" -j path specify objects search path\n"
" -L path specify libraries search path\n"
@ -1163,7 +1149,7 @@ int main(int argc, char ** argv)
options.verbose = 0;
options.align = 16;
options.warnUnresolved = 0;
options.dynalink = 0;
options.strip = 0;
error_file = stderr;
@ -1201,10 +1187,8 @@ int main(int argc, char ** argv)
case 's':
options.strip = 1;
break;
case 'x':
options.warnUnresolved = 1;
if (argv[0][2]=='e')
options.warnUnresolved++;
case 'd':
if (argv[0][2] == 'y') options.dynalink = 1;
break;
case 'o':
outname = argv[1];
@ -1212,40 +1196,40 @@ int main(int argc, char ** argv)
break;
case 'j':
if (!objpath) {
options.objpath = 1;
objpath = argv[1];
argv++, argc--;
break;
options.objpath = 1;
objpath = argv[1];
argv++, argc--;
break;
} else {
fprintf(stderr,"ldrdf: more than one objects search path specified\n");
exit(1);
fprintf(stderr,"ldrdf: more than one objects search path specified\n");
exit(1);
}
case 'L':
if (!libpath) {
options.libpath = 1;
libpath = argv[1];
argv++, argc--;
break;
options.libpath = 1;
libpath = argv[1];
argv++, argc--;
break;
} else {
fprintf(stderr,"ldrdf: more than one libraries search path specified\n");
exit(1);
fprintf(stderr,"ldrdf: more than one libraries search path specified\n");
exit(1);
}
case '@': {
int i=0;
char buf[256];
FILE *f;
int i=0;
char buf[256];
FILE *f;
options.respfile = 1;
if (argv[1] != NULL) f = fopen(argv[1],"r");
options.respfile = 1;
if (argv[1] != NULL) f = fopen(argv[1],"r");
else {
fprintf(stderr,"ldrdf: no response file name specified\n");
exit(1);
}
}
if (f == NULL) {
fprintf(stderr,"ldrdf: unable to open response file\n");
exit(1);
}
}
argv++, argc--;
while (fgets(buf, sizeof(buf), f) != NULL) {
@ -1253,14 +1237,14 @@ int main(int argc, char ** argv)
if (buf[0]=='\n') continue;
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);
fprintf(stderr,"ldrdf: too many input files\n");
exit(1);
}
*(respstrings + i) = newstr(buf);
argc++, i++;
}
}
break;
}
}
case '2':
options.stderr_redir = 1;
error_file = stdout;
@ -1268,7 +1252,7 @@ int main(int argc, char ** argv)
case 'g':
generic_rec_file = argv[1];
argv++, argc--;
break;
break;
default:
usage();
}
@ -1281,14 +1265,12 @@ int main(int argc, char ** argv)
printf(" output name: `%s'\n", outname);
if (options.strip)
printf(" strip symbols\n");
if (options.warnUnresolved == 1)
printf(" warn about unresolved symbols\n");
if (options.warnUnresolved == 2)
printf(" error if unresolved symbols\n");
if (options.dynalink)
printf(" Unix-style dynamic linking\n");
if (options.objpath)
printf(" objects search path: %s\n",objpath);
printf(" objects search path: %s\n", objpath);
if (options.libpath)
printf(" libraries search path: %s\n",libpath);
printf(" libraries search path: %s\n", libpath);
printf("\n");
}
@ -1303,14 +1285,16 @@ int main(int argc, char ** argv)
while (argc) {
if (!*argv) argv = respstrings;
if (!*argv) break;
if (!strncmp(*argv, "-l", 2)) /* library */
{
if(libpath) add_library(newstrcat(libpath,*argv + 2));
else add_library(*argv + 2);
}
else {
if(objpath) loadmodule(newstrcat(objpath,*argv));
else loadmodule(*argv);
if (!strncmp(*argv, "-l", 2)) {
if(libpath && (*argv[2] != '/'))
add_library(newstrcat(libpath,*argv + 2));
else
add_library(*argv + 2);
} else {
if(objpath && (*argv[0] != '/'))
loadmodule(newstrcat(objpath, *argv));
else
loadmodule(*argv);
moduleloaded = 1;
}
argv++, argc--;

View file

@ -10,8 +10,9 @@
FILE *infile;
long translatelong(long in) { /* translate from little endian to
local representation */
/* Translate from little endian to local representation */
long translatelong(long in)
{
long r;
unsigned char *i;
@ -24,7 +25,8 @@ long translatelong(long in) { /* translate from little endian to
return r;
}
int16 translateshort(int16 in) {
int16 translateshort(int16 in)
{
int r;
unsigned char *i;
@ -37,16 +39,16 @@ int16 translateshort(int16 in) {
void print_header(long length, int rdf_version)
{
char buf[129],t,l,s,flags;
unsigned char reclen;
long o,ll;
int16 rs;
unsigned char reclen;
long o,ll;
int16 rs;
while (length > 0) {
fread(&t,1,1,infile);
if (rdf_version >= 2) {
fread(&reclen,1,1,infile);
}
switch(t) {
while (length > 0) {
fread(&t,1,1,infile);
if (rdf_version >= 2) {
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);
@ -54,90 +56,92 @@ void print_header(long length, int rdf_version)
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)
printf(" warning: reclen != 8\n");
if (rdf_version == 1) length -= 9;
if (rdf_version == 1 && t == 6)
printf(" warning: seg relocation not supported in RDOFF1\n");
break;
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)
printf(" warning: reclen != 8\n");
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(&rs,2,1,infile);
ll = 0;
fread(&flags, 1, 1, infile);
fread(&rs, 2, 1, infile);
ll = 0;
if (rdf_version == 1) {
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
if (rdf_version == 1) {
do {
fread(&buf[ll], 1, 1, infile);
} while (buf[ll++]);
} else {
for (;ll < reclen - 2; ll++)
fread(&buf[ll],1,1,infile);
}
for (;ll < reclen - 3; ll++)
fread(&buf[ll], 1, 1, infile);
}
printf(" %simport: segment %04x = %s\n",t == 7 ? "far " : "",
translateshort(rs),buf);
if (rdf_version == 1) length -= ll + 3;
if (rdf_version == 1 && t == 7)
printf (" warning: far import not supported in RDOFF1\n");
break;
if (t == 7)
printf("far ");
printf((flags & SYM_IMPORT) ? " import" : " extern");
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 && t == 7)
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);
ll = 0;
fread(&flags, 1, 1, infile);
fread(&s, 1, 1, infile);
fread(&o, 4, 1, infile);
ll = 0;
if (rdf_version == 1) {
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
if (rdf_version == 1) {
do {
fread(&buf[ll], 1, 1, infile);
} while (buf[ll++]);
} else {
for (; ll < reclen - 6; ll ++)
fread(&buf[ll],1,1,infile);
}
if (flags & SYM_GLOBAL)
printf(" export");
else
printf(" global");
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;
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_MODNAME:
ll = 0;
if (rdf_version == 1) {
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
ll = 0;
if (rdf_version == 1) {
do {
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 (rdf_version == 1) length -= ll + 1;
break;
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 (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;
if (rdf_version > 1 && reclen != 4)
printf(" warning: reclen != 4\n");
break;
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: {
unsigned short seg, align;
@ -150,19 +154,19 @@ void print_header(long length, int rdf_version)
fread(buf+ll, 1, 1, infile);
printf(" common: segment %04x = %s, %ld:%d\n", translateshort(seg),
buf, translatelong(size), translateshort(align));
break;
break;
}
default:
default:
printf(" unrecognized record (type %d", (int)t);
if (rdf_version > 1) {
printf(", length %d",(int)reclen);
fseek(infile,reclen,SEEK_CUR);
if (rdf_version > 1) {
printf(", length %d",(int)reclen);
fseek(infile,reclen,SEEK_CUR);
} else length --;
printf(")\n");
printf(")\n");
}
if (rdf_version != 1) length -= 2 + reclen;
}
if (rdf_version != 1) length -= 2 + reclen;
}
}
char * knowntypes[8] = {"NULL", "text", "data", "object comment",
@ -192,7 +196,9 @@ int main(int argc,char **argv) {
long headerlength = 0;
long objectlength = 0;
puts("RDOFF Dump utility v2.1\n(c) Copyright 1996,99,2000 Julian R Hall, Yuri M Zaporogets");
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);

View file

@ -25,9 +25,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
/* functions supported:

View file

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

View file

@ -377,6 +377,7 @@ rdfheaderrec *rdfgetheaderrec(rdffile *f)
case RDFREC_IMPORT: /* Imported symbol record */
case RDFREC_FARIMPORT:
RI8(r.i.flags);
RI16(r.i.segment);
RS(r.i.label,32);
break;
@ -464,6 +465,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r)
case RDFREC_IMPORT: /* import */
case RDFREC_FARIMPORT:
membufwrite(h->buf,&r->i.flags,1);
membufwrite(h->buf,&r->i.segment,-2);
membufwrite(h->buf,&r->i.label,strlen(r->i.label) + 1);
break ;

View file

@ -47,6 +47,7 @@ struct RelocRec {
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
records - label is assumed to be at offset zero
in this segment, so linker must fix up with offset
@ -92,9 +93,10 @@ struct CommonRec {
};
/* Flags for ExportRec */
#define SYM_DATA 0x01
#define SYM_FUNCTION 0x02
#define SYM_GLOBAL 0x04
#define SYM_DATA 1
#define SYM_FUNCTION 2
#define SYM_GLOBAL 4
#define SYM_IMPORT 8
/*
* GenericRec - contains the type and length field, plus a 128 byte