Annotation of gdb/blockframe.c, revision 1.1.1.3

1.1       root        1: /* Get info from stack frames;
                      2:    convert between frames, blocks, functions and pc values.
1.1.1.2   root        3:    Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
1.1       root        4: 
                      5: GDB is distributed in the hope that it will be useful, but WITHOUT ANY
                      6: WARRANTY.  No author or distributor accepts responsibility to anyone
                      7: for the consequences of using it or for whether it serves any
                      8: particular purpose or works at all, unless he says so in writing.
                      9: Refer to the GDB General Public License for full details.
                     10: 
                     11: Everyone is granted permission to copy, modify and redistribute GDB,
                     12: but only under the conditions described in the GDB General Public
                     13: License.  A copy of this license is supposed to have been given to you
                     14: along with GDB so you can know your rights and responsibilities.  It
                     15: should be in a file named COPYING.  Among other things, the copyright
                     16: notice and this notice must be preserved on all copies.
                     17: 
                     18: In other words, go ahead and share GDB, but don't try to stop
                     19: anyone else from sharing it farther.  Help stamp out software hoarding!
                     20: */
                     21: 
                     22: #include "defs.h"
                     23: #include "initialize.h"
                     24: #include "param.h"
                     25: #include "symtab.h"
                     26: #include "frame.h"
                     27: 
                     28: /* Address of end of first object file.
                     29:    This file is assumed to be a startup file
                     30:    and frames with pc's inside it
                     31:    are treated as nonexistent.  */
                     32: 
                     33: CORE_ADDR first_object_file_end;
                     34: 
                     35: /* Address of innermost stack frame (contents of FP register) */
                     36: 
                     37: static FRAME current_frame;
                     38: 
                     39: struct block *block_for_pc ();
                     40: CORE_ADDR get_pc_function_start ();
                     41: 
                     42: START_FILE
                     43: 
                     44: /* Return the innermost (currently executing) stack frame.  */
                     45: 
                     46: FRAME
                     47: get_current_frame ()
                     48: {
                     49:   /* We assume its address is kept in a general register;
                     50:      param.h says which register.  */
                     51: 
                     52:   return current_frame;
                     53: }
                     54: 
                     55: void
                     56: set_current_frame (frame)
                     57:      FRAME frame;
                     58: {
                     59:   current_frame = frame;
                     60: }
                     61: 
                     62: /* Return the frame that called FRAME.
                     63:    If FRAME is the original frame (it has no caller), return 0.  */
                     64: 
                     65: FRAME
                     66: get_prev_frame (frame)
                     67:      FRAME frame;
                     68: {
                     69:   CORE_ADDR pointer;
                     70:   /* The caller of "no frame" is the innermost frame.  */
                     71:   if (frame == 0)
                     72:     return get_current_frame ();
                     73: 
                     74:   /* Two macros defined in param.h specify the machine-dependent
                     75:      actions to be performed here.  */
                     76:   /* First, get the frame's chain-pointer.
                     77:      If that is zero, the frame is the outermost frame.  */
                     78:   pointer = FRAME_CHAIN (frame);
                     79:   if (!FRAME_CHAIN_VALID (pointer, frame))
                     80:     return 0;
                     81:   /* If frame has a caller, combine the chain pointer and the frame's own
                     82:      address to get the address of the caller.  */
                     83:   return FRAME_CHAIN_COMBINE (pointer, frame);
                     84: }
                     85: 
                     86: /* Return a structure containing various interesting information
                     87:    about a specified stack frame.  */
                     88: 
                     89: struct frame_info
                     90: get_frame_info (frame)
                     91:      FRAME frame;
                     92: {
                     93:   struct frame_info val;
                     94:   FRAME current = get_current_frame ();
                     95:   register FRAME frame1;
                     96: 
                     97:   val.frame = frame;
                     98: 
                     99:   if (frame == current)
                    100:     {
                    101:       val.pc = read_pc ();
                    102:       val.next_frame = 0;
                    103:     }
                    104:   else 
                    105:     {
                    106:       for (frame1 = current; frame1; frame1 = get_prev_frame (frame1))
                    107:        {
                    108:          QUIT;
                    109:          if (frame1 == frame)
                    110:            break;
                    111: 
                    112:          val.pc = FRAME_SAVED_PC (frame1);
                    113:          val.next_frame = frame1;
                    114:        }
                    115:     }
                    116: 
                    117:   return val;
                    118: }
                    119: 
                    120: /* Return a structure containing various interesting information
                    121:    about the frame that called FRAME.
                    122: 
                    123:    This is much faster than get_frame_info (get_prev_frame (FRAME))
                    124:    because it does not need to search the entire stack
                    125:    to find the frame called by the one being described -- that is FRAME.  */
                    126: 
                    127: struct frame_info
                    128: get_prev_frame_info (next_frame)
                    129:      FRAME next_frame;
                    130: {
                    131:   struct frame_info val;
                    132:   register FRAME frame = get_prev_frame (next_frame);
                    133: 
                    134:   val.frame = frame;
                    135:   val.next_frame = next_frame;
                    136: 
                    137:   if (next_frame == 0)
                    138:     {
                    139:       val.pc = read_pc ();
                    140:     }
                    141:   else 
                    142:     {
                    143:       val.pc = FRAME_SAVED_PC (next_frame);
                    144:     }
                    145: 
                    146:   return val;
                    147: }
                    148: 
                    149: CORE_ADDR
                    150: get_frame_pc (frame)
                    151:      FRAME frame;
                    152: {
                    153:   struct frame_info fi;
                    154:   fi = get_frame_info (frame);
                    155:   return fi.pc;
                    156: }
                    157: 
                    158: /* Find the addresses in which registers are saved in FRAME.  */
                    159: 
                    160: void
                    161: get_frame_saved_regs (frame_info_addr, saved_regs_addr)
                    162:      struct frame_info *frame_info_addr;
                    163:      struct frame_saved_regs *saved_regs_addr;
                    164: {
                    165:   FRAME_FIND_SAVED_REGS (*frame_info_addr, *saved_regs_addr);
                    166: }
                    167: 
                    168: /* Return the innermost lexical block in execution
                    169:    in a specified stack frame.  The frame address is assumed valid.  */
                    170: 
                    171: struct block *
                    172: get_frame_block (frame)
                    173:      FRAME frame;
                    174: {
                    175:   struct frame_info fi;
                    176: 
                    177:   fi = get_frame_info (frame);
                    178:   return block_for_pc (fi.pc);
                    179: }
                    180: 
                    181: struct block *
                    182: get_current_block ()
                    183: {
                    184:   return block_for_pc (read_pc ());
                    185: }
                    186: 
                    187: CORE_ADDR
                    188: get_pc_function_start (pc)
                    189:      CORE_ADDR pc;
                    190: {
                    191:   register struct block *bl = block_for_pc (pc);
                    192:   register struct symbol *symbol;
                    193:   if (bl == 0)
                    194:     {
                    195:       register int misc_index = find_pc_misc_function (pc);
                    196:       if (misc_index >= 0)
                    197:        return misc_function_vector[misc_index].address;
                    198:       return 0;
                    199:     }
                    200:   symbol = block_function (bl);
                    201:   bl = SYMBOL_BLOCK_VALUE (symbol);
                    202:   return BLOCK_START (bl);
                    203: }  
                    204: 
                    205: /* Return the symbol for the function executing in frame FRAME.  */
                    206: 
                    207: struct symbol *
                    208: get_frame_function (frame)
                    209:      FRAME frame;
                    210: {
                    211:   register struct block *bl = get_frame_block (frame);
                    212:   if (bl == 0)
                    213:     return 0;
                    214:   return block_function (bl);
                    215: }
                    216: 
                    217: /* Return the innermost lexical block containing the specified pc value,
                    218:    or 0 if there is none.  */
                    219: 
                    220: struct block *
                    221: block_for_pc (pc)
                    222:      register CORE_ADDR pc;
                    223: {
                    224:   register struct block *b;
                    225:   register int bot, top, half;
                    226:   register struct symtab *s;
                    227:   struct blockvector *bl;
                    228: 
                    229:   /* First search all symtabs for one whose file contains our pc */
                    230: 
                    231:   for (s = symtab_list; s; s = s->next)
                    232:     {
                    233:       bl = BLOCKVECTOR (s);
                    234:       b = BLOCKVECTOR_BLOCK (bl, 0);
                    235:       if (BLOCK_START (b) <= pc
                    236:          && BLOCK_END (b) > pc)
                    237:        break;
                    238:     }
                    239: 
                    240:   if (s == 0)
                    241:     return 0;
                    242: 
                    243:   /* Then search that symtab for the smallest block that wins.  */
                    244:   /* Use binary search to find the last block that starts before PC.  */
                    245: 
                    246:   bot = 0;
                    247:   top = BLOCKVECTOR_NBLOCKS (bl);
                    248: 
                    249:   while (top - bot > 1)
                    250:     {
                    251:       half = (top - bot + 1) >> 1;
                    252:       b = BLOCKVECTOR_BLOCK (bl, bot + half);
                    253:       if (BLOCK_START (b) <= pc)
                    254:        bot += half;
                    255:       else
                    256:        top = bot + half;
                    257:     }
                    258: 
                    259:   /* Now search backward for a block that ends after PC.  */
                    260: 
                    261:   while (bot >= 0)
                    262:     {
                    263:       b = BLOCKVECTOR_BLOCK (bl, bot);
                    264:       if (BLOCK_END (b) > pc)
                    265:        return b;
                    266:       bot--;
                    267:     }
                    268: 
                    269:   return 0;
                    270: }
                    271: 
                    272: /* Return the function containing pc value PC.
                    273:    Returns 0 if function is not known.  */
                    274: 
                    275: struct symbol *
                    276: find_pc_function (pc)
                    277:      CORE_ADDR pc;
                    278: {
                    279:   register struct block *b = block_for_pc (pc);
                    280:   if (b == 0)
                    281:     return 0;
                    282:   return block_function (b);
                    283: }
                    284: 
                    285: /* Find the misc function whose address is the largest
                    286:    while being less than PC.  Return its index in misc_function_vector.
                    287:    Returns -1 if PC is not in suitable range.  */
                    288: 
                    289: int
                    290: find_pc_misc_function (pc)
