--- /dev/null
+/* This is a cheap hack. The xa51 has a couple of ways to scramble
+ relocation info into it's opcode that the standard linker can't
+ handle.
+
+ The relocatable format looks like the known one, BUT ISN'T.
+
+ The only things that are handled now are:
+
+ "SDCCXA rel, version %f" must be the first line
+ "H %d areas %d global symbols" defines the # of areas and globals
+ "S <symbol> [Ref000 | DefXXXX]" Def's are supposed to be defined in
+ their own area/segment
+ "A <seg> size %d flags %d" switch to another segment. this can happen
+ multiple times and should be equal. flags is ignored
+ "T xx xx bb bb ..." where x is the address within the current segment
+ and bb are the bytes
+ "R xx <how> <symbol>" the relocation tag. xx is the offset within the
+ previous "T .." line. <how> could be something like REL_FF, REL_FFFF,
+ ABS_F0FF. and symbol is the previous defined symbol it refers to
+
+ Thats all for now.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "xa_version.h"
+
+static char outFileName[PATH_MAX];
+
+void baseName(char *name, char*base) {
+ int i, first, last;
+
+ // find the last path seperator in name
+ for (first=strlen(name)-1;
+ (name[first]!='/' && name[first]!='\\') && first;
+ first--);
+ if (name[first]=='/' || name[first]=='\\') {
+ first++;
+ }
+
+ // find the last ext seperator in name
+ for (last=strlen(name)-1;
+ (name[last]!='.' && last);
+ last--);
+ if (!last) {
+ last=strlen(name);
+ }
+
+ printf ("baseName: %s %d %d\n", name, first, last);
+ // fill the base with the baseName
+ for (i=first; i<last; i++) {
+ base[i-first]=name[i];
+ }
+ base[i]='\0';
+}
+
+void readModule(char *module) {
+ double thisVersion;
+ char line[132];
+ FILE *relModule;
+
+ if ((relModule=fopen(module, "r"))==NULL) {
+ perror (module);
+ exit (1);
+ }
+ printf ("ReadModule: %s\n", module);
+ // first we need to check if this is a valid file
+ if (sscanf(line, "SDCCXA rel, version %lf", &thisVersion)!=1) {
+ fprintf (stderr, "%s is not a valid input file\n", module);
+ exit (1);
+ }
+ if (thisVersion!=version) {
+ fprintf (stderr, "version conflict; we: %f != module: %f\n",
+ version, thisVersion);
+ }
+
+ fclose (relModule);
+}
+
+void writeModule(char *module) {
+ if (!outFileName[0]) {
+ sprintf (outFileName, "%s.bin", module);
+ }
+ printf ("WriteModule: %s\n", outFileName);
+}
+
+void usage (char * progName, int errNo) {
+ fprintf (stderr, "usage: %s f.rel [f1.rel [f2.rel [...]]]\n", progName);
+ if (errNo) {
+ exit (errNo);
+ }
+}
+
+int main(int argc, char **argv) {
+ char outputName[PATH_MAX];
+ int i;
+
+ // no options yet
+ if (argc<2) {
+ usage(argv[0], 1);
+ }
+ baseName(argv[1], outputName);
+ printf ("using baseName: %s\n", outputName);
+ for (i=1; i<argc; i++) {
+ readModule(argv[i]);
+ }
+ writeModule (outputName);
+ return 0;
+}
+
#define printf(x...) fprintf(stderr,x)
#include "xa_main.h"
-
+#include "xa_version.h"
extern void yyrestart(FILE *new_file);
extern int yyparse();
int opcode, operand;
char symbol_name[1000];
struct area_struct area[NUM_AREAS];
-int current_area=AREA_CSEG;
+int current_area=0;
char rel_line[2][132];
fprintf (sym_fp, "%-5s", "SFR");
} else if (p->isbit && !p->area) {
fprintf (sym_fp, "%-5s", "SBIT");
+ } else if (!p->isdef) {
+ fprintf (sym_fp,"EXTRN");
} else {
fprintf (sym_fp, "%-5s", areaToString(p->area));
}
area[AREA_HOME].start=area[AREA_HOME].alloc_position = 0;
}
-void addAreaSymbols() {
+void relPrelude() {
//char buffer[132];
int i, areas=0, globals=0;
struct symbol *p;
- fprintf (frel, "XH\n");
+ fprintf (frel, "SDCCXA rel, version %1.1f\n", version);
for (i=0; i<NUM_AREAS; i++) {
if ((area[i].size=area[i].alloc_position-area[i].start)) {
areas++;
init_areas();
yyparse();
- addAreaSymbols();
+ relPrelude();
if (createSymbolFile) print_symbol_table();
if (verbose) printf("Pass 3: Generating Object Code:\n");