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