Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6400 | punk_joker | 1 | /*********************************************************************** |
2 | * |
||
3 | * avra - Assembler for the Atmel AVR microcontroller series |
||
4 | * |
||
5 | * Copyright (C) 1998-2004 Jon Anders Haugum, Tobias Weber |
||
6 | * |
||
7 | * coff.c - Common Object File Format (COFF) support |
||
8 | * |
||
9 | * This file was developed for the avra assembler in order to produce COFF output files |
||
10 | * for use with the Atmel AVR Studio. The Lean C Compiler (LCC) debugging stabs |
||
11 | * output was used as input to the assembler. The information used to develop this file |
||
12 | * was obtained from various sources on the Internet, most notably, the Free Software Foundation, |
||
13 | * The "stabs" debug format, ??? Chapter 7: Common Object File Format (COFF), |
||
14 | * |
||
15 | * This software has absolutely no warrantee! The money you paid for this will be |
||
16 | * promptly refunded if not fully satisfied. |
||
17 | * |
||
18 | * Beta release 1/20/2000 by Bob Harris |
||
19 | * |
||
20 | * This software has not been fully tested and probably has a few software deficiencies. |
||
21 | * Some software support may be possible by sending a problem description report to |
||
22 | * rth@mclean.sparta.com |
||
23 | * |
||
24 | * Made the recommended change in write_coff_program(). |
||
25 | * Fixed an obvious typo in SkipPastDigits(). The if() statement was terminated |
||
26 | * with a semicolon, which terminated the if(); early. JEG 4-01-03 |
||
27 | */ |
||
28 | |||
29 | #include |
||
30 | #include |
||
31 | #include |
||
32 | #include |
||
33 | #include |
||
34 | |||
35 | #include "misc.h" |
||
36 | #include "avra.h" |
||
37 | #include "args.h" |
||
38 | |||
39 | #include "coff.h" |
||
40 | #include "device.h" /* device flash and eeprom size */ |
||
41 | |||
42 | |||
43 | struct FundamentalType { |
||
44 | |||
45 | char const *pString; |
||
46 | int Type; |
||
47 | int Size; |
||
48 | }; |
||
49 | |||
50 | struct FundamentalType FundamentalTypes[] = { |
||
51 | {"null", T_NULL, 0}, |
||
52 | {"void", T_VOID, 0}, |
||
53 | {"char", T_CHAR, 1}, |
||
54 | {"short", T_SHORT, 1}, |
||
55 | {"int", T_INT, 1}, |
||
56 | {"long", T_LONG, 2}, |
||
57 | {"float", T_FLOAT, 4}, |
||
58 | {"double", T_DOUBLE, 4}, |
||
59 | {"struct", T_STRUCT, 0}, |
||
60 | {"union", T_UNION, 0}, |
||
61 | {"enum", T_ENUM, 0}, |
||
62 | {"moe", T_MOE, 0}, |
||
63 | {"unsigned char", T_UCHAR, 1}, |
||
64 | {"unsigned short", T_USHORT, 1}, |
||
65 | {"unsigned int", T_UINT, 1}, |
||
66 | {"unsigned long", T_ULONG, 2}, |
||
67 | {"long double", T_LNGDBL, 2}, |
||
68 | {"long long int", T_LONG, 2}, |
||
69 | {"long int", T_LONG, 2}, |
||
70 | {"unsigned long long", T_ULONG, 2}, |
||
71 | {"signed char", T_CHAR, 1}, |
||
72 | {0, 0} |
||
73 | }; |
||
74 | |||
75 | |||
76 | struct coff_info *ci; |
||
77 | |||
78 | /****************************************************************************************/ |
||
79 | |||
80 | FILE *open_coff_file(struct prog_info *pi, char *filename){ |
||
81 | |||
82 | int ok /*, i*/; |
||
83 | FILE *fp; |
||
84 | //unsigned long *pu4; |
||
85 | char*p; |
||
86 | |||
87 | |||
88 | ci = calloc( 1, sizeof(struct coff_info) ); |
||
89 | if ( !ci ) |
||
90 | return( 0 ); |
||
91 | |||
92 | ok = True; |
||
93 | /* default values */ |
||
94 | ci->CurrentFileNumber = 0; |
||
95 | ci->pRomMemory = 0; |
||
96 | ci->pEEPRomMemory = 0; |
||
97 | ci->MaxRomAddress = 0; |
||
98 | ci->MaxEepromAddress = 0; |
||
99 | ci->NeedLineNumberFixup = 0; |
||
100 | ci->GlobalStartAddress = -1; |
||
101 | ci->GlobalEndAddress = 0; |
||
102 | |||
103 | /* Linked lists start out at zero */ |
||
104 | InitializeList( &ci->ListOfSectionHeaders ); |
||
105 | InitializeList( &ci->ListOfRawData ); |
||
106 | InitializeList( &ci->ListOfRelocations ); |
||
107 | InitializeList( &ci->ListOfLineNumbers ); |
||
108 | InitializeList( &ci->ListOfSymbols ); |
||
109 | InitializeList( &ci->ListOfGlobals ); |
||
110 | InitializeList( &ci->ListOfSpecials ); |
||
111 | InitializeList( &ci->ListOfUndefined ); |
||
112 | InitializeList( &ci->ListOfStrings ); |
||
113 | InitializeList( &ci->ListOfTypes ); |
||
114 | InitializeList( &ci->ListOfSplitLines ); |
||
115 | |||
116 | /* add two default sections to SectionHeaders */ |
||
117 | if ( !AllocateListObject( &ci->ListOfSectionHeaders, sizeof(struct external_scnhdr) ) || |
||
118 | !AllocateListObject( &ci->ListOfSectionHeaders, sizeof(struct external_scnhdr) ) ) { |
||
119 | |||
120 | fprintf(stderr, "\nOut of memory allocating section headers!"); |
||
121 | return( 0 ); |
||
122 | } |
||
123 | |||
124 | /* add to string table */ |
||
125 | p = (char *)AllocateListObject( &ci->ListOfStrings, 4 ); |
||
126 | if ( !p ) { |
||
127 | fprintf(stderr, "\nOut of memory allocating string table space!"); |
||
128 | return( 0 ); |
||
129 | } |
||
130 | |||
131 | /* Allocate space for binary output into ROM, and EEPROM memory buffers for COFF output */ |
||
132 | /* ASSUMES ci->device is accurate */ |
||
133 | if ( (ci->pRomMemory = AllocateListObject( &ci->ListOfRawData, pi->device->flash_size * 2 ) ) != 0) { |
||
134 | if ( (ci->pEEPRomMemory = AllocateListObject( &ci->ListOfRawData, pi->device->eeprom_size )) != 0) { |
||
135 | ok = True; /* only true if both buffers are properly allocated */ |
||
136 | /* now fill them with 0xff's to simulate flash erasure */ |
||
137 | memset( (void *)ci->pRomMemory, 0xff, pi->device->flash_size * 2 ); |
||
138 | memset( ( void *)ci->pEEPRomMemory, 0xff, pi->device->eeprom_size ); |
||
139 | } |
||
140 | } |
||
141 | if ( ok != True ) |
||
142 | return( 0 ); |
||
143 | |||
144 | fp = fopen(filename,"wb"); |
||
145 | if ( fp == NULL ) { |
||
146 | fprintf(stderr,"Error: cannot write coff file\n"); |
||
147 | return( fp ); |
||
148 | } |
||
149 | /* simulate void type .stabs void:t15=r1;*/ |
||
150 | stab_add_local_type( "void", "15=r1;0;0;" ); |
||
151 | |||
152 | return( fp ); |
||
153 | } |
||
154 | |||
155 | /****************************************************************************************/ |
||
156 | void write_coff_file(struct prog_info *pi){ |
||
157 | |||
158 | //FILE *fp; |
||
159 | //struct label *label; |
||
160 | char /* File[256],*/*p; |
||
161 | struct external_scnhdr *pSectionHdr; |
||
162 | struct syment *pEntry; |
||
163 | union auxent *pAux; |
||
164 | unsigned long *plong; |
||
165 | int NumberOfSymbols, SymbolIndex, LastFileIndex, LastFunctionIndex, LastFunctionAddress; |
||
166 | LISTNODE *pNode; |
||
167 | int LinesOffset, SymbolsOffset, StringsOffset, RawOffset; |
||
168 | struct lineno *pLine; |
||
169 | |||
170 | /* add two special sections */ |
||
171 | /* one for .text */ |
||
172 | if ( ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfSpecials, sizeof(struct syment) * 2 ) ) == 0 ) { |
||
173 | fprintf(stderr, "\nOut of memory allocating special headers for .text!"); |
||
174 | return; |
||
175 | } |
||
176 | memset( pEntry->n_name, 0, 8 ); |
||
177 | strcpy( pEntry->n_name, ".text" ); |
||
178 | pEntry->n_value = 0; |
||
179 | pEntry->n_scnum = 1; |
||
180 | pEntry->n_type = 0; |
||
181 | pEntry->n_sclass = C_STAT; |
||
182 | pEntry->n_numaux = 1; |
||
183 | pEntry++; |
||
184 | pAux = (union auxent *)pEntry; |
||
185 | pAux->x_scn.x_scnlen = ci->MaxRomAddress + 2; |
||
186 | pAux->x_scn.x_nreloc = 0; |
||
187 | pAux->x_scn.x_nlinno = ci->ListOfLineNumbers.TotalItems; |
||
188 | /* one for .bss */ |
||
189 | if ( ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfSpecials, sizeof(struct syment) * 2 ) ) == 0 ) { |
||
190 | fprintf(stderr, "\nOut of memory allocating special header for .bss!"); |
||
191 | return; |
||
192 | } |
||
193 | memset( pEntry->n_name, 0, 8 ); |
||
194 | strcpy( pEntry->n_name, ".bss" ); |
||
195 | if ( ci->GlobalStartAddress == -1 ) { |
||
196 | ci->GlobalEndAddress = ci->GlobalStartAddress = 0x60; |
||
197 | } |
||
198 | pEntry->n_value = ci->GlobalStartAddress; |
||
199 | pEntry->n_scnum = 2; |
||
200 | pEntry->n_type = 0; |
||
201 | pEntry->n_sclass = C_STAT; |
||
202 | pEntry->n_numaux = 1; |
||
203 | pEntry++; |
||
204 | pAux = (union auxent *)pEntry; |
||
205 | pAux->x_scn.x_scnlen = 0; /* we don't store any data here */ |
||
206 | pAux->x_scn.x_nreloc = 0; |
||
207 | pAux->x_scn.x_nlinno = 0; |
||
208 | |||
209 | /* one more for .data - eeprom ??? */ |
||
210 | |||
211 | /* Calculate common offsets into the file */ |
||
212 | RawOffset = sizeof(struct external_filehdr) + ci->ListOfSectionHeaders.TotalBytes; |
||
213 | LinesOffset = RawOffset + ci->MaxRomAddress + 2; /* ignore eeprom for now */ |
||
214 | SymbolsOffset = LinesOffset + ci->ListOfLineNumbers.TotalBytes; |
||
215 | StringsOffset = SymbolsOffset + ci->ListOfSymbols.TotalBytes + ci->ListOfSpecials.TotalBytes + ci->ListOfGlobals.TotalBytes; |
||
216 | |||
217 | /* Clean up loose ends in string table */ |
||
218 | if ( !(plong = (unsigned long *)FindFirstListObject(&ci->ListOfStrings)) ) { |
||
219 | fprintf(stderr,"\nInternal error in string table!"); |
||
220 | return; |
||
221 | } |
||
222 | *plong = ci->ListOfStrings.TotalBytes; /* Size of string table */ |
||
223 | |||
224 | /* Clean up loose ends in symbol table */ |
||
225 | |||
226 | /* symbol table - Filename value - index to next .file or global symbol */ |
||
227 | /* The value of that symbol equals the symbol table entry index of the next .file symbol or .global */ |
||
228 | LastFunctionAddress = ci->MaxRomAddress; |
||
229 | NumberOfSymbols = ci->ListOfSymbols.TotalItems + ci->ListOfSpecials.TotalItems + ci->ListOfGlobals.TotalItems; |
||
230 | SymbolIndex = LastFileIndex = NumberOfSymbols; |
||
231 | LastFunctionIndex = 0; /* set to zero on last function */ |
||
232 | for ( pEntry = (struct syment *)FindLastListObject(&ci->ListOfSymbols); |
||
233 | pEntry != 0; |
||
234 | pEntry = (struct syment *)FindNextLastListObject(&ci->ListOfSymbols) ) { |
||
235 | |||
236 | /* Search for .file entries designated by C_FILE */ |
||
237 | if ( pEntry->n_sclass == C_FILE ) { |
||
238 | pEntry->n_value = LastFileIndex; |
||
239 | LastFileIndex = SymbolIndex; /* save current index */ |
||
240 | } |
||
241 | /* Search for Function entries C_EXT */ |
||
242 | else if ( pEntry->n_sclass == C_EXT ) { |
||
243 | pEntry++; |
||
244 | pAux = (union auxent *)pEntry; |
||
245 | pAux->x_sym.x_misc.x_fsize = LastFunctionAddress - pEntry->n_value; /* function updated size */ |
||
246 | pAux->x_sym.x_fcnary.x_fcn.x_lnnoptr += LinesOffset; |
||
247 | LastFunctionAddress = pEntry->n_value; |
||
248 | pAux->x_sym.x_fcnary.x_fcn.x_endndx = LastFunctionIndex; /* point to next function index */ |
||
249 | pAux->x_sym.x_tvndx = 0; /* ??? */ |
||
250 | LastFunctionIndex = SymbolIndex; |
||
251 | } else if ( (pEntry->n_sclass == C_FCN ) || ( pEntry->n_sclass == C_BLOCK) ) { |
||
252 | if ( pEntry->n_name[1] == 'b' ) { |
||
253 | /* .bf and .bb */ |
||
254 | pEntry++; |
||
255 | pAux = (union auxent *)pEntry; |
||
256 | pAux->x_sym.x_fcnary.x_fcn.x_endndx = LastFunctionIndex; |
||
257 | } |
||
258 | } |
||
259 | /* else do nothing */ |
||
260 | |||
261 | /* update current symbol index */ |
||
262 | pNode = GetCurrentNode( &ci->ListOfSymbols ); |
||
263 | SymbolIndex -= ( pNode->Size / sizeof(struct syment) ); |
||
264 | } |
||
265 | |||
266 | // File Header |
||
267 | ci->FileHeader.f_magic = MAGIC_NUMBER_AVR; |
||
268 | ci->FileHeader.f_nscns = 2; |
||
269 | // ci->FileHeader.f_timdat = time( (time_t *)&ci->FileHeader.f_timdat); |
||
270 | ci->FileHeader.f_timdat = pi->time; |
||
271 | ci->FileHeader.f_symptr = SymbolsOffset; |
||
272 | ci->FileHeader.f_nsyms = NumberOfSymbols; |
||
273 | ci->FileHeader.f_opthdr = 0; |
||
274 | ci->FileHeader.f_flags = 0xff; /*F_RELFLG;*/ /* No relocation information available */ |
||
275 | |||
276 | /* write it out */ |
||
277 | if ( fwrite(&ci->FileHeader, 1, sizeof(struct external_filehdr), pi->coff_file ) != sizeof(struct external_filehdr) ) { |
||
278 | fprintf(stderr,"\nFile error writing header ...(disk full?)"); |
||
279 | return; |
||
280 | } |
||
281 | |||
282 | // Optional Information |
||
283 | |||
284 | // Section 1 Header |
||
285 | pSectionHdr = (struct external_scnhdr *)FindFirstListObject(&ci->ListOfSectionHeaders); |
||
286 | if ( !pSectionHdr ) { |
||
287 | fprintf(stderr, "\nInternal Coff error - cannot find section header .text!"); |
||
288 | return; |
||
289 | } |
||
290 | memset( &pSectionHdr->s_name[0], 0, sizeof(struct external_scnhdr) ); |
||
291 | strcpy( &pSectionHdr->s_name[0], ".text"); |
||
292 | pSectionHdr->s_paddr = 0; |
||
293 | pSectionHdr->s_vaddr = 0; |
||
294 | pSectionHdr->s_size = ci->MaxRomAddress + 2; /* remember the last instruction */ |
||
295 | pSectionHdr->s_scnptr = RawOffset; |
||
296 | pSectionHdr->s_relptr = 0; |
||
297 | pSectionHdr->s_lnnoptr = LinesOffset; |
||
298 | pSectionHdr->s_nreloc = 0; |
||
299 | pSectionHdr->s_nlnno = ci->ListOfLineNumbers.TotalBytes/sizeof(struct lineno); |
||
300 | pSectionHdr->s_flags = STYP_TEXT; |
||
301 | |||
302 | /* write it out */ |
||
303 | if ( fwrite(&pSectionHdr->s_name[0], 1, sizeof(struct external_scnhdr), pi->coff_file ) != sizeof(struct external_scnhdr) ) { |
||
304 | fprintf(stderr,"\nFile error writing section header ...(disk full?)"); |
||
305 | return; |
||
306 | } |
||
307 | |||
308 | // Section 2 Header |
||
309 | pSectionHdr = (struct external_scnhdr *)FindNextListObject(&ci->ListOfSectionHeaders); |
||
310 | if ( !pSectionHdr ) { |
||
311 | fprintf(stderr, "\nInternal Coff error - cannot find section header .bss!"); |
||
312 | return; |
||
313 | } |
||
314 | memset( &pSectionHdr->s_name[0], 0, sizeof(struct external_scnhdr) ); |
||
315 | strcpy( &pSectionHdr->s_name[0], ".bss"); |
||
316 | /* later expansion */ |
||
317 | pSectionHdr->s_paddr = ci->GlobalStartAddress; |
||
318 | pSectionHdr->s_vaddr = ci->GlobalStartAddress; |
||
319 | pSectionHdr->s_flags = STYP_DATA; /* seems it should be STYP_BSS */ |
||
320 | |||
321 | /* write it out */ |
||
322 | if ( fwrite(&pSectionHdr->s_name[0], 1, sizeof(struct external_scnhdr), pi->coff_file ) != sizeof(struct external_scnhdr) ) { |
||
323 | fprintf(stderr,"\nFile error writing section header ...(disk full?)"); |
||
324 | return; |
||
325 | } |
||
326 | |||
327 | /* Section N Header - .data or eeprom */ |
||
328 | |||
329 | // Raw Data for Section 1 |
||
330 | if ( (p = FindFirstListObject(&ci->ListOfRawData) ) == 0 ) { |
||
331 | fprintf(stderr,"\nInternal error - unable to find binary data!"); |
||
332 | return; |
||
333 | } |
||
334 | |||
335 | /* write it out */ |
||
336 | if ( fwrite( p, 1, ci->MaxRomAddress + 2, pi->coff_file ) != (size_t)(ci->MaxRomAddress + 2) ) { |
||
337 | fprintf(stderr,"\nFile error writing raw .text data ...(disk full?)"); |
||
338 | return; |
||
339 | } |
||
340 | // Raw data for section n |
||
341 | |||
342 | // Relocation Info for section 1 |
||
343 | |||
344 | // Relocation info for section n |
||
345 | |||
346 | // Line numbers for section 1 |
||
347 | for ( pLine = (struct lineno *)FindFirstListObject( &ci->ListOfLineNumbers ); |
||
348 | pLine != 0; |
||
349 | pLine = (struct lineno *)FindNextListObject( &ci->ListOfLineNumbers ) ) { |
||
350 | |||
351 | pNode = GetCurrentNode( &ci->ListOfLineNumbers ); |
||
352 | |||
353 | /* write it out */ |
||
354 | if ( fwrite( pLine, 1, pNode->Size, pi->coff_file ) != pNode->Size ) { |
||
355 | fprintf(stderr,"\nFile error writing line numbers ...(disk full?)"); |
||
356 | return; |
||
357 | } |
||
358 | } |
||
359 | |||
360 | |||
361 | // Line numbers for section n |
||
362 | |||
363 | // Symbol table |
||
364 | for ( pEntry = (struct syment *)FindFirstListObject( &ci->ListOfSymbols ); |
||
365 | pEntry != 0; |
||
366 | pEntry = (struct syment *)FindNextListObject( &ci->ListOfSymbols ) ) { |
||
367 | |||
368 | pNode = GetCurrentNode( &ci->ListOfSymbols ); |
||
369 | |||
370 | /* write it out */ |
||
371 | if ( fwrite( pEntry, 1, pNode->Size, pi->coff_file ) != pNode->Size ) { |
||
372 | fprintf(stderr,"\nFile error writing symbol table ...(disk full?)"); |
||
373 | return; |
||
374 | } |
||
375 | } |
||
376 | |||
377 | // Symbol table of Globals |
||
378 | for ( pEntry = (struct syment *)FindFirstListObject( &ci->ListOfGlobals ); |
||
379 | pEntry != 0; |
||
380 | pEntry = (struct syment *)FindNextListObject( &ci->ListOfGlobals ) ) { |
||
381 | |||
382 | pNode = GetCurrentNode( &ci->ListOfGlobals ); |
||
383 | |||
384 | /* write it out */ |
||
385 | if ( fwrite( pEntry, 1, pNode->Size, pi->coff_file ) != pNode->Size ) { |
||
386 | fprintf(stderr,"\nFile error writing global symbols ...(disk full?)"); |
||
387 | return; |
||
388 | } |
||
389 | } |
||
390 | |||
391 | /* Specials .text, .bss, .data */ |
||
392 | |||
393 | for ( pEntry = (struct syment *)FindFirstListObject( &ci->ListOfSpecials ); |
||
394 | pEntry != 0; |
||
395 | pEntry = (struct syment *)FindNextListObject( &ci->ListOfSpecials ) ) { |
||
396 | |||
397 | pNode = GetCurrentNode( &ci->ListOfSpecials ); |
||
398 | |||
399 | /* write it out */ |
||
400 | if ( fwrite( pEntry, 1, pNode->Size, pi->coff_file ) != pNode->Size ) { |
||
401 | fprintf(stderr,"\nFile error writing special symbols ...(disk full?)"); |
||
402 | return; |
||
403 | } |
||
404 | } |
||
405 | |||
406 | // String Table |
||
407 | for ( p = (char *)FindFirstListObject( &ci->ListOfStrings ); |
||
408 | p != 0; |
||
409 | p = (char *)FindNextListObject( &ci->ListOfStrings ) ) { |
||
410 | |||
411 | pNode = GetCurrentNode( &ci->ListOfStrings ); |
||
412 | |||
413 | /* write it out */ |
||
414 | if ( fwrite( p, 1, pNode->Size, pi->coff_file ) != pNode->Size ) { |
||
415 | fprintf(stderr,"\nFile error writing strings data ...(disk full?)"); |
||
416 | return; |
||
417 | } |
||
418 | } |
||
419 | |||
420 | return; |
||
421 | } |
||
422 | |||
423 | /****************************************************************************************/ |
||
424 | |||
425 | void write_coff_eeprom( struct prog_info *pi, int address, unsigned char data){ |
||
426 | |||
427 | if ( !GET_ARG(pi->args, ARG_COFF) ) |
||
428 | return; |
||
429 | |||
430 | /* Coff output keeps track of binary data in memory buffers */ |
||
431 | if ( ci->pEEPRomMemory ) { |
||
432 | if ( address <= pi->device->eeprom_size ) { |
||
433 | *(ci->pEEPRomMemory + address) = data; |
||
434 | if ( address >= ci->MaxEepromAddress ) |
||
435 | ci->MaxEepromAddress = address; /* keep high water mark */ |
||
436 | } else { |
||
437 | pi->error_count++; |
||
438 | fprintf(stderr, "Error: EEPROM address %d exceeds max range %d", address, pi->device->eeprom_size ); |
||
439 | } |
||
440 | } |
||
441 | } |
||
442 | /****************************************************************************************/ |
||
443 | |||
444 | void write_coff_program( struct prog_info *pi, int address, unsigned int data){ |
||
445 | |||
446 | unsigned char *pByte; |
||
447 | |||
448 | if ( !GET_ARG(pi->args, ARG_COFF) ) |
||
449 | return; |
||
450 | |||
451 | /* Coff output keeps track of binary data in memory buffers, address is in bytes not words */ |
||
452 | if ( ci->pRomMemory ) { |
||
453 | /* JEG if ( address <= pi->device->flash_size ) { */ /* JEG 4-23-03 */ |
||
454 | if ( address <= pi->device->flash_size*2 ) { |
||
455 | pByte = (unsigned char *)(ci->pRomMemory + address); /* point to low byte in memory */ |
||
456 | *pByte++ = (data & 0xff); /* low byte */ |
||
457 | *pByte = ((data >> 8) & 0xff); /* high byte */ |
||
458 | |||
459 | if ( address >= ci->MaxRomAddress ) |
||
460 | ci->MaxRomAddress = address; /* keep high water mark */ |
||
461 | } else { |
||
462 | pi->error_count++; |
||
463 | /* JEG fprintf(stderr, "Error: FLASH address %d exceeds max range %d", address, pi->device->flash_size ); */ |
||
464 | fprintf(stderr, "Error: FLASH address %d exceeds max range %d", address, pi->device->flash_size*2 ); |
||
465 | } |
||
466 | } |
||
467 | } |
||
468 | |||
469 | /****************************************************************************************/ |
||
470 | |||
471 | void close_coff_file(struct prog_info *pi, FILE *fp){ |
||
472 | |||
473 | /* close the output file */ |
||
474 | fclose( fp ); |
||
475 | pi->coff_file = 0; |
||
476 | |||
477 | /* free all the internal memory buffers used by ci */ |
||
478 | |||
479 | FreeList( &ci->ListOfSectionHeaders ); |
||
480 | FreeList( &ci->ListOfRawData ); |
||
481 | FreeList( &ci->ListOfRelocations ); |
||
482 | FreeList( &ci->ListOfLineNumbers ); |
||
483 | FreeList( &ci->ListOfSymbols ); |
||
484 | FreeList( &ci->ListOfGlobals ); |
||
485 | FreeList( &ci->ListOfUndefined ); |
||
486 | FreeList( &ci->ListOfStrings ); |
||
487 | FreeList( &ci->ListOfTypes ); |
||
488 | FreeList( &ci->ListOfSplitLines ); |
||
489 | |||
490 | /* now free ci */ |
||
491 | free( ci ); |
||
492 | ci = 0; |
||
493 | } |
||
494 | |||
495 | /****************************************************************************************/ |
||
496 | |||
497 | int parse_stabs( struct prog_info *pi, char *p ){ |
||
498 | |||
499 | int ok = True; |
||
500 | int TypeCode, n; |
||
501 | char *pString, *p2, *p3, *p4, *p5, *pType, *pEnd, *pp, *pJoined; |
||
502 | |||
503 | |||
504 | if ( !GET_ARG(pi->args, ARG_COFF) || ( pi->pass == PASS_1 ) ) |
||
505 | return(True); |
||
506 | |||
507 | /* stabs debugging information is in the form: |
||
508 | .stabs "symbolic info string", HexorDecimalTypecode, parm3, parm4, parm5 |
||
509 | parm1, parm2, parm3 depend on typecode |
||
510 | |||
511 | N_LSYM 0x80 local sym: name,,0,type,offset |
||
512 | N_OPT 0x3c compiler options |
||
513 | N_SO 0x64 source file name: name,,0,0,address |
||
514 | N_SOL 0x84 #included file name: name,,0,0,address |
||
515 | N_FUN 0x24 procedure: name,,0,linenumber,address |
||
516 | N_GSYM 0x20 global symbol: name,,0,type,0 |
||
517 | N_LCSYM 0x28 .lcomm symbol: name,,0,type,address |
||
518 | N_STSYM 0x26 static symbol: name,,0,type,address |
||
519 | N_RSYM 0x40 register sym: name,,0,type,register |
||
520 | N_PSYM 0xa0 parameter: name,,0,type,offset |
||
521 | |||
522 | */ |
||
523 | |||
524 | /* Look for multiple commands per line */ |
||
525 | |||
526 | /* .stabs "linktag:T19=s46next:20=*19,0,16;last:20,16,16;a:21=ar1;0;2;22=ar1;0;3;1,32,96;\\",128,0,0,0 */ |
||
527 | /* .stabs "b:23=ar1;0;4;24=ar1;0;5;2,128,240;;",128,0,0,0 */ |
||
528 | |||
529 | |||
530 | /* Look for continuation lines per line */ |
||
531 | |||
532 | /* Get String information as a token */ |
||
533 | /* Parse the tokens in the stabn line buffer */ |
||
534 | pString = get_next_token(p, TERM_DOUBLEQUOTE ); /* zap first doublequote */ |
||
535 | p2 = get_next_token(pString, TERM_DOUBLEQUOTE ); /* zap last doublequote */ |
||
536 | p2 = get_next_token(p2, TERM_COMMA ); /* zap comma */ |
||
537 | p3 = get_next_token(p2, TERM_COMMA ); |
||
538 | p4 = get_next_token(p3, TERM_COMMA ); |
||
539 | p5 = get_next_token(p4, TERM_COMMA ); |
||
540 | pEnd = get_next_token(p5, TERM_END ); /* zap CR LF, make ASCIIZ */ |
||
541 | |||
542 | if ( !pString || !p2 || !p3 || !p4 || !p5 ) |
||
543 | return( False ); |
||
544 | |||
545 | /* Check for split lines */ |
||
546 | n = strlen( pString ); |
||
547 | if ( ( pString[n - 1] == '\\' ) && (pString[n - 2] == '\\') ) { |
||
548 | /* We have a continuation string here */ |
||
549 | pString[n - 2] = 0; |
||
550 | n -= 2; |
||
551 | if ( !(pp = (char *)AllocateListObject( &ci->ListOfSplitLines, n + 1 )) ) { |
||
552 | fprintf(stderr, "\nOut of memory allocating continuation line!"); |
||
553 | return( False ); |
||
554 | } |
||
555 | strcpy( pp, pString ); /* loose the continuation characters */ |
||
556 | return(True); |
||
557 | } |
||
558 | if ( ci->ListOfSplitLines.TotalItems > 0 ) { |
||
559 | /* Join lines together and process */ |
||
560 | if ( !(pJoined = calloc( 1, n + ci->ListOfSplitLines.TotalBytes ) ) ) { |
||
561 | fprintf(stderr, "\nOut of memory joining continuation lines!"); |
||
562 | return( False ); |
||
563 | } |
||
564 | for ( pp = (char *)FindFirstListObject( &ci->ListOfSplitLines ); |
||
565 | pp != 0; |
||
566 | pp = (char *)FindNextListObject( &ci->ListOfSplitLines ) ) { |
||
567 | |||
568 | strcat( pJoined, pp ); /* connect the lines */ |
||
569 | } |
||
570 | strcat( pJoined, pString ); |
||
571 | FreeList( &ci->ListOfSplitLines ); |
||
572 | if ( !AddListObject( &ci->ListOfSplitLines, pJoined, n + ci->ListOfSplitLines.TotalBytes ) ) { |
||
573 | fprintf(stderr, "\nUnable to add joined continuation line"); |
||
574 | return( False ); |
||
575 | } |
||
576 | pString = pJoined; |
||
577 | } |
||
578 | |||
579 | |||
580 | if ( *p2 == '0' ) |
||
581 | TypeCode = atox(p2); /* presume to be hex 0x */ |
||
582 | else |
||
583 | TypeCode = atoi(p2); |
||
584 | |||
585 | switch ( TypeCode ) { |
||
586 | |||
587 | case N_OPT: /* compiler options */ |
||
588 | break; /* nothing used here */ |
||
589 | |||
590 | case N_SO: /* source file name: name,,0,0,address */ |
||
591 | ok = stab_add_filename( pString, p5 ); |
||
592 | break; |
||
593 | |||
594 | case N_GSYM: /* global symbol: name,,0,type,0 */ |
||
595 | pType = get_next_token(pString, TERM_COLON ); /* separate at colon */ |
||
596 | ok = stab_add_global( pi, pString, pType ); |
||
597 | break; |
||
598 | |||
599 | case N_FUN: /* procedure: name,,0,linenumber,address */ |
||
600 | ok = stab_add_function( pi, pString, p5 ); |
||
601 | break; |
||
602 | |||
603 | case N_LSYM: /* local sym: name,,0,type,offset */ |
||
604 | /* pString, p2 = TypeCode, p3 = 0, p4 = 0, p5 = offset */ |
||
605 | pType = get_next_token(pString, TERM_COLON ); /* pType = symbol descriptor (character after the colon) */ |
||
606 | if ( *pType == 't') |
||
607 | ok = stab_add_local_type( pString, ++pType ); |
||
608 | else if (*pType == 'T') |
||
609 | ok = stab_add_tag_type( pString, ++pType ); |
||
610 | else |
||
611 | ok = stab_add_local( pi, pString, pType, p5 ); |
||
612 | break; |
||
613 | |||
614 | case N_RSYM: /* Symbol:[P|r]type,0,size,register */ |
||
615 | pType = get_next_token(pString, TERM_COLON ); /* separate at colon */ |
||
616 | ok = stab_add_local_register( pi, pString, pType, p5 ); |
||
617 | break; |
||
618 | |||
619 | case N_LCSYM: /* .lcomm symbol: name,,0,type,address */ |
||
620 | ok = True; |
||
621 | break; /* ignore constants */ |
||
622 | |||
623 | case N_STSYM: /* static symbol: name,,0,type,address */ |
||
624 | pType = get_next_token(pString, TERM_COLON ); /* separate at colon */ |
||
625 | ok = stab_add_static_symbol( pi, pString, pType, p5 ); |
||
626 | break; |
||
627 | |||
628 | case N_PSYM: /* parameter: name,,0,type,offset */ |
||
629 | pType = get_next_token(pString, TERM_COLON ); /* separate at colon */ |
||
630 | ok = stab_add_parameter_symbol( pi, pString, pType, p5 ); |
||
631 | break; |
||
632 | |||
633 | case N_SOL: /* #included file name: name,,0,0,address */ |
||
634 | ok = True; |
||
635 | break; /* ignore include files */ |
||
636 | |||
637 | default: |
||
638 | ok = False; |
||
639 | } |
||
640 | |||
641 | if ( ci->ListOfSplitLines.TotalItems > 0 ) |
||
642 | FreeList( &ci->ListOfSplitLines ); |
||
643 | |||
644 | return( ok ); |
||
645 | } |
||
646 | /****************************************************************************************/ |
||
647 | |||
648 | int parse_stabn( struct prog_info *pi, char *p ){ |
||
649 | |||
650 | int ok = True; |
||
651 | int TypeCode /* , LineNumber */, Level; |
||
652 | char *p1, *p2, *p3, *p4, *pLabel, *pFunction, *pEnd; |
||
653 | |||
654 | /* stabn debugging information is in the form: |
||
655 | .stabn TypeCode, 0, parm1, parm2 |
||
656 | parm1 is level |
||
657 | parm2 is Label-Function |
||
658 | |||
659 | compiler currently produces the following TypeCodes: |
||
660 | N_LBRAC 0xc0 left bracket: 0,,0,nesting level,address |
||
661 | N_RBRAC 0xe0 right bracket: 0,,0,nesting level,address |
||
662 | N_SLINE 0x44 src line: 0,,0,linenumber,address |
||
663 | */ |
||
664 | |||
665 | if ( !GET_ARG(pi->args, ARG_COFF) || ( pi->pass == PASS_1 ) ) |
||
666 | return(True); |
||
667 | |||
668 | /* Parse the tokens in the stabn line buffer */ |
||
669 | p1 = get_next_token(p, TERM_SPACE ); |
||
670 | p2 = get_next_token(p1, TERM_COMMA ); |
||
671 | p3 = get_next_token(p2, TERM_COMMA ); |
||
672 | p4 = get_next_token(p3, TERM_COMMA ); |
||
673 | pEnd = get_next_token(p4, TERM_END ); /* zap CR LF, make ASCIIZ */ |
||
674 | |||
675 | if ( !p1 || !p2 || !p3 || !p4 ) |
||
676 | return( False ); |
||
677 | |||
678 | /* first convert TypeCode to binary */ |
||
679 | if ( *p1 == '0' ) |
||
680 | TypeCode = atox(p1); /* presume to be hex 0x */ |
||
681 | else |
||
682 | TypeCode = atoi(p1); |
||
683 | |||
684 | Level = atoi(p3); /* line number or level */ |
||
685 | pLabel = p4; /* Assembly label */ |
||
686 | pFunction = get_next_token( pLabel, TERM_DASH ); /* Function */ |
||
687 | |||
688 | switch ( TypeCode ) { |
||
689 | case N_SLINE: /* src line: 0,,0,linenumber,address */ |
||
690 | ok = stab_add_lineno( pi, Level, pLabel, pFunction ); |
||
691 | break; |
||
692 | |||
693 | case N_LBRAC: /* left bracket: 0,,0,nesting level,address */ |
||
694 | ok = stab_add_lbracket( pi, Level, pLabel, pFunction ); |
||
695 | break; |
||
696 | |||
697 | case N_RBRAC: /* right bracket: 0,,0,nesting level,address */ |
||
698 | ok = stab_add_rbracket( pi, Level, pLabel, pFunction ); |
||
699 | break; |
||
700 | |||
701 | default: |
||
702 | fprintf(stderr, "\nUnknown .stabn TypeCode = 0x%x", TypeCode ); |
||
703 | ok = False; |
||
704 | } |
||
705 | return( ok ); |
||
706 | } |
||
707 | |||
708 | /****************************************************************************************/ |
||
709 | int stab_add_lineno( struct prog_info *pi, int LineNumber, char *pLabel, char *pFunction ){ |
||
710 | |||
711 | int Address; |
||
712 | struct lineno *pln; |
||
713 | struct syment *pEntry; |
||
714 | union auxent *pAux; |
||
715 | |||
716 | /* Allocate LineNumber Table entry and fill it in */ |
||
717 | pln = (struct lineno *)AllocateListObject(&ci->ListOfLineNumbers, sizeof(struct lineno) ); |
||
718 | if ( !pln ) { |
||
719 | fprintf(stderr, "\nOut of memory allocating lineno table for function %s", pFunction ); |
||
720 | return( False ); |
||
721 | } |
||
722 | /* set value field to be address of label in bytes */ |
||
723 | if ( !get_symbol(pi, pLabel, &Address) ) { |
||
724 | fprintf(stderr, "\nUnable to locate label %s", pLabel ); |
||
725 | return( False ); |
||
726 | } |
||
727 | pln->l_addr.l_paddr = Address * 2; /* need byte quanities */ |
||
728 | |||
729 | /* Line number is relative to beginning of function, starts at 1 */ |
||
730 | if ( ci->FunctionStartLine == 0 ) { |
||
731 | /* This line number is that same as the function start */ |
||
732 | ci->FunctionStartLine = LineNumber; |
||
733 | } |
||
734 | pln->l_lnno = LineNumber - ci->FunctionStartLine + 1; |
||
735 | ci->CurrentSourceLine = LineNumber; /* keep track of source line for .eb .ef arrays */ |
||
736 | if ( ci->NeedLineNumberFixup ) { |
||
737 | /* need to go into symbol table and fix last NeedLineNumberFixup entries */ |
||
738 | for ( pEntry = (struct syment *)FindLastListObject(&ci->ListOfSymbols); |
||
739 | (pEntry != 0) && ( ci->NeedLineNumberFixup != 0); |
||
740 | pEntry = (struct syment *)FindNextLastListObject(&ci->ListOfSymbols) ) { |
||
741 | |||
742 | /* Fix up line number entries */ |
||
743 | if ( (pEntry->n_sclass == C_FCN ) || ( pEntry->n_sclass == C_BLOCK ) || ( pEntry->n_sclass == C_EXT) ) { |
||
744 | pEntry++; |
||
745 | pAux = (union auxent *)pEntry; |
||
746 | pAux->x_sym.x_misc.x_lnsz.x_lnno = LineNumber; |
||
747 | ci->NeedLineNumberFixup--; |
||
748 | } |
||
749 | } |
||
750 | } |
||
751 | |||
752 | return(True); |
||
753 | } |
||
754 | /****************************************************************************************/ |
||
755 | |||
756 | int stab_add_lbracket( struct prog_info *pi, int Level, char *pLabel, char *pFunction ){ |
||
757 | |||
758 | int Address; |
||
759 | struct syment *pEntry; |
||
760 | union auxent *pAux; |
||
761 | //char *p; |
||
762 | //struct lineno *pln; |
||
763 | |||
764 | if ( !get_symbol(pi, pLabel, &Address) ) { |
||
765 | fprintf(stderr, "\nUnable to locate label %s", pLabel ); |
||
766 | return( False ); |
||
767 | } |
||
768 | |||
769 | /* Now create a .bb symbol table entry and aux entry too */ |
||
770 | pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 ); |
||
771 | if ( !pEntry ) { |
||
772 | fprintf(stderr, "\nOut of memory allocating symbol table entry for .bb %s", pLabel ); |
||
773 | return( False ); |
||
774 | } |
||
775 | /* n_name */ |
||
776 | memset( pEntry->n_name, 0, 8 ); |
||
777 | strcpy( pEntry->n_name, ".bb" ); |
||
778 | |||
779 | pEntry->n_value = Address * 2; /* bytes not words */ |
||
780 | pEntry->n_scnum = 1; /* .text */ |
||
781 | pEntry->n_type = 0; |
||
782 | pEntry->n_sclass = C_BLOCK; |
||
783 | pEntry->n_numaux = 1; |
||
784 | pEntry++; /* point to aux entry */ |
||
785 | pAux = (union auxent *)pEntry; |
||
786 | pAux->x_sym.x_misc.x_lnsz.x_lnno = 0; /* UNKNOWN - post process */ |
||
787 | pAux->x_sym.x_misc.x_lnsz.x_size = 0; /* UNKNOWN - post process */ |
||
788 | ci->NeedLineNumberFixup++; /* once for .bb block */ |
||
789 | return(True); |
||
790 | } |
||
791 | |||
792 | /****************************************************************************************/ |
||
793 | int stab_add_rbracket( struct prog_info *pi, int Level, char *pLabel, char *pFunction ){ |
||
794 | |||
795 | int Address; |
||
796 | struct syment *pEntry; |
||
797 | union auxent *pAux; |
||
798 | //char *p; |
||
799 | //struct lineno *pln; |
||
800 | |||
801 | if ( !get_symbol(pi, pLabel, &Address) ) { |
||
802 | fprintf(stderr, "\nUnable to locate label %s", pLabel ); |
||
803 | return( False ); |
||
804 | } |
||
805 | |||
806 | /* Now create a .eb symbol table entry */ |
||
807 | pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 ); |
||
808 | if ( !pEntry ) { |
||
809 | fprintf(stderr, "\nOut of memory allocating symbol table entry for .eb %s", pLabel ); |
||
810 | return( False ); |
||
811 | } |
||
812 | /* n_name */ |
||
813 | memset( pEntry->n_name, 0, 8 ); |
||
814 | strcpy( pEntry->n_name, ".eb" ); |
||
815 | pEntry->n_sclass = C_BLOCK; |
||
816 | pEntry->n_value = Address * 2; /* bytes not words */ |
||
817 | pEntry->n_scnum = 1; /* .text */ |
||
818 | pEntry->n_type = 0; |
||
819 | pEntry->n_numaux = 1; |
||
820 | pEntry++; /* point to aux entry */ |
||
821 | pAux = (union auxent *)pEntry; |
||
822 | pAux->x_sym.x_misc.x_lnsz.x_lnno = ci->CurrentSourceLine; |
||
823 | |||
824 | /* create an .ef if at level 0 */ |
||
825 | if ( Level == 0 ) { |
||
826 | |||
827 | /* Now create a .ef symbol table entry */ |
||
828 | pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 ); |
||
829 | if ( !pEntry ) { |
||
830 | fprintf(stderr, "\nOut of memory allocating symbol table entry for .ef %s", pLabel ); |
||
831 | return( False ); |
||
832 | } |
||
833 | /* n_name */ |
||
834 | memset( pEntry->n_name, 0, 8 ); |
||
835 | strcpy( pEntry->n_name, ".ef" ); |
||
836 | pEntry->n_sclass = C_FCN; |
||
837 | pEntry->n_value = Address * 2; /* bytes not words */ |
||
838 | pEntry->n_scnum = 1; /* .text */ |
||
839 | pEntry->n_type = 0; |
||
840 | pEntry->n_numaux = 1; |
||
841 | pEntry++; /* point to aux entry */ |
||
842 | pAux = (union auxent *)pEntry; |
||
843 | pAux->x_sym.x_misc.x_lnsz.x_lnno = ci->CurrentSourceLine; |
||
844 | } |
||
845 | return(True); |
||
846 | } |
||
847 | |||
848 | /****************************************************************************************/ |
||
849 | int stab_add_filename( char *pName, char *pLabel ){ |
||
850 | |||
851 | int ok, n; |
||
852 | struct syment *pEntry; |
||
853 | union auxent *pAux; |
||
854 | char *p; |
||
855 | |||
856 | /* if( pLabel == "Ltext0" ) then beginning of .text, pName = cwd, next pName = file */ |
||
857 | |||
858 | /* if( pLabel == "Letext" ) then end of .text , pName == NULL */ |
||
859 | |||
860 | /* we only need the one not ending in Slash */ |
||
861 | ok = True; |
||
862 | n = strlen(pName); |
||
863 | if ( n > 0 ) { |
||
864 | if ( ( pName[ n - 1] == '\\') || (pName[ n - 1] == '/') ) |
||
865 | return(True); /* ignore */ |
||
866 | } else |
||
867 | return(True); |
||
868 | |||
869 | |||
870 | /* allocate entry in symbol table list */ |
||
871 | pEntry = (struct syment *)AllocateTwoListObjects( |
||
872 | &ci->ListOfSymbols, sizeof(struct syment) * 2 ); /* aux entry too */ |
||
873 | if ( !pEntry ) { |
||
874 | fprintf(stderr, "\nOut of memory allocating symbol table entry for global %s", pName ); |
||
875 | return( False ); |
||
876 | } |
||
877 | /* n_name */ |
||
878 | memset( pEntry->n_name, 0, 8 ); |
||
879 | strcpy( pEntry->n_name, ".file" ); |
||
880 | /* n_value is determined after processing done UNKNOWN - post process */ |
||
881 | /* The value of that symbol equals the symbol table entry index of the next .file symbol or .global */ |
||
882 | /* post process */ |
||
883 | pEntry->n_scnum = N_DEBUG; |
||
884 | pEntry->n_sclass = C_FILE; |
||
885 | pEntry->n_numaux = 1; |
||
886 | pEntry++; /* point to aux entry */ |
||
887 | pAux = (union auxent *)pEntry; |
||
888 | |||
889 | /* Add Label name to symbol table */ |
||
890 | if ( n <= FILNMLEN ) { |
||
891 | /* inline filename */ |
||
892 | memset( pAux->x_file.x_fname, 0, FILNMLEN ); |
||
893 | strncpy( pAux->x_file.x_fname, pName, n ); /* might not be zero terminated */ |
||
894 | } else { |
||
895 | pAux->x_file.x_n.x_zeroes = 0; /* symbol name is in string table */ |
||
896 | pAux->x_file.x_n.x_offset = ci->ListOfStrings.TotalBytes; |
||
897 | |||
898 | /* add to string table */ |
||
899 | p = (char *)AllocateListObject( &ci->ListOfStrings, n + 1 ); |
||
900 | if ( !p ) { |
||
901 | fprintf(stderr, "\nOut of memory allocating string table space!"); |
||
902 | return( False ); |
||
903 | } |
||
904 | strcpy( p, pName ); |
||
905 | } |
||
906 | return( ok ); |
||
907 | } |
||
908 | |||
909 | /****************************************************************************************/ |
||
910 | int stab_add_function( struct prog_info *pi, char *pName, char *pLabel ){ |
||
911 | |||
912 | int n, Address; |
||
913 | unsigned short CoffType, Type; |
||
914 | struct syment *pEntry; |
||
915 | char *pType; |
||
916 | struct lineno *pln; |
||
917 | union auxent *pAux; |
||
918 | int SymbolIndex; |
||
919 | |||
920 | pType = get_next_token(pName, TERM_COLON ); /* pType = symbol descriptor (character after the colon) */ |
||
921 | Type = atoi(pType + 1); /* skip past F, predefined variable type */ |
||
922 | if ( (CoffType = GetCoffType( Type )) == 0 ) { |
||
923 | fprintf(stderr, "\nUnrecognized return type found for function %s = %d", pName, Type ); |
||
924 | return(False); |
||
925 | } |
||
926 | /* Get Current Symbol Index, Allocate Symbol Table entry and fill it in */ |
||
927 | SymbolIndex = ci->ListOfSymbols.TotalItems; |
||
928 | pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 ); |
||
929 | if ( !pEntry ) { |
||
930 | fprintf(stderr, "\nOut of memory allocating symbol table entry for function %s", pName ); |
||
931 | return( False ); |
||
932 | } |
||
933 | if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { |
||
934 | fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); |
||
935 | } |
||
936 | if ( !get_symbol(pi, pLabel, &Address) ) { |
||
937 | fprintf(stderr, "\nUnable to locate function %s", pName ); |
||
938 | return( False ); |
||
939 | } |
||
940 | pEntry->n_value = Address * 2; /* convert words to bytes */ |
||
941 | pEntry->n_scnum = 2; /* .bss */ |
||
942 | if ( (CoffType = GetCoffType( Type )) == 0 ) { |
||
943 | fprintf(stderr, "\nUnrecognized type found for function %s = %d", pName, Type ); |
||
944 | return(False); |
||
945 | } |
||
946 | pEntry->n_type = (unsigned short)(CoffType | (DT_FCN << 4)); |
||
947 | pEntry->n_sclass = C_EXT; |
||
948 | pEntry->n_numaux = 1; |
||
949 | pEntry++; /* point to aux entry */ |
||
950 | pAux = (union auxent *)pEntry; |
||
951 | pAux->x_sym.x_tagndx = SymbolIndex + 1; /* point to the .bf entry index */ |
||
952 | // wrong! |
||
953 | // pAux->x_sym.x_misc.x_lnsz.x_lnno = ci->ListOfLineNumbers.TotalBytes; /* Relative Fixup point to where line numbers start */ |
||
954 | // pAux->x_sym.x_misc.x_lnsz.x_size = 0; /* UNKNOWN till next function called */ |
||
955 | pAux->x_sym.x_misc.x_fsize = 0; /* unknown till end */ |
||
956 | pAux->x_sym.x_fcnary.x_fcn.x_lnnoptr = ci->ListOfLineNumbers.TotalBytes; /* relative offset to line number entry */ |
||
957 | pAux->x_sym.x_fcnary.x_fcn.x_endndx = 0; /* index to next entry */ |
||
958 | |||
959 | /* Now add function entry into the line number table */ |
||
960 | /* Allocate Symbol Table entry and fill it in */ |
||
961 | pln = (struct lineno *)AllocateListObject(&ci->ListOfLineNumbers, sizeof(struct lineno) ); |
||
962 | if ( !pln ) { |
||
963 | fprintf(stderr, "\nOut of memory allocating lineno table for function %s", pName ); |
||
964 | return( False ); |
||
965 | } |
||
966 | pln->l_lnno = 0; |
||
967 | pln->l_addr.l_symndx = SymbolIndex; |
||
968 | |||
969 | /* Initialize the FunctionStartLine from the beginning of the function */ |
||
970 | ci->FunctionStartLine = 0; |
||
971 | |||
972 | /* Allocate Symbol Table entry and fill it in */ |
||
973 | pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 ); |
||
974 | if ( !pEntry ) { |
||
975 | fprintf(stderr, "\nOut of memory allocating symbol table entry .bf for function %s", pName ); |
||
976 | return( False ); |
||
977 | } |
||
978 | memset( pEntry->n_name, 0, 8 ); |
||
979 | strcpy( pEntry->n_name, ".bf" ); |
||
980 | pEntry->n_value = Address * 2; /* bytes not words */ |
||
981 | pEntry->n_scnum = 1; /* .text */ |
||
982 | pEntry->n_type = 0; |
||
983 | pEntry->n_sclass = C_FCN; |
||
984 | pEntry->n_numaux = 1; |
||
985 | pEntry++; /* point to aux entry */ |
||
986 | pAux = (union auxent *)pEntry; |
||
987 | pAux->x_sym.x_misc.x_lnsz.x_lnno = 0; /* UNKNOWN - post process */ |
||
988 | pAux->x_sym.x_misc.x_lnsz.x_size = 0; /* UNKNOWN - post process */ |
||
989 | |||
990 | ci->NeedLineNumberFixup++; /* once for function C_EXT symbol */ |
||
991 | ci->NeedLineNumberFixup++; /* once for .bf block */ |
||
992 | return( True ); |
||
993 | } |
||
994 | /****************************************************************************************/ |
||
995 | |||
996 | int stab_add_global( struct prog_info *pi, char *pName, char *pType ){ |
||
997 | |||
998 | int n, Address, IsArray, SymbolIndex; |
||
999 | unsigned short CoffType, Type; |
||
1000 | struct syment *pEntry; |
||
1001 | char *p; |
||
1002 | STABCOFFMAP *pMap; |
||
1003 | |||
1004 | |||
1005 | n = strlen( pName ); /* see if it's 8 bytes or less */ |
||
1006 | Type = atoi(pType + 1); /* skip past G, predefined variable type */ |
||
1007 | if ( (CoffType = GetCoffType( Type )) == 0 ) { |
||
1008 | fprintf(stderr, "\nUnrecognized type found for global %s = %d", pName, Type ); |
||
1009 | return(False); |
||
1010 | } |
||
1011 | pMap = (STABCOFFMAP *)GetCurrentListObject( &ci->ListOfTypes ); |
||
1012 | |||
1013 | SymbolIndex = ci->ListOfSymbols.TotalItems; |
||
1014 | /* Allocate Symbol Table entry and fill it in, Auxiliary table if its an array */ |
||
1015 | if ( IsTypeArray( CoffType ) == True ) { |
||
1016 | IsArray = True; |
||
1017 | pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ); |
||
1018 | } else { |
||
1019 | IsArray = False; |
||
1020 | pEntry = (struct syment *)AllocateListObject( &ci->ListOfGlobals, sizeof(struct syment) ); |
||
1021 | } |
||
1022 | if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { |
||
1023 | fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); |
||
1024 | } |
||
1025 | /* set value field to be address of label in bytes */ |
||
1026 | /* add underscore to lookup label */ |
||
1027 | if ( (p = calloc( 1, n + 2)) == 0 ) { |
||
1028 | fprintf(stderr,"\nOut of memory adding global %s", pName ); |
||
1029 | return(False); |
||
1030 | } |
||
1031 | *p = '_'; |
||
1032 | strcpy( p + 1, pName ); |
||
1033 | if ( !get_symbol(pi, p, &Address) ) { |
||
1034 | fprintf(stderr, "\nUnable to locate global %s", p ); |
||
1035 | free( p ); |
||
1036 | return( False ); |
||
1037 | } |
||
1038 | free( p ); |
||
1039 | pEntry->n_value = Address; /* already in bytes */ |
||
1040 | if ( ci->GlobalStartAddress == -1 ) { |
||
1041 | ci->GlobalStartAddress = Address; |
||
1042 | } |
||
1043 | if ( Address < ci->GlobalStartAddress ) |
||
1044 | ci->GlobalStartAddress = Address; |
||
1045 | if ( Address > ci->GlobalEndAddress ) |
||
1046 | ci->GlobalEndAddress = Address; |
||
1047 | |||
1048 | pEntry->n_scnum = 2; /* .bss */ |
||
1049 | pEntry->n_type = CoffType; |
||
1050 | pEntry->n_sclass = C_STAT; |
||
1051 | if ( IsArray == False ) |
||
1052 | pEntry->n_numaux = 0; |
||
1053 | else { |
||
1054 | pEntry->n_numaux = 1; |
||
1055 | pEntry++; |
||
1056 | AddArrayAuxInfo( (union auxent *)pEntry, (unsigned short)SymbolIndex, pMap ); |
||
1057 | } |
||
1058 | return( True ); |
||
1059 | } |
||
1060 | |||
1061 | /****************************************************************************************/ |
||
1062 | int stab_add_local( struct prog_info *pi, char *pName, char *pType, char *pOffset ){ |
||
1063 | |||
1064 | int n, Offset, IsArray; |
||
1065 | unsigned short CoffType, Type, SymbolIndex; |
||
1066 | struct syment *pEntry; |
||
1067 | STABCOFFMAP *pMap; |
||
1068 | |||
1069 | n = strlen( pName ); /* see if it's 8 bytes or less */ |
||
1070 | Type = atoi(pType); /* predefined variable type */ |
||
1071 | Offset = atoi(pOffset); /* offset in stack frame */ |
||
1072 | if ( (CoffType = GetCoffType( Type )) == 0 ) { |
||
1073 | fprintf(stderr, "\nUnrecognized type found for local %s = %d", pName, Type ); |
||
1074 | return(False); |
||
1075 | } |
||
1076 | pMap = (STABCOFFMAP *)GetCurrentListObject( &ci->ListOfTypes ); |
||
1077 | SymbolIndex = ci->ListOfSymbols.TotalItems; |
||
1078 | /* Allocate Symbol Table entry and fill it in, Auxiliary table if its an array */ |
||
1079 | if ( IsTypeArray( CoffType ) == True ) { |
||
1080 | IsArray = True; |
||
1081 | pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ); |
||
1082 | } else { |
||
1083 | IsArray = False; |
||
1084 | pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) ); |
||
1085 | } |
||
1086 | if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { |
||
1087 | fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); |
||
1088 | } |
||
1089 | pEntry->n_type = CoffType; |
||
1090 | pEntry->n_sclass = C_AUTO; |
||
1091 | pEntry->n_scnum = N_ABS; |
||
1092 | pEntry->n_value = Offset + 1; /* Silly avr studio is set in its ways */ |
||
1093 | if ( IsArray == False ) |
||
1094 | pEntry->n_numaux = 0; |
||
1095 | else { |
||
1096 | pEntry->n_numaux = 1; |
||
1097 | pEntry++; |
||
1098 | AddArrayAuxInfo( (union auxent *)pEntry, SymbolIndex, pMap ); |
||
1099 | } |
||
1100 | return( True ); |
||
1101 | } |
||
1102 | |||
1103 | /****************************************************************************************/ |
||
1104 | int stab_add_parameter_symbol( struct prog_info *pi, char *pName, char *pType, char *pOffset ){ |
||
1105 | |||
1106 | int n, Offset; |
||
1107 | unsigned short CoffType, Type; |
||
1108 | struct syment *pEntry; |
||
1109 | |||
1110 | n = strlen( pName ); /* see if it's 8 bytes or less */ |
||
1111 | Type = atoi(pType); /* predefined variable type */ |
||
1112 | Offset = atoi(pOffset); /* offset in stack frame */ |
||
1113 | if ( (CoffType = GetCoffType( Type )) == 0 ) { |
||
1114 | fprintf(stderr, "\nUnrecognized type found for %s = %d", pName, Type ); |
||
1115 | return(False); |
||
1116 | } |
||
1117 | /* Allocate Symbol Table entry and fill it in */ |
||
1118 | pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) ); |
||
1119 | if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { |
||
1120 | fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); |
||
1121 | } |
||
1122 | pEntry->n_type = CoffType; |
||
1123 | pEntry->n_sclass = C_ARG; |
||
1124 | pEntry->n_scnum = N_ABS; |
||
1125 | pEntry->n_value = Offset; |
||
1126 | pEntry->n_numaux = 0; |
||
1127 | return( True ); |
||
1128 | } |
||
1129 | /****************************************************************************************/ |
||
1130 | int stab_add_static_symbol( struct prog_info *pi, char *pName, char *pType, char *pLabel ){ |
||
1131 | |||
1132 | int n, Address; |
||
1133 | unsigned short CoffType, Type; |
||
1134 | struct syment *pEntry; |
||
1135 | |||
1136 | n = strlen( pName ); /* see if it's 8 bytes or less */ |
||
1137 | Type = atoi(pType + 1); /* skip past S, predefined variable type */ |
||
1138 | if ( (CoffType = GetCoffType( Type )) == 0 ) { |
||
1139 | fprintf(stderr, "\nUnrecognized type found for %s = %d", pName, Type ); |
||
1140 | return(False); |
||
1141 | } |
||
1142 | /* Allocate Symbol Table entry and fill it in */ |
||
1143 | pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) ); |
||
1144 | if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { |
||
1145 | fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); |
||
1146 | } |
||
1147 | pEntry->n_type = CoffType; |
||
1148 | pEntry->n_sclass = C_STAT; |
||
1149 | pEntry->n_scnum = N_ABS; |
||
1150 | if ( !get_symbol(pi, pLabel, &Address) ) { |
||
1151 | fprintf(stderr, "\nUnable to locate label %s", pLabel ); |
||
1152 | return( False ); |
||
1153 | } |
||
1154 | pEntry->n_value = Address * 2; /* find address of variable in bytes */ |
||
1155 | pEntry->n_numaux = 0; |
||
1156 | return( True ); |
||
1157 | } |
||
1158 | /****************************************************************************************/ |
||
1159 | |||
1160 | int stab_add_local_register( struct prog_info *pi, char *pName, char *pType, char *pRegister ){ |
||
1161 | |||
1162 | int n, Register, Size; |
||
1163 | unsigned short CoffType, Type; |
||
1164 | struct syment *pEntry; |
||
1165 | |||
1166 | n = strlen( pName ); /* see if it's 8 bytes or less */ |
||
1167 | Type = (unsigned short)atoi(pType + 1); /* skip past P, predefined variable type */ |
||
1168 | Register = atoi(pRegister); /* offset in stack frame */ |
||
1169 | if ( (CoffType = GetCoffType( Type )) == 0 ) { |
||
1170 | fprintf(stderr, "\nUnrecognized type found for %s = %d", pName, Type ); |
||
1171 | return(False); |
||
1172 | } |
||
1173 | Size = GetCoffTypeSize( Type ); /* Silly requirement for avr studio */ |
||
1174 | /* Allocate Symbol Table entry and fill it in */ |
||
1175 | pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) ); |
||
1176 | if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { |
||
1177 | fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); |
||
1178 | return(False); |
||
1179 | } |
||
1180 | pEntry->n_type = CoffType; |
||
1181 | // if( (*pType == 'r') || (*pType == 'R') ) |
||
1182 | // pEntry->n_sclass = C_REG; |
||
1183 | // else if( (*pType == 'p') || (*pType == 'P') ) |
||
1184 | pEntry->n_sclass = C_REGPARM; /* Silly avr studio only accepts this for registers */ |
||
1185 | // else{ |
||
1186 | // fprintf(stderr,"\nUnknown register type -> %s", pType ); |
||
1187 | // return(False); |
||
1188 | // } |
||
1189 | pEntry->n_scnum = N_ABS; |
||
1190 | pEntry->n_numaux = 0; |
||
1191 | if ( Size == 1 ) |
||
1192 | pEntry->n_value = 0xffffff00 | Register; /* Silly requirement for avr studio */ |
||
1193 | else if ( Size == 2 ) |
||
1194 | pEntry->n_value = 0xffff0000 | ((Register + 1) << 8) | Register; /* Silly requirement for avr studio */ |
||
1195 | else if ( Size == 4 ) |
||
1196 | pEntry->n_value = ((Register + 3) << 24) | ((Register + 3) << 16) | ((Register + 1) << 8) | Register; /* Silly requirement for avr studio */ |
||
1197 | else { |
||
1198 | fprintf(stderr,"\nUnknown register size (%d) and coff type (%d)", Size, CoffType ); |
||
1199 | return(False); |
||
1200 | } |
||
1201 | return( True ); |
||
1202 | } |
||
1203 | |||
1204 | /****************************************************************************************/ |
||
1205 | |||
1206 | int stab_add_local_type( char *pName, char *pType ){ |
||
1207 | |||
1208 | char *p; |
||
1209 | unsigned short StabType; |
||
1210 | |||
1211 | /* .stabs "int:t1=r1;-128;127;",128,0,0,0 */ |
||
1212 | /* .stabs ":t20=ar1;0;1;21=ar1;0;1;2",128,0,0,0 */ |
||
1213 | /* pType-----^ */ |
||
1214 | /* Stab Type - convert to Coff type at end (after inline assignments */ |
||
1215 | if ( GetStabType( pType, &StabType, &p ) != True ) { |
||
1216 | fprintf(stderr,"\nInvalid tag type found in structure item -> %s", p); |
||
1217 | return(False); |
||
1218 | } |
||
1219 | |||
1220 | return(True); |
||
1221 | } |
||
1222 | |||
1223 | /****************************************************************************************/ |
||
1224 | |||
1225 | int GetStructUnionTagItem( char *p, char **pEnd, char **pName, unsigned short *pType, unsigned short *pBitOffset, unsigned short *pBitSize) { |
||
1226 | |||
1227 | unsigned short StabType; |
||
1228 | /* Structure or Union Tag Item consists of -> name:type,bitoffset,bitsize; */ |
||
1229 | |||
1230 | /* name */ |
||
1231 | *pName = p; |
||
1232 | while ( *p && (*p != ':') ) p++; // locate colon |
||
1233 | if ( *p != ':' ) { |
||
1234 | fprintf(stderr,"\nNo colon found in structure item -> %s", *pName); |
||
1235 | return(False); |
||
1236 | } |
||
1237 | *p++ = 0; // Asciiz |
||
1238 | |||
1239 | /* Stab Type - convert to Coff type at end (after inline assignments */ |
||
1240 | if ( GetStabType( p, &StabType, &p ) != True ) { |
||
1241 | fprintf(stderr,"\nInvalid tag type found in structure item -> %s", p); |
||
1242 | return(False); |
||
1243 | } |
||
1244 | |||
1245 | /* BitSize */ |
||
1246 | if ( *p != ',' ) { |
||
1247 | fprintf(stderr,"\nNo Bit size found in structure item -> %s", p ); |
||
1248 | return(False); |
||
1249 | } |
||
1250 | *pBitOffset = (unsigned short)atoi( ++p ); |
||
1251 | while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits |
||
1252 | |||
1253 | /* BitOffset */ |
||
1254 | if ( *p != ',' ) { |
||
1255 | fprintf(stderr,"\nNo Bit offset found in structure item -> %s", p ); |
||
1256 | return(False); |
||
1257 | } |
||
1258 | *pBitSize = (unsigned short)atoi( ++p ); |
||
1259 | while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits |
||
1260 | |||
1261 | /* Now convert stab type to COFF */ |
||
1262 | if ( (*pType = GetCoffType( (unsigned short)StabType)) == 0 ) { |
||
1263 | fprintf(stderr,"\nNo COFF type found for stab type %d", StabType ); |
||
1264 | return( False); |
||
1265 | } |
||
1266 | if ( *++p == ';' ) /* Now eat last semicolon(s) */ |
||
1267 | p++; |
||
1268 | *pEnd = p; |
||
1269 | |||
1270 | return( True ); |
||
1271 | } |
||
1272 | /****************************************************************************************/ |
||
1273 | |||
1274 | int GetEnumTagItem( char *p, char **pEnd, char **pEnumName, int *pEnumValue ) { |
||
1275 | |||
1276 | /* Enum Tag Item consists of -> member1:value,member2:value2,; */ |
||
1277 | *pEnumName = p; |
||
1278 | while ( *p && (*p != ':') ) p++; // locate colon |
||
1279 | if ( *p != ':' ) { |
||
1280 | fprintf(stderr,"\nNo colon found in enum item -> %s", *pEnumName); |
||
1281 | return(False); |
||
1282 | } |
||
1283 | *p++ = 0; // Asciiz |
||
1284 | *pEnumValue = atoi(p); |
||
1285 | |||
1286 | while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits |
||
1287 | if ( *p != ',' ) { |
||
1288 | fprintf(stderr,"\nNo comma found after enum value -> %s", p ); |
||
1289 | return(False); |
||
1290 | } |
||
1291 | if ( *++p ==';' ) |
||
1292 | p++; /* eat last semicolon */ |
||
1293 | *pEnd = p; |
||
1294 | return( True ); |
||
1295 | } |
||
1296 | |||
1297 | /****************************************************************************************/ |
||
1298 | int GetArrayType( char *p, char **pEnd, STABCOFFMAP *pMap, unsigned short *DerivedBits, int ExtraLevels ){ |
||
1299 | |||
1300 | int MinIndex, MaxIndex, Result, Size, i; |
||
1301 | char *pMinIndex, *pMaxIndex, *pType; |
||
1302 | unsigned short Type; |
||
1303 | |||
1304 | Result = True; |
||
1305 | |||
1306 | pMinIndex = pMaxIndex = pType = 0; |
||
1307 | while ( *p && (*p != ';') ) p++; /* find min index */ |
||
1308 | pMinIndex = ++p; |
||
1309 | while ( *p && (*p != ';') ) p++; /* find max index */ |
||
1310 | pMaxIndex = ++p; |
||
1311 | while ( *p && (*p != ';') ) p++; /* find type index */ |
||
1312 | pType = ++p; |
||
1313 | |||
1314 | /* bump the pointers to the digits */ |
||
1315 | if ( !isdigit(*pMinIndex) ) |
||
1316 | Result = False; |
||
1317 | if ( !isdigit(*pMaxIndex) ) |
||
1318 | Result = False; |
||
1319 | if ( !isdigit(*pType) ) |
||
1320 | Result = False; |
||
1321 | /* Is syntax ok ? */ |
||
1322 | if ( Result != True ) { |
||
1323 | fprintf(stderr,"\nSyntax error on array parameters %s%s%s", pMinIndex, pMaxIndex, pType ); |
||
1324 | return(False); |
||
1325 | } |
||
1326 | MinIndex = atoi(pMinIndex); |
||
1327 | MaxIndex = atoi(pMaxIndex); |
||
1328 | |||
1329 | if ( GetStabType( p, &Type, &p ) != True ) |
||
1330 | return(False); |
||
1331 | |||
1332 | if ( !SetupDefinedType( Type, pMap, DerivedBits, ExtraLevels ) ) |
||
1333 | return( False ); |
||
1334 | |||
1335 | /* Now update the size based on the indicies */ |
||
1336 | Size = (MaxIndex - MinIndex) + 1; |
||
1337 | pMap->ByteSize *= Size; |
||
1338 | pMap->Line = ci->CurrentSourceLine; |
||
1339 | /* add the dimension information */ |
||
1340 | for ( i = 5; i >= 0; i-- ) { |
||
1341 | if ( pMap->Dimensions[i] != 0 ) { |
||
1342 | i++; |
||
1343 | pMap->Dimensions[i] = Size; |
||
1344 | break; |
||
1345 | } |
||
1346 | } |
||
1347 | |||
1348 | *pEnd = p; |
||
1349 | return(True); |
||
1350 | } |
||
1351 | |||
1352 | /****************************************************************************************/ |
||
1353 | int GetStabType( char *p, unsigned short *pType, char **pEnd ) { |
||
1354 | |||
1355 | STABCOFFMAP *pMap; |
||
1356 | int extra, ok; |
||
1357 | unsigned short derivedbits[6]; |
||
1358 | unsigned short LStabType, RStabType; |
||
1359 | char *pHigh, *pLow; |
||
1360 | |||
1361 | |||
1362 | LStabType = atoi( p ); |
||
1363 | while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits |
||
1364 | |||
1365 | *pType = LStabType; |
||
1366 | |||
1367 | if ( GetCoffType( LStabType ) != 0 ) { |
||
1368 | *pEnd = p; |
||
1369 | return(True); |
||
1370 | } |
||
1371 | if ( *p != '=' ) { |
||
1372 | fprintf(stderr, "\nSyntax error in type assignment -> %s", p ); |
||
1373 | return(False); |
||
1374 | } |
||
1375 | p++; |
||
1376 | |||
1377 | /* Allocate space for new internal type */ |
||
1378 | if ( !(pMap = (STABCOFFMAP *)AllocateListObject(&ci->ListOfTypes, sizeof(STABCOFFMAP)) ) ) { |
||
1379 | fprintf(stderr, "\nOut of memory allocating type info!"); |
||
1380 | return(False); |
||
1381 | } |
||
1382 | pMap->StabType = LStabType; |
||
1383 | |||
1384 | /* process items to right of equals */ |
||
1385 | for ( extra = 0; extra < 6; extra++ ) { |
||
1386 | |||
1387 | if ( isdigit( *p ) ) { |
||
1388 | /* Finally found base type, try to terminate loop */ |
||
1389 | GetStabType( p, &RStabType, &p ); |
||
1390 | // RStabType = atoi( p ); |
||
1391 | while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits |
||
1392 | if ( SetupDefinedType( RStabType, pMap, &derivedbits[0], extra ) != True ) |
||
1393 | return( False ); |
||
1394 | break; |
||
1395 | } else if ( *p == 'a' ) { |
||
1396 | derivedbits[extra] = DT_ARY; |
||
1397 | p++; |
||
1398 | /* Calculate size */ |
||
1399 | /* Since type assignment will be made we need to set extra bits here */ |
||
1400 | extra++; |
||
1401 | /* =ar1;MinIndex;MaxIndex;BaseType */ |
||
1402 | if ( GetArrayType( p, &p, pMap, &derivedbits[0], extra ) != True ) |
||
1403 | return(False); |
||
1404 | break; |
||
1405 | |||
1406 | } else if ( *p == 'f' ) { |
||
1407 | derivedbits[extra] = DT_FCN; |
||
1408 | p++; |
||
1409 | } else if ( *p == '*' ) { |
||
1410 | derivedbits[extra] = DT_PTR; |
||
1411 | p++; |
||
1412 | } else if ( *p == 'r' ) { |
||
1413 | // if( LStabType < 15 ) |
||
1414 | // ok = GetInternalType( pString, pMap ); /* internal types not yet installed */ |
||
1415 | // else |
||
1416 | while ( *p && (*p != ';' ) ) p++; |
||
1417 | pLow = p++; |
||
1418 | while ( *p && (*p != ';' ) ) p++; |
||
1419 | pHigh = p++; |
||
1420 | ok = GetSubRangeType( LStabType, pMap, pLow, pHigh ); |
||
1421 | if ( ok != True ) |
||
1422 | return(False); |
||
1423 | while ( *p && (*p != ';' ) ) p++; /* find end of range */ |
||
1424 | p++; |
||
1425 | break; |
||
1426 | } else { |
||
1427 | fprintf(stderr, "\nUnrecognized Type modifier %c!", *p ); |
||
1428 | return(False); |
||
1429 | } |
||
1430 | } |
||
1431 | *pEnd = p; /* Update return pointer */ |
||
1432 | |||
1433 | return(True); |
||
1434 | } |
||
1435 | |||
1436 | |||
1437 | /****************************************************************************************/ |
||
1438 | int stab_add_tag_type( char *pName, char *pString ){ |
||
1439 | |||
1440 | int SymbolIndex, StabType, TotalSize, n, EnumValue; |
||
1441 | unsigned short TagType, ItemType, BitOffset, BitSize; |
||
1442 | char *p; |
||
1443 | struct syment* pEntry; |
||
1444 | union auxent *pAux; |
||
1445 | STABCOFFMAP *pMap; |
||
1446 | |||
1447 | /* We arrived here due to :T defining either a structure, union or enumeration */ |
||
1448 | /* store the basic type as for internals and emit coff structures for debugging */ |
||
1449 | /* .stabs "stag:T17=s2i:1,0,8;c:2,8,8;;",128,0,0,0 */ |
||
1450 | /* .stabs "2:T18=u2a:2,0,8;b:1,0,8;c:6,0,16;;",128,0,0,0 */ |
||
1451 | /* .stabs "1:T19=eenum1:1,enum2:2,enum3:3,;",128,0,0,0 */ |
||
1452 | /* we don't care about the name */ |
||
1453 | |||
1454 | |||
1455 | /* check for bogus errors */ |
||
1456 | if ( !pName || !pString ) { |
||
1457 | fprintf(stderr,"\nInvalid .stabs type format - no information!"); |
||
1458 | return(False); |
||
1459 | } |
||
1460 | |||
1461 | p = pString; |
||
1462 | /* Stab Type - convert to Coff type at end (after inline assignments */ |
||
1463 | if ( (StabType = (unsigned short)atoi(p)) == 0 ) { |
||
1464 | fprintf(stderr,"\nInvalid .stabs type format - no information! - > %s", p ); |
||
1465 | return(False); |
||
1466 | } |
||
1467 | while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits |
||
1468 | if ( *p != '=' ) { |
||
1469 | fprintf(stderr,"\nInvalid .stabs type format - no equals - > %s", p ); |
||
1470 | return(False); |
||
1471 | } |
||
1472 | SymbolIndex = ci->ListOfSymbols.TotalItems; |
||
1473 | if ( ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ) ) == 0 ) { |
||
1474 | fprintf(stderr, "\nOut of memory allocating symbol tag entries"); |
||
1475 | return(False); |
||
1476 | } |
||
1477 | /* Prepare Tag Header */ |
||
1478 | if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { |
||
1479 | fprintf(stderr,"\nOut of memory adding local %s to string table", pString ); |
||
1480 | return(False); |
||
1481 | } |
||
1482 | if ( !(pMap = (STABCOFFMAP *)AllocateListObject(&ci->ListOfTypes, sizeof(STABCOFFMAP)) ) ) { |
||
1483 | fprintf(stderr, "\nOut of memory allocating type info!"); |
||
1484 | return(False); |
||
1485 | } |
||
1486 | pMap->StabType = StabType; |
||
1487 | pEntry->n_value = 0; |
||
1488 | pEntry->n_scnum = N_DEBUG; |
||
1489 | pEntry->n_numaux = 1; |
||
1490 | if ( *++p == 's' ) { |
||
1491 | TagType = pEntry->n_type = pMap->CoffType = T_STRUCT; |
||
1492 | pEntry->n_sclass = C_STRTAG; |
||
1493 | TotalSize = (unsigned short)atoi(++p); |
||
1494 | } else if ( *p == 'u' ) { |
||
1495 | TagType = pEntry->n_type = pMap->CoffType = T_UNION; |
||
1496 | pEntry->n_sclass = C_UNTAG; |
||
1497 | TotalSize = (unsigned short)atoi(++p); |
||
1498 | } else if ( *p == 'e' ) { |
||
1499 | TagType = pEntry->n_type = pMap->CoffType = T_ENUM; |
||
1500 | pEntry->n_sclass = C_ENTAG; |
||
1501 | TotalSize = FundamentalTypes[T_INT].Size; /* use size of int for enums */ |
||
1502 | } else { |
||
1503 | fprintf(stderr,"\nUnknown tag type -> %s", p ); |
||
1504 | return(False); |
||
1505 | } |
||
1506 | while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits |
||
1507 | pEntry++; /* point to aux entry */ |
||
1508 | pAux = (union auxent *)pEntry; |
||
1509 | pAux->x_sym.x_tagndx = SymbolIndex; |
||
1510 | pAux->x_sym.x_misc.x_lnsz.x_size = TotalSize; |
||
1511 | |||
1512 | /* update our local knowledge of tag type */ |
||
1513 | pMap->CoffType = TagType; |
||
1514 | pMap->ByteSize = TotalSize; |
||
1515 | pMap->Line = ci->CurrentSourceLine; |
||
1516 | |||
1517 | /* Process the items until the end of the line */ |
||
1518 | while ( *pName ) { |
||
1519 | |||
1520 | if ( ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ) ) == 0 ) { |
||
1521 | fprintf(stderr, "\nOut of memory allocating symbol tag member entries"); |
||
1522 | return(False); |
||
1523 | } |
||
1524 | |||
1525 | if ( TagType == T_STRUCT ) { |
||
1526 | if ( GetStructUnionTagItem( p, &p, &pName, &ItemType, &BitOffset, &BitSize) != True ) { |
||
1527 | return(False); |
||
1528 | } |
||
1529 | pEntry->n_value = BitOffset/8; |
||
1530 | pEntry->n_type = ItemType; |
||
1531 | pEntry->n_sclass = C_MOS; |
||
1532 | } else if ( TagType == T_UNION ) { |
||
1533 | if ( GetStructUnionTagItem( p, &p, &pName, &ItemType, &BitOffset, &BitSize) != True ) { |
||
1534 | return(False); |
||
1535 | } |
||
1536 | pEntry->n_value = BitOffset/8; |
||
1537 | pEntry->n_type = ItemType; |
||
1538 | pEntry->n_sclass = C_MOU; |
||
1539 | } else { /* T_ENUM */ |
||
1540 | if ( GetEnumTagItem( p, &p, &pName, &EnumValue ) != True ) { |
||
1541 | return(False); |
||
1542 | } |
||
1543 | pEntry->n_value = EnumValue; |
||
1544 | pEntry->n_type = TotalSize; |
||
1545 | pEntry->n_sclass = C_MOE; |
||
1546 | } |
||
1547 | |||
1548 | /* Prepare Common Tag Header items */ |
||
1549 | if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { |
||
1550 | fprintf(stderr,"\nOut of memory adding local %s to string table", pString ); |
||
1551 | return(False); |
||
1552 | } |
||
1553 | pEntry->n_scnum = N_ABS; |
||
1554 | pEntry->n_numaux = 1; |
||
1555 | pEntry++; /* point to aux entry */ |
||
1556 | pAux = (union auxent *)pEntry; |
||
1557 | pAux->x_sym.x_tagndx = SymbolIndex; |
||
1558 | pAux->x_sym.x_misc.x_lnsz.x_size = TotalSize; |
||
1559 | pName = p; |
||
1560 | } |
||
1561 | |||
1562 | /* End of Structures/Unions/Enumberations */ |
||
1563 | if ( ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ) ) == 0 ) { |
||
1564 | fprintf(stderr, "\nOut of memory allocating special headers for structure!"); |
||
1565 | return(False); |
||
1566 | } |
||
1567 | strcpy( pEntry->n_name, ".eos" ); |
||
1568 | pEntry->n_value = TotalSize; |
||
1569 | pEntry->n_scnum = N_ABS; |
||
1570 | pEntry->n_type = 0; |
||
1571 | pEntry->n_sclass = C_EOS; |
||
1572 | pEntry->n_numaux = 1; |
||
1573 | pEntry++; /* point to aux entry */ |
||
1574 | pAux = (union auxent *)pEntry; |
||
1575 | pAux->x_sym.x_tagndx = SymbolIndex; /* point to the .bf entry index */ |
||
1576 | pAux->x_sym.x_misc.x_lnsz.x_size = TotalSize; |
||
1577 | |||
1578 | return(True); |
||
1579 | } |
||
1580 | |||
1581 | /****************************************************************************************/ |
||
1582 | int SetupDefinedType( unsigned short Type, STABCOFFMAP *pMap, unsigned short *DerivedBits, int ExtraLevels ){ |
||
1583 | |||
1584 | int i, Dlimit, Dstart; |
||
1585 | unsigned short StabType; |
||
1586 | |||
1587 | StabType = pMap->StabType; /* save the new type we found earlier */ |
||
1588 | if ( CopyStabCoffMap( Type, pMap ) != True ) { |
||
1589 | fprintf(stderr, "\nCould not find defined type %d", Type ); |
||
1590 | return(False); |
||
1591 | } |
||
1592 | pMap->StabType = StabType; /* save the new type we found earlier */ |
||
1593 | |||
1594 | /* Determine existing derived types for base class */ |
||
1595 | for ( i = 0; i < 6; i++ ) { |
||
1596 | if ( (pMap->CoffType & ( 3 << (4 + i + i))) == 0 ) |
||
1597 | break; |
||
1598 | } |
||
1599 | Dstart = i; |
||
1600 | Dlimit = i + ExtraLevels; |
||
1601 | if ( (Dlimit) >= 6 ) { |
||
1602 | fprintf(stderr, "\nStab Type %d has too many derived (%d) types!", pMap->StabType, Dlimit ); |
||
1603 | return(False); |
||
1604 | } |
||
1605 | /* Add the new derived levels */ |
||
1606 | for ( ; i < Dlimit; i++ ) { |
||
1607 | pMap->CoffType |= ( ( DerivedBits[i - Dstart] & 3) << (4 + i + i) ); /* add in the derived bits */ |
||
1608 | } |
||
1609 | return(True); |
||
1610 | } |
||
1611 | |||
1612 | /****************************************************************************************/ |
||
1613 | int GetArrayDefinitions( STABCOFFMAP *pMap , char *pMinIndex, char *pMaxIndex, char *pType, unsigned short *DerivedBits, int ExtraLevels ){ |
||
1614 | |||
1615 | int MinIndex, MaxIndex, Result, Size, i; |
||
1616 | unsigned short Type; |
||
1617 | |||
1618 | Result = True; |
||
1619 | if ( (*pMinIndex != ';') || (*pMaxIndex != ';') || (*pType != ';') ) |
||
1620 | Result = False; |
||
1621 | /* bump the pointers to the digits */ |
||
1622 | pMinIndex++; |
||
1623 | if ( !isdigit(*pMinIndex) ) |
||
1624 | Result = False; |
||
1625 | pMaxIndex++; |
||
1626 | if ( !isdigit(*pMaxIndex) ) |
||
1627 | Result = False; |
||
1628 | pType++; |
||
1629 | if ( !isdigit(*pType) ) |
||
1630 | Result = False; |
||
1631 | /* Is syntax ok ? */ |
||
1632 | if ( Result != True ) { |
||
1633 | fprintf(stderr,"\nSyntax error on array parameters %s%s%s", pMinIndex, pMaxIndex, pType ); |
||
1634 | return(False); |
||
1635 | } |
||
1636 | MinIndex = atoi(pMinIndex); |
||
1637 | MaxIndex = atoi(pMaxIndex); |
||
1638 | Type = (unsigned short)atoi(pType); |
||
1639 | if ( SetupDefinedType( Type, pMap, DerivedBits, ExtraLevels ) != True ) |
||
1640 | return( False ); |
||
1641 | /* Now update the size based on the indicies */ |
||
1642 | Size = (MaxIndex - MinIndex) + 1; |
||
1643 | pMap->ByteSize *= Size; |
||
1644 | pMap->Line = ci->CurrentSourceLine; |
||
1645 | /* add the dimension information */ |
||
1646 | for ( i = 5; i >= 0; i-- ) { |
||
1647 | if ( pMap->Dimensions[i] != 0 ) { |
||
1648 | i++; |
||
1649 | pMap->Dimensions[i] = Size; |
||
1650 | break; |
||
1651 | } |
||
1652 | } |
||
1653 | return(True); |
||
1654 | } |
||
1655 | |||
1656 | /****************************************************************************************/ |
||
1657 | |||
1658 | int GetInternalType( char *pName, STABCOFFMAP *pMap ){ |
||
1659 | |||
1660 | int n, found, i; |
||
1661 | |||
1662 | if ( !pName ) { |
||
1663 | return(False); |
||
1664 | } |
||
1665 | |||
1666 | found = False; |
||
1667 | n = strlen(pName); |
||
1668 | /* Find out if it is a local type */ |
||
1669 | for (i = 0; FundamentalTypes[i].pString != 0; i++) { |
||
1670 | if ( !strncmp(pName, FundamentalTypes[i].pString, n) ) { |
||
1671 | /* found an internal type */ |
||
1672 | pMap->CoffType = FundamentalTypes[i].Type; |
||
1673 | pMap->ByteSize = FundamentalTypes[i].Size; |
||
1674 | found = True; |
||
1675 | } |
||
1676 | } |
||
1677 | return(found); |
||
1678 | } |
||
1679 | |||
1680 | /****************************************************************************************/ |
||
1681 | int GetSubRangeType( unsigned short Type, STABCOFFMAP *pMap , char *pLow, char *pHigh ){ |
||
1682 | |||
1683 | int Result, i; |
||
1684 | long High, Low; |
||
1685 | unsigned long Test; |
||
1686 | |||
1687 | Result = True; |
||
1688 | if ( (*pLow != ';') || (*pHigh != ';') || (Type <= 0) ) |
||
1689 | Result = False; |
||
1690 | |||
1691 | /* Is syntax ok ? */ |
||
1692 | if ( Result != True ) { |
||
1693 | fprintf(stderr,"\nSyntax error on sub range parameters!" ); |
||
1694 | return(False); |
||
1695 | } |
||
1696 | Low = atol(++pLow); |
||
1697 | High = atol(++pHigh); |
||
1698 | |||
1699 | /* Special handling of type void */ |
||
1700 | if ( (Low == 0) && (High == 0) ) { |
||
1701 | /* Declare type void */ |
||
1702 | pMap->ByteSize =0; |
||
1703 | pMap->CoffType = T_VOID; |
||
1704 | pMap->Line = ci->CurrentSourceLine; |
||
1705 | return(True); |
||
1706 | } |
||
1707 | |||
1708 | if ( (pMap->CoffType = GetCoffType( Type )) != 0 ) { |
||
1709 | pMap->ByteSize = GetCoffTypeSize( Type ); |
||
1710 | } else { |
||
1711 | /* Try to base everything off integer */ |
||
1712 | pMap->ByteSize = FundamentalTypes[T_INT].Size; |
||
1713 | } |
||
1714 | |||
1715 | /* Now calculate the byte size */ |
||
1716 | if ( High == 0 ) { |
||
1717 | pMap->ByteSize = (unsigned short)Low; /* floating point */ |
||
1718 | } else { |
||
1719 | if ( Low == 0 ) { |
||
1720 | /* Unsigned */ |
||
1721 | Test = (unsigned long)High; |
||
1722 | } else if ( Low < 0 ) { |
||
1723 | /* signed */ |
||
1724 | Test = (unsigned long)High << 1; |
||
1725 | } else { |
||
1726 | if ( Low <= High ) |
||
1727 | Test = (unsigned long)High; |
||
1728 | else |
||
1729 | Test = (unsigned long)Low; |
||
1730 | } |
||
1731 | if ( pMap->ByteSize == 0 ) { |
||
1732 | fprintf(stderr,"\nType Range Error 1, need previous type %d size!", pMap->CoffType ); |
||
1733 | return(False); |
||
1734 | } |
||
1735 | for ( i = 0; i < sizeof(unsigned long); i++ ) { |
||
1736 | if ( !(Test & (0xff << (i * 8))) ) |
||
1737 | break; |
||
1738 | } |
||
1739 | pMap->ByteSize = i; |
||
1740 | } |
||
1741 | /* Now determine the best fit based on byte size, compare against IAR Compiler */ |
||
1742 | if ( pMap->ByteSize == 1 ) { |
||
1743 | if ( Low < 0 ) |
||
1744 | pMap->CoffType = T_CHAR; |
||
1745 | else |
||
1746 | pMap->CoffType = T_UCHAR; |
||
1747 | } else if ( pMap->ByteSize == 2 ) { |
||
1748 | if ( Low < 0 ) |
||
1749 | pMap->CoffType = T_INT; |
||
1750 | else |
||
1751 | pMap->CoffType = T_UINT; |
||
1752 | } else if ( pMap->ByteSize == 4 ) { |
||
1753 | if ( Low == 0 ) |
||
1754 | pMap->CoffType = T_FLOAT; |
||
1755 | if ( Low < 0 ) |
||
1756 | pMap->CoffType = T_LONG; |
||
1757 | else |
||
1758 | pMap->CoffType = T_ULONG; |
||
1759 | } else { |
||
1760 | fprintf(stderr,"\nGetSubRangeType failure - byte size %d", pMap->ByteSize ); |
||
1761 | return(False); |
||
1762 | } |
||
1763 | return(True); |
||
1764 | } |
||
1765 | |||
1766 | /****************************************************************************************/ |
||
1767 | int CopyStabCoffMap( unsigned short StabType, STABCOFFMAP *pMap ){ |
||
1768 | |||
1769 | STABCOFFMAP *p; |
||
1770 | |||
1771 | for ( p = FindFirstListObject( &ci->ListOfTypes ); p != 0; p = FindNextListObject( &ci->ListOfTypes) ) { |
||
1772 | if ( p->StabType == StabType ) { |
||
1773 | memcpy( pMap, p, sizeof(STABCOFFMAP) ); |
||
1774 | return(True); |
||
1775 | } |
||
1776 | } |
||
1777 | return( False ); /* Nothing found */ |
||
1778 | } |
||
1779 | |||
1780 | /****************************************************************************************/ |
||
1781 | unsigned short GetCoffType( unsigned short StabType ){ |
||
1782 | |||
1783 | STABCOFFMAP *p; |
||
1784 | |||
1785 | for ( p = FindFirstListObject( &ci->ListOfTypes ); p != 0; p = FindNextListObject( &ci->ListOfTypes) ) { |
||
1786 | if ( p->StabType == StabType ) |
||
1787 | return( p->CoffType ); |
||
1788 | } |
||
1789 | return( 0 ); /* Nothing found */ |
||
1790 | } |
||
1791 | |||
1792 | /****************************************************************************************/ |
||
1793 | unsigned short GetCoffTypeSize( unsigned short StabType ){ |
||
1794 | |||
1795 | STABCOFFMAP *p; |
||
1796 | |||
1797 | for ( p = FindFirstListObject( &ci->ListOfTypes ); p != 0; p = FindNextListObject( &ci->ListOfTypes) ) { |
||
1798 | if ( p->StabType == StabType ) |
||
1799 | return( p->ByteSize ); |
||
1800 | } |
||
1801 | return( 0 ); /* Nothing found */ |
||
1802 | } |
||
1803 | |||
1804 | |||
1805 | /****************************************************************************************/ |
||
1806 | int GetDigitLength( char *p ){ |
||
1807 | |||
1808 | int i; |
||
1809 | |||
1810 | if ( p == 0 ) |
||
1811 | return(0); |
||
1812 | |||
1813 | for ( i = 0; (*p != 0) && ( *p >= '0' ) && ( *p <= '9' ); i++ ); |
||
1814 | |||
1815 | return( i ); |
||
1816 | |||
1817 | } |
||
1818 | |||
1819 | /****************************************************************************************/ |
||
1820 | int GetStringDelimiters( char *pString, char **pTokens, int MaxTokens ){ |
||
1821 | |||
1822 | int i; |
||
1823 | char *p; |
||
1824 | |||
1825 | p = pString; |
||
1826 | |||
1827 | if ( !p ) |
||
1828 | return( 0 ); |
||
1829 | |||
1830 | for ( i = 0; i < MaxTokens; i++ ) { |
||
1831 | while ( True ) { |
||
1832 | if ( (*p == ':') || (*p == ';') || (*p == '=') || (*p == ',') || (*p == '"') || (*p == 0 ) ) { |
||
1833 | *(pTokens + i) = p; /* Remember this location */ |
||
1834 | p++; |
||
1835 | if ( *p == 0 ) |
||
1836 | return( i ); |
||
1837 | break; |
||
1838 | } |
||
1839 | p++; |
||
1840 | } |
||
1841 | } |
||
1842 | return( i ); |
||
1843 | } |
||
1844 | |||
1845 | /****************************************************************************************/ |
||
1846 | int IsTypeArray( unsigned short CoffType ){ |
||
1847 | |||
1848 | int Result; |
||
1849 | |||
1850 | Result = False; |
||
1851 | |||
1852 | if ( (CoffType & (DT_ARY << 4 )) == (DT_ARY << 4 ) ) |
||
1853 | Result = True; |
||
1854 | if ( (CoffType & (DT_ARY << 6 )) == (DT_ARY << 6 ) ) |
||
1855 | Result = True; |
||
1856 | if ( (CoffType & (DT_ARY << 8 )) == (DT_ARY << 8 ) ) |
||
1857 | Result = True; |
||
1858 | if ( (CoffType & (DT_ARY << 10 )) == (DT_ARY << 10 ) ) |
||
1859 | Result = True; |
||
1860 | if ( (CoffType & (DT_ARY << 12 )) == (DT_ARY << 12 ) ) |
||
1861 | Result = True; |
||
1862 | if ( (CoffType & (DT_ARY << 14 )) == (DT_ARY << 14 ) ) |
||
1863 | Result = True; |
||
1864 | |||
1865 | return(Result); |
||
1866 | } |
||
1867 | |||
1868 | /****************************************************************************************/ |
||
1869 | void AddArrayAuxInfo( union auxent *pAux, unsigned short SymbolIndex, STABCOFFMAP *pMap ){ |
||
1870 | |||
1871 | int i; |
||
1872 | |||
1873 | pAux->x_sym.x_tagndx = SymbolIndex; /* point to the .bf entry index */ |
||
1874 | pAux->x_sym.x_misc.x_lnsz.x_lnno = pMap->Line; |
||
1875 | pAux->x_sym.x_misc.x_lnsz.x_size = pMap->ByteSize; |
||
1876 | for ( i = 0; i < 4; i++ ) |
||
1877 | pAux->x_sym.x_fcnary.x_ary.x_dimen[i] = pMap->Dimensions[i]; |
||
1878 | } |
||
1879 | |||
1880 | /****************************************************************************************/ |
||
1881 | int AddNameToEntry( char *pName, struct syment *pEntry ) { |
||
1882 | |||
1883 | int n; |
||
1884 | char *p; |
||
1885 | |||
1886 | n = strlen( pName ); /* see if it's 8 bytes or less */ |
||
1887 | if ( n <= 8 ) { |
||
1888 | strncpy( pEntry->n_name, pName, 8 ); |
||
1889 | } else { |
||
1890 | /* point to current offset in string table */ |
||
1891 | pEntry->n_offset = ci->ListOfStrings.TotalBytes; |
||
1892 | /* Allocate string table entry */ |
||
1893 | if ( (p = (char *)AllocateListObject( &ci->ListOfStrings, n + 1 )) == 0 ) { |
||
1894 | return(0); |
||
1895 | } |
||
1896 | strcpy( p, pName ); |
||
1897 | } |
||
1898 | return(n); /* return size of string */ |
||
1899 | } |
||
1900 | |||
1901 | /****************************************************************************************/ |
||
1902 | |||
1903 | char *SkipPastDigits( char *p ){ |
||
1904 | |||
1905 | if ( !p ) |
||
1906 | return(p); |
||
1907 | /* if ( *p == 0 ); */ /* JEG 5-01-03 */ |
||
1908 | if ( *p == 0 ) |
||
1909 | return(p); /* This line s/b indented JEG */ |
||
1910 | for ( p--; (*p >= '0') && (*p <= '9') && (*p != 0); p-- ); |
||
1911 | return(p); |
||
1912 | } |
||
1913 | |||
1914 | /****************************************************************************************/ |
||
1915 | |||
1916 | /****************************************************************************************/ |
||
1917 | /****************************************************************************************/ |
||
1918 | /* List management routines */ |
||
1919 | /****************************************************************************************/ |
||
1920 | /****************************************************************************************/ |
||
1921 | |||
1922 | /****************************************************************************************/ |
||
1923 | |||
1924 | /****************************************************************************************/ |
||
1925 | void InitializeList( LISTNODEHEAD *pHead ){ |
||
1926 | |||
1927 | pHead->Node.Next = &pHead->Node; |
||
1928 | pHead->Node.Last = &pHead->Node; |
||
1929 | pHead->TotalBytes = 0; |
||
1930 | pHead->TotalItems = 0; |
||
1931 | pHead->current = &pHead->Node; |
||
1932 | return; |
||
1933 | } |
||
1934 | |||
1935 | /****************************************************************************************/ |
||
1936 | |||
1937 | void *AllocateTwoListObjects( LISTNODEHEAD *pHead, int size ){ |
||
1938 | |||
1939 | void *p; |
||
1940 | |||
1941 | if ( (p = AllocateListObject( pHead, size ) ) ) |
||
1942 | pHead->TotalItems++; /* already incremented once in addtolist */ |
||
1943 | return( p ); |
||
1944 | } |
||
1945 | |||
1946 | /****************************************************************************************/ |
||
1947 | void *AllocateListObject( LISTNODEHEAD *pHead, int size ){ |
||
1948 | |||
1949 | void *pObject; |
||
1950 | |||
1951 | LISTNODE *pNode; |
||
1952 | |||
1953 | if ( (pObject = calloc( 1, size )) != 0 ) { |
||
1954 | if ( !(pNode = AddListObject( pHead, pObject, size )) ) { |
||
1955 | free( pObject ); |
||
1956 | pObject = 0; |
||
1957 | } |
||
1958 | } |
||
1959 | return( pObject ); |
||
1960 | } |
||
1961 | |||
1962 | /****************************************************************************************/ |
||
1963 | LISTNODE *AddListObject(LISTNODEHEAD *pHead, void *pObject, int size ){ |
||
1964 | |||
1965 | LISTNODE *pNode; |
||
1966 | |||
1967 | if ( (pNode = calloc( 1, sizeof(LISTNODE) )) != 0 ) { |
||
1968 | pNode->pObject = pObject; |
||
1969 | pNode->Size = size; |
||
1970 | pNode->FileNumber = ci->CurrentFileNumber; |
||
1971 | AddNodeToList( pHead, pNode ); |
||
1972 | } |
||
1973 | return( pNode ); |
||
1974 | } |
||
1975 | |||
1976 | /****************************************************************************************/ |
||
1977 | LISTNODE *AllocateListNode( void *pObject, int size ){ |
||
1978 | |||
1979 | LISTNODE *pNew; |
||
1980 | |||
1981 | if ( (pNew = calloc( 1, sizeof( LISTNODE ) ) ) != 0 ) { |
||
1982 | /* Then we initialize the node */ |
||
1983 | pNew->pObject = pObject; |
||
1984 | pNew->Size = size; |
||
1985 | pNew->FileNumber = ci->CurrentFileNumber; |
||
1986 | } |
||
1987 | return(pNew); |
||
1988 | } |
||
1989 | |||
1990 | /****************************************************************************************/ |
||
1991 | void AddNodeToList( LISTNODEHEAD *pHead, LISTNODE *pNode ){ |
||
1992 | |||
1993 | LISTNODE *p; |
||
1994 | |||
1995 | p = &pHead->Node; |
||
1996 | |||
1997 | pNode->Next = p->Last->Next; |
||
1998 | p->Last->Next = pNode; |
||
1999 | pNode->Last = p->Last; |
||
2000 | p->Last = pNode; |
||
2001 | |||
2002 | /* and update current size of data contained in the list */ |
||
2003 | pHead->TotalBytes += pNode->Size; |
||
2004 | pHead->TotalItems++; |
||
2005 | } |
||
2006 | |||
2007 | /****************************************************************************************/ |
||
2008 | void RemoveNodeFromList( LISTNODEHEAD *pHead, LISTNODE *pNode ){ |
||
2009 | |||
2010 | pNode->Last->Next = pNode->Next; |
||
2011 | pNode->Next->Last = pNode->Last; |
||
2012 | |||
2013 | pHead->TotalBytes -= pNode->Size; |
||
2014 | pHead->TotalItems--; |
||
2015 | } |
||
2016 | |||
2017 | |||
2018 | /****************************************************************************************/ |
||
2019 | void *FindFirstListObject( LISTNODEHEAD *pHead ){ |
||
2020 | |||
2021 | if ( pHead->Node.Next == &pHead->Node ) |
||
2022 | return(0); /* Nothing in list */ |
||
2023 | |||
2024 | pHead->current = pHead->Node.Next; |
||
2025 | return( pHead->current->pObject ); |
||
2026 | } |
||
2027 | /****************************************************************************************/ |
||
2028 | void *FindNextListObject( LISTNODEHEAD *pHead ){ |
||
2029 | |||
2030 | if ( pHead->current->Next == &pHead->Node ) |
||
2031 | return( 0 ); |
||
2032 | |||
2033 | pHead->current = pHead->current->Next; |
||
2034 | |||
2035 | return( pHead->current->pObject ); |
||
2036 | } |
||
2037 | /****************************************************************************************/ |
||
2038 | |||
2039 | LISTNODE *GetCurrentNode( LISTNODEHEAD *pHead ){ |
||
2040 | |||
2041 | return( pHead->current ); |
||
2042 | } |
||
2043 | |||
2044 | /****************************************************************************************/ |
||
2045 | void *GetCurrentListObject( LISTNODEHEAD *pHead ){ |
||
2046 | |||
2047 | return( pHead->current->pObject ); |
||
2048 | } |
||
2049 | |||
2050 | |||
2051 | /****************************************************************************************/ |
||
2052 | void *FindLastListObject( LISTNODEHEAD *pHead ){ |
||
2053 | |||
2054 | if ( pHead->Node.Last == &pHead->Node ) |
||
2055 | return(0); /* Nothing in list */ |
||
2056 | |||
2057 | pHead->current = pHead->Node.Last; |
||
2058 | return( pHead->current->pObject ); |
||
2059 | } |
||
2060 | /****************************************************************************************/ |
||
2061 | void *FindNextLastListObject( LISTNODEHEAD *pHead ){ |
||
2062 | |||
2063 | if ( pHead->current->Last == &pHead->Node ) |
||
2064 | return( 0 ); |
||
2065 | |||
2066 | pHead->current = pHead->current->Last; |
||
2067 | |||
2068 | return( pHead->current->pObject ); |
||
2069 | } |
||
2070 | |||
2071 | /****************************************************************************************/ |
||
2072 | |||
2073 | void FreeList( LISTNODEHEAD *pHead ){ |
||
2074 | |||
2075 | LISTNODE *pNode; |
||
2076 | |||
2077 | for ( pNode = pHead->Node.Last; pNode->Next != &pHead->Node; pNode = pHead->Node.Last ) { |
||
2078 | |||
2079 | RemoveNodeFromList( pHead, pNode ); |
||
2080 | free( pNode->pObject ); |
||
2081 | free( pNode ); |
||
2082 | } |
||
2083 | pHead->TotalBytes = 0; |
||
2084 | pHead->TotalItems = 0; |
||
2085 | pHead->current = &pHead->Node; |
||
2086 | } |
||
2087 | /****************************************************************************************/=>=>>><>><>><>><>><>><>><>><>><>><>><>><>>=>>>>><>>=>><>>=>><>>><>>=>=>>=>>=>=>=>=>><>><>><>><>>><>=>=>=>=> |
||
2088 |