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