1.1.1.2   root      291:      register CORE_ADDR pc;
1.1       root      292: {
1.1.1.2   root      293:   register int lo = 0;
                    294:   register int hi = misc_function_count-1;
                    295:   register int new;
                    296:   register int distance;
1.1       root      297: 
                    298:   /* Note that the last thing in the vector is always _etext.  */
1.1.1.2   root      299: 
1.1.1.3 ! root      300:   /* Above statement is not *always* true - fix for case where there are */
        !           301:   /* no misc functions at all (ie no symbol table has been read). */
        !           302:   if (hi < 0) return -1;        /* no misc functions recorded */
        !           303: 
1.1.1.2   root      304:   /* trivial reject range test */
                    305:   if (pc < misc_function_vector[0].address || 
                    306:       pc > misc_function_vector[hi].address)
                    307:     return -1;
                    308: 
                    309:   do {
                    310:     new = (lo + hi) >> 1;
                    311:     distance = misc_function_vector[new].address - pc;
                    312:     if (distance == 0)
                    313:       return new;              /* an exact match */
                    314:     else if (distance > 0)
                    315:       hi = new;
                    316:     else
                    317:       lo = new;
                    318:   } while (hi-lo != 1);
                    319: 
                    320:   /* if here, we had no exact match, so return the lower choice */
                    321:   return lo;
1.1       root      322: }
                    323: 
                    324: /* Return the innermost stack frame executing inside of the specified block,
                    325:    or zero if there is no such frame.  */
                    326: 
                    327: FRAME
                    328: block_innermost_frame (block)
                    329:      struct block *block;
                    330: {
                    331:   struct frame_info fi;
                    332:   register FRAME frame;
                    333:   register CORE_ADDR start = BLOCK_START (block);
                    334:   register CORE_ADDR end = BLOCK_END (block);
                    335: 
                    336:   frame = 0;
                    337:   while (1)
                    338:     {
                    339:       fi = get_prev_frame_info (frame);
                    340:       frame = fi.frame;
                    341:       if (frame == 0)
                    342:        return 0;
                    343:       if (fi.pc >= start && fi.pc < end)
                    344:        return frame;
                    345:     }
                    346: }
                    347: 
                    348: static
                    349: initialize ()
                    350: {
                    351: }
                    352: 
                    353: END_FILE

unix.superglobalmegacorp.com

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