static struct symtab * get_java_class_symtab (void) { if (class_symtab == NULL) { struct objfile *objfile = get_dynamics_objfile (); struct blockvector *bv; struct block *bl; class_symtab = allocate_symtab ("<java-classes>", objfile); class_symtab->language = language_java; bv = (struct blockvector *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct blockvector) + sizeof (struct block *)); BLOCKVECTOR_NBLOCKS (bv) = 1; BLOCKVECTOR (class_symtab) = bv; /* Allocate dummy STATIC_BLOCK. */ bl = allocate_block (&objfile->objfile_obstack); BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack, NULL); BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl; /* Allocate GLOBAL_BLOCK. */ bl = allocate_block (&objfile->objfile_obstack); BLOCK_DICT (bl) = dict_create_hashed_expandable (); BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl; class_symtab->free_func = free_class_block; } return class_symtab; }
static struct block * find_block_in_blockvector (struct blockvector *bl, CORE_ADDR pc) { struct block *b; int bot, top, half; /* If we have an addrmap mapping code addresses to blocks, then use that. */ if (BLOCKVECTOR_MAP (bl)) return addrmap_find (BLOCKVECTOR_MAP (bl), pc); /* Otherwise, use binary search to find the last block that starts before PC. Note: GLOBAL_BLOCK is block 0, STATIC_BLOCK is block 1. They both have the same START,END values. Historically this code would choose STATIC_BLOCK over GLOBAL_BLOCK but the fact that this choice was made was subtle, now we make it explicit. */ gdb_assert (BLOCKVECTOR_NBLOCKS (bl) >= 2); bot = STATIC_BLOCK; top = BLOCKVECTOR_NBLOCKS (bl); while (top - bot > 1) { half = (top - bot + 1) >> 1; b = BLOCKVECTOR_BLOCK (bl, bot + half); if (BLOCK_START (b) <= pc) bot += half; else top = bot + half; } /* Now search backward for a block that ends after PC. */ while (bot >= STATIC_BLOCK) { b = BLOCKVECTOR_BLOCK (bl, bot); if (BLOCK_END (b) > pc) return b; bot--; } return NULL; }
struct blockvector * blockvector_for_pc_sect (CORE_ADDR pc, struct bfd_section *section, int *pindex, struct symtab *symtab) { struct block *b; int bot, top, half; struct blockvector *bl; if (symtab == 0) /* if no symtab specified by caller */ { /* First search all symtabs for one whose file contains our pc */ symtab = find_pc_sect_symtab (pc, section); if (symtab == 0) return 0; } bl = BLOCKVECTOR (symtab); b = BLOCKVECTOR_BLOCK (bl, 0); /* Then search that symtab for the smallest block that wins. */ /* Use binary search to find the last block that starts before PC. */ bot = 0; top = BLOCKVECTOR_NBLOCKS (bl); while (top - bot > 1) { half = (top - bot + 1) >> 1; b = BLOCKVECTOR_BLOCK (bl, bot + half); if (BLOCK_START (b) <= pc) bot += half; else top = bot + half; } /* Now search backward for a block that ends after PC. */ while (bot >= 0) { b = BLOCKVECTOR_BLOCK (bl, bot); if (BLOCK_END (b) > pc) { if (pindex) *pindex = bot; return bl; } bot--; } return 0; }
static struct symtab * get_java_class_symtab (struct gdbarch *gdbarch) { struct objfile *objfile = get_dynamics_objfile (gdbarch); struct symtab *class_symtab = objfile->symtabs; if (class_symtab == NULL) { struct blockvector *bv; struct block *bl; struct jv_per_objfile_data *jv_data; class_symtab = allocate_symtab ("<java-classes>", objfile); class_symtab->language = language_java; bv = (struct blockvector *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct blockvector) + sizeof (struct block *)); BLOCKVECTOR_NBLOCKS (bv) = 1; BLOCKVECTOR (class_symtab) = bv; /* Allocate dummy STATIC_BLOCK. */ bl = allocate_block (&objfile->objfile_obstack); BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack, NULL); BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl; /* Allocate GLOBAL_BLOCK. */ bl = allocate_global_block (&objfile->objfile_obstack); BLOCK_DICT (bl) = dict_create_hashed_expandable (); set_block_symtab (bl, class_symtab); BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl; /* Arrange to free the dict. */ jv_data = objfile_data (objfile, jv_dynamics_objfile_data_key); jv_data->dict = BLOCK_DICT (bl); } return class_symtab; }
static struct type * get_out_value_type (struct symbol *func_sym, struct objfile *objfile, enum compile_i_scope_types scope) { struct symbol *gdb_ptr_type_sym; /* Initialize it just to avoid a GCC false warning. */ struct symbol *gdb_val_sym = NULL; struct type *gdb_ptr_type, *gdb_type_from_ptr, *gdb_type, *retval; /* Initialize it just to avoid a GCC false warning. */ const struct block *block = NULL; const struct blockvector *bv; int nblocks = 0; int block_loop = 0; bv = SYMTAB_BLOCKVECTOR (func_sym->owner.symtab); nblocks = BLOCKVECTOR_NBLOCKS (bv); gdb_ptr_type_sym = NULL; for (block_loop = 0; block_loop < nblocks; block_loop++) { struct symbol *function = NULL; const struct block *function_block; block = BLOCKVECTOR_BLOCK (bv, block_loop); if (BLOCK_FUNCTION (block) != NULL) continue; gdb_val_sym = block_lookup_symbol (block, COMPILE_I_EXPR_VAL, VAR_DOMAIN); if (gdb_val_sym == NULL) continue; function_block = block; while (function_block != BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) && function_block != BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) { function_block = BLOCK_SUPERBLOCK (function_block); function = BLOCK_FUNCTION (function_block); if (function != NULL) break; } if (function != NULL && (BLOCK_SUPERBLOCK (function_block) == BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) && (strcmp (SYMBOL_LINKAGE_NAME (function), GCC_FE_WRAPPER_FUNCTION) == 0)) break; } if (block_loop == nblocks) error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE); gdb_type = SYMBOL_TYPE (gdb_val_sym); gdb_type = check_typedef (gdb_type); gdb_ptr_type_sym = block_lookup_symbol (block, COMPILE_I_EXPR_PTR_TYPE, VAR_DOMAIN); if (gdb_ptr_type_sym == NULL) error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE); gdb_ptr_type = SYMBOL_TYPE (gdb_ptr_type_sym); gdb_ptr_type = check_typedef (gdb_ptr_type); if (TYPE_CODE (gdb_ptr_type) != TYPE_CODE_PTR) error (_("Type of \"%s\" is not a pointer"), COMPILE_I_EXPR_PTR_TYPE); gdb_type_from_ptr = TYPE_TARGET_TYPE (gdb_ptr_type); if (types_deeply_equal (gdb_type, gdb_type_from_ptr)) { if (scope != COMPILE_I_PRINT_ADDRESS_SCOPE) error (_("Expected address scope in compiled module \"%s\"."), objfile_name (objfile)); return gdb_type; } if (TYPE_CODE (gdb_type) != TYPE_CODE_PTR) error (_("Invalid type code %d of symbol \"%s\" " "in compiled module \"%s\"."), TYPE_CODE (gdb_type_from_ptr), COMPILE_I_EXPR_VAL, objfile_name (objfile)); retval = gdb_type_from_ptr; switch (TYPE_CODE (gdb_type_from_ptr)) { case TYPE_CODE_ARRAY: gdb_type_from_ptr = TYPE_TARGET_TYPE (gdb_type_from_ptr); break; case TYPE_CODE_FUNC: break; default: error (_("Invalid type code %d of symbol \"%s\" " "in compiled module \"%s\"."), TYPE_CODE (gdb_type_from_ptr), COMPILE_I_EXPR_PTR_TYPE, objfile_name (objfile)); } if (!types_deeply_equal (gdb_type_from_ptr, TYPE_TARGET_TYPE (gdb_type))) error (_("Referenced types do not match for symbols \"%s\" and \"%s\" " "in compiled module \"%s\"."), COMPILE_I_EXPR_PTR_TYPE, COMPILE_I_EXPR_VAL, objfile_name (objfile)); if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE) return NULL; return retval; }
struct blockvector * blockvector_for_pc_sect (CORE_ADDR pc, struct bfd_section *section, int *pindex, struct symtab *symtab) { struct block *b; struct block *static_block; int bot, top, half; struct blockvector *bl; if (pindex) *pindex = 0; /* APPLE LOCAL begin cache lookup values for improved performance */ if ((pc == last_blockvector_lookup_pc) && (pc == last_mapped_section_lookup_pc) && (section == cached_mapped_section) && cached_blockvector && (pindex != NULL)) { *pindex = cached_blockvector_index; return cached_blockvector; } last_blockvector_lookup_pc = pc; /* APPLE LOCAL end cache lookup values for improved performance */ if (symtab == 0) /* if no symtab specified by caller */ { /* First search all symtabs for one whose file contains our pc */ symtab = find_pc_sect_symtab (pc, section); if (symtab == 0) /* APPLE LOCAL begin cache lookup values for improved performance */ { cached_blockvector_index = -1; cached_blockvector = NULL; return 0; } /* APPLE LOCAL end cache lookup values for improved performance */ } bl = BLOCKVECTOR(symtab); static_block = BLOCKVECTOR_BLOCK(bl, STATIC_BLOCK); b = BLOCKVECTOR_BLOCK(bl, 0); gdb_assert(b != NULL); /* Then search that symtab for the smallest block that wins. */ /* Use binary search to find the last block that starts before PC. */ bot = 0; top = BLOCKVECTOR_NBLOCKS(bl); while (top - bot > 1) { half = (top - bot + 1) >> 1; b = BLOCKVECTOR_BLOCK(bl, (bot + half)); /* APPLE LOCAL begin address ranges */ if (BLOCK_LOWEST_PC(b) <= pc) /* APPLE LOCAL end address ranges */ bot += half; else top = bot + half; } /* APPLE LOCAL We start with the block whose start/end address is higher than PC. */ /* Now search backward for a block that ends after PC. */ /* APPLE LOCAL: Stop at the first local block; i.e. don't iterate down to the global/static blocks. */ while (bot >= FIRST_LOCAL_BLOCK) { b = BLOCKVECTOR_BLOCK(bl, bot); /* APPLE LOCAL begin address ranges */ /* This condition is a little tricky. Given a function like func () { { subblock} // pc here } BOT may be pointing to "subblock" and so the BOT block start/end addrs are less than PC. But we don't want to terminate the search in this case - we need to keep iterating backwards to find "func"'s block. So I'm trying to restrict this to only quit searching if we're looking at a function's overall scope and both its highest/lowest addresses are lower than PC. */ if (BLOCK_SUPERBLOCK (b) == static_block && BLOCK_LOWEST_PC (b) < pc && BLOCK_HIGHEST_PC (b) < pc) /* APPLE LOCAL begin cache lookup values for improved performance */ { cached_blockvector_index = -1; cached_blockvector = NULL; return 0; } /* APPLE LOCAL end cache lookup values for improved performance */ if (block_contains_pc(b, pc)) /* APPLE LOCAL end address ranges */ { if (pindex) *pindex = bot; /* APPLE LOCAL begom cache lookup values for improved performance */ cached_blockvector_index = bot; cached_blockvector = bl; /* APPLE LOCAL end cache lookup values for improved performance */ return bl; } bot--; } /* APPLE LOCAL begin cache lookup values for improved performance */ cached_blockvector_index = -1; cached_blockvector = NULL; /* APPLE LOCAL end cache lookup values for improved performance */ return 0; }
struct blockvector * blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section, struct block **pblock, struct symtab *symtab) { struct block *b; int bot, top, half; struct blockvector *bl; if (symtab == 0) /* if no symtab specified by caller */ { /* First search all symtabs for one whose file contains our pc */ symtab = find_pc_sect_symtab (pc, section); if (symtab == 0) return 0; } bl = BLOCKVECTOR (symtab); /* Then search that symtab for the smallest block that wins. */ /* If we have an addrmap mapping code addresses to blocks, then use that. */ if (BLOCKVECTOR_MAP (bl)) { b = addrmap_find (BLOCKVECTOR_MAP (bl), pc); if (b) { if (pblock) *pblock = b; return bl; } else return 0; } /* Otherwise, use binary search to find the last block that starts before PC. */ bot = 0; top = BLOCKVECTOR_NBLOCKS (bl); while (top - bot > 1) { half = (top - bot + 1) >> 1; b = BLOCKVECTOR_BLOCK (bl, bot + half); if (BLOCK_START (b) <= pc) bot += half; else top = bot + half; } /* Now search backward for a block that ends after PC. */ while (bot >= 0) { b = BLOCKVECTOR_BLOCK (bl, bot); if (BLOCK_END (b) > pc) { if (pblock) *pblock = b; return bl; } bot--; } return 0; }