[BACK]Return to compile-c-symbols.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / gdb.old / dist / gdb / compile

Annotation of src/external/gpl3/gdb.old/dist/gdb/compile/compile-c-symbols.c, Revision 1.4

1.1       christos    1: /* Convert symbols from GDB to GCC
                      2:
1.4     ! christos    3:    Copyright (C) 2014-2016 Free Software Foundation, Inc.
1.1       christos    4:
                      5:    This file is part of GDB.
                      6:
                      7:    This program is free software; you can redistribute it and/or modify
                      8:    it under the terms of the GNU General Public License as published by
                      9:    the Free Software Foundation; either version 3 of the License, or
                     10:    (at your option) any later version.
                     11:
                     12:    This program is distributed in the hope that it will be useful,
                     13:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15:    GNU General Public License for more details.
                     16:
                     17:    You should have received a copy of the GNU General Public License
                     18:    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
                     19:
                     20:
                     21: #include "defs.h"
                     22: #include "compile-internal.h"
                     23: #include "symtab.h"
                     24: #include "parser-defs.h"
                     25: #include "block.h"
                     26: #include "objfiles.h"
                     27: #include "compile.h"
                     28: #include "value.h"
                     29: #include "exceptions.h"
                     30: #include "gdbtypes.h"
                     31: #include "dwarf2loc.h"
                     32:
                     33: 
                     34:
                     35: /* Object of this type are stored in the compiler's symbol_err_map.  */
                     36:
                     37: struct symbol_error
                     38: {
                     39:   /* The symbol.  */
                     40:
                     41:   const struct symbol *sym;
                     42:
                     43:   /* The error message to emit.  This is malloc'd and owned by the
                     44:      hash table.  */
                     45:
                     46:   char *message;
                     47: };
                     48:
                     49: /* Hash function for struct symbol_error.  */
                     50:
                     51: static hashval_t
                     52: hash_symbol_error (const void *a)
                     53: {
1.4     ! christos   54:   const struct symbol_error *se = (const struct symbol_error *) a;
1.1       christos   55:
                     56:   return htab_hash_pointer (se->sym);
                     57: }
                     58:
                     59: /* Equality function for struct symbol_error.  */
                     60:
                     61: static int
                     62: eq_symbol_error (const void *a, const void *b)
                     63: {
1.4     ! christos   64:   const struct symbol_error *sea = (const struct symbol_error *) a;
        !            65:   const struct symbol_error *seb = (const struct symbol_error *) b;
1.1       christos   66:
                     67:   return sea->sym == seb->sym;
                     68: }
                     69:
                     70: /* Deletion function for struct symbol_error.  */
                     71:
                     72: static void
                     73: del_symbol_error (void *a)
                     74: {
1.4     ! christos   75:   struct symbol_error *se = (struct symbol_error *) a;
1.1       christos   76:
                     77:   xfree (se->message);
                     78:   xfree (se);
                     79: }
                     80:
                     81: /* Associate SYMBOL with some error text.  */
                     82:
                     83: static void
                     84: insert_symbol_error (htab_t hash, const struct symbol *sym, const char *text)
                     85: {
                     86:   struct symbol_error e;
                     87:   void **slot;
                     88:
                     89:   e.sym = sym;
                     90:   slot = htab_find_slot (hash, &e, INSERT);
                     91:   if (*slot == NULL)
                     92:     {
                     93:       struct symbol_error *e = XNEW (struct symbol_error);
                     94:
                     95:       e->sym = sym;
                     96:       e->message = xstrdup (text);
                     97:       *slot = e;
                     98:     }
                     99: }
                    100:
                    101: /* Emit the error message corresponding to SYM, if one exists, and
                    102:    arrange for it not to be emitted again.  */
                    103:
                    104: static void
                    105: error_symbol_once (struct compile_c_instance *context,
                    106:                   const struct symbol *sym)
                    107: {
                    108:   struct symbol_error search;
                    109:   struct symbol_error *err;
                    110:   char *message;
                    111:
                    112:   if (context->symbol_err_map == NULL)
                    113:     return;
                    114:
                    115:   search.sym = sym;
1.4     ! christos  116:   err = (struct symbol_error *) htab_find (context->symbol_err_map, &search);
1.1       christos  117:   if (err == NULL || err->message == NULL)
                    118:     return;
                    119:
                    120:   message = err->message;
                    121:   err->message = NULL;
                    122:   make_cleanup (xfree, message);
                    123:   error (_("%s"), message);
                    124: }
                    125:
                    126: 
                    127:
                    128: /* Compute the name of the pointer representing a local symbol's
                    129:    address.  */
                    130:
                    131: static char *
                    132: symbol_substitution_name (struct symbol *sym)
                    133: {
                    134:   return concat ("__", SYMBOL_NATURAL_NAME (sym), "_ptr", (char *) NULL);
                    135: }
                    136:
                    137: /* Convert a given symbol, SYM, to the compiler's representation.
                    138:    CONTEXT is the compiler instance.  IS_GLOBAL is true if the
                    139:    symbol came from the global scope.  IS_LOCAL is true if the symbol
                    140:    came from a local scope.  (Note that the two are not strictly
                    141:    inverses because the symbol might have come from the static
                    142:    scope.)  */
                    143:
                    144: static void
                    145: convert_one_symbol (struct compile_c_instance *context,
1.4     ! christos  146:                    struct block_symbol sym,
1.1       christos  147:                    int is_global,
                    148:                    int is_local)
                    149: {
                    150:   gcc_type sym_type;
1.4     ! christos  151:   const char *filename = symbol_symtab (sym.symbol)->filename;
        !           152:   unsigned short line = SYMBOL_LINE (sym.symbol);
1.1       christos  153:
1.4     ! christos  154:   error_symbol_once (context, sym.symbol);
1.1       christos  155:
1.4     ! christos  156:   if (SYMBOL_CLASS (sym.symbol) == LOC_LABEL)
1.1       christos  157:     sym_type = 0;
                    158:   else
1.4     ! christos  159:     sym_type = convert_type (context, SYMBOL_TYPE (sym.symbol));
1.1       christos  160:
1.4     ! christos  161:   if (SYMBOL_DOMAIN (sym.symbol) == STRUCT_DOMAIN)
1.1       christos  162:     {
                    163:       /* Binding a tag, so we don't need to build a decl.  */
                    164:       C_CTX (context)->c_ops->tagbind (C_CTX (context),
1.4     ! christos  165:                                       SYMBOL_NATURAL_NAME (sym.symbol),
1.1       christos  166:                                       sym_type, filename, line);
                    167:     }
                    168:   else
                    169:     {
                    170:       gcc_decl decl;
                    171:       enum gcc_c_symbol_kind kind;
                    172:       CORE_ADDR addr = 0;
                    173:       char *symbol_name = NULL;
                    174:
1.4     ! christos  175:       switch (SYMBOL_CLASS (sym.symbol))
1.1       christos  176:        {
                    177:        case LOC_TYPEDEF:
                    178:          kind = GCC_C_SYMBOL_TYPEDEF;
                    179:          break;
                    180:
                    181:        case LOC_LABEL:
                    182:          kind = GCC_C_SYMBOL_LABEL;
1.4     ! christos  183:          addr = SYMBOL_VALUE_ADDRESS (sym.symbol);
1.1       christos  184:          break;
                    185:
                    186:        case LOC_BLOCK:
                    187:          kind = GCC_C_SYMBOL_FUNCTION;
1.4     ! christos  188:          addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym.symbol));
        !           189:          if (is_global && TYPE_GNU_IFUNC (SYMBOL_TYPE (sym.symbol)))
1.3       christos  190:            addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
1.1       christos  191:          break;
                    192:
                    193:        case LOC_CONST:
1.4     ! christos  194:          if (TYPE_CODE (SYMBOL_TYPE (sym.symbol)) == TYPE_CODE_ENUM)
1.1       christos  195:            {
                    196:              /* Already handled by convert_enum.  */
                    197:              return;
                    198:            }
1.4     ! christos  199:          C_CTX (context)->c_ops->build_constant
        !           200:            (C_CTX (context),
        !           201:             sym_type, SYMBOL_NATURAL_NAME (sym.symbol),
        !           202:             SYMBOL_VALUE (sym.symbol),
        !           203:             filename, line);
1.1       christos  204:          return;
                    205:
                    206:        case LOC_CONST_BYTES:
                    207:          error (_("Unsupported LOC_CONST_BYTES for symbol \"%s\"."),
1.4     ! christos  208:                 SYMBOL_PRINT_NAME (sym.symbol));
1.1       christos  209:
                    210:        case LOC_UNDEF:
                    211:          internal_error (__FILE__, __LINE__, _("LOC_UNDEF found for \"%s\"."),
1.4     ! christos  212:                          SYMBOL_PRINT_NAME (sym.symbol));
1.1       christos  213:
                    214:        case LOC_COMMON_BLOCK:
                    215:          error (_("Fortran common block is unsupported for compilation "
                    216:                   "evaluaton of symbol \"%s\"."),
1.4     ! christos  217:                 SYMBOL_PRINT_NAME (sym.symbol));
1.1       christos  218:
                    219:        case LOC_OPTIMIZED_OUT:
                    220:          error (_("Symbol \"%s\" cannot be used for compilation evaluation "
                    221:                   "as it is optimized out."),
1.4     ! christos  222:                 SYMBOL_PRINT_NAME (sym.symbol));
1.1       christos  223:
                    224:        case LOC_COMPUTED:
                    225:          if (is_local)
                    226:            goto substitution;
                    227:          /* Probably TLS here.  */
                    228:          warning (_("Symbol \"%s\" is thread-local and currently can only "
                    229:                     "be referenced from the current thread in "
                    230:                     "compiled code."),
1.4     ! christos  231:                   SYMBOL_PRINT_NAME (sym.symbol));
1.1       christos  232:          /* FALLTHROUGH */
                    233:        case LOC_UNRESOLVED:
                    234:          /* 'symbol_name' cannot be used here as that one is used only for
                    235:             local variables from compile_dwarf_expr_to_c.
                    236:             Global variables can be accessed by GCC only by their address, not
                    237:             by their name.  */
                    238:          {
                    239:            struct value *val;
                    240:            struct frame_info *frame = NULL;
                    241:
1.4     ! christos  242:            if (symbol_read_needs_frame (sym.symbol))
1.1       christos  243:              {
                    244:                frame = get_selected_frame (NULL);
                    245:                if (frame == NULL)
                    246:                  error (_("Symbol \"%s\" cannot be used because "
                    247:                           "there is no selected frame"),
1.4     ! christos  248:                         SYMBOL_PRINT_NAME (sym.symbol));
1.1       christos  249:              }
                    250:
1.4     ! christos  251:            val = read_var_value (sym.symbol, sym.block, frame);
1.1       christos  252:            if (VALUE_LVAL (val) != lval_memory)
                    253:              error (_("Symbol \"%s\" cannot be used for compilation "
                    254:                       "evaluation as its address has not been found."),
1.4     ! christos  255:                     SYMBOL_PRINT_NAME (sym.symbol));
1.1       christos  256:
                    257:            kind = GCC_C_SYMBOL_VARIABLE;
                    258:            addr = value_address (val);
                    259:          }
                    260:          break;
                    261:
                    262:
                    263:        case LOC_REGISTER:
                    264:        case LOC_ARG:
                    265:        case LOC_REF_ARG:
                    266:        case LOC_REGPARM_ADDR:
                    267:        case LOC_LOCAL:
                    268:        substitution:
                    269:          kind = GCC_C_SYMBOL_VARIABLE;
1.4     ! christos  270:          symbol_name = symbol_substitution_name (sym.symbol);
1.1       christos  271:          break;
                    272:
                    273:        case LOC_STATIC:
                    274:          kind = GCC_C_SYMBOL_VARIABLE;
1.4     ! christos  275:          addr = SYMBOL_VALUE_ADDRESS (sym.symbol);
1.1       christos  276:          break;
                    277:
                    278:        case LOC_FINAL_VALUE:
                    279:        default:
                    280:          gdb_assert_not_reached ("Unreachable case in convert_one_symbol.");
                    281:
                    282:        }
                    283:
                    284:       /* Don't emit local variable decls for a raw expression.  */
                    285:       if (context->base.scope != COMPILE_I_RAW_SCOPE
                    286:          || symbol_name == NULL)
                    287:        {
1.4     ! christos  288:          decl = C_CTX (context)->c_ops->build_decl
        !           289:            (C_CTX (context),
        !           290:             SYMBOL_NATURAL_NAME (sym.symbol),
        !           291:             kind,
        !           292:             sym_type,
        !           293:             symbol_name, addr,
        !           294:             filename, line);
1.1       christos  295:
                    296:          C_CTX (context)->c_ops->bind (C_CTX (context), decl, is_global);
                    297:        }
                    298:
                    299:       xfree (symbol_name);
                    300:     }
                    301: }
                    302:
                    303: /* Convert a full symbol to its gcc form.  CONTEXT is the compiler to
                    304:    use, IDENTIFIER is the name of the symbol, SYM is the symbol
                    305:    itself, and DOMAIN is the domain which was searched.  */
                    306:
                    307: static void
                    308: convert_symbol_sym (struct compile_c_instance *context, const char *identifier,
1.4     ! christos  309:                    struct block_symbol sym, domain_enum domain)
1.1       christos  310: {
1.4     ! christos  311:   const struct block *static_block;
1.1       christos  312:   int is_local_symbol;
                    313:
                    314:   /* If we found a symbol and it is not in the  static or global
                    315:      scope, then we should first convert any static or global scope
                    316:      symbol of the same name.  This lets this unusual case work:
                    317:
                    318:      int x; // Global.
                    319:      int func(void)
                    320:      {
                    321:      int x;
                    322:      // At this spot, evaluate "extern int x; x"
                    323:      }
                    324:   */
                    325:
1.4     ! christos  326:   static_block = block_static_block (sym.block);
1.1       christos  327:   /* STATIC_BLOCK is NULL if FOUND_BLOCK is the global block.  */
1.4     ! christos  328:   is_local_symbol = (sym.block != static_block && static_block != NULL);
1.1       christos  329:   if (is_local_symbol)
                    330:     {
1.4     ! christos  331:       struct block_symbol global_sym;
1.1       christos  332:
                    333:       global_sym = lookup_symbol (identifier, NULL, domain, NULL);
                    334:       /* If the outer symbol is in the static block, we ignore it, as
                    335:         it cannot be referenced.  */
1.4     ! christos  336:       if (global_sym.symbol != NULL
        !           337:          && global_sym.block != block_static_block (global_sym.block))
1.1       christos  338:        {
                    339:          if (compile_debug)
1.3       christos  340:            fprintf_unfiltered (gdb_stdlog,
1.1       christos  341:                                "gcc_convert_symbol \"%s\": global symbol\n",
                    342:                                identifier);
                    343:          convert_one_symbol (context, global_sym, 1, 0);
                    344:        }
                    345:     }
                    346:
                    347:   if (compile_debug)
1.3       christos  348:     fprintf_unfiltered (gdb_stdlog,
1.1       christos  349:                        "gcc_convert_symbol \"%s\": local symbol\n",
                    350:                        identifier);
                    351:   convert_one_symbol (context, sym, 0, is_local_symbol);
                    352: }
                    353:
                    354: /* Convert a minimal symbol to its gcc form.  CONTEXT is the compiler
                    355:    to use and BMSYM is the minimal symbol to convert.  */
                    356:
                    357: static void
                    358: convert_symbol_bmsym (struct compile_c_instance *context,
                    359:                      struct bound_minimal_symbol bmsym)
                    360: {
                    361:   struct minimal_symbol *msym = bmsym.minsym;
                    362:   struct objfile *objfile = bmsym.objfile;
                    363:   struct type *type;
                    364:   enum gcc_c_symbol_kind kind;
                    365:   gcc_type sym_type;
                    366:   gcc_decl decl;
                    367:   CORE_ADDR addr;
                    368:
1.3       christos  369:   addr = MSYMBOL_VALUE_ADDRESS (objfile, msym);
                    370:
1.1       christos  371:   /* Conversion copied from write_exp_msymbol.  */
                    372:   switch (MSYMBOL_TYPE (msym))
                    373:     {
                    374:     case mst_text:
                    375:     case mst_file_text:
                    376:     case mst_solib_trampoline:
                    377:       type = objfile_type (objfile)->nodebug_text_symbol;
                    378:       kind = GCC_C_SYMBOL_FUNCTION;
                    379:       break;
                    380:
                    381:     case mst_text_gnu_ifunc:
1.3       christos  382:       /* nodebug_text_gnu_ifunc_symbol would cause:
                    383:         function return type cannot be function  */
                    384:       type = objfile_type (objfile)->nodebug_text_symbol;
1.1       christos  385:       kind = GCC_C_SYMBOL_FUNCTION;
1.3       christos  386:       addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
1.1       christos  387:       break;
                    388:
                    389:     case mst_data:
                    390:     case mst_file_data:
                    391:     case mst_bss:
                    392:     case mst_file_bss:
                    393:       type = objfile_type (objfile)->nodebug_data_symbol;
                    394:       kind = GCC_C_SYMBOL_VARIABLE;
                    395:       break;
                    396:
                    397:     case mst_slot_got_plt:
                    398:       type = objfile_type (objfile)->nodebug_got_plt_symbol;
                    399:       kind = GCC_C_SYMBOL_FUNCTION;
                    400:       break;
                    401:
                    402:     default:
                    403:       type = objfile_type (objfile)->nodebug_unknown_symbol;
                    404:       kind = GCC_C_SYMBOL_VARIABLE;
                    405:       break;
                    406:     }
                    407:
                    408:   sym_type = convert_type (context, type);
                    409:   decl = C_CTX (context)->c_ops->build_decl (C_CTX (context),
                    410:                                             MSYMBOL_NATURAL_NAME (msym),
                    411:                                             kind, sym_type, NULL, addr,
                    412:                                             NULL, 0);
                    413:   C_CTX (context)->c_ops->bind (C_CTX (context), decl, 1 /* is_global */);
                    414: }
                    415:
                    416: /* See compile-internal.h.  */
                    417:
                    418: void
                    419: gcc_convert_symbol (void *datum,
                    420:                    struct gcc_c_context *gcc_context,
                    421:                    enum gcc_c_oracle_request request,
                    422:                    const char *identifier)
                    423: {
1.4     ! christos  424:   struct compile_c_instance *context = (struct compile_c_instance *) datum;
1.1       christos  425:   domain_enum domain;
                    426:   int found = 0;
                    427:
                    428:   switch (request)
                    429:     {
                    430:     case GCC_C_ORACLE_SYMBOL:
                    431:       domain = VAR_DOMAIN;
                    432:       break;
                    433:     case GCC_C_ORACLE_TAG:
                    434:       domain = STRUCT_DOMAIN;
                    435:       break;
                    436:     case GCC_C_ORACLE_LABEL:
                    437:       domain = LABEL_DOMAIN;
                    438:       break;
                    439:     default:
                    440:       gdb_assert_not_reached ("Unrecognized oracle request.");
                    441:     }
                    442:
                    443:   /* We can't allow exceptions to escape out of this callback.  Safest
                    444:      is to simply emit a gcc error.  */
1.3       christos  445:   TRY
1.1       christos  446:     {
1.4     ! christos  447:       struct block_symbol sym;
1.1       christos  448:
                    449:       sym = lookup_symbol (identifier, context->base.block, domain, NULL);
1.4     ! christos  450:       if (sym.symbol != NULL)
1.1       christos  451:        {
                    452:          convert_symbol_sym (context, identifier, sym, domain);
                    453:          found = 1;
                    454:        }
                    455:       else if (domain == VAR_DOMAIN)
                    456:        {
                    457:          struct bound_minimal_symbol bmsym;
                    458:
                    459:          bmsym = lookup_minimal_symbol (identifier, NULL, NULL);
                    460:          if (bmsym.minsym != NULL)
                    461:            {
                    462:              convert_symbol_bmsym (context, bmsym);
                    463:              found = 1;
                    464:            }
                    465:        }
                    466:     }
                    467:
1.3       christos  468:   CATCH (e, RETURN_MASK_ALL)
                    469:     {
                    470:       C_CTX (context)->c_ops->error (C_CTX (context), e.message);
                    471:     }
                    472:   END_CATCH
1.1       christos  473:
                    474:   if (compile_debug && !found)
1.3       christos  475:     fprintf_unfiltered (gdb_stdlog,
1.1       christos  476:                        "gcc_convert_symbol \"%s\": lookup_symbol failed\n",
                    477:                        identifier);
                    478:   return;
                    479: }
                    480:
                    481: /* See compile-internal.h.  */
                    482:
                    483: gcc_address
                    484: gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context,
                    485:                    const char *identifier)
                    486: {
1.4     ! christos  487:   struct compile_c_instance *context = (struct compile_c_instance *) datum;
1.1       christos  488:   gcc_address result = 0;
                    489:   int found = 0;
                    490:
                    491:   /* We can't allow exceptions to escape out of this callback.  Safest
                    492:      is to simply emit a gcc error.  */
1.3       christos  493:   TRY
1.1       christos  494:     {
                    495:       struct symbol *sym;
                    496:
                    497:       /* We only need global functions here.  */
1.4     ! christos  498:       sym = lookup_symbol (identifier, NULL, VAR_DOMAIN, NULL).symbol;
1.1       christos  499:       if (sym != NULL && SYMBOL_CLASS (sym) == LOC_BLOCK)
                    500:        {
                    501:          if (compile_debug)
1.3       christos  502:            fprintf_unfiltered (gdb_stdlog,
1.1       christos  503:                                "gcc_symbol_address \"%s\": full symbol\n",
                    504:                                identifier);
                    505:          result = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
1.3       christos  506:          if (TYPE_GNU_IFUNC (SYMBOL_TYPE (sym)))
                    507:            result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
1.1       christos  508:          found = 1;
                    509:        }
                    510:       else
                    511:        {
                    512:          struct bound_minimal_symbol msym;
                    513:
                    514:          msym = lookup_bound_minimal_symbol (identifier);
                    515:          if (msym.minsym != NULL)
                    516:            {
                    517:              if (compile_debug)
1.3       christos  518:                fprintf_unfiltered (gdb_stdlog,
1.1       christos  519:                                    "gcc_symbol_address \"%s\": minimal "
                    520:                                    "symbol\n",
                    521:                                    identifier);
                    522:              result = BMSYMBOL_VALUE_ADDRESS (msym);
1.3       christos  523:              if (MSYMBOL_TYPE (msym.minsym) == mst_text_gnu_ifunc)
                    524:                result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
1.1       christos  525:              found = 1;
                    526:            }
                    527:        }
                    528:     }
                    529:
1.3       christos  530:   CATCH (e, RETURN_MASK_ERROR)
                    531:     {
                    532:       C_CTX (context)->c_ops->error (C_CTX (context), e.message);
                    533:     }
                    534:   END_CATCH
1.1       christos  535:
                    536:   if (compile_debug && !found)
1.3       christos  537:     fprintf_unfiltered (gdb_stdlog,
1.1       christos  538:                        "gcc_symbol_address \"%s\": failed\n",
                    539:                        identifier);
                    540:   return result;
                    541: }
                    542:
                    543: 
                    544:
                    545: /* A hash function for symbol names.  */
                    546:
                    547: static hashval_t
                    548: hash_symname (const void *a)
                    549: {
1.4     ! christos  550:   const struct symbol *sym = (const struct symbol *) a;
1.1       christos  551:
                    552:   return htab_hash_string (SYMBOL_NATURAL_NAME (sym));
                    553: }
                    554:
                    555: /* A comparison function for hash tables that just looks at symbol
                    556:    names.  */
                    557:
                    558: static int
                    559: eq_symname (const void *a, const void *b)
                    560: {
1.4     ! christos  561:   const struct symbol *syma = (const struct symbol *) a;
        !           562:   const struct symbol *symb = (const struct symbol *) b;
1.1       christos  563:
                    564:   return strcmp (SYMBOL_NATURAL_NAME (syma), SYMBOL_NATURAL_NAME (symb)) == 0;
                    565: }
                    566:
                    567: /* If a symbol with the same name as SYM is already in HASHTAB, return
                    568:    1.  Otherwise, add SYM to HASHTAB and return 0.  */
                    569:
                    570: static int
                    571: symbol_seen (htab_t hashtab, struct symbol *sym)
                    572: {
                    573:   void **slot;
                    574:
                    575:   slot = htab_find_slot (hashtab, sym, INSERT);
                    576:   if (*slot != NULL)
                    577:     return 1;
                    578:
                    579:   *slot = sym;
                    580:   return 0;
                    581: }
                    582:
                    583: /* Generate C code to compute the length of a VLA.  */
                    584:
                    585: static void
                    586: generate_vla_size (struct compile_c_instance *compiler,
                    587:                   struct ui_file *stream,
                    588:                   struct gdbarch *gdbarch,
                    589:                   unsigned char *registers_used,
                    590:                   CORE_ADDR pc,
                    591:                   struct type *type,
                    592:                   struct symbol *sym)
                    593: {
                    594:   type = check_typedef (type);
                    595:
                    596:   if (TYPE_CODE (type) == TYPE_CODE_REF)
                    597:     type = check_typedef (TYPE_TARGET_TYPE (type));
                    598:
                    599:   switch (TYPE_CODE (type))
                    600:     {
                    601:     case TYPE_CODE_RANGE:
                    602:       {
                    603:        if (TYPE_HIGH_BOUND_KIND (type) == PROP_LOCEXPR
                    604:            || TYPE_HIGH_BOUND_KIND (type) == PROP_LOCLIST)
                    605:          {
                    606:            const struct dynamic_prop *prop = &TYPE_RANGE_DATA (type)->high;
                    607:            char *name = c_get_range_decl_name (prop);
                    608:            struct cleanup *cleanup = make_cleanup (xfree, name);
                    609:
                    610:            dwarf2_compile_property_to_c (stream, name,
                    611:                                          gdbarch, registers_used,
                    612:                                          prop, pc, sym);
                    613:            do_cleanups (cleanup);
                    614:          }
                    615:       }
                    616:       break;
                    617:
                    618:     case TYPE_CODE_ARRAY:
                    619:       generate_vla_size (compiler, stream, gdbarch, registers_used, pc,
                    620:                         TYPE_INDEX_TYPE (type), sym);
                    621:       generate_vla_size (compiler, stream, gdbarch, registers_used, pc,
                    622:                         TYPE_TARGET_TYPE (type), sym);
                    623:       break;
                    624:
                    625:     case TYPE_CODE_UNION:
                    626:     case TYPE_CODE_STRUCT:
                    627:       {
                    628:        int i;
                    629:
                    630:        for (i = 0; i < TYPE_NFIELDS (type); ++i)
                    631:          if (!field_is_static (&TYPE_FIELD (type, i)))
                    632:            generate_vla_size (compiler, stream, gdbarch, registers_used, pc,
                    633:                               TYPE_FIELD_TYPE (type, i), sym);
                    634:       }
                    635:       break;
                    636:     }
                    637: }
                    638:
                    639: /* Generate C code to compute the address of SYM.  */
                    640:
                    641: static void
                    642: generate_c_for_for_one_variable (struct compile_c_instance *compiler,
                    643:                                 struct ui_file *stream,
                    644:                                 struct gdbarch *gdbarch,
                    645:                                 unsigned char *registers_used,
                    646:                                 CORE_ADDR pc,
                    647:                                 struct symbol *sym)
                    648: {
                    649:
1.3       christos  650:   TRY
1.1       christos  651:     {
                    652:       if (is_dynamic_type (SYMBOL_TYPE (sym)))
                    653:        {
                    654:          struct ui_file *size_file = mem_fileopen ();
                    655:          struct cleanup *cleanup = make_cleanup_ui_file_delete (size_file);
                    656:
                    657:          generate_vla_size (compiler, size_file, gdbarch, registers_used, pc,
                    658:                             SYMBOL_TYPE (sym), sym);
                    659:          ui_file_put (size_file, ui_file_write_for_put, stream);
                    660:
                    661:          do_cleanups (cleanup);
                    662:        }
                    663:
                    664:       if (SYMBOL_COMPUTED_OPS (sym) != NULL)
                    665:        {
                    666:          char *generated_name = symbol_substitution_name (sym);
                    667:          struct cleanup *cleanup = make_cleanup (xfree, generated_name);
                    668:          /* We need to emit to a temporary buffer in case an error
                    669:             occurs in the middle.  */
                    670:          struct ui_file *local_file = mem_fileopen ();
                    671:
                    672:          make_cleanup_ui_file_delete (local_file);
                    673:          SYMBOL_COMPUTED_OPS (sym)->generate_c_location (sym, local_file,
                    674:                                                          gdbarch,
                    675:                                                          registers_used,
                    676:                                                          pc, generated_name);
                    677:          ui_file_put (local_file, ui_file_write_for_put, stream);
                    678:
                    679:          do_cleanups (cleanup);
                    680:        }
                    681:       else
                    682:        {
                    683:          switch (SYMBOL_CLASS (sym))
                    684:            {
                    685:            case LOC_REGISTER:
                    686:            case LOC_ARG:
                    687:            case LOC_REF_ARG:
                    688:            case LOC_REGPARM_ADDR:
                    689:            case LOC_LOCAL:
                    690:              error (_("Local symbol unhandled when generating C code."));
                    691:
                    692:            case LOC_COMPUTED:
                    693:              gdb_assert_not_reached (_("LOC_COMPUTED variable "
                    694:                                        "missing a method."));
                    695:
                    696:            default:
                    697:              /* Nothing to do for all other cases, as they don't represent
                    698:                 local variables.  */
                    699:              break;
                    700:            }
                    701:        }
                    702:     }
                    703:
1.3       christos  704:   CATCH (e, RETURN_MASK_ERROR)
                    705:     {
                    706:       if (compiler->symbol_err_map == NULL)
                    707:        compiler->symbol_err_map = htab_create_alloc (10,
                    708:                                                      hash_symbol_error,
                    709:                                                      eq_symbol_error,
                    710:                                                      del_symbol_error,
                    711:                                                      xcalloc,
                    712:                                                      xfree);
                    713:       insert_symbol_error (compiler->symbol_err_map, sym, e.message);
                    714:     }
                    715:   END_CATCH
1.1       christos  716: }
                    717:
                    718: /* See compile-internal.h.  */
                    719:
                    720: unsigned char *
                    721: generate_c_for_variable_locations (struct compile_c_instance *compiler,
                    722:                                   struct ui_file *stream,
                    723:                                   struct gdbarch *gdbarch,
                    724:                                   const struct block *block,
                    725:                                   CORE_ADDR pc)
                    726: {
                    727:   struct cleanup *cleanup, *outer;
                    728:   htab_t symhash;
                    729:   const struct block *static_block = block_static_block (block);
                    730:   unsigned char *registers_used;
                    731:
                    732:   /* If we're already in the static or global block, there is nothing
                    733:      to write.  */
                    734:   if (static_block == NULL || block == static_block)
                    735:     return NULL;
                    736:
                    737:   registers_used = XCNEWVEC (unsigned char, gdbarch_num_regs (gdbarch));
                    738:   outer = make_cleanup (xfree, registers_used);
                    739:
                    740:   /* Ensure that a given name is only entered once.  This reflects the
                    741:      reality of shadowing.  */
                    742:   symhash = htab_create_alloc (1, hash_symname, eq_symname, NULL,
                    743:                               xcalloc, xfree);
                    744:   cleanup = make_cleanup_htab_delete (symhash);
                    745:
                    746:   while (1)
                    747:     {
                    748:       struct symbol *sym;
                    749:       struct block_iterator iter;
                    750:
                    751:       /* Iterate over symbols in this block, generating code to
                    752:         compute the location of each local variable.  */
                    753:       for (sym = block_iterator_first (block, &iter);
                    754:           sym != NULL;
                    755:           sym = block_iterator_next (&iter))
                    756:        {
                    757:          if (!symbol_seen (symhash, sym))
                    758:            generate_c_for_for_one_variable (compiler, stream, gdbarch,
                    759:                                             registers_used, pc, sym);
                    760:        }
                    761:
                    762:       /* If we just finished the outermost block of a function, we're
                    763:         done.  */
                    764:       if (BLOCK_FUNCTION (block) != NULL)
                    765:        break;
                    766:       block = BLOCK_SUPERBLOCK (block);
                    767:     }
                    768:
                    769:   do_cleanups (cleanup);
                    770:   discard_cleanups (outer);
                    771:   return registers_used;
                    772: }

CVSweb <webmaster@jp.NetBSD.org>