summaryrefslogtreecommitdiff
path: root/rdoff/ldrdf.c
diff options
context:
space:
mode:
Diffstat (limited to 'rdoff/ldrdf.c')
-rw-r--r--rdoff/ldrdf.c1705
1 files changed, 868 insertions, 837 deletions
diff --git a/rdoff/ldrdf.c b/rdoff/ldrdf.c
index 22e077e6..977aeb8c 100644
--- a/rdoff/ldrdf.c
+++ b/rdoff/ldrdf.c
@@ -45,20 +45,19 @@
*/
struct segment_infonode {
- int dest_seg; /* output segment to be placed into, -1 to
- skip linking this segment */
- long reloc; /* segment's relocation factor */
+ int dest_seg; /* output segment to be placed into, -1 to
+ skip linking this segment */
+ long reloc; /* segment's relocation factor */
};
-
struct modulenode {
- rdffile f; /* the RDOFF file structure */
- struct segment_infonode seginfo[RDF_MAXSEGS]; /* what are we doing
- with each segment? */
- void * header;
- char * name;
- struct modulenode * next;
- long bss_reloc;
+ rdffile f; /* the RDOFF file structure */
+ struct segment_infonode seginfo[RDF_MAXSEGS]; /* what are we doing
+ with each segment? */
+ void *header;
+ char *name;
+ struct modulenode *next;
+ long bss_reloc;
};
#include "ldsegs.h"
@@ -70,64 +69,63 @@ struct modulenode {
* Function prototypes of private utility functions
*/
-void processmodule(const char * filename, struct modulenode * mod);
-int allocnewseg(uint16 type,uint16 reserved);
-int findsegment(uint16 type,uint16 reserved);
-void symtab_add(const char * symbol, int segment, long offset);
-int symtab_get(const char * symbol, int * segment, long * offset);
+void processmodule(const char *filename, struct modulenode *mod);
+int allocnewseg(uint16 type, uint16 reserved);
+int findsegment(uint16 type, uint16 reserved);
+void symtab_add(const char *symbol, int segment, long offset);
+int symtab_get(const char *symbol, int *segment, long *offset);
/* =========================================================================
* Global data structures.
*/
/* a linked list of modules that will be included in the output */
-struct modulenode * modules = NULL;
-struct modulenode * lastmodule = NULL;
+struct modulenode *modules = NULL;
+struct modulenode *lastmodule = NULL;
/* a linked list of libraries to be searched for unresolved imported symbols */
-struct librarynode * libraries = NULL;
-struct librarynode * lastlib = NULL;
+struct librarynode *libraries = NULL;
+struct librarynode *lastlib = NULL;
/* the symbol table */
-void * symtab = NULL;
+void *symtab = NULL;
/* objects search path */
-char * objpath = NULL;
+char *objpath = NULL;
/* libraries search path */
-char * libpath = NULL;
+char *libpath = NULL;
/* file to embed as a generic record */
-char * generic_rec_file = NULL;
+char *generic_rec_file = NULL;
/* error file */
-static FILE * error_file;
+static FILE *error_file;
/* the header of the output file, built up stage by stage */
-rdf_headerbuf * newheader = NULL;
+rdf_headerbuf *newheader = NULL;
/* The current state of segment allocation, including information about
* which output segment numbers have been allocated, and their types and
* amount of data which has already been allocated inside them.
*/
-struct SegmentHeaderRec outputseg[RDF_MAXSEGS];
-int nsegs = 0;
-long bss_length;
+struct SegmentHeaderRec outputseg[RDF_MAXSEGS];
+int nsegs = 0;
+long bss_length;
/* global options which affect how the program behaves */
struct ldrdfoptions {
- int verbose;
- int align;
- int dynalink;
- int strip;
- int respfile;
- int stderr_redir;
- int objpath;
- int libpath;
+ int verbose;
+ int align;
+ int dynalink;
+ int strip;
+ int respfile;
+ int stderr_redir;
+ int objpath;
+ int libpath;
} options;
-int errorcount = 0; /* determines main program exit status */
-
+int errorcount = 0; /* determines main program exit status */
/* =========================================================================
* Utility functions
@@ -149,14 +147,13 @@ void initsegments()
outputseg[1].number = 1;
outputseg[1].reserved = 0;
outputseg[1].length = 0;
- outputseg[2].type = 0xFFFF; /* reserved segment type */
+ outputseg[2].type = 0xFFFF; /* reserved segment type */
outputseg[2].number = 2;
outputseg[2].reserved = 0;
outputseg[2].length = 0;
bss_length = 0;
}
-
/*
* loadmodule
*
@@ -164,29 +161,29 @@ void initsegments()
* each segment it contains (including determining destination segments and
* relocation factors for segments that are kept).
*/
-void loadmodule(const char * filename)
+void loadmodule(const char *filename)
{
if (options.verbose)
- printf("loading `%s'\n", filename);
+ printf("loading `%s'\n", filename);
/* allocate a new module entry on the end of the modules list */
if (!modules) {
- modules = malloc (sizeof(*modules));
- lastmodule = modules;
+ modules = malloc(sizeof(*modules));
+ lastmodule = modules;
} else {
- lastmodule->next = malloc (sizeof(*modules));
- lastmodule = lastmodule->next;
+ lastmodule->next = malloc(sizeof(*modules));
+ lastmodule = lastmodule->next;
}
if (!lastmodule) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
+ 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) {
- rdfperror("ldrdf", filename);
- exit(1);
+ rdfperror("ldrdf", filename);
+ exit(1);
}
/*
@@ -201,7 +198,6 @@ void loadmodule(const char * filename)
processmodule(filename, lastmodule);
}
-
/*
* processmodule()
*
@@ -211,82 +207,83 @@ 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)
+void processmodule(const char *filename, struct modulenode *mod)
{
struct segconfig sconf;
- int seg, outseg;
- void * header;
- rdfheaderrec * hr;
- long bssamount = 0;
- int bss_was_referenced = 0;
+ int seg, outseg;
+ void *header;
+ rdfheaderrec *hr;
+ long bssamount = 0;
+ int bss_was_referenced = 0;
for (seg = 0; seg < mod->f.nsegs; seg++) {
- /*
- * get the segment configuration for this type from the segment
- * table. getsegconfig() is a macro, defined in ldsegs.h.
- */
- getsegconfig(sconf, mod->f.seg[seg].type);
-
- if (options.verbose > 1) {
- printf ("%s %04x [%04x:%10s] ", filename, mod->f.seg[seg].number,
- mod->f.seg[seg].type, sconf.typedesc);
- }
- /*
- * sconf->dowhat tells us what to do with a segment of this type.
- */
- switch (sconf.dowhat) {
- case SEG_IGNORE:
- /*
- * Set destination segment to -1, to indicate that this segment
- * should be ignored for the purpose of output, ie it is left
- * out of the linked executable.
- */
- mod->seginfo[seg].dest_seg = -1;
- if (options.verbose > 1) printf("IGNORED\n");
- break;
-
- case SEG_NEWSEG:
- /*
- * The configuration tells us to create a new segment for
- * each occurrence of this segment type.
- */
- outseg = allocnewseg(sconf.mergetype,
- mod->f.seg[seg].reserved);
- mod->seginfo[seg].dest_seg = outseg;
- mod->seginfo[seg].reloc = 0;
- outputseg[outseg].length = mod->f.seg[seg].length;
- if (options.verbose > 1)
- printf ("=> %04x:%08lx (+%04lx)\n", outseg,
- mod->seginfo[seg].reloc,
- mod->f.seg[seg].length);
- break;
-
- case SEG_MERGE:
- /*
- * The configuration tells us to merge the segment with
- * a previously existing segment of type 'sconf.mergetype',
- * if one exists. Otherwise a new segment is created.
- * This is handled transparently by 'findsegment()'.
- */
- outseg = findsegment(sconf.mergetype,
- mod->f.seg[seg].reserved);
- mod->seginfo[seg].dest_seg = outseg;
-
- /*
- * We need to add alignment to these segments.
- */
- if (outputseg[outseg].length % options.align != 0)
- outputseg[outseg].length +=
- options.align - (outputseg[outseg].length % options.align);
-
- mod->seginfo[seg].reloc = outputseg[outseg].length;
- outputseg[outseg].length += mod->f.seg[seg].length;
-
- if (options.verbose > 1)
- printf ("=> %04x:%08lx (+%04lx)\n", outseg,
- mod->seginfo[seg].reloc,
- mod->f.seg[seg].length);
- }
+ /*
+ * get the segment configuration for this type from the segment
+ * table. getsegconfig() is a macro, defined in ldsegs.h.
+ */
+ getsegconfig(sconf, mod->f.seg[seg].type);
+
+ if (options.verbose > 1) {
+ printf("%s %04x [%04x:%10s] ", filename,
+ mod->f.seg[seg].number, mod->f.seg[seg].type,
+ sconf.typedesc);
+ }
+ /*
+ * sconf->dowhat tells us what to do with a segment of this type.
+ */
+ switch (sconf.dowhat) {
+ case SEG_IGNORE:
+ /*
+ * Set destination segment to -1, to indicate that this segment
+ * should be ignored for the purpose of output, ie it is left
+ * out of the linked executable.
+ */
+ mod->seginfo[seg].dest_seg = -1;
+ if (options.verbose > 1)
+ printf("IGNORED\n");
+ break;
+
+ case SEG_NEWSEG:
+ /*
+ * The configuration tells us to create a new segment for
+ * each occurrence of this segment type.
+ */
+ outseg = allocnewseg(sconf.mergetype,
+ mod->f.seg[seg].reserved);
+ mod->seginfo[seg].dest_seg = outseg;
+ mod->seginfo[seg].reloc = 0;
+ outputseg[outseg].length = mod->f.seg[seg].length;
+ if (options.verbose > 1)
+ printf("=> %04x:%08lx (+%04lx)\n", outseg,
+ mod->seginfo[seg].reloc, mod->f.seg[seg].length);
+ break;
+
+ case SEG_MERGE:
+ /*
+ * The configuration tells us to merge the segment with
+ * a previously existing segment of type 'sconf.mergetype',
+ * if one exists. Otherwise a new segment is created.
+ * This is handled transparently by 'findsegment()'.
+ */
+ outseg = findsegment(sconf.mergetype,
+ mod->f.seg[seg].reserved);
+ mod->seginfo[seg].dest_seg = outseg;
+
+ /*
+ * We need to add alignment to these segments.
+ */
+ if (outputseg[outseg].length % options.align != 0)
+ outputseg[outseg].length +=
+ options.align -
+ (outputseg[outseg].length % options.align);
+
+ mod->seginfo[seg].reloc = outputseg[outseg].length;
+ outputseg[outseg].length += mod->f.seg[seg].length;
+
+ if (options.verbose > 1)
+ printf("=> %04x:%08lx (+%04lx)\n", outseg,
+ mod->seginfo[seg].reloc, mod->f.seg[seg].length);
+ }
}
@@ -296,89 +293,92 @@ void processmodule(const char * filename, struct modulenode * mod)
*/
header = malloc(mod->f.header_len);
if (!header) {
- fprintf(stderr, "ldrdf: not enough memory\n");
- exit(1);
+ fprintf(stderr, "ldrdf: not enough memory\n");
+ exit(1);
}
if (rdfloadseg(&mod->f, RDOFF_HEADER, header)) {
- rdfperror("ldrdf", filename);
- exit(1);
+ rdfperror("ldrdf", filename);
+ exit(1);
}
- while ((hr = rdfgetheaderrec (&mod->f))) {
- switch(hr->type) {
- case RDFREC_IMPORT: /* imported symbol */
- case RDFREC_FARIMPORT:
- /* Define with seg = -1 */
- symtab_add(hr->i.label, -1, 0);
- break;
-
- case RDFREC_GLOBAL: { /* exported symbol */
- 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;
+ while ((hr = rdfgetheaderrec(&mod->f))) {
+ switch (hr->type) {
+ case RDFREC_IMPORT: /* imported symbol */
+ case RDFREC_FARIMPORT:
+ /* Define with seg = -1 */
+ symtab_add(hr->i.label, -1, 0);
+ break;
+
+ case RDFREC_GLOBAL:{ /* exported symbol */
+ 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;
} else {
- if ((destseg = mod->seginfo[(int)hr->e.segment].dest_seg) == -1)
- continue;
- destreloc = mod->seginfo[(int)hr->e.segment].reloc;
+ 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;
-
- 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;
- }
- }
+ 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;
+
+ 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 || bss_was_referenced) {
- /*
- * handle the BSS segment - first pad the existing bss length
- * to the correct alignment, then store the length in bss_reloc
- * for this module. Then add this module's BSS length onto
- * bss_length.
- */
- if (bss_length % options.align != 0)
- bss_length += options.align - (bss_length % options.align);
-
- mod->bss_reloc = bss_length;
- if (options.verbose > 1) {
- printf ("%s 0002 [ BSS] => 0002:%08lx (+%04lx)\n",
- filename, bss_length, bssamount);
- }
- bss_length += bssamount;
+ /*
+ * handle the BSS segment - first pad the existing bss length
+ * to the correct alignment, then store the length in bss_reloc
+ * for this module. Then add this module's BSS length onto
+ * bss_length.
+ */
+ if (bss_length % options.align != 0)
+ bss_length += options.align - (bss_length % options.align);
+
+ mod->bss_reloc = bss_length;
+ if (options.verbose > 1) {
+ printf("%s 0002 [ BSS] => 0002:%08lx (+%04lx)\n",
+ filename, bss_length, bssamount);
+ }
+ bss_length += bssamount;
}
-
#ifdef STINGY_MEMORY
/*
* we free the header buffer here, to save memory later.
@@ -392,7 +392,6 @@ void processmodule(const char * filename, struct modulenode * mod)
}
-
/*
* Return 1 if a given module is in the list, 0 otherwise.
*/
@@ -400,14 +399,14 @@ int lookformodule(const char *name)
{
struct modulenode *curr = modules;
- while(curr) {
- if (!strcmp(name, curr->name)) return 1;
- curr = curr->next;
+ while (curr) {
+ if (!strcmp(name, curr->name))
+ return 1;
+ curr = curr->next;
}
return 0;
}
-
/*
* allocnewseg()
* findsegment()
@@ -418,7 +417,7 @@ int lookformodule(const char *name)
* a segment of the type requested, and if one isn't found allocates a
* new one.
*/
-int allocnewseg(uint16 type,uint16 reserved)
+int allocnewseg(uint16 type, uint16 reserved)
{
outputseg[nsegs].type = type;
outputseg[nsegs].number = nsegs;
@@ -430,17 +429,17 @@ int allocnewseg(uint16 type,uint16 reserved)
return nsegs++;
}
-int findsegment(uint16 type,uint16 reserved)
+int findsegment(uint16 type, uint16 reserved)
{
int i;
for (i = 0; i < nsegs; i++)
- if (outputseg[i].type == type) return i;
+ if (outputseg[i].type == type)
+ return i;
- return allocnewseg(type,reserved);
+ return allocnewseg(type, reserved);
}
-
/*
* symtab_add()
*
@@ -458,41 +457,43 @@ int findsegment(uint16 type,uint16 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)
+void symtab_add(const char *symbol, int segment, long offset)
{
- symtabEnt * ste;
+ symtabEnt *ste;
ste = symtabFind(symtab, symbol);
if (ste) {
- if (ste->segment >= 0) {
- /*
- * symbol previously defined
- */
- if (segment < 0) return;
- fprintf (error_file, "warning: `%s' redefined\n", symbol);
- return;
- }
-
- /*
- * somebody wanted the symbol, and put an undefined symbol
- * marker into the table
- */
- if (segment == -1) return;
- /*
- * we have more information now - update the symbol's entry
- */
- ste->segment = segment;
- ste->offset = offset;
- ste->flags = 0;
- return;
+ if (ste->segment >= 0) {
+ /*
+ * symbol previously defined
+ */
+ if (segment < 0)
+ return;
+ fprintf(error_file, "warning: `%s' redefined\n", symbol);
+ return;
+ }
+
+ /*
+ * somebody wanted the symbol, and put an undefined symbol
+ * marker into the table
+ */
+ if (segment == -1)
+ return;
+ /*
+ * we have more information now - update the symbol's entry
+ */
+ ste->segment = segment;
+ ste->offset = offset;
+ ste->flags = 0;
+ return;
}
/*
* this is the first declaration of this symbol
*/
ste = malloc(sizeof(symtabEnt));
if (!ste) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
+ fprintf(stderr, "ldrdf: out of memory\n");
+ exit(1);
}
ste->name = strdup(symbol);
ste->segment = segment;
@@ -508,57 +509,55 @@ 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)
+int symtab_get(const char *symbol, int *segment, long *offset)
{
- symtabEnt * ste = symtabFind(symtab, symbol);
+ symtabEnt *ste = symtabFind(symtab, symbol);
if (!ste) {
- *segment = -1;
- *offset = 0;
- return 0;
+ *segment = -1;
+ *offset = 0;
+ return 0;
} else {
- *segment = ste->segment;
- *offset = ste->offset;
- return 1;
+ *segment = ste->segment;
+ *offset = ste->offset;
+ return 1;
}
}
-
/*
* 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)
+void add_library(const char *name)
{
if (rdl_verify(name)) {
- rdl_perror("ldrdf", name);
- errorcount++;
- return;
+ rdl_perror("ldrdf", name);
+ errorcount++;
+ return;
}
if (!libraries) {
- lastlib = libraries = malloc(sizeof(*libraries));
- if (! libraries) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
+ lastlib = libraries = malloc(sizeof(*libraries));
+ if (!libraries) {
+ fprintf(stderr, "ldrdf: out of memory\n");
+ exit(1);
+ }
} else {
- lastlib->next = malloc(sizeof(*libraries));
- if (!lastlib->next) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
- lastlib = lastlib->next;
+ lastlib->next = malloc(sizeof(*libraries));
+ if (!lastlib->next) {
+ fprintf(stderr, "ldrdf: out of memory\n");
+ exit(1);
+ }
+ lastlib = lastlib->next;
}
lastlib->next = NULL;
if (rdl_open(lastlib, name)) {
- rdl_perror("ldrdf", name);
- errorcount++;
- return;
+ rdl_perror("ldrdf", name);
+ errorcount++;
+ return;
}
}
-
/*
* search_libraries()
*
@@ -571,102 +570,104 @@ void add_library(const char * name)
*/
int search_libraries()
{
- struct librarynode * cur;
+ struct librarynode *cur;
rdffile f;
- int i;
- void * header;
- int segment;
- long offset;
- int doneanything = 0, pass = 1, keepfile;
- rdfheaderrec * hr;
+ int i;
+ void *header;
+ int segment;
+ long offset;
+ int doneanything = 0, pass = 1, keepfile;
+ rdfheaderrec *hr;
cur = libraries;
while (cur) {
- if (options.verbose > 2)
- printf("scanning library `%s', pass %d...\n", cur->name, pass);
-
- for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++) {
- if (pass == 2 && lookformodule(f.name)) continue;
-
- if (options.verbose > 3)
- printf(" looking in module `%s'\n", f.name);
-
- header = malloc(f.header_len);
- if (!header) {
- fprintf(stderr, "ldrdf: not enough memory\n");
- exit(1);
- }
- if (rdfloadseg(&f, RDOFF_HEADER, header)) {
- rdfperror("ldrdf", f.name);
- errorcount++;
- return 0;
- }
-
- keepfile = 0;
-
- while ((hr = rdfgetheaderrec (&f))) {
+ if (options.verbose > 2)
+ printf("scanning library `%s', pass %d...\n", cur->name, pass);
+
+ for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++) {
+ if (pass == 2 && lookformodule(f.name))
+ continue;
+
+ if (options.verbose > 3)
+ printf(" looking in module `%s'\n", f.name);
+
+ header = malloc(f.header_len);
+ if (!header) {
+ fprintf(stderr, "ldrdf: not enough memory\n");
+ exit(1);
+ }
+ if (rdfloadseg(&f, RDOFF_HEADER, header)) {
+ rdfperror("ldrdf", f.name);
+ errorcount++;
+ return 0;
+ }
+
+ keepfile = 0;
+
+ while ((hr = rdfgetheaderrec(&f))) {
/* We're only interested in exports, so skip others */
- if (hr->type != RDFREC_GLOBAL) continue;
-
- /*
- * 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)
- continue;
- }
-
- doneanything = 1;
- keepfile = 1;
-
- /*
- * as there are undefined symbols, we can assume that
- * there are modules on the module list by the time
- * we get here.
- */
- lastmodule->next = malloc(sizeof(*lastmodule->next));
- if (!lastmodule->next) {
- fprintf(stderr, "ldrdf: not enough memory\n");
- exit(1);
- }
- lastmodule = lastmodule->next;
- memcpy(&lastmodule->f, &f, sizeof(f));
- lastmodule->name = strdup(f.name);
+ if (hr->type != RDFREC_GLOBAL)
+ continue;
+
+ /*
+ * 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)
+ continue;
+ }
+
+ doneanything = 1;
+ keepfile = 1;
+
+ /*
+ * as there are undefined symbols, we can assume that
+ * there are modules on the module list by the time
+ * we get here.
+ */
+ lastmodule->next = malloc(sizeof(*lastmodule->next));
+ if (!lastmodule->next) {
+ fprintf(stderr, "ldrdf: not enough memory\n");
+ exit(1);
+ }
+ lastmodule = lastmodule->next;
+ memcpy(&lastmodule->f, &f, sizeof(f));
+ lastmodule->name = strdup(f.name);
lastmodule->next = NULL;
- processmodule(f.name, lastmodule);
- break;
- }
- if (!keepfile) {
- free(f.name);
- f.name = NULL;
- f.fp = NULL;
+ processmodule(f.name, lastmodule);
+ break;
+ }
+ if (!keepfile) {
+ free(f.name);
+ f.name = NULL;
+ f.fp = NULL;
}
- }
- if (rdl_error != 0 && rdl_error != RDL_ENOTFOUND)
- rdl_perror("ldrdf", cur->name);
-
- cur = cur->next;
- if (cur == NULL && pass == 1) {
- cur = libraries;
- pass++;
- }
+ }
+ if (rdl_error != 0 && rdl_error != RDL_ENOTFOUND)
+ rdl_perror("ldrdf", cur->name);
+
+ cur = cur->next;
+ if (cur == NULL && pass == 1) {
+ cur = libraries;
+ pass++;
+ }
}
return doneanything;
}
-
/*
* write_output()
*
@@ -674,28 +675,28 @@ int search_libraries()
* all the modules into a single output module, and then writes this to a
* file.
*/
-void write_output(const char * filename)
+void write_output(const char *filename)
{
- FILE * f;
- rdf_headerbuf * rdfheader;
- struct modulenode * cur;
- int i, availableseg, seg, localseg, isrelative;
- void * header;
- rdfheaderrec * hr, newrec;
- symtabEnt * se;
- segtab segs;
- long offset;
- byte * data;
-
- if ((f = fopen(filename, "wb"))==NULL) {
- fprintf(stderr, "ldrdf: couldn't open %s for output\n", filename);
- exit(1);
+ FILE *f;
+ rdf_headerbuf *rdfheader;
+ struct modulenode *cur;
+ int i, availableseg, seg, localseg, isrelative;
+ void *header;
+ rdfheaderrec *hr, newrec;
+ symtabEnt *se;
+ segtab segs;
+ long offset;
+ byte *data;
+
+ if ((f = fopen(filename, "wb")) == NULL) {
+ fprintf(stderr, "ldrdf: couldn't open %s for output\n", filename);
+ exit(1);
}
- if ((rdfheader=rdfnewheader())==NULL) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
+ if ((rdfheader = rdfnewheader()) == NULL) {
+ fprintf(stderr, "ldrdf: out of memory\n");
+ exit(1);
}
-
+
/*
* If '-g' option was given, first record in output file will be a
* `generic' record, filled with a given file content.
@@ -703,31 +704,35 @@ void write_output(const char * filename)
* compliant kernels.
*/
if (generic_rec_file) {
- FILE *ff;
-
- if (options.verbose)
- printf("\nadding generic record from binary file %s\n", 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);
- 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);
-
+ 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);
+ rdfaddheader(rdfheader, hr);
free(hr);
}
if (options.verbose)
- printf ("\nbuilding output module (%d segments)\n", nsegs);
+ printf("\nbuilding output module (%d segments)\n", nsegs);
/*
* Allocate the memory for the segments. We may be better off
@@ -736,13 +741,14 @@ void write_output(const char * filename)
* And you could always use DJGPP...
*/
for (i = 0; i < nsegs; i++) {
- outputseg[i].data=NULL;
- if(!outputseg[i].length) continue;
- outputseg[i].data = malloc(outputseg[i].length);
- if (!outputseg[i].data) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
+ outputseg[i].data = NULL;
+ if (!outputseg[i].length)
+ continue;
+ outputseg[i].data = malloc(outputseg[i].length);
+ if (!outputseg[i].data) {
+ fprintf(stderr, "ldrdf: out of memory\n");
+ exit(1);
+ }
}
/*
@@ -754,302 +760,314 @@ void write_output(const char * filename)
/*
* Step through the modules, performing required actions on each one
*/
- for (cur = modules; cur; cur=cur->next) {
- /*
- * Read the actual segment contents into the correct places in
- * the newly allocated segments
- */
-
- for (i = 0; i < cur->f.nsegs; i++) {
- int dest = cur->seginfo[i].dest_seg;
-
- if (dest == -1) continue;
- if (rdfloadseg(&cur->f, i,
- outputseg[dest].data + cur->seginfo[i].reloc)) {
- rdfperror("ldrdf", cur->name);
- exit(1);
- }
- }
-
- /*
- * Perform fixups, and add new header records where required
- */
-
- header = malloc(cur->f.header_len);
- if (!header) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
-
- if (cur->f.header_loc)
- rdfheaderrewind(&cur->f);
- else
- if (rdfloadseg(&cur->f, RDOFF_HEADER, header)) {
- rdfperror("ldrdf", cur->name);
- exit(1);
- }
-
- /*
- * we need to create a local segment number -> location
- * table for the segments in this module.
- */
- init_seglocations(&segs);
- for (i = 0; i < cur->f.nsegs; i++) {
- add_seglocation(&segs, cur->f.seg[i].number,
- cur->seginfo[i].dest_seg, cur->seginfo[i].reloc);
- }
- /*
- * and the BSS segment (doh!)
- */
- add_seglocation(&segs, 2, 2, cur->bss_reloc);
-
- while ((hr = rdfgetheaderrec(&cur->f))) {
- switch(hr->type) {
- 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).
- *
- * To do this we add to the number stored the relocation
- * factor associated with the segment that contains the
- * target segment.
- *
- * The relocation could be a relative relocation, in which
- * case we have to first subtract the amount we've relocated
- * the containing segment by.
- */
- if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) {
- fprintf(stderr, "%s: reloc to undefined segment %04x\n",
- cur->name, (int) hr->r.refseg);
- errorcount++;
- break;
- }
-
- isrelative = (hr->r.segment & RDOFF_RELATIVEMASK) == RDOFF_RELATIVEMASK;
- hr->r.segment &= (RDOFF_RELATIVEMASK-1);
-
- if (hr->r.segment == 2 ||
- (localseg = rdffindsegment(&cur->f, hr->r.segment)) == -1) {
- fprintf(stderr, "%s: reloc from %s segment (%d)\n",
- cur->name,
- hr->r.segment == 2 ? "BSS" : "unknown",
- hr->r.segment);
- errorcount++;
- break;
- }
-
- if (hr->r.length != 1 && hr->r.length != 2 &&
- hr->r.length != 4 ) {
- fprintf(stderr, "%s: nonstandard length reloc "
- "(%d bytes)\n", cur->name, hr->r.length);
- errorcount++;
- break;
- }
-
- /*
- * okay, now the relocation is in the segment pointed to by
- * cur->seginfo[localseg], and we know everything else is
- * okay to go ahead and do the relocation
- */
- data = outputseg[cur->seginfo[localseg].dest_seg].data;
- data += cur->seginfo[localseg].reloc + hr->r.offset;
-
- /*
- * data now points to the reference that needs
- * relocation. Calculate the relocation factor.
- * Factor is:
- * offset of referred object in segment [in offset]
- * (- relocation of localseg, if ref is relative)
- * For simplicity, the result is stored in 'offset'.
- * Then add 'offset' onto the value at data.
- */
-
- if (isrelative)
- offset -= cur->seginfo[localseg].reloc;
- switch (hr->r.length) {
- case 1:
- offset += *data;
- if (offset < -127 || offset > 128)
- fprintf(error_file, "warning: relocation out of range "
- "at %s(%02x:%08lx)\n", cur->name,
- (int)hr->r.segment, hr->r.offset);
- *data = (char) offset;
- break;
- case 2:
- offset += * (short *)data;
- if (offset < -32767 || offset > 32768)
- fprintf(error_file, "warning: relocation out of range "
- "at %s(%02x:%08lx)\n", cur->name,
- (int)hr->r.segment, hr->r.offset);
- * (short *)data = (short) offset;
- break;
- case 4:
- * (long *)data += offset;
- /* we can't easily detect overflow on this one */
- break;
- }
-
- /*
- * If the relocation was relative between two symbols in
- * the same segment, then we're done.
- *
- * 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;
- hr->r.offset += cur->seginfo[localseg].reloc;
- hr->r.refseg = seg;
- if (isrelative)
- hr->r.segment += RDOFF_RELATIVEMASK;
- rdfaddheader(rdfheader, hr);
- }
- break;
-
- case RDFREC_IMPORT: /* import symbol */
- case RDFREC_FARIMPORT:
- /*
- * scan the global symbol table for the symbol
- * and associate its location with the segment number
- * for this module
- */
- se = symtabFind(symtab, hr->i.label);
- if (!se || se->segment == -1) {
- 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
- * symbol, and store it in the symbol table for
- * future reference
- */
- if (!se) {
- se=malloc(sizeof(*se));
- if (!se) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
- se->name = strdup(hr->i.label);
- se->flags = 0;
- se->segment = availableseg++;
- se->offset = 0;
- symtabInsert(symtab, se);
- }
- else {
- se->segment = availableseg++;
- se->offset = 0;
- }
- /*
- * output a header record that imports it to the
- * recently allocated segment number...
- */
- newrec = *hr;
- newrec.i.segment = se->segment;
- rdfaddheader(rdfheader, &newrec);
- }
-
- add_seglocation(&segs, hr->i.segment, se->segment, se->offset);
- break;
-
- 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
- * stripping, put the symbol if it's marked as SYM_GLOBAL.
- */
- if (options.strip && !(hr->e.flags & SYM_GLOBAL))
- break;
-
- if (hr->e.segment == 2) {
- seg = 2;
- offset = cur->bss_reloc;
- }
- else {
- localseg = rdffindsegment(&cur->f, hr->e.segment);
- if (localseg == -1) {
- fprintf(stderr, "%s: exported symbol `%s' from "
- "unrecognised segment\n", cur->name,
- hr->e.label);
- errorcount++;
- break;
- }
- offset = cur->seginfo[localseg].reloc;
- seg = cur->seginfo[localseg].dest_seg;
- }
-
- hr->e.segment = seg;
- hr->e.offset += offset;
- rdfaddheader(rdfheader, hr);
- break;
-
- 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 RDFREC_SEGRELOC: /* segment fixup */
- /*
- * modify the segment numbers if necessary, and
- * pass straight through to the output module header
- *
- * *** FIXME ***
- */
- if (hr->r.segment == 2) {
- fprintf(stderr, "%s: segment fixup in BSS section\n",
- cur->name);
- errorcount++;
- break;
- }
- localseg = rdffindsegment(&cur->f, hr->r.segment);
- if (localseg == -1) {
- fprintf(stderr, "%s: segment fixup in unrecognised"
- " segment (%d)\n", cur->name, hr->r.segment);
- errorcount++;
- break;
- }
- hr->r.segment = cur->seginfo[localseg].dest_seg;
- hr->r.offset += cur->seginfo[localseg].reloc;
-
- if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) {
- fprintf(stderr, "%s: segment fixup to undefined "
- "segment %04x\n", cur->name, (int)hr->r.refseg);
- errorcount++;
- break;
- }
- 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;
- }
- }
-
- free(header);
- done_seglocations(&segs);
+ for (cur = modules; cur; cur = cur->next) {
+ /*
+ * Read the actual segment contents into the correct places in
+ * the newly allocated segments
+ */
+
+ for (i = 0; i < cur->f.nsegs; i++) {
+ int dest = cur->seginfo[i].dest_seg;
+
+ if (dest == -1)
+ continue;
+ if (rdfloadseg(&cur->f, i,
+ outputseg[dest].data + cur->seginfo[i].reloc)) {
+ rdfperror("ldrdf", cur->name);
+ exit(1);
+ }
+ }
+
+ /*
+ * Perform fixups, and add new header records where required
+ */
+
+ header = malloc(cur->f.header_len);
+ if (!header) {
+ fprintf(stderr, "ldrdf: out of memory\n");
+ exit(1);
+ }
+
+ if (cur->f.header_loc)
+ rdfheaderrewind(&cur->f);
+ else if (rdfloadseg(&cur->f, RDOFF_HEADER, header)) {
+ rdfperror("ldrdf", cur->name);
+ exit(1);
+ }
+
+ /*
+ * we need to create a local segment number -> location
+ * table for the segments in this module.
+ */
+ init_seglocations(&segs);
+ for (i = 0; i < cur->f.nsegs; i++) {
+ add_seglocation(&segs, cur->f.seg[i].number,
+ cur->seginfo[i].dest_seg,
+ cur->seginfo[i].reloc);
+ }
+ /*
+ * and the BSS segment (doh!)
+ */
+ add_seglocation(&segs, 2, 2, cur->bss_reloc);
+
+ while ((hr = rdfgetheaderrec(&cur->f))) {
+ switch (hr->type) {
+ 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).
+ *
+ * To do this we add to the number stored the relocation
+ * factor associated with the segment that contains the
+ * target segment.
+ *
+ * The relocation could be a relative relocation, in which
+ * case we have to first subtract the amount we've relocated
+ * the containing segment by.
+ */
+ if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) {
+ fprintf(stderr,
+ "%s: reloc to undefined segment %04x\n",
+ cur->name, (int)hr->r.refseg);
+ errorcount++;
+ break;
+ }
+
+ isrelative =
+ (hr->r.segment & RDOFF_RELATIVEMASK) ==
+ RDOFF_RELATIVEMASK;
+ hr->r.segment &= (RDOFF_RELATIVEMASK - 1);
+
+ if (hr->r.segment == 2 ||
+ (localseg =
+ rdffindsegment(&cur->f, hr->r.segment)) == -1) {
+ fprintf(stderr, "%s: reloc from %s segment (%d)\n",
+ cur->name,
+ hr->r.segment == 2 ? "BSS" : "unknown",
+ hr->r.segment);
+ errorcount++;
+ break;
+ }
+
+ if (hr->r.length != 1 && hr->r.length != 2 &&
+ hr->r.length != 4) {
+ fprintf(stderr, "%s: nonstandard length reloc "
+ "(%d bytes)\n", cur->name, hr->r.length);
+ errorcount++;
+ break;
+ }
+
+ /*
+ * okay, now the relocation is in the segment pointed to by
+ * cur->seginfo[localseg], and we know everything else is
+ * okay to go ahead and do the relocation
+ */
+ data = outputseg[cur->seginfo[localseg].dest_seg].data;
+ data += cur->seginfo[localseg].reloc + hr->r.offset;
+
+ /*
+ * data now points to the reference that needs
+ * relocation. Calculate the relocation factor.
+ * Factor is:
+ * offset of referred object in segment [in offset]
+ * (- relocation of localseg, if ref is relative)
+ * For simplicity, the result is stored in 'offset'.
+ * Then add 'offset' onto the value at data.
+ */
+
+ if (isrelative)
+ offset -= cur->seginfo[localseg].reloc;
+ switch (hr->r.length) {
+ case 1:
+ offset += *data;
+ if (offset < -127 || offset > 128)
+ fprintf(error_file,
+ "warning: relocation out of range "
+ "at %s(%02x:%08lx)\n", cur->name,
+ (int)hr->r.segment, hr->r.offset);
+ *data = (char)offset;
+ break;
+ case 2:
+ offset += *(short *)data;
+ if (offset < -32767 || offset > 32768)
+ fprintf(error_file,
+ "warning: relocation out of range "
+ "at %s(%02x:%08lx)\n", cur->name,
+ (int)hr->r.segment, hr->r.offset);
+ *(short *)data = (short)offset;
+ break;
+ case 4:
+ *(long *)data += offset;
+ /* we can't easily detect overflow on this one */
+ break;
+ }
+
+ /*
+ * If the relocation was relative between two symbols in
+ * the same segment, then we're done.
+ *
+ * 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;
+ hr->r.offset += cur->seginfo[localseg].reloc;
+ hr->r.refseg = seg;
+ if (isrelative)
+ hr->r.segment += RDOFF_RELATIVEMASK;
+ rdfaddheader(rdfheader, hr);
+ }
+ break;
+
+ case RDFREC_IMPORT: /* import symbol */
+ case RDFREC_FARIMPORT:
+ /*
+ * scan the global symbol table for the symbol
+ * and associate its location with the segment number
+ * for this module
+ */
+ se = symtabFind(symtab, hr->i.label);
+ if (!se || se->segment == -1) {
+ 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
+ * symbol, and store it in the symbol table for
+ * future reference
+ */
+ if (!se) {
+ se = malloc(sizeof(*se));
+ if (!se) {
+ fprintf(stderr, "ldrdf: out of memory\n");
+ exit(1);
+ }
+ se->name = strdup(hr->i.label);
+ se->flags = 0;
+ se->segment = availableseg++;
+ se->offset = 0;
+ symtabInsert(symtab, se);
+ } else {
+ se->segment = availableseg++;
+ se->offset = 0;
+ }
+ /*
+ * output a header record that imports it to the
+ * recently allocated segment number...
+ */
+ newrec = *hr;
+ newrec.i.segment = se->segment;
+ rdfaddheader(rdfheader, &newrec);
+ }
+
+ add_seglocation(&segs, hr->i.segment, se->segment,
+ se->offset);
+ break;
+
+ 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
+ * stripping, put the symbol if it's marked as SYM_GLOBAL.
+ */
+ if (options.strip && !(hr->e.flags & SYM_GLOBAL))
+ break;
+
+ if (hr->e.segment == 2) {
+ seg = 2;
+ offset = cur->bss_reloc;
+ } else {
+ localseg = rdffindsegment(&cur->f, hr->e.segment);
+ if (localseg == -1) {
+ fprintf(stderr, "%s: exported symbol `%s' from "
+ "unrecognised segment\n", cur->name,
+ hr->e.label);
+ errorcount++;
+ break;
+ }
+ offset = cur->seginfo[localseg].reloc;
+ seg = cur->seginfo[localseg].dest_seg;
+ }
+
+ hr->e.segment = seg;
+ hr->e.offset += offset;
+ rdfaddheader(rdfheader, hr);
+ break;
+
+ 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 RDFREC_SEGRELOC: /* segment fixup */
+ /*
+ * modify the segment numbers if necessary, and
+ * pass straight through to the output module header
+ *
+ * *** FIXME ***
+ */
+ if (hr->r.segment == 2) {
+ fprintf(stderr, "%s: segment fixup in BSS section\n",
+ cur->name);
+ errorcount++;
+ break;
+ }
+ localseg = rdffindsegment(&cur->f, hr->r.segment);
+ if (localseg == -1) {
+ fprintf(stderr, "%s: segment fixup in unrecognised"
+ " segment (%d)\n", cur->name, hr->r.segment);
+ errorcount++;
+ break;
+ }
+ hr->r.segment = cur->seginfo[localseg].dest_seg;
+ hr->r.offset += cur->seginfo[localseg].reloc;
+
+ if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) {
+ fprintf(stderr, "%s: segment fixup to undefined "
+ "segment %04x\n", cur->name,
+ (int)hr->r.refseg);
+ errorcount++;
+ break;
+ }
+ 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;
+ }
+ }
+
+ free(header);
+ done_seglocations(&segs);
}
@@ -1065,33 +1083,35 @@ void write_output(const char * filename)
* Write the header
*/
for (i = 0; i < nsegs; i++) {
- if (i == 2) continue;
- rdfaddsegment (rdfheader, outputseg[i].length);
+ if (i == 2)
+ continue;
+ rdfaddsegment(rdfheader, outputseg[i].length);
}
-
+
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++) {
- uint16 s;
- long l;
-
- if (i == 2) continue;
-
- s = translateshort(outputseg[i].type);
- fwrite(&s, 2, 1, f);
- s = translateshort(outputseg[i].number);
- fwrite(&s, 2, 1, f);
- s = translateshort(outputseg[i].reserved);
- fwrite(&s, 2, 1, f);
- l = translatelong(outputseg[i].length);
- fwrite(&l, 4, 1, f);
-
- fwrite(outputseg[i].data, outputseg[i].length, 1, f);
+ uint16 s;
+ long l;
+
+ if (i == 2)
+ continue;
+
+ s = translateshort(outputseg[i].type);
+ fwrite(&s, 2, 1, f);
+ s = translateshort(outputseg[i].number);
+ fwrite(&s, 2, 1, f);
+ s = translateshort(outputseg[i].reserved);
+ fwrite(&s, 2, 1, f);
+ l = translatelong(outputseg[i].length);
+ fwrite(&l, 4, 1, f);
+
+ fwrite(outputseg[i].data, outputseg[i].length, 1, f);
}
fwrite("\0\0\0\0\0\0\0\0\0\0", 10, 1, f);
@@ -1118,11 +1138,11 @@ void usage()
exit(0);
}
-int main(int argc, char ** argv)
+int main(int argc, char **argv)
{
- char * outname = "aout.rdf";
- int moduleloaded = 0;
- char *respstrings[128] = {0, };
+ char *outname = "aout.rdf";
+ int moduleloaded = 0;
+ char *respstrings[128] = { 0, };
options.verbose = 0;
options.align = 16;
@@ -1132,166 +1152,177 @@ int main(int argc, char ** argv)
error_file = stderr;
argc--, argv++;
- if (argc == 0) usage();
+ if (argc == 0)
+ usage();
while (argc && *argv && **argv == '-' && argv[0][1] != 'l') {
- switch(argv[0][1]) {
- case 'r':
- printf("ldrdf (linker for RDF files) version " LDRDF_VERSION "\n");
- printf("RDOFF2 revision %s\n", RDOFF2_REVISION);
- exit(0);
- case 'v':
- if (argv[0][2] == '=') {
- options.verbose = argv[0][3] - '0';
- if (options.verbose < 0 || options.verbose > 9) {
- fprintf(stderr, "ldrdf: verbosity level must be a number"
- " between 0 and 9\n");
- exit(1);
- }
- }
- else
- options.verbose++;
- break;
- case 'a':
- options.align = atoi(argv[1]);
- if (options.align <= 0) {
- fprintf(stderr,
- "ldrdf: -a expects a positive number argument\n");
- exit(1);
- }
- argv++, argc--;
- break;
- case 's':
- options.strip = 1;
- break;
- case 'd':
- if (argv[0][2] == 'y') options.dynalink = 1;
- break;
- case 'o':
- outname = argv[1];
- argv++, argc--;
- break;
- case 'j':
- if (!objpath) {
- options.objpath = 1;
- objpath = argv[1];
- argv++, argc--;
- break;
- } else {
- 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;
- } else {
- fprintf(stderr,"ldrdf: more than one libraries search path specified\n");
- exit(1);
- }
- case '@': {
- int i=0;
- char buf[256];
- FILE *f;
-
- 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) {
- char *p;
- 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);
- argc++, i++;
- }
+ switch (argv[0][1]) {
+ case 'r':
+ printf("ldrdf (linker for RDF files) version " LDRDF_VERSION
+ "\n");
+ printf("RDOFF2 revision %s\n", RDOFF2_REVISION);
+ exit(0);
+ case 'v':
+ if (argv[0][2] == '=') {
+ options.verbose = argv[0][3] - '0';
+ if (options.verbose < 0 || options.verbose > 9) {
+ fprintf(stderr,
+ "ldrdf: verbosity level must be a number"
+ " between 0 and 9\n");
+ exit(1);
+ }
+ } else
+ options.verbose++;
+ break;
+ case 'a':
+ options.align = atoi(argv[1]);
+ if (options.align <= 0) {
+ fprintf(stderr,
+ "ldrdf: -a expects a positive number argument\n");
+ exit(1);
+ }
+ argv++, argc--;
+ break;
+ case 's':
+ options.strip = 1;
break;
- }
- case '2':
+ case 'd':
+ if (argv[0][2] == 'y')
+ options.dynalink = 1;
+ break;
+ case 'o':
+ outname = argv[1];
+ argv++, argc--;
+ break;
+ case 'j':
+ if (!objpath) {
+ options.objpath = 1;
+ objpath = argv[1];
+ argv++, argc--;
+ break;
+ } else {
+ 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;
+ } else {
+ fprintf(stderr,
+ "ldrdf: more than one libraries search path specified\n");
+ exit(1);
+ }
+ case '@':{
+ int i = 0;
+ char buf[256];
+ FILE *f;
+
+ 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) {
+ char *p;
+ 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);
+ argc++, i++;
+ }
+ break;
+ }
+ case '2':
options.stderr_redir = 1;
- error_file = stdout;
- break;
- case 'g':
- generic_rec_file = argv[1];
- argv++, argc--;
- break;
- default:
- usage();
- }
- argv++, argc--;
+ error_file = stdout;
+ break;
+ case 'g':
+ generic_rec_file = argv[1];
+ argv++, argc--;
+ break;
+ default:
+ usage();
+ }
+ argv++, argc--;
}
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.dynalink)
- printf(" Unix-style dynamic linking\n");
+ 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.dynalink)
+ printf(" Unix-style dynamic linking\n");
if (options.objpath)
printf(" objects search path: %s\n", objpath);
if (options.libpath)
printf(" libraries search path: %s\n", libpath);
- printf("\n");
+ printf("\n");
}
symtab = symtabNew();
initsegments();
if (!symtab) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
+ fprintf(stderr, "ldrdf: out of memory\n");
+ exit(1);
}
while (argc) {
- if (!*argv) argv = respstrings;
- if (!*argv) break;
- if (!strncmp(*argv, "-l", 2)) {
- if(libpath && (argv[0][2] != '/'))
- add_library(newstrcat(libpath,*argv + 2));
+ if (!*argv)
+ argv = respstrings;
+ if (!*argv)
+ break;
+ if (!strncmp(*argv, "-l", 2)) {
+ if (libpath && (argv[0][2] != '/'))
+ add_library(newstrcat(libpath, *argv + 2));
else
- add_library(*argv + 2);
+ add_library(*argv + 2);
} else {
- if(objpath && (argv[0][0] != '/'))
- loadmodule(newstrcat(objpath, *argv));
- else
- loadmodule(*argv);
- moduleloaded = 1;
- }
- argv++, argc--;
+ if (objpath && (argv[0][0] != '/'))
+ loadmodule(newstrcat(objpath, *argv));
+ else
+ loadmodule(*argv);
+ moduleloaded = 1;
+ }
+ argv++, argc--;
}
- if (! moduleloaded) {
- printf("ldrdf: nothing to do. ldrdf -h for usage\n");
- return 0;
+ if (!moduleloaded) {
+ printf("ldrdf: nothing to do. ldrdf -h for usage\n");
+ return 0;
}
search_libraries();
- if (options.verbose > 2)
- {
- printf ("symbol table:\n");
- symtabDump(symtab, stdout);
+ if (options.verbose > 2) {
+ printf("symbol table:\n");
+ symtabDump(symtab, stdout);
}
write_output(outname);
- if (errorcount > 0) exit(1);
+ if (errorcount > 0)
+ exit(1);
return 0;
}
-