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