Annotation of 43BSDReno/contrib/emacs-18.55/gdb/values.c, revision 1.1

1.1     ! root        1: /* Low level packing and unpacking of values for GDB.
        !             2:    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
        !             3: 
        !             4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY
        !             5: WARRANTY.  No author or distributor accepts responsibility to anyone
        !             6: for the consequences of using it or for whether it serves any
        !             7: particular purpose or works at all, unless he says so in writing.
        !             8: Refer to the GDB General Public License for full details.
        !             9: 
        !            10: Everyone is granted permission to copy, modify and redistribute GDB,
        !            11: but only under the conditions described in the GDB General Public
        !            12: License.  A copy of this license is supposed to have been given to you
        !            13: along with GDB so you can know your rights and responsibilities.  It
        !            14: should be in a file named COPYING.  Among other things, the copyright
        !            15: notice and this notice must be preserved on all copies.
        !            16: 
        !            17: In other words, go ahead and share GDB, but don't try to stop
        !            18: anyone else from sharing it farther.  Help stamp out software hoarding!
        !            19: */
        !            20: 
        !            21: #include <stdio.h>
        !            22: #include "defs.h"
        !            23: #include "initialize.h"
        !            24: #include "param.h"
        !            25: #include "symtab.h"
        !            26: #include "value.h"
        !            27: 
        !            28: /* The value-history records all the values printed
        !            29:    by print commands during this session.  Each chunk
        !            30:    records 60 consecutive values.  The first chunk on
        !            31:    the chain records the most recent values.
        !            32:    The total number of values is in value_history_count.  */
        !            33: 
        !            34: #define VALUE_HISTORY_CHUNK 60
        !            35: 
        !            36: struct value_history_chunk
        !            37: {
        !            38:   struct value_history_chunk *next;
        !            39:   value values[VALUE_HISTORY_CHUNK];
        !            40: };
        !            41: 
        !            42: /* Chain of chunks now in use.  */
        !            43: 
        !            44: static struct value_history_chunk *value_history_chain;
        !            45: 
        !            46: static int value_history_count;        /* Abs number of last entry stored */
        !            47: 
        !            48: START_FILE
        !            49: 
        !            50: /* List of all value objects currently allocated
        !            51:    (except for those released by calls to release_value)
        !            52:    This is so they can be freed after each command.  */
        !            53: 
        !            54: static value all_values;
        !            55: 
        !            56: /* Allocate a  value  that has the correct length for type TYPE.  */
        !            57: 
        !            58: value
        !            59: allocate_value (type)
        !            60:      struct type *type;
        !            61: {
        !            62:   register value val;
        !            63: 
        !            64:   val = (value) xmalloc (sizeof (struct value) + TYPE_LENGTH (type));
        !            65:   VALUE_NEXT (val) = all_values;
        !            66:   all_values = val;
        !            67:   VALUE_TYPE (val) = type;
        !            68:   VALUE_LVAL (val) = not_lval;
        !            69:   VALUE_ADDRESS (val) = 0;
        !            70:   VALUE_OFFSET (val) = 0;
        !            71:   VALUE_BITPOS (val) = 0;
        !            72:   VALUE_BITSIZE (val) = 0;
        !            73:   VALUE_REPEATED (val) = 0;
        !            74:   VALUE_REPETITIONS (val) = 0;
        !            75:   VALUE_REGNO (val) = -1;
        !            76:   return val;
        !            77: }
        !            78: 
        !            79: /* Allocate a  value  that has the correct length
        !            80:    for COUNT repetitions type TYPE.  */
        !            81: 
        !            82: value
        !            83: allocate_repeat_value (type, count)
        !            84:      struct type *type;
        !            85:      int count;
        !            86: {
        !            87:   register value val;
        !            88: 
        !            89:   val = (value) xmalloc (sizeof (struct value) + TYPE_LENGTH (type) * count);
        !            90:   VALUE_NEXT (val) = all_values;
        !            91:   all_values = val;
        !            92:   VALUE_TYPE (val) = type;
        !            93:   VALUE_LVAL (val) = not_lval;
        !            94:   VALUE_ADDRESS (val) = 0;
        !            95:   VALUE_OFFSET (val) = 0;
        !            96:   VALUE_BITPOS (val) = 0;
        !            97:   VALUE_BITSIZE (val) = 0;
        !            98:   VALUE_REPEATED (val) = 1;
        !            99:   VALUE_REPETITIONS (val) = count;
        !           100:   VALUE_REGNO (val) = -1;
        !           101:   return val;
        !           102: }
        !           103: 
        !           104: /* Free all the values that have been allocated (except for those released).
        !           105:    Called after each command, successful or not.  */
        !           106: 
        !           107: void
        !           108: free_all_values ()
        !           109: {
        !           110:   register value val, next;
        !           111: 
        !           112:   for (val = all_values; val; val = next)
        !           113:     {
        !           114:       next = VALUE_NEXT (val);
        !           115:       free (val);
        !           116:     }
        !           117: 
        !           118:   all_values = 0;
        !           119: }
        !           120: 
        !           121: /* Remove VAL from the chain all_values
        !           122:    so it will not be freed automatically.  */
        !           123: 
        !           124: void
        !           125: release_value (val)
        !           126:      register value val;
        !           127: {
        !           128:   register value v;
        !           129: 
        !           130:   if (all_values == val)
        !           131:     {
        !           132:       all_values = val->next;
        !           133:       return;
        !           134:     }
        !           135: 
        !           136:   for (v = all_values; v; v = v->next)
        !           137:     {
        !           138:       if (v->next == val)
        !           139:        {
        !           140:          v->next = val->next;
        !           141:          break;
        !           142:        }
        !           143:     }
        !           144: }
        !           145: 
        !           146: /* Return a copy of the value ARG.
        !           147:    It contains the same contents, for same memory address,
        !           148:    but it's a different block of storage.  */
        !           149: 
        !           150: static value
        !           151: value_copy (arg)
        !           152:      value arg;
        !           153: {
        !           154:   register value val;
        !           155:   register struct type *type = VALUE_TYPE (arg);
        !           156:   if (VALUE_REPEATED (arg))
        !           157:     val = allocate_repeat_value (type, VALUE_REPETITIONS (arg));
        !           158:   else
        !           159:     val = allocate_value (type);
        !           160:   VALUE_LVAL (val) = VALUE_LVAL (arg);
        !           161:   VALUE_ADDRESS (val) = VALUE_ADDRESS (arg);
        !           162:   VALUE_OFFSET (val) = VALUE_OFFSET (arg);
        !           163:   VALUE_BITPOS (val) = VALUE_BITPOS (arg);
        !           164:   VALUE_BITSIZE (val) = VALUE_BITSIZE (arg);
        !           165:   VALUE_REGNO (val) = VALUE_REGNO (arg);
        !           166:   bcopy (VALUE_CONTENTS (arg), VALUE_CONTENTS (val),
        !           167:         TYPE_LENGTH (VALUE_TYPE (arg))
        !           168:         * (VALUE_REPEATED (arg) ? VALUE_REPETITIONS (arg) : 1));
        !           169:   return val;
        !           170: }
        !           171: 
        !           172: /* Access to the value history.  */
        !           173: 
        !           174: /* Record a new value in the value history.
        !           175:    Returns the absolute history index of the entry.  */
        !           176: 
        !           177: int
        !           178: record_latest_value (val)
        !           179:      value val;
        !           180: {
        !           181:   register int i;
        !           182: 
        !           183:   /* Get error now if about to store an invalid float.  */
        !           184:   if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT)
        !           185:     value_as_double (val);
        !           186: 
        !           187:   /* Here we treat value_history_count as origin-zero
        !           188:      and applying to the value being stored now.  */
        !           189: 
        !           190:   i = value_history_count % VALUE_HISTORY_CHUNK;
        !           191:   if (i == 0)
        !           192:     {
        !           193:       register struct value_history_chunk *new
        !           194:        = (struct value_history_chunk *) xmalloc (sizeof (struct value_history_chunk));
        !           195:       bzero (new->values, sizeof new->values);
        !           196:       new->next = value_history_chain;
        !           197:       value_history_chain = new;
        !           198:     }
        !           199: 
        !           200:   value_history_chain->values[i] = val;
        !           201:   release_value (val);
        !           202: 
        !           203:   /* Now we regard value_history_count as origin-one
        !           204:      and applying to the value just stored.  */
        !           205: 
        !           206:   return ++value_history_count;
        !           207: }
        !           208: 
        !           209: /* Return a copy of the value in the history with sequence number NUM.  */
        !           210: 
        !           211: value
        !           212: access_value_history (num)
        !           213:      int num;
        !           214: {
        !           215:   register struct value_history_chunk *chunk;
        !           216:   register int i;
        !           217:   register int absnum = num;
        !           218: 
        !           219:   if (absnum <= 0)
        !           220:     absnum += value_history_count;
        !           221: 
        !           222:   if (absnum <= 0)
        !           223:     {
        !           224:       if (num == 0)
        !           225:        error ("The history is empty.");
        !           226:       else if (num == 1)
        !           227:        error ("There is only one value in the history.");
        !           228:       else
        !           229:        error ("History does not go back to $$%d.", -num);
        !           230:     }
        !           231:   if (absnum > value_history_count)
        !           232:     error ("History has not yet reached $%d.", absnum);
        !           233: 
        !           234:   absnum--;
        !           235: 
        !           236:   /* Now absnum is always absolute and origin zero.  */
        !           237: 
        !           238:   chunk = value_history_chain;
        !           239:   for (i = (value_history_count - 1) / VALUE_HISTORY_CHUNK - absnum / VALUE_HISTORY_CHUNK;
        !           240:        i > 0; i--)
        !           241:     chunk = chunk->next;
        !           242: 
        !           243:   return value_copy (chunk->values[absnum % VALUE_HISTORY_CHUNK]);
        !           244: }
        !           245: 
        !           246: /* Clear the value history entirely.
        !           247:    Must be done when new symbol tables are loaded,
        !           248:    because the type pointers become invalid.  */
        !           249: 
        !           250: void
        !           251: clear_value_history ()
        !           252: {
        !           253:   register struct value_history_chunk *next;
        !           254:   register int i;
        !           255:   register value val;
        !           256: 
        !           257:   while (value_history_chain)
        !           258:     {
        !           259:       for (i = 0; i < VALUE_HISTORY_CHUNK; i++)
        !           260:        if (val = value_history_chain->values[i])
        !           261:          free (val);
        !           262:       next = value_history_chain->next;
        !           263:       free (value_history_chain);
        !           264:       value_history_chain = next;
        !           265:     }
        !           266:   value_history_count = 0;
        !           267: }
        !           268: 
        !           269: static void
        !           270: history_info (num_exp)
        !           271:      char *num_exp;
        !           272: {
        !           273:   register int i;
        !           274:   register value val;
        !           275:   register int num;
        !           276: 
        !           277:   if (num_exp)
        !           278:     num = parse_and_eval_address (num_exp) - 5;
        !           279:   else
        !           280:     num = value_history_count - 9;
        !           281: 
        !           282:   if (num <= 0)
        !           283:     num = 1;
        !           284: 
        !           285:   for (i = num; i < num + 10 && i <= value_history_count; i++)
        !           286:     {
        !           287:       val = access_value_history (i);
        !           288:       printf ("$%d = ", i);
        !           289:       value_print (val, stdout, 0);
        !           290:       printf ("\n");
        !           291:     }
        !           292: }
        !           293: 
        !           294: /* Internal variables.  These are variables within the debugger
        !           295:    that hold values assigned by debugger commands.
        !           296:    The user refers to them with a '$' prefix
        !           297:    that does not appear in the variable names stored internally.  */
        !           298: 
        !           299: static struct internalvar *internalvars;
        !           300: 
        !           301: /* Look up an internal variable with name NAME.  NAME should not
        !           302:    normally include a dollar sign.
        !           303: 
        !           304:    If the specified internal variable does not exist,
        !           305:    one is created, with a void value.  */
        !           306: 
        !           307: struct internalvar *
        !           308: lookup_internalvar (name)
        !           309:      char *name;
        !           310: {
        !           311:   register struct internalvar *var;
        !           312: 
        !           313:   for (var = internalvars; var; var = var->next)
        !           314:     if (!strcmp (var->name, name))
        !           315:       return var;
        !           316: 
        !           317:   var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
        !           318:   var->name = concat (name, "", "");
        !           319:   var->value = allocate_value (builtin_type_void);
        !           320:   release_value (var->value);
        !           321:   var->next = internalvars;
        !           322:   internalvars = var;
        !           323:   return var;
        !           324: }
        !           325: 
        !           326: value
        !           327: value_of_internalvar (var)
        !           328:      struct internalvar *var;
        !           329: {
        !           330:   register value val = value_copy (var->value);
        !           331:   VALUE_LVAL (val) = lval_internalvar;
        !           332:   VALUE_INTERNALVAR (val) = var;
        !           333:   return val;
        !           334: }
        !           335: 
        !           336: void
        !           337: set_internalvar_component (var, offset, bitpos, bitsize, newval)
        !           338:      struct internalvar *var;
        !           339:      int offset, bitpos, bitsize;
        !           340:      value newval;
        !           341: {
        !           342:   register char *addr = VALUE_CONTENTS (var->value) + offset;
        !           343:   if (bitsize)
        !           344:     modify_field (addr, value_as_long (newval),
        !           345:                  bitpos, bitsize);
        !           346:   else
        !           347:     bcopy (VALUE_CONTENTS (newval), addr,
        !           348:           TYPE_LENGTH (VALUE_TYPE (newval)));
        !           349: }
        !           350: 
        !           351: void
        !           352: set_internalvar (var, val)
        !           353:      struct internalvar *var;
        !           354:      value val;
        !           355: {
        !           356:   free (var->value);
        !           357:   var->value = value_copy (val);
        !           358:   release_value (var->value);
        !           359: }
        !           360: 
        !           361: char *
        !           362: internalvar_name (var)
        !           363:      struct internalvar *var;
        !           364: {
        !           365:   return var->name;
        !           366: }
        !           367: 
        !           368: /* Free all internalvars.  Done when new symtabs are loaded,
        !           369:    because that makes the values invalid.  */
        !           370: 
        !           371: void
        !           372: clear_internalvars ()
        !           373: {
        !           374:   register struct internalvar *var;
        !           375: 
        !           376:   while (internalvars)
        !           377:     {
        !           378:       var = internalvars;
        !           379:       internalvars = var->next;
        !           380:       free (var->name);
        !           381:       free (var->value);
        !           382:       free (var);
        !           383:     }
        !           384: }
        !           385: 
        !           386: static void
        !           387: convenience_info ()
        !           388: {
        !           389:   register struct internalvar *var;
        !           390: 
        !           391:   if (internalvars)
        !           392:     printf ("Debugger convenience variables:\n\n");
        !           393:   else
        !           394:     printf ("No debugger convenience variables now defined.\n\
        !           395: Convenience variables have names starting with \"$\";\n\
        !           396: use \"set\" as in \"set $foo = 5\" to define them.\n");
        !           397: 
        !           398:   for (var = internalvars; var; var = var->next)
        !           399:     {
        !           400:       printf ("$%s: ", var->name);
        !           401:       value_print (var->value, stdout, 0);
        !           402:       printf ("\n");
        !           403:     }
        !           404: }
        !           405: 
        !           406: /* Extract a value as a C number (either long or double).
        !           407:    Knows how to convert fixed values to double, or
        !           408:    floating values to long.
        !           409:    Does not deallocate the value.  */
        !           410: 
        !           411: long
        !           412: value_as_long (val)
        !           413:      register value val;
        !           414: {
        !           415:   return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
        !           416: }
        !           417: 
        !           418: double
        !           419: value_as_double (val)
        !           420:      register value val;
        !           421: {
        !           422:   return unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val));
        !           423: }
        !           424: 
        !           425: /* Unpack raw data (copied from debugee) at VALADDR
        !           426:    as a long, or as a double, assuming the raw data is described
        !           427:    by type TYPE.  Knows how to convert different sizes of values
        !           428:    and can convert between fixed and floating point.  */
        !           429: 
        !           430: long
        !           431: unpack_long (type, valaddr)
        !           432:      struct type *type;
        !           433:      char *valaddr;
        !           434: {
        !           435:   register enum type_code code = TYPE_CODE (type);
        !           436:   register int len = TYPE_LENGTH (type);
        !           437:   register int nosign = TYPE_UNSIGNED (type);
        !           438: 
        !           439:   if (code == TYPE_CODE_ENUM)
        !           440:     code = TYPE_CODE_INT;
        !           441:   if (code == TYPE_CODE_FLT)
        !           442:     {
        !           443:       if (len == sizeof (float))
        !           444:        return * (float *) valaddr;
        !           445: 
        !           446:       if (len == sizeof (double))
        !           447:        return * (double *) valaddr;
        !           448:     }
        !           449:   else if (code == TYPE_CODE_INT && nosign)
        !           450:     {
        !           451:       if (len == sizeof (char))
        !           452:        return * (unsigned char *) valaddr;
        !           453: 
        !           454:       if (len == sizeof (short))
        !           455:        return * (unsigned short *) valaddr;
        !           456: 
        !           457:       if (len == sizeof (int))
        !           458:        return * (unsigned int *) valaddr;
        !           459: 
        !           460:       if (len == sizeof (long))
        !           461:        return * (unsigned long *) valaddr;
        !           462:     }
        !           463:   else if (code == TYPE_CODE_INT)
        !           464:     {
        !           465:       if (len == sizeof (char))
        !           466:        return * (char *) valaddr;
        !           467: 
        !           468:       if (len == sizeof (short))
        !           469:        return * (short *) valaddr;
        !           470: 
        !           471:       if (len == sizeof (int))
        !           472:        return * (int *) valaddr;
        !           473: 
        !           474:       if (len == sizeof (long))
        !           475:        return * (long *) valaddr;
        !           476:     }
        !           477:   else if (code == TYPE_CODE_PTR)
        !           478:     {
        !           479:       if (len == sizeof (char *))
        !           480:        return (CORE_ADDR) * (char **) valaddr;
        !           481:     }
        !           482: 
        !           483:   error ("Value not integer or pointer.");
        !           484: }
        !           485: 
        !           486: double
        !           487: unpack_double (type, valaddr)
        !           488:      struct type *type;
        !           489:      char *valaddr;
        !           490: {
        !           491:   register enum type_code code = TYPE_CODE (type);
        !           492:   register int len = TYPE_LENGTH (type);
        !           493:   register int nosign = TYPE_UNSIGNED (type);
        !           494: 
        !           495:   if (code == TYPE_CODE_FLT)
        !           496:     {
        !           497:       if (INVALID_FLOAT (valaddr, len))
        !           498:        error ("Invalid floating value found in program.");
        !           499: 
        !           500:       if (len == sizeof (float))
        !           501:        return * (float *) valaddr;
        !           502: 
        !           503:       if (len == sizeof (double))
        !           504:        {
        !           505:          /* Some machines require doubleword alignment for doubles.
        !           506:             This code works on them, and on other machines.  */
        !           507:          double temp;
        !           508:          bcopy ((char *) valaddr, (char *) &temp, sizeof (double));
        !           509:          return temp;
        !           510:        }
        !           511:     }
        !           512:   else if (code == TYPE_CODE_INT && nosign)
        !           513:     {
        !           514:       if (len == sizeof (char))
        !           515:        return * (unsigned char *) valaddr;
        !           516: 
        !           517:       if (len == sizeof (short))
        !           518:        return * (unsigned short *) valaddr;
        !           519: 
        !           520:       if (len == sizeof (int))
        !           521:        return * (unsigned int *) valaddr;
        !           522: 
        !           523:       if (len == sizeof (long))
        !           524:        return * (unsigned long *) valaddr;
        !           525:     }
        !           526:   else if (code == TYPE_CODE_INT)
        !           527:     {
        !           528:       if (len == sizeof (char))
        !           529:        return * (char *) valaddr;
        !           530: 
        !           531:       if (len == sizeof (short))
        !           532:        return * (short *) valaddr;
        !           533: 
        !           534:       if (len == sizeof (int))
        !           535:        return * (int *) valaddr;
        !           536: 
        !           537:       if (len == sizeof (long))
        !           538:        return * (long *) valaddr;
        !           539:     }
        !           540: 
        !           541:   error ("Value not floating number.");
        !           542: }
        !           543: 
        !           544: /* Given a value ARG1 of a struct or union type,
        !           545:    extract and return the value of one of its fields.
        !           546:    FIELDNO says which field.  */
        !           547: 
        !           548: value
        !           549: value_field (arg1, fieldno)
        !           550:      register value arg1;
        !           551:      register int fieldno;
        !           552: {
        !           553:   register value v;
        !           554:   register struct type *type = TYPE_FIELD_TYPE (VALUE_TYPE (arg1), fieldno);
        !           555:   register int offset;
        !           556: 
        !           557:   /* Handle packed fields */
        !           558: 
        !           559:   offset = TYPE_FIELD_BITPOS (VALUE_TYPE (arg1), fieldno) / 8;
        !           560:   if (TYPE_FIELD_BITSIZE (VALUE_TYPE (arg1), fieldno))
        !           561:     {
        !           562:       v = value_from_long (type,
        !           563:                           unpack_field_as_long (VALUE_TYPE (arg1),
        !           564:                                                 VALUE_CONTENTS (arg1),
        !           565:                                                 fieldno));
        !           566:       VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (VALUE_TYPE (arg1), fieldno) % 8;
        !           567:       VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (VALUE_TYPE (arg1), fieldno);
        !           568:     }
        !           569:   else
        !           570:     {
        !           571:       v = allocate_value (type);
        !           572:       bcopy (VALUE_CONTENTS (arg1) + offset,
        !           573:             VALUE_CONTENTS (v),
        !           574:             TYPE_LENGTH (type));
        !           575:     }
        !           576:   VALUE_LVAL (v) = VALUE_LVAL (arg1);
        !           577:   if (VALUE_LVAL (arg1) == lval_internalvar)
        !           578:     VALUE_LVAL (v) = lval_internalvar_component;
        !           579:   VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);
        !           580:   VALUE_OFFSET (v) = offset + VALUE_OFFSET (arg1);
        !           581:   return v;
        !           582: }
        !           583: 
        !           584: long
        !           585: unpack_field_as_long (type, valaddr, fieldno)
        !           586:      struct type *type;
        !           587:      char *valaddr;
        !           588:      int fieldno;
        !           589: {
        !           590:   long val;
        !           591:   int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
        !           592:   int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
        !           593:   union { int i; char c; } test;
        !           594: 
        !           595:   bcopy (valaddr + bitpos / 8, &val, sizeof val);
        !           596: 
        !           597:   /* Extracting bits depends on endianness of the machine.  */
        !           598:   test.i = 1;
        !           599:   if (test.c == 1)
        !           600:     /* Little-endian.  */
        !           601:     val = val >> (bitpos % 8);
        !           602:   else
        !           603:     val = val >> (sizeof val * 8 - bitpos % 8 - bitsize);
        !           604: 
        !           605:   val &= (1 << bitsize) - 1;
        !           606:   return val;
        !           607: }
        !           608: 
        !           609: modify_field (addr, fieldval, bitpos, bitsize)
        !           610:      char *addr;
        !           611:      int fieldval;
        !           612:      int bitpos, bitsize;
        !           613: {
        !           614:   long oword;
        !           615:   union { int i; char c; } test;
        !           616: 
        !           617:   bcopy (addr, &oword, sizeof oword);
        !           618: 
        !           619:   /* Shifting for bit field depends on endianness of the machine.  */
        !           620:   test.c = 1;
        !           621:   if (test.i != 1)
        !           622:     /* not little-endian: assume big-endian.  */
        !           623:     bitpos = sizeof oword * 8 - bitpos - bitsize;
        !           624: 
        !           625:   oword &= ~(((1 << bitsize) - 1) << bitpos);
        !           626:   oword |= fieldval << bitpos;
        !           627:   bcopy (&oword, addr, sizeof oword);
        !           628: }
        !           629: 
        !           630: /* Convert C numbers into newly allocated values */
        !           631: 
        !           632: value
        !           633: value_from_long (type, num)
        !           634:      struct type *type;
        !           635:      register long num;
        !           636: {
        !           637:   register value val = allocate_value (type);
        !           638:   register enum type_code code = TYPE_CODE (type);
        !           639:   register int len = TYPE_LENGTH (type);
        !           640: 
        !           641:   if (code == TYPE_CODE_INT || code == TYPE_CODE_ENUM)
        !           642:     {
        !           643:       if (len == sizeof (char))
        !           644:        * (char *) VALUE_CONTENTS (val) = num;
        !           645:       else if (len == sizeof (short))
        !           646:        * (short *) VALUE_CONTENTS (val) = num;
        !           647:       else if (len == sizeof (int))
        !           648:        * (int *) VALUE_CONTENTS (val) = num;
        !           649:       else if (len == sizeof (long))
        !           650:        * (long *) VALUE_CONTENTS (val) = num;
        !           651:       else
        !           652:        error ("Integer type encountered with unexpected data length.");
        !           653:     }
        !           654:   else
        !           655:     error ("Unexpected type encountered for integer constant.");
        !           656: 
        !           657:   return val;
        !           658: }
        !           659: 
        !           660: value
        !           661: value_from_double (type, num)
        !           662:      struct type *type;
        !           663:      double num;
        !           664: {
        !           665:   register value val = allocate_value (type);
        !           666:   register enum type_code code = TYPE_CODE (type);
        !           667:   register int len = TYPE_LENGTH (type);
        !           668: 
        !           669:   if (code == TYPE_CODE_FLT)
        !           670:     {
        !           671:       if (len == sizeof (float))
        !           672:        * (float *) VALUE_CONTENTS (val) = num;
        !           673:       else if (len == sizeof (double))
        !           674:        * (double *) VALUE_CONTENTS (val) = num;
        !           675:       else
        !           676:        error ("Floating type encountered with unexpected data length.");
        !           677:     }
        !           678:   else
        !           679:     error ("Unexpected type encountered for floating constant.");
        !           680: 
        !           681:   return val;
        !           682: }
        !           683: 
        !           684: /* Deal with the value that is "about to be returned".  */
        !           685: 
        !           686: /* Return the value that a function returning now
        !           687:    would be returning to its caller, assuming its type is VALTYPE.
        !           688:    RETBUF is where we look for what ought to be the contents
        !           689:    of the registers (in raw form).  This is because it is often
        !           690:    desirable to restore old values to those registers
        !           691:    after saving the contents of interest, and then call
        !           692:    this function using the saved values.  */
        !           693: 
        !           694: value
        !           695: value_being_returned (valtype, retbuf)
        !           696:      register struct type *valtype;
        !           697:      char retbuf[REGISTER_BYTES];
        !           698: {
        !           699:   register value val;
        !           700: 
        !           701:   if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
        !           702:       || TYPE_CODE (valtype) == TYPE_CODE_UNION)
        !           703:     return value_at (valtype, EXTRACT_STRUCT_VALUE_ADDRESS (retbuf));
        !           704: 
        !           705:   val = allocate_value (valtype);
        !           706:   EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS (val));
        !           707: 
        !           708:   return val;
        !           709: }
        !           710: 
        !           711: /* Store VAL so it will be returned if a function returns now.
        !           712:    Does not verify that VAL's type matches what the current
        !           713:    function wants to return.  */
        !           714: 
        !           715: void
        !           716: set_return_value (val)
        !           717:      value val;
        !           718: {
        !           719:   register enum type_code code = TYPE_CODE (VALUE_TYPE (val));
        !           720:   char regbuf[REGISTER_BYTES];
        !           721:   double dbuf;
        !           722:   long lbuf;
        !           723: 
        !           724:   if (code == TYPE_CODE_STRUCT
        !           725:       || code == TYPE_CODE_UNION)
        !           726:     error ("Specifying a struct or union return value is not supported.");
        !           727: 
        !           728:   if (code == TYPE_CODE_FLT)
        !           729:     {
        !           730:       dbuf = value_as_double (val);
        !           731: 
        !           732:       STORE_RETURN_VALUE (VALUE_TYPE (val), &dbuf);
        !           733:     }
        !           734:   else
        !           735:     {
        !           736:       lbuf = value_as_long (val);
        !           737:       STORE_RETURN_VALUE (VALUE_TYPE (val), &lbuf);
        !           738:     }
        !           739: }
        !           740: 
        !           741: static
        !           742: initialize ()
        !           743: {
        !           744:   add_info ("convenience", convenience_info,
        !           745:            "Debugger convenience (\"$foo\") variables.\n\
        !           746: These variables are created when you assign them values;\n\
        !           747: thus, \"print $foo=1\" gives \"$foo\" the value 1.  Values may be any type.\n\n\
        !           748: A few convenience variables are given values automatically GDB:\n\
        !           749: \"$_\"holds the last address examined with \"x\" or \"info lines\",\n\
        !           750: \"$__\" holds the contents of the last address examined with \"x\".");
        !           751: 
        !           752:   add_info ("history", history_info,
        !           753:            "Elements of value history (around item number IDX, or last ten).");
        !           754: }
        !           755: 
        !           756: END_FILE

unix.superglobalmegacorp.com

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