2004-09-15 14:54:34 +08:00
|
|
|
/*
|
|
|
|
* rdf2bin.c - convert an RDOFF object file to flat binary
|
|
|
|
*/
|
2002-05-01 04:52:08 +08:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "rdfload.h"
|
2007-04-14 09:24:14 +08:00
|
|
|
#include "nasmlib.h"
|
2002-05-01 04:52:08 +08:00
|
|
|
|
2007-04-12 10:40:54 +08:00
|
|
|
int32_t origin = 0;
|
2002-05-01 04:52:08 +08:00
|
|
|
int align = 16;
|
|
|
|
|
2007-04-14 00:47:53 +08:00
|
|
|
char *getfilename(char *pathname)
|
2002-05-01 04:52:08 +08:00
|
|
|
{
|
2007-04-14 00:47:53 +08:00
|
|
|
char *lastslash = pathname - 1;
|
|
|
|
char *i = pathname;
|
2002-05-01 04:52:08 +08:00
|
|
|
|
2005-01-16 06:15:51 +08:00
|
|
|
while (*i) {
|
|
|
|
if (*i == '/')
|
|
|
|
lastslash = i;
|
|
|
|
i++;
|
2002-05-01 04:52:08 +08:00
|
|
|
}
|
|
|
|
return lastslash + 1;
|
|
|
|
}
|
|
|
|
|
2007-04-13 00:54:50 +08:00
|
|
|
int main(int argc, char **argv)
|
2002-05-01 04:52:08 +08:00
|
|
|
{
|
2005-01-16 06:15:51 +08:00
|
|
|
rdfmodule *m;
|
|
|
|
int tmp;
|
|
|
|
FILE *of;
|
2007-04-14 00:47:53 +08:00
|
|
|
char *padding;
|
2005-01-16 06:15:51 +08:00
|
|
|
int codepad, datapad, bsspad = 0;
|
2002-05-01 04:52:08 +08:00
|
|
|
|
|
|
|
if (argc < 2) {
|
2005-01-16 06:15:51 +08:00
|
|
|
puts("Usage: rdf2bin [-o relocation-origin] [-p segment-alignment] " "input-file output-file");
|
|
|
|
puts(" rdf2com [-p segment-alignment] input-file output-file");
|
|
|
|
return 1;
|
2002-05-01 04:52:08 +08:00
|
|
|
}
|
|
|
|
|
2005-01-16 06:15:51 +08:00
|
|
|
if (!nasm_stricmp(getfilename(*argv), "rdf2com")) {
|
|
|
|
origin = 0x100;
|
2002-05-01 04:52:08 +08:00
|
|
|
}
|
|
|
|
argv++, argc--;
|
|
|
|
|
|
|
|
while (argc > 2) {
|
2005-01-16 06:15:51 +08:00
|
|
|
if (!strcmp(*argv, "-o")) {
|
|
|
|
argv++, argc--;
|
|
|
|
origin = readnum(*argv, &tmp);
|
|
|
|
if (tmp) {
|
|
|
|
fprintf(stderr, "rdf2bin: invalid parameter: %s\n", *argv);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else if (!strcmp(*argv, "-p")) {
|
|
|
|
argv++, argc--;
|
|
|
|
align = readnum(*argv, &tmp);
|
|
|
|
if (tmp) {
|
|
|
|
fprintf(stderr, "rdf2bin: invalid parameter: %s\n", *argv);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else if (!strcmp(*argv, "-b")) {
|
|
|
|
argv++, argc--;
|
|
|
|
bsspad = readnum(*argv, &tmp);
|
|
|
|
if (tmp) {
|
|
|
|
fprintf(stderr, "rdf2bin: invalid parameter: %s\n", *argv);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
|
|
|
|
argv++, argc--;
|
2002-05-01 04:52:08 +08:00
|
|
|
}
|
|
|
|
if (argc < 2) {
|
2005-01-16 06:15:51 +08:00
|
|
|
puts("rdf2bin: required parameter missing");
|
|
|
|
return -1;
|
2002-05-01 04:52:08 +08:00
|
|
|
}
|
|
|
|
m = rdfload(*argv);
|
|
|
|
|
2005-01-16 06:15:51 +08:00
|
|
|
if (!m) {
|
|
|
|
rdfperror("rdf2bin", *argv);
|
|
|
|
return 1;
|
2002-05-01 04:52:08 +08:00
|
|
|
}
|
2007-04-14 09:24:14 +08:00
|
|
|
printf("relocating %s: origin=%"PRIx32", align=%d\n", *argv, origin, align);
|
2002-05-01 04:52:08 +08:00
|
|
|
|
|
|
|
m->textrel = origin;
|
2002-05-01 04:58:18 +08:00
|
|
|
m->datarel = origin + m->f.seg[0].length;
|
2002-05-01 04:52:08 +08:00
|
|
|
if (m->datarel % align != 0) {
|
2005-01-16 06:15:51 +08:00
|
|
|
codepad = align - (m->datarel % align);
|
|
|
|
m->datarel += codepad;
|
|
|
|
} else
|
|
|
|
codepad = 0;
|
2002-05-01 04:52:08 +08:00
|
|
|
|
2002-05-01 04:58:18 +08:00
|
|
|
m->bssrel = m->datarel + m->f.seg[1].length;
|
2002-05-01 04:52:08 +08:00
|
|
|
if (m->bssrel % align != 0) {
|
2005-01-16 06:15:51 +08:00
|
|
|
datapad = align - (m->bssrel % align);
|
|
|
|
m->bssrel += datapad;
|
|
|
|
} else
|
|
|
|
datapad = 0;
|
2002-05-01 04:52:08 +08:00
|
|
|
|
2007-04-14 09:24:14 +08:00
|
|
|
printf("code: %08"PRIx32"\ndata: %08"PRIx32"\nbss: %08"PRIx32"\n",
|
2005-01-16 06:15:51 +08:00
|
|
|
m->textrel, m->datarel, m->bssrel);
|
2002-05-01 04:52:08 +08:00
|
|
|
|
|
|
|
rdf_relocate(m);
|
|
|
|
|
|
|
|
argv++;
|
|
|
|
|
2005-01-16 06:15:51 +08:00
|
|
|
of = fopen(*argv, "wb");
|
2002-05-01 04:52:08 +08:00
|
|
|
if (!of) {
|
2005-01-16 06:15:51 +08:00
|
|
|
fprintf(stderr, "rdf2bin: could not open output file %s\n", *argv);
|
|
|
|
return 1;
|
2002-05-01 04:52:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
padding = malloc(align);
|
|
|
|
if (!padding) {
|
2005-01-16 06:15:51 +08:00
|
|
|
fprintf(stderr, "rdf2bin: out of memory\n");
|
|
|
|
return 1;
|
2002-05-01 04:52:08 +08:00
|
|
|
}
|
|
|
|
|
2005-01-16 06:15:51 +08:00
|
|
|
if (fwrite(m->t, 1, m->f.seg[0].length, of) != m->f.seg[0].length ||
|
|
|
|
fwrite(padding, 1, codepad, of) != codepad ||
|
|
|
|
fwrite(m->d, 1, m->f.seg[1].length, of) != m->f.seg[1].length) {
|
|
|
|
fprintf(stderr, "rdf2bin: error writing to %s\n", *argv);
|
|
|
|
return 1;
|
2002-05-01 04:52:08 +08:00
|
|
|
}
|
2005-01-16 06:15:51 +08:00
|
|
|
|
2002-05-01 05:00:33 +08:00
|
|
|
if (bsspad) {
|
2005-01-16 06:15:51 +08:00
|
|
|
void *p = calloc(bsspad -= (m->bssrel - origin), 1);
|
|
|
|
fwrite(p, 1, bsspad, of);
|
2002-05-01 05:00:33 +08:00
|
|
|
}
|
2002-05-01 04:52:08 +08:00
|
|
|
|
|
|
|
fclose(of);
|
|
|
|
return 0;
|
|
|
|
}
|