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