work in progress
[fw/sdcc] / as / xa51 / xa_link.c
1 /* This is a cheap hack. The xa51 has a couple of ways to scramble
2    relocation info into it's opcode that the standard linker can't
3    handle. 
4
5    The relocatable format looks like the known one, BUT ISN'T.
6
7    The only things that are handled now are:
8
9    "SDCCXA rel, version %f" must be the first line
10    "H %d areas %d global symbols" defines the # of areas and globals
11    "S <symbol> [Ref000 | DefXXXX]" Def's are supposed to be defined in
12      their own area/segment
13    "A <seg> size %d flags %d" switch to another segment. this can happen
14      multiple times and should be equal. flags is ignored
15    "T xx xx bb bb ..." where x is the address within the current segment
16      and bb are the bytes
17    "R xx <how> <symbol>" the relocation tag. xx is the offset within the
18      previous "T .." line. <how> could be something like REL_FF, REL_FFFF, 
19      ABS_F0FF. and symbol is the previous defined symbol it refers to
20
21    Thats all for now.
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <limits.h>
27
28 #include "xa_version.h"
29
30 static char outFileName[PATH_MAX];
31
32 void baseName(char *name, char*base) {
33   int i, first, last;
34
35   // find the last path seperator in name
36   for (first=strlen(name)-1; 
37        (name[first]!='/' && name[first]!='\\') && first;
38        first--);
39   if (name[first]=='/' || name[first]=='\\') {
40     first++;
41   }
42
43   // find the last ext seperator in name
44   for (last=strlen(name)-1; 
45        (name[last]!='.' && last);
46        last--);
47   if (!last) {
48     last=strlen(name);
49   }
50
51   printf ("baseName: %s %d %d\n", name, first, last);
52   // fill the base with the baseName
53   for (i=first; i<last; i++) {
54     base[i-first]=name[i];
55   }
56   base[i]='\0';
57 }
58   
59 void readModule(char *module) {
60   double thisVersion;
61   char line[132];
62   FILE *relModule;
63
64   if ((relModule=fopen(module, "r"))==NULL) {
65     perror (module);
66     exit (1);
67   }
68   printf ("ReadModule: %s\n", module);
69   // first we need to check if this is a valid file
70   if (sscanf(line, "SDCCXA rel, version %lf", &thisVersion)!=1) {
71     fprintf (stderr, "%s is not a valid input file\n", module);
72     exit (1);
73   }
74   if (thisVersion!=version) {
75     fprintf (stderr, "version conflict; we: %f != module: %f\n", 
76              version, thisVersion);
77   }
78
79   fclose (relModule);
80 }
81
82 void writeModule(char *module) {
83   if (!outFileName[0]) {
84     sprintf (outFileName, "%s.bin", module);
85   }
86   printf ("WriteModule: %s\n", outFileName);
87 }
88
89 void usage (char * progName, int errNo) {
90   fprintf (stderr, "usage: %s f.rel [f1.rel [f2.rel [...]]]\n", progName);
91   if (errNo) {
92     exit (errNo);
93   }
94 }
95
96 int main(int argc, char **argv) {
97   char outputName[PATH_MAX];
98   int i;
99
100   // no options yet
101   if (argc<2) {
102     usage(argv[0], 1);
103   }
104   baseName(argv[1], outputName);
105   printf ("using baseName: %s\n", outputName);
106   for (i=1; i<argc; i++) {
107     readModule(argv[i]);
108   }
109   writeModule (outputName);
110   return 0;
111 }
112