744bda0f78450d764f919cade9c61d67394fd666
[fw/sdcc] / as / mcs51 / lknoice.c
1 /* lknoice.c */
2
3 /*
4  * Extensions to CUG 292 linker ASLINK to produce NoICE debug files
5  *
6  * 31-Oct-1997 by John Hartman
7  * 30-Jan-98 JLH add page to DefineNoICE for 8051
8  *  2-Feb-98 JLH Allow optional .nest on local vars - C scoping rules...
9  */
10
11 #include <stdio.h>
12 #include <setjmp.h>
13 #include <string.h>
14 #include "aslink.h"
15
16 static void DefineGlobal( char *name, Addr_T value, int page );
17 static void DefineScoped( char *name, Addr_T value, int page );
18 static void DefineFile( char *name, Addr_T value, int page );
19 static void DefineFunction( char *name, Addr_T value, int page );
20 static void DefineStaticFunction( char *name, Addr_T value, int page );
21 static void DefineEndFunction( Addr_T value, int page );
22 static void DefineLine( char *lineString, Addr_T value, int page );
23 static void PagedAddress( Addr_T value, int page );
24
25 /*
26  * Called from lstarea in lklist.c for each symbol.
27  *
28  * Generates appropriate NoICE commands into output file, if any is open
29  *
30  */
31 void DefineNoICE( char *name, Addr_T value, int page )
32 {
33         char token1[NCPS];                      /* parse for file.function.symbol */
34         char token2[NCPS];
35         char token3[NCPS];
36         //      char token4[NCPS];
37         char sep1, sep2;
38         int  j, level;
39
40         /* no output if file is not open */
41         if (jfp == NULL) return;
42
43         j = sscanf( name, "%[^.]%c%[^.]%c%s",
44                     token1, &sep1, token2, &sep2, token3 );
45         switch (j)
46         {
47                 /* file.function.symbol, or file.function..SPECIAL */
48                 case 5:
49                         DefineFile( token1, 0, 0 );
50                         if (token3[0] == '.')
51                         {
52                                 if (strcmp( token3, ".FN" ) == 0)
53                                 {
54                                         /* Global function */
55                                         DefineFunction( token2, value, page );
56                                 }
57                                 else if (strcmp( token3, ".SFN" ) == 0)
58                                 {
59                                         /* Static (file-scope) function */
60                                         DefineStaticFunction( token2, value, page );
61                                 }
62                                 else if (strcmp( token3, ".EFN" ) == 0)
63                                 {
64                                         /* End of function */
65                                         DefineEndFunction( value, page );
66                                 }
67                         }
68                         else
69                         {
70                                 /* Function-scope var. */
71                                 DefineFunction( token2, 0, 0 );
72
73                                 /* Look for optional level integer */
74                                 j = sscanf( token3, "%[^.]%c%u", token1, &sep1, &level );
75                                 if ((j == 3) && (level != 0))
76                                 {
77                                         sprintf( &token1[ strlen(token1) ], "_%u", level );
78                                 }
79                                 DefineScoped( token1, value, page );
80                         }
81                         break;
82
83                 /* file.func. is illegal */
84                 case 4:
85                         break;
86
87                 /* either file.symbol or file.line# */
88                 case 3:
89                         DefineFile( token1, 0, 0 );
90                         if ((token2[0] >= '0') && (token2[0] <= '9'))
91                         {
92                                 /* Line number */
93                                 DefineLine( token2, value, page );
94                         }
95                         else
96                         {
97                                 /* File-scope symbol.  (Kill any function) */
98                                 DefineEndFunction( 0, 0 );
99                                 DefineScoped( token2, value, page );
100                         }
101                         break;
102
103                 /* symbol. is illegal */
104                 case 2:
105                         break;
106
107                 /* just a symbol */
108                 case 1:
109                         DefineGlobal( token1, value, page );
110                         break;
111         }
112 }
113
114 static char currentFile[NCPS];
115 static char currentFunction[NCPS];
116
117 /*
118  * static function:
119  * Define "name" as a global symbol
120  */
121 void DefineGlobal( char *name, Addr_T value, int page )
122 {
123         fprintf( jfp, "DEF %s ", name );
124         PagedAddress( value, page );
125 }
126
127 /*
128  * static function:
129  * Define "name" as a static (scoped) symbol
130  */
131 void DefineScoped( char *name, Addr_T value, int page )
132 {
133         fprintf( jfp, "DEFS %s ", name );
134         PagedAddress( value, page );
135 }
136
137 /*
138  * static function:
139  * Define "name" as the current file
140  */
141 void DefineFile( char *name, Addr_T value, int page )
142 {
143         if (strcmpi( name, currentFile ) != 0)
144         {
145                 strcpy( currentFile, name );
146                 if (value != 0)
147                 {
148                         fprintf( jfp, "FILE %s ", name );
149                         PagedAddress( value, page );
150                 }
151                 else
152                 {
153                         fprintf( jfp, "FILE %s\n", name );
154                 }
155         }
156 }
157
158 /*
159  * static function:
160  * Define "name" as the current function
161  */
162 void DefineFunction( char *name, Addr_T value, int page )
163 {
164         if (strcmpi( name, currentFunction ) != 0)
165         {
166                 strcpy( currentFunction, name );
167                 if (value != 0)
168                 {
169                         fprintf( jfp, "DEF %s ", name );
170                         PagedAddress( value, page );
171                         fprintf( jfp, "FUNC %s ", name );
172                         PagedAddress( value, page );
173                 }
174                 else
175                 {
176                         fprintf( jfp, "FUNC %s\n", name );
177                 }
178         }
179 }
180
181 /*
182  * static function:
183  * Define "name" as the current static (scoped) function
184  */
185 void DefineStaticFunction( char *name, Addr_T value, int page )
186 {
187         if (strcmpi( name, currentFunction ) != 0)
188         {
189                 strcpy( currentFunction, name );
190                 if (value != 0)
191                 {
192                         fprintf( jfp, "DEFS %s ", name );
193                         PagedAddress( value, page );
194                         fprintf( jfp, "SFUNC %s ", name );
195                         PagedAddress( value, page );
196                 }
197                 else
198                 {
199                         fprintf( jfp, "SFUNC %s\n", name );
200                 }
201         }
202 }
203
204 /*
205  * static function:
206  * Define the end of the current function
207  */
208 void DefineEndFunction( Addr_T value, int page )
209 {
210         if (currentFunction[0] != 0)
211         {
212                 if (value != 0)
213                 {
214                         fprintf( jfp, "ENDF " );
215                         PagedAddress( value, page );
216                 }
217                 else
218                 {
219                         fprintf( jfp, "ENDF\n" );
220                 }
221
222                 currentFunction[0] = 0;
223         }
224 }
225
226 /*
227  * static function:
228  * Define "lineNumber" as a line in the current file
229  */
230 void DefineLine( char *lineString, Addr_T value, int page )
231 {
232         int indigit, lineNumber = 0;
233
234         while( (indigit=digit( *lineString++, 10 )) >= 0)
235         {
236                 lineNumber = 10*lineNumber + indigit;
237         }
238         fprintf( jfp, "LINE %u ", lineNumber );
239         PagedAddress( value, page );
240 }
241
242 void PagedAddress( Addr_T value, int page )
243 {
244         fprintf( jfp, "%X:0x%X\n", page, value );
245 }