Annotation of researchv10dc/cmd/gcc/symout.c, revision 1.1.1.1

1.1       root        1: /* Output GDB-format symbol table information from GNU compiler.
                      2:    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU CC General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU CC, but only under the conditions described in the
                     15: GNU CC General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU CC so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.  */
                     20: 
                     21: 
                     22: #include "config.h"
                     23: #include "tree.h"
                     24: #include "symseg.h"
                     25: #include "rtl.h"
                     26: #include "gdbfiles.h"
                     27: #include <stdio.h>
                     28: 
                     29: /* Get N_SO from stab.h if we can expect the file to exist.  */
                     30: #ifndef NO_DBX_FORMAT
                     31: #include <stab.h>
                     32: #endif
                     33: 
                     34: /* .stabs code for source file name.  */
                     35: #ifndef N_SO
                     36: #define        N_SO 0x64
                     37: #endif
                     38: 
                     39: /* Unix maximum on file name length.  Needed for getwd.  */
                     40: #define MAXNAMLEN 1024
                     41: 
                     42: /* Get the number to output for a reference to type TYPE.  */
                     43: #define TYPE_OUTPUT_ADDRESS(TYPE) \
                     44:   TYPE_SYMTAB_ADDRESS (TYPE_MAIN_VARIANT (TYPE))
                     45: 
                     46: /* Stream for writing symbol table file.  */
                     47: static FILE *symfile;
                     48: 
                     49: /* Name of symbol table file.  */
                     50: static char *symfile_name;
                     51: 
                     52: /* Stream for writing to assembler file.  */
                     53: static FILE *asmfile;
                     54: 
                     55: /* Address for allocating space in symbol table file.
                     56:    Changes in this variable are paired globally with writes to symfile,
                     57:    but often we allocate many structures, advancing next_address,
                     58:    before writing any of them.  */
                     59: static int next_address;
                     60: 
                     61: /* Chain recording all the types that have been output,
                     62:    giving the address-in-the-symseg of each one.  */
                     63: 
                     64: struct typevec_elt
                     65: {
                     66:   int address;
                     67:   struct typevec_elt *next;
                     68: };
                     69: 
                     70: static struct typevec_elt *typevec;
                     71: 
                     72: /* Number of types recorded so far in the chain.  */
                     73: 
                     74: static int total_types;
                     75: 
                     76: /* `blockvec' is a chain recording all the symbol-blocks that have been output,
                     77:    giving the address-in-the-symseg of each one.  */
                     78: 
                     79: struct blockvec_elt
                     80: {
                     81:   int address;
                     82:   struct blockvec_elt *next;
                     83: };
                     84: 
                     85: static struct blockvec_elt *blockvec;
                     86: 
                     87: /* Number of blocks recorded so far in the chain.  */
                     88: 
                     89: static int total_blocks;
                     90: 
                     91: static void symout_range_bounds ();
                     92: static void symout_array_domain ();
                     93: static void symout_record_fields ();
                     94: static void symout_enum_values ();
                     95: static void symout_record_field_names ();
                     96: static void symout_enum_value_names ();
                     97: static int subrange_p ();
                     98: static void symout_strings_skip ();
                     99: static void symout_strings_print ();
                    100: 
                    101: /* At the beginning of compilation, start writing the symbol table.
                    102:    Initialize the type and block chain.
                    103:    Also open and initialize the symseg file.  */
                    104: 
                    105: void
                    106: symout_init (filename, asm_file, sourcename)
                    107:      char *filename;
                    108:      FILE *asm_file;
                    109:      char *sourcename;
                    110: {
                    111:   struct symbol_root buffer;
                    112: 
                    113: #ifdef VMS
                    114:   fatal ("Cannot write GDB debugging format on VMS");
                    115: #endif
                    116: 
                    117:   asmfile = asm_file;
                    118:   fprintf (asmfile, ".text 0\n.gdbbeg 0\n.gdbbeg 1\n");
                    119:   fprintf (asmfile,
                    120:           "Ltext:\t.stabs \"%s\",%d,0,0,Ltext\n",
                    121:           sourcename, N_SO);
                    122:   fprintf (asmfile, ".data 0\nLdata:\n");
                    123:   ASM_OUTPUT_LOCAL (asmfile, "Lbss", 0);
                    124:   fprintf (asmfile, ".gdbsym Ldata,%d\n",
                    125:           (char *) &buffer.databeg - (char *) &buffer);
                    126:   fprintf (asmfile, ".gdbsym Lbss,%d\n",
                    127:           (char *) &buffer.bssbeg - (char *) &buffer);
                    128: 
                    129:   symfile = fopen (filename, "w");
                    130:   if (symfile == 0)
                    131:     pfatal_with_name (symfile);
                    132:   symfile_name = (char *) malloc (strlen (filename) + 1);
                    133:   strcpy (symfile_name, filename);
                    134: 
                    135:   typevec = 0;
                    136:   blockvec = 0;
                    137:   total_types = 0;
                    138:   total_blocks = 0;
                    139: 
                    140:   bzero (&buffer, sizeof buffer);
                    141:   fwrite (&buffer, sizeof buffer, 1, symfile);
                    142: 
                    143:   next_address = sizeof buffer;
                    144: }
                    145: 
                    146: /* Functions for outputting strings into the symbol table.
                    147:    The string to be output is effectively the concatenation of
                    148:    the two strings P1 and P2.  Their lengths are given as S1 and S2.
                    149:    If P1 or P2 is zero, that string is not used.
                    150: 
                    151:    A null character is output to terminate the string,
                    152:    and it is followed by more nulls as padding to a word boundary.  */
                    153: 
                    154: static void
                    155: symout_strings (p1, s1, p2, s2)
                    156:      char *p1;
                    157:      int s1;
                    158:      char *p2;
                    159:      int s2;
                    160: {
                    161:   symout_strings_print (p1, s1, p2, s2);
                    162:   symout_strings_skip (p1, s1, p2, s2);
                    163: }
                    164: 
                    165: /* Like symout_strings but only output; do not update next_address.  */
                    166: 
                    167: static void
                    168: symout_strings_print (p1, s1, p2, s2)
                    169:      char *p1;
                    170:      int s1;
                    171:      char *p2;
                    172:      int s2;
                    173: {
                    174:   register int total;
                    175: 
                    176:   if (p1 && s1 == 0)
                    177:     s1 = strlen (p1);
                    178:   if (p2 && s2 == 0)
                    179:     s2 = strlen (p2);
                    180: 
                    181:   if (p1)
                    182:     fwrite (p1, s1, 1, symfile);
                    183:   if (p2)
                    184:     fwrite (p2, s2, 1, symfile);
                    185:   putc (0, symfile);
                    186: 
                    187:   total = s1 + s2 + 1;
                    188:   while (total % sizeof (int))
                    189:     {
                    190:       putc (0, symfile);
                    191:       total++;
                    192:     }
                    193: }
                    194: 
                    195: /* Like symout_strings but just update next_address; do not output.  */
                    196: 
                    197: static void
                    198: symout_strings_skip (p1, s1, p2, s2)
                    199:      char *p1;
                    200:      int s1;
                    201:      char *p2;
                    202:      int s2;
                    203: {
                    204:   register int total;
                    205: 
                    206:   if (p1 && s1 == 0)
                    207:     s1 = strlen (p1);
                    208:   if (p2 && s2 == 0)
                    209:     s2 = strlen (p2);
                    210: 
                    211:   total = s1 + s2 + 1;
                    212:   while (total % sizeof (int))
                    213:     total++;
                    214: 
                    215:   next_address += total;
                    216: }
                    217: 
                    218: /* Call here to output a chain of types.
                    219:    After each function, this is done first for the chain of permanent types
                    220:    made during the function, and then for the chain of temporary types.
                    221:    This must be done before outputting the symbols and blocks of the function.
                    222: 
                    223:    At the end of compilation, this is done for all the permanent types
                    224:    made since the last function.
                    225: 
                    226:    Each permanent type is done once, at the beginning of the next function,
                    227:    or at the end of the compilation if no functions follow.
                    228:    Once a type has been processed here, its TYPE_SYMTAB_ADDRESS remains
                    229:    set up.  */
                    230: 
                    231: void
                    232: symout_types (types)
                    233:      tree types;
                    234: {
                    235:   struct typerec
                    236:   {
                    237:     int number;
                    238:     int address;
                    239:     int nfields;
                    240:     int fields_address;
                    241:     int name_address;
                    242:     char *name;
                    243:     char *name_prefix;
                    244:   };
                    245: 
                    246:   register int n_types, i;
                    247:   register struct typerec *records;
                    248:   register tree next;
                    249:   struct type buffer;
                    250: 
                    251:   for (next = types, n_types = 0;
                    252:        next;
                    253:        next = TREE_CHAIN (next), n_types++);
                    254: 
                    255:   records = (struct typerec *) alloca (n_types * sizeof (struct typerec));
                    256: 
                    257:   for (next = types, i = 0;
                    258:        next;
                    259:        next = TREE_CHAIN (next), i++)
                    260:     {
                    261:       register struct typevec_elt *velt
                    262:        = (struct typevec_elt *) xmalloc (sizeof (struct typevec_elt));
                    263:       velt->next = typevec;
                    264:       typevec = velt;
                    265: 
                    266:       total_types++;
                    267: 
                    268:       if (TYPE_NAME (next))
                    269:        {
                    270:          records[i].name_address = next_address;
                    271: 
                    272:          if (TREE_CODE (TYPE_NAME (next)) == IDENTIFIER_NODE)
                    273:            {
                    274:              records[i].name = IDENTIFIER_POINTER (TYPE_NAME (next));
                    275:              switch (TREE_CODE (next))
                    276:                {
                    277:                case RECORD_TYPE:
                    278:                  records[i].name_prefix = "struct ";
                    279:                  break;
                    280: 
                    281:                case UNION_TYPE:
                    282:                  records[i].name_prefix = "union ";
                    283:                  break;
                    284: 
                    285:                case ENUMERAL_TYPE:
                    286:                  records[i].name_prefix = "enum ";
                    287:                  break;
                    288:                }
                    289:            }
                    290:          else
                    291:            {
                    292:              records[i].name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (next)));
                    293:              records[i].name_prefix = 0;
                    294:            }
                    295:          symout_strings_skip (records[i].name_prefix, 0,
                    296:                               records[i].name, 0);
                    297: 
                    298:        }
                    299:       else
                    300:        {
                    301:          records[i].name = 0;
                    302:          records[i].name_address = 0;
                    303:          records[i].name_prefix = 0;
                    304:        }
                    305: 
                    306:       records[i].address = next_address;
                    307:       TYPE_SYMTAB_ADDRESS (next) = next_address;
                    308:       velt->address = next_address;
                    309:       next_address += sizeof (struct type);
                    310:       records[i].nfields = 0;
                    311:       records[i].fields_address = 0;
                    312:       switch (TREE_CODE (next))
                    313:        {
                    314:        case ARRAY_TYPE:
                    315:          records[i].nfields
                    316:            = (TYPE_DOMAIN(next)
                    317:               ? ! integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (next)))
                    318:               : 0 );
                    319:          break;
                    320: 
                    321:        case INTEGER_TYPE:
                    322:          if (subrange_p (next))
                    323:            buffer.nfields = 2;
                    324:          break;
                    325: 
                    326:        case RECORD_TYPE:
                    327:        case UNION_TYPE:
                    328:        case ENUMERAL_TYPE:
                    329:          records[i].nfields = list_length (TYPE_FIELDS (next));
                    330:        }
                    331:       if (records[i].nfields)
                    332:        records[i].fields_address = next_address;
                    333:       next_address += records[i].nfields * sizeof (struct field);
                    334:     }
                    335: 
                    336:   for (next = types, i = 0;
                    337:        next;
                    338:        next = TREE_CHAIN (next), i++)
                    339:     {
                    340:       if (records[i].name)
                    341:        symout_strings_print (records[i].name_prefix, 0,
                    342:                              records[i].name, 0);
                    343: 
                    344:       if (TYPE_SIZE (next) == 0)
                    345:        buffer.length = 0;
                    346:       else
                    347:        buffer.length
                    348:          = (TREE_INT_CST_LOW (TYPE_SIZE (next))
                    349:             * TYPE_SIZE_UNIT (next) / BITS_PER_UNIT);
                    350:       buffer.name = (char *) records[i].name_address;
                    351:       buffer.target_type = (struct type *) (TREE_TYPE (next) ? TYPE_OUTPUT_ADDRESS (TREE_TYPE (next)) : 0);
                    352: 
                    353:       buffer.pointer_type = 0;
                    354:       buffer.function_type = 0;
                    355:       buffer.flags
                    356:        = ((TREE_CODE (next) == INTEGER_TYPE || TREE_CODE (next) == ENUMERAL_TYPE)
                    357:           && TREE_UNSIGNED (next))
                    358:          ? TYPE_FLAG_UNSIGNED : 0;
                    359:       buffer.nfields = records[i].nfields;
                    360:       buffer.fields = (struct field *) records[i].fields_address;
                    361: 
                    362:       switch (TREE_CODE (next))
                    363:        {
                    364:        case INTEGER_TYPE:
                    365:          buffer.code = TYPE_CODE_INT;
                    366:          if (buffer.nfields)
                    367:            buffer.code = TYPE_CODE_RANGE;
                    368:          break;
                    369: 
                    370:        case REAL_TYPE:
                    371:          buffer.code = TYPE_CODE_FLT;
                    372:          break;
                    373: 
                    374:        case VOID_TYPE:
                    375:          buffer.code = TYPE_CODE_VOID;
                    376:          break;
                    377: 
                    378:        case POINTER_TYPE:
                    379:          buffer.code = TYPE_CODE_PTR;
                    380:          break;
                    381: 
                    382:        case ARRAY_TYPE:
                    383:          if (buffer.nfields == 0)
                    384:            buffer.code = TYPE_CODE_ARRAY;
                    385:          else
                    386:            buffer.code = TYPE_CODE_PASCAL_ARRAY;
                    387:          break;
                    388: 
                    389:        case RECORD_TYPE:
                    390:          buffer.code = TYPE_CODE_STRUCT;
                    391:          break;
                    392: 
                    393:        case UNION_TYPE:
                    394:          buffer.code = TYPE_CODE_UNION;
                    395:          break;
                    396: 
                    397:        case FUNCTION_TYPE:
                    398:          buffer.code = TYPE_CODE_FUNC;
                    399:          break;
                    400: 
                    401:        case ENUMERAL_TYPE:
                    402:          buffer.code = TYPE_CODE_ENUM;
                    403:          break;
                    404: 
                    405:        default:
                    406:          abort ();
                    407:        }
                    408: 
                    409:       fwrite (&buffer, sizeof buffer, 1, symfile);
                    410: 
                    411:       switch (TREE_CODE (next))
                    412:        {
                    413:        case ARRAY_TYPE:
                    414:          if (buffer.nfields)
                    415:            symout_array_domain (next);
                    416:          break;
                    417: 
                    418:        case RECORD_TYPE:
                    419:        case UNION_TYPE:
                    420:          symout_record_fields (next);
                    421:          break;
                    422: 
                    423:        case ENUMERAL_TYPE:
                    424:          symout_enum_values (next);
                    425:          break;
                    426: 
                    427:        case INTEGER_TYPE:
                    428:          if (buffer.nfields)
                    429:            symout_range_bounds (next);
                    430:        }
                    431:     }
                    432: 
                    433:   for (next = types, i = 0;
                    434:        next;
                    435:        next = TREE_CHAIN (next), i++)
                    436:     {
                    437:       switch (TREE_CODE (next))
                    438:        {
                    439:        case RECORD_TYPE:
                    440:        case UNION_TYPE:
                    441:          symout_record_field_names (next);
                    442:          break;
                    443: 
                    444:        case ENUMERAL_TYPE:
                    445:          symout_enum_value_names (next);
                    446:          break;
                    447:        }
                    448:     }
                    449: }
                    450: 
                    451: /* Return nonzero if TYPE's range of possible values
                    452:    is not the full range allowed by the number of bits it has.
                    453:    TYPE is assumed to be an INTEGER_TYPE or ENUMERAL_TYPE.  */
                    454: 
                    455: static int
                    456: subrange_p (type)
                    457:      tree type;
                    458: {
                    459:   int uns = TREE_UNSIGNED (type);
                    460: 
                    461:   if (TYPE_PRECISION (type) >= HOST_BITS_PER_INT)
                    462:     {
                    463:       if (uns)
                    464:        return integer_zerop (TYPE_MIN_VALUE (type))
                    465:          && TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == 0
                    466:            && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (type))
                    467:                == (1 << (TYPE_PRECISION (type) - HOST_BITS_PER_INT)) - 1);
                    468:       return TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
                    469:        && TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == 0
                    470:          && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type))
                    471:              == (-1) << (TYPE_PRECISION (type) - 1 - HOST_BITS_PER_INT))
                    472:            && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (type))
                    473:                == (1 << (TYPE_PRECISION (type) - 1 - HOST_BITS_PER_INT)) - 1);
                    474:     }
                    475: 
                    476:   if (uns)
                    477:     return integer_zerop (TYPE_MIN_VALUE (type))
                    478:       && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))
                    479:          == (1 << TYPE_PRECISION (type)) - 1);
                    480:   else
                    481:     return (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type))
                    482:            == (-1) << (TYPE_PRECISION (type) - 1))
                    483:       && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))
                    484:          == (1 << (TYPE_PRECISION (type) - 1)) - 1);
                    485: }
                    486: 
                    487: /* Functions to output the "fields" of various kinds of types.
                    488:    These assume that next_address has already been incremented to
                    489:    cover these fields, and the fields of all the other types being
                    490:    output in this batch; so next_address can be used to allocate
                    491:    space to store field names, etc.  */
                    492: 
                    493: static void
                    494: symout_array_domain (type)
                    495:      tree type;
                    496: {
                    497:   struct field buffer;
                    498: 
                    499:   buffer.bitpos = 0;
                    500:   buffer.bitsize = 0;
                    501:   buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TYPE_DOMAIN (type));
                    502:   buffer.name = 0;
                    503:   fwrite (&buffer, sizeof (struct field), 1, symfile);
                    504: }
                    505: 
                    506: static void
                    507: symout_range_bounds (type)
                    508:      tree type;
                    509: {
                    510:   struct field buffer;
                    511: 
                    512:   buffer.bitpos = TREE_INT_CST_LOW (TYPE_MIN_VALUE (type));
                    513:   buffer.bitsize = 0;
                    514:   buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
                    515:   buffer.name = 0;
                    516:   fwrite (&buffer, sizeof (struct field), 1, symfile);
                    517: 
                    518:   buffer.bitpos = TREE_INT_CST_LOW (TYPE_MAX_VALUE (type));
                    519:   buffer.bitsize = 0;
                    520:   buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
                    521:   buffer.name = 0;
                    522:   fwrite (&buffer, sizeof (struct field), 1, symfile);
                    523: }
                    524: 
                    525: static void
                    526: symout_record_fields (type)
                    527:      tree type;
                    528: {
                    529:   struct field buffer;
                    530:   register tree field;
                    531: 
                    532:   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
                    533:     {
                    534:       buffer.bitpos = DECL_OFFSET (field);
                    535:       buffer.bitsize
                    536:        = (TREE_PACKED (field)
                    537:           ? TREE_INT_CST_LOW (DECL_SIZE (field)) * DECL_SIZE_UNIT (field)
                    538:           : 0);
                    539:       buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_TYPE (field));
                    540:       if (DECL_NAME (field))
                    541:        {
                    542:          buffer.name = (char *) next_address;
                    543:          symout_strings_skip (0, IDENTIFIER_LENGTH (DECL_NAME (field)), 0, 0);
                    544:        }
                    545:       else
                    546:        buffer.name = 0;
                    547:       fwrite (&buffer, sizeof (struct field), 1, symfile);
                    548:     }
                    549: }
                    550: 
                    551: static void
                    552: symout_enum_values (type)
                    553:      tree type;
                    554: {
                    555:   struct field buffer;
                    556:   register tree link, value;
                    557: 
                    558:   for (link = TYPE_VALUES (type); link; link = TREE_CHAIN (link))
                    559:     {
                    560:       value = TREE_VALUE (link);
                    561:       buffer.bitpos = TREE_INT_CST_LOW (value);
                    562:       buffer.bitsize = 0;
                    563:       buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
                    564:       buffer.name = (char *) next_address;
                    565:       symout_strings_skip (0, IDENTIFIER_LENGTH (TREE_PURPOSE (link)), 0, 0);
                    566:       fwrite (&buffer, sizeof buffer, 1, symfile);
                    567:     }
                    568: }
                    569: 
                    570: /* Output field names or value names for the fields of a type.
                    571:    This is called, for the types that need it, after the fields
                    572:    have been output for all the types in the batch.
                    573:    We do not update next_address here, because it has already been 
                    574:    updated for all the names in all the fields in all the types.  */
                    575: 
                    576: static void
                    577: symout_record_field_names (type)
                    578:      tree type;
                    579: {
                    580:   register tree field;
                    581: 
                    582:   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
                    583:     if (DECL_NAME (field))
                    584:       symout_strings_print (IDENTIFIER_POINTER (DECL_NAME (field)),
                    585:                            IDENTIFIER_LENGTH (DECL_NAME (field)),
                    586:                            0, 0);
                    587: }
                    588: 
                    589: static void
                    590: symout_enum_value_names (type)
                    591:      tree type;
                    592: {
                    593:   register tree value;
                    594: 
                    595:   for (value = TYPE_VALUES (type); value; value = TREE_CHAIN (value))
                    596:     symout_strings_print (IDENTIFIER_POINTER (TREE_PURPOSE (value)),
                    597:                          IDENTIFIER_LENGTH (TREE_PURPOSE (value)),
                    598:                          0, 0);
                    599: }
                    600: 
                    601: /* Output the symbols of a block, given the list of decl nodes.
                    602:    Store the file addresses at which the symbols are output
                    603:    into ADDR_BUFFER, a vector which has just the right length.
                    604: 
                    605:    If FILTER is 1, do only the private symbols in DECLS.
                    606:    If FILTER is 2, do only the public ones (but no externals).
                    607:    If FILTER is 0, do all (except external functions).  */
                    608: 
                    609: static void
                    610: symout_block_symbols (decls, addr_buffer, filter)
                    611:      tree decls;
                    612:      int *addr_buffer;
                    613:      int filter;
                    614: {
                    615:   register tree decl;
                    616:   struct symbol buffer;
                    617:   register int i;
                    618: 
                    619:   for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
                    620:     {
                    621:       register name_address = next_address;
                    622: 
                    623:       if (filter == (TREE_PUBLIC (decl) ? 1 : 2))
                    624:        continue;
                    625: 
                    626:       /* Do not mention external functions.
                    627:         Let their own files mention them.
                    628:         In the top blocks, don't mention external anything.  */
                    629: 
                    630:       if (TREE_EXTERNAL (decl)
                    631:          && (filter || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE))
                    632:        continue;
                    633: 
                    634:       if (TREE_TYPE (decl) == error_mark_node)
                    635:        continue;
                    636: 
                    637:       symout_strings (IDENTIFIER_POINTER (DECL_NAME (decl)),
                    638:                      IDENTIFIER_LENGTH (DECL_NAME (decl)),
                    639:                      0, 0);
                    640:       addr_buffer[i] = next_address;
                    641:       buffer.name = (char *) name_address;
                    642:       buffer.namespace = VAR_NAMESPACE;
                    643:       buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_TYPE (decl));
                    644:       switch (TREE_CODE (decl))
                    645:        {
                    646:        case PARM_DECL:
                    647:          buffer.class = LOC_ARG;
                    648:          buffer.value.value = DECL_OFFSET (decl) / BITS_PER_UNIT;
                    649:          break;
                    650: 
                    651:        case VAR_DECL:
                    652:        case RESULT_DECL:
                    653:          if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))
                    654:            {
                    655:              if (! TREE_PUBLIC (decl) || DECL_INITIAL (decl))
                    656:                {
                    657:                  char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
                    658:                  fprintf (asmfile, "\t.gdbsym ");
                    659:                  ASM_OUTPUT_LABELREF (asmfile, str);
                    660:                  fprintf (asmfile, ",%d\n",
                    661:                           next_address + (char *)&buffer.value - (char *)&buffer);
                    662:                  buffer.class = LOC_STATIC;
                    663:                }
                    664:              else
                    665:                /* Uninitialized public symbols are output as .comm;
                    666:                   Tell GDB to get address from loader global symbol.
                    667:                   Also come here for symbols declared extern.  */
                    668:                buffer.class = LOC_EXTERNAL;
                    669:            }
                    670:          else
                    671:            {
                    672:              if (GET_CODE (DECL_RTL (decl)) == REG)
                    673:                {
                    674:                  buffer.class = LOC_REGISTER;
                    675:                  buffer.value.value = REGNO (DECL_RTL (decl));
                    676:                  /* Detect vars that were optimized entirely away.  */
                    677:                  if (buffer.value.value == -1)
                    678:                    buffer.class = LOC_CONST;
                    679:                }
                    680:              /* Locals in memory are expected to be addressed as
                    681:                 (PLUS (REG ...) (CONST_INT ...)).
                    682:                 Bomb out if that is not so.  */
                    683:              else if (GET_CODE (DECL_RTL (decl)) == MEM)
                    684:                {
                    685:                  register rtx addr = XEXP (DECL_RTL (decl), 0);
                    686:                  if (GET_CODE (addr) != PLUS && GET_CODE (addr) != MINUS)
                    687:                    abort ();
                    688:                  if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
                    689:                    abort ();
                    690:                  buffer.class = LOC_LOCAL;
                    691:                  buffer.value.value = INTVAL (XEXP (addr, 1));
                    692:                  if (GET_CODE (addr) == MINUS)
                    693:                    buffer.value.value = - buffer.value.value;
                    694:                }
                    695:              else
                    696:                abort ();
                    697:            }
                    698:          break;
                    699: 
                    700:        case TYPE_DECL:
                    701:          buffer.class = LOC_TYPEDEF;
                    702:          buffer.value.value = 0;
                    703:          break;
                    704: 
                    705:        case CONST_DECL:
                    706:          buffer.class = LOC_CONST;
                    707:          buffer.value.value = TREE_INT_CST_LOW (DECL_INITIAL (decl));
                    708:          break;
                    709: 
                    710:        case FUNCTION_DECL:
                    711:          if (DECL_INITIAL (decl))
                    712:            {
                    713:              buffer.class = LOC_BLOCK;
                    714:              buffer.value.value = DECL_BLOCK_SYMTAB_ADDRESS (decl);
                    715:            }
                    716:          else
                    717:            buffer.class = LOC_EXTERNAL;
                    718:        }
                    719: 
                    720:       fwrite (&buffer, sizeof buffer, 1, symfile);
                    721:       next_address += sizeof buffer;
                    722:       i++;
                    723:     }
                    724: }
                    725: 
                    726: /* Output the tags (struct, union and enum definitions) for a block,
                    727:    given a list of them (a chain of TREE_LIST nodes) in TAGS.
                    728:    Store their addresses in the file into ADDR_BUFFER.  */
                    729: 
                    730: static void
                    731: symout_block_tags (tags, addr_buffer)
                    732:      tree tags;
                    733:      int *addr_buffer;
                    734: {
                    735:   register tree tag;
                    736:   struct symbol buffer;
                    737:   register int i;
                    738: 
                    739:   for (tag = tags, i = 0; tag; tag = TREE_CHAIN (tag), i++)
                    740:     {
                    741:       buffer.name = (char *) next_address;
                    742: 
                    743:       symout_strings (IDENTIFIER_POINTER (TREE_PURPOSE (tag)),
                    744:                      IDENTIFIER_LENGTH (TREE_PURPOSE (tag)),
                    745:                      0, 0);
                    746:       addr_buffer[i] = next_address;
                    747:       buffer.namespace = STRUCT_NAMESPACE;
                    748:       buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_VALUE (tag));
                    749:       buffer.class = LOC_TYPEDEF;
                    750:       buffer.value.value = 0;
                    751: 
                    752:       fwrite (&buffer, sizeof buffer, 1, symfile);
                    753:       next_address += sizeof buffer;
                    754:     }
                    755: }
                    756: 
                    757: /* Output all the data structure for a "block"
                    758:    (any binding contour).
                    759:    DECLS is the chain of declarations of variables in this block.
                    760:    TAGS is the list of struct, union and enum tag definitions of this block.
                    761:    SUPERBLOCK_ADDRESS is the symtab file address of the containing block's
                    762:    data structure.  */
                    763: 
                    764: int
                    765: symout_block (decls, tags, args, superblock_address)
                    766:      tree decls;
                    767:      tree tags;
                    768:      tree args;
                    769:      int superblock_address;
                    770: {
                    771:   register tree decl;
                    772:   register int i;
                    773:   register int *addr_buffer;
                    774:   struct block buffer;
                    775:   int n_decls, n_tags, n_args, total;
                    776:   register struct blockvec_elt *velt;
                    777:   int block_address;
                    778: 
                    779:   for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
                    780:     if (! TREE_EXTERNAL (decl)
                    781:        || TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE)
                    782:       i++;
                    783: 
                    784:   n_decls = i;
                    785: 
                    786:   for (decl = args, i = 0; decl; decl = TREE_CHAIN (decl), i++);
                    787:   n_args = i;
                    788: 
                    789:   for (decl = tags, i = 0; decl; decl = TREE_CHAIN (decl), i++);
                    790:   n_tags = i;
                    791: 
                    792:   total = n_decls + n_args + n_tags;
                    793: 
                    794:   addr_buffer = (int *) alloca (total * sizeof (int));
                    795: 
                    796:   symout_block_symbols (args, addr_buffer, 0);
                    797:   symout_block_symbols (decls, addr_buffer + n_args, 0);
                    798:   symout_block_tags (tags, addr_buffer + n_decls + n_args);
                    799: 
                    800:   velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
                    801:   velt->next = blockvec;
                    802:   velt->address = next_address;
                    803:   blockvec = velt;
                    804: 
                    805:   buffer.startaddr = 0;
                    806:   buffer.endaddr = 0;
                    807:   buffer.superblock = (struct block *) superblock_address;
                    808:   buffer.function = 0;
                    809:   buffer.nsyms = total;
                    810: 
                    811:   block_address = next_address;
                    812:   fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
                    813:   next_address += sizeof buffer - sizeof buffer.sym;
                    814: 
                    815:   fwrite (addr_buffer, sizeof (int), total, symfile);
                    816:   next_address += total * sizeof (int);
                    817: 
                    818:   fprintf (asmfile, "\t.gdbblock %d,%d\n", total_blocks + 2, block_address);
                    819:   total_blocks++;
                    820: 
                    821:   return block_address;
                    822: }
                    823: 
                    824: /* Walk STMT, the body of a function, and output symtab data on
                    825:    all the blocks that compose it and all symbols inside them.
                    826:    ARGS is a chain of decls for argument variables of the function.
                    827:    SUPERBLOCK_ADDRESS is the address of symbol data for the
                    828:    innermost block containing STMT; it is used for recursive calls,
                    829:    and is always 0 for the outermost call (since the containing
                    830:    block for a function is output later than the function).  */
                    831: 
                    832: int
                    833: symout_function (stmt, args, superblock_address)
                    834:      register tree stmt;
                    835:      tree args;
                    836:      int superblock_address;
                    837: {
                    838:   int address = superblock_address;
                    839: 
                    840:   while (stmt)
                    841:     {
                    842:       switch (TREE_CODE (stmt))
                    843:        {
                    844:        case COMPOUND_STMT:
                    845:        case LOOP_STMT:
                    846:          symout_function (STMT_BODY (stmt), 0, address);
                    847:          break;
                    848: 
                    849:        case IF_STMT:
                    850:          symout_function (STMT_THEN (stmt), 0, address);
                    851:          symout_function (STMT_ELSE (stmt), 0, address);
                    852:          break;
                    853: 
                    854:        case LET_STMT:
                    855:          address =
                    856:            symout_block (STMT_VARS (stmt), STMT_TYPE_TAGS (stmt), args,
                    857:                          superblock_address);
                    858: 
                    859:          symout_function (STMT_BODY (stmt), 0, address);
                    860:        }
                    861:       stmt = TREE_CHAIN (stmt);
                    862:     }
                    863:   return address;
                    864: }
                    865: 
                    866: /* Output all the data structure for a top two blocks in a compilation.
                    867:    The top block is for public (global) symbols;
                    868:    the next one is for private (this file only) symbols.
                    869: 
                    870:    DECLS is the chain of declarations of variables in this block.
                    871:    TAGS is the list of struct, union and enum tag definitions.  */
                    872: 
                    873: void
                    874: symout_top_blocks (decls, tags)
                    875:      tree decls;
                    876:      tree tags;
                    877: {
                    878:   register tree decl;
                    879:   register int i;
                    880:   register int *addr_buffer;
                    881:   struct block buffer;
                    882:   int n_decls, n_tags;
                    883:   register struct blockvec_elt *velt;
                    884:   int top_block_addr;
                    885: 
                    886:   /* First do the public-symbols block.  */
                    887: 
                    888:   for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
                    889:     if (TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl))
                    890:       i++;
                    891:   n_decls = i;
                    892: 
                    893:   addr_buffer = (int *) alloca (n_decls * sizeof (int));
                    894: 
                    895:   symout_block_symbols (decls, addr_buffer, 2);
                    896: 
                    897:   fprintf (asmfile, ".text 0\n\t.gdbend 0\n");
                    898:   fprintf (asmfile, "\t.gdbblock 0,%d\n", next_address);
                    899: 
                    900:   total_blocks++;
                    901:   velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
                    902:   velt->next = blockvec;
                    903:   velt->address = next_address;
                    904:   blockvec = velt;
                    905: 
                    906:   top_block_addr = next_address;
                    907: 
                    908:   buffer.startaddr = 0;
                    909:   buffer.endaddr = 0;
                    910:   buffer.superblock = 0;
                    911:   buffer.function = 0;
                    912:   buffer.nsyms = n_decls;;
                    913: 
                    914:   fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
                    915:   next_address += sizeof buffer - sizeof buffer.sym;
                    916: 
                    917:   fwrite (addr_buffer, sizeof (int), n_decls, symfile);
                    918:   next_address += n_decls * sizeof (int);
                    919: 
                    920:   /* Next do the private-symbols block.  */
                    921: 
                    922:   for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
                    923:     if (! TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl))
                    924:       i++;
                    925:   n_decls = i;
                    926: 
                    927:   for (decl = tags, i = 0; decl; decl = TREE_CHAIN (decl), i++);
                    928:   n_tags = i;
                    929: 
                    930:   addr_buffer = (int *) alloca ((n_decls + n_tags) * sizeof (int));
                    931: 
                    932:   symout_block_symbols (decls, addr_buffer, 1);
                    933:   symout_block_tags (tags, addr_buffer + n_decls);
                    934: 
                    935:   fprintf (asmfile, "\t.gdbend 1\n");
                    936:   fprintf (asmfile, "\t.gdbblock 1,%d\n", next_address);
                    937: 
                    938:   total_blocks++;
                    939:   velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
                    940:   velt->next = blockvec;
                    941:   velt->address = next_address;
                    942:   blockvec = velt;
                    943: 
                    944:   buffer.startaddr = 0;
                    945:   buffer.endaddr = 0;
                    946:   buffer.superblock = (struct block *) top_block_addr;
                    947:   buffer.function = 0;
                    948:   buffer.nsyms = n_decls + n_tags;;
                    949: 
                    950:   fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
                    951:   next_address += sizeof buffer - sizeof buffer.sym;
                    952: 
                    953:   fwrite (addr_buffer, sizeof (int), n_decls + n_tags, symfile);
                    954:   next_address += (n_decls + n_tags) * sizeof (int);
                    955: }
                    956: 
                    957: /* Output the source-line-number information.  */
                    958: 
                    959: /* Output a `struct source' for the source file described by F.
                    960:    Return the address-in-the-symseg of the `struct source'.  */
                    961: 
                    962: static int
                    963: symout_source_file (f)
                    964:      struct gdbfile *f;
                    965: {
                    966:   /* Make the `struct source' big enough for as many lines as
                    967:      this file has.  */
                    968:   int size = sizeof (struct source) + (f->nlines - 1) * sizeof (struct line);
                    969:   struct source *buffer
                    970:     = (struct source *) alloca (size);
                    971:   int addr;
                    972: 
                    973:   /* Use zero for the line data, since assembler will store the real data.  */
                    974:   bzero (buffer, size);
                    975: 
                    976:   /* Output the file's name as a string.  The assembler doesn't know this.  */
                    977:   buffer->name = (char *) next_address;
                    978:   symout_strings (f->name, 0, 0, 0);
                    979:   buffer->nlines = f->nlines;
                    980: 
                    981:   /* Write the structure.  */
                    982:   addr = next_address;
                    983:   fwrite (buffer, 1, size, symfile);
                    984:   next_address += size;
                    985: 
                    986:   /* Tell assembler where to write the real line-number data.  */
                    987:   fprintf (asmfile, "\t.gdblinetab %d,%d\n",
                    988:           f->filenum, addr + sizeof (int));
                    989: 
                    990:   return addr;
                    991: }
                    992: 
                    993: /* Output the `struct sourcevector' which describes all the
                    994:    source files and points a `struct source' for each one.  */
                    995: 
                    996: static int
                    997: symout_sources ()
                    998: {
                    999:   register struct gdbfile *f;
                   1000:   int nfiles = 0;
                   1001:   struct sourcevector *s;
                   1002:   int i;
                   1003:   int size;
                   1004:   int addr;
                   1005: 
                   1006:   /* Count number of files to determine size of the sourcevector.  */
                   1007:   for (f = gdbfiles; f; f = f->next)
                   1008:     ++nfiles;
                   1009: 
                   1010:   /* Allocate buffer for the sourcevector and record its length.  */
                   1011:   size = sizeof (int) + nfiles * sizeof (struct source *);
                   1012:   s = (struct sourcevector *) alloca (size);
                   1013:   s->length = nfiles;
                   1014: 
                   1015:   /* Output a `struct source' for each file; put address into sourcevector.  */
                   1016:   for (f = gdbfiles, i = 0; f; f = f->next, i++)
                   1017:     s->source[i] = (struct source *) symout_source_file (f);
                   1018: 
                   1019:   /* Output the sourcevector.  */
                   1020:   addr = next_address;
                   1021:   fwrite (s, 1, size, symfile);
                   1022:   next_address += size;
                   1023:   return addr;
                   1024: }
                   1025: 
                   1026: /* Call here at the end of compilation, after outputting all the
                   1027:    blocks and symbols, to output the blockvector and typevector
                   1028:    and close the symbol table file.  FILETIME is source file's
                   1029:    creation time.  */
                   1030: 
                   1031: void
                   1032: symout_finish (filename, filetime)
                   1033:      char *filename;
                   1034:      int filetime;
                   1035: {
                   1036:   int *blockvector = (int *) alloca ((total_blocks + 1) * sizeof (int));
                   1037:   int *typevector = (int *) alloca ((total_types + 1) * sizeof (int));
                   1038:   int now = time (0);
                   1039:   register int i;
                   1040:   struct symbol_root buffer;
                   1041:   char dir[MAXNAMLEN];
                   1042: 
                   1043:   buffer.language = language_c;
                   1044:   buffer.blockvector = (struct blockvector *) next_address;
                   1045: 
                   1046:   /* The two blocks at the beginning of the chain
                   1047:      are the file's private symbols block and public symbols block.
                   1048:      They belong at the front of the blockvector, in that order.  */
                   1049:   blockvector[2] = blockvec->address;
                   1050:   blockvec = blockvec->next;
                   1051:   blockvector[1] = blockvec->address;
                   1052:   blockvec = blockvec->next;
                   1053: 
                   1054:   /* The rest of the blocks are in the chain in reverse order.  */
                   1055:   for (i = total_blocks; i > 2; i--)
                   1056:     {
                   1057:       blockvector[i] = blockvec->address;
                   1058:       blockvec = blockvec->next;
                   1059:     }
                   1060:   blockvector[0] = total_blocks;
                   1061: 
                   1062:   fwrite (blockvector, sizeof (int), total_blocks + 1, symfile);
                   1063:   next_address += sizeof (int) * (total_blocks + 1);
                   1064: 
                   1065:   buffer.typevector = (struct typevector *) next_address;
                   1066: 
                   1067:   for (i = total_types; i > 0; i--)
                   1068:     {
                   1069:       typevector[i] = typevec->address;
                   1070:       typevec = typevec->next;
                   1071:     }
                   1072:   typevector[0] = total_types;
                   1073: 
                   1074:   fwrite (typevector, sizeof (int), total_types + 1, symfile);
                   1075:   next_address += sizeof (int) * (total_types + 1);
                   1076: 
                   1077:   buffer.sourcevector = (struct sourcevector *) symout_sources ();
                   1078: 
                   1079:   buffer.format = 1;
                   1080:   buffer.textrel = 0;          /* These four will be set up by linker.  */
                   1081:   buffer.datarel = 0;          /* Make them 0 now, which is right for */
                   1082:   buffer.bssrel = 0;           /* looking at the .o file in gdb.  */
                   1083:   buffer.ldsymoff = 0;
                   1084: 
                   1085:   buffer.version = (char *) next_address;
                   1086:   symout_strings (ctime (&filetime), 0, 0, 0);
                   1087: 
                   1088:   buffer.compilation = (char *) next_address;
                   1089:   symout_strings (ctime (&now), 0, 0, 0);
                   1090: 
                   1091:   buffer.filename = (char *) next_address;
                   1092:   symout_strings (filename, 0, 0, 0);
                   1093: 
                   1094:   buffer.filedir = (char *) next_address;
                   1095: #ifdef USG
                   1096:   strcpy (dir, getcwd (dir, MAXNAMLEN));
                   1097: #else
                   1098: #ifndef VMS
                   1099:   getwd (dir);
                   1100: #else
                   1101:   abort ();
                   1102: #endif
                   1103: #endif
                   1104:   symout_strings (dir, 0, 0, 0);
                   1105: 
                   1106:   fflush (symfile);
                   1107: 
                   1108:   if (ferror (symfile) != 0)
                   1109:     fatal_io_error (symfile_name);
                   1110: 
                   1111:   buffer.length = next_address;
                   1112: 
                   1113:   if (lseek (fileno (symfile), 0, 0) < 0)
                   1114:     pfatal_with_name (symfile_name);
                   1115:   if (write (fileno (symfile), &buffer, sizeof buffer) < 0)
                   1116:     pfatal_with_name (symfile_name);
                   1117:   close (fileno (symfile));
                   1118: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.