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