LONGEST value_ptrdiff (struct value *arg1, struct value *arg2) { struct type *type1, *type2; LONGEST sz; arg1 = coerce_array (arg1); arg2 = coerce_array (arg2); type1 = check_typedef (value_type (arg1)); type2 = check_typedef (value_type (arg2)); gdb_assert (TYPE_CODE (type1) == TYPE_CODE_PTR); gdb_assert (TYPE_CODE (type2) == TYPE_CODE_PTR); if (TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))) != TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type2)))) error (_("First argument of `-' is a pointer and " "second argument is neither\n" "an integer nor a pointer of the same type.")); sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))); if (sz == 0) { warning (_("Type size unknown, assuming 1. " "Try casting to a known type, or void *.")); sz = 1; } return (value_as_long (arg1) - value_as_long (arg2)) / sz; }
/* Obtain argument values for binary operation, converting from other types if one of them is not floating point. */ static void value_args_as_target_float (struct value *arg1, struct value *arg2, gdb_byte *x, struct type **eff_type_x, gdb_byte *y, struct type **eff_type_y) { struct type *type1, *type2; type1 = check_typedef (value_type (arg1)); type2 = check_typedef (value_type (arg2)); /* At least one of the arguments must be of floating-point type. */ gdb_assert (is_floating_type (type1) || is_floating_type (type2)); if (is_floating_type (type1) && is_floating_type (type2) && TYPE_CODE (type1) != TYPE_CODE (type2)) /* The DFP extension to the C language does not allow mixing of * decimal float types with other float types in expressions * (see WDTR 24732, page 12). */ error (_("Mixing decimal floating types with " "other floating types is not allowed.")); /* Obtain value of arg1, converting from other types if necessary. */ if (is_floating_type (type1)) { *eff_type_x = type1; memcpy (x, value_contents (arg1), TYPE_LENGTH (type1)); } else if (is_integral_type (type1)) { *eff_type_x = type2; if (TYPE_UNSIGNED (type1)) target_float_from_ulongest (x, *eff_type_x, value_as_long (arg1)); else target_float_from_longest (x, *eff_type_x, value_as_long (arg1)); } else error (_("Don't know how to convert from %s to %s."), TYPE_NAME (type1), TYPE_NAME (type2)); /* Obtain value of arg2, converting from other types if necessary. */ if (is_floating_type (type2)) { *eff_type_y = type2; memcpy (y, value_contents (arg2), TYPE_LENGTH (type2)); } else if (is_integral_type (type2)) { *eff_type_y = type1; if (TYPE_UNSIGNED (type2)) target_float_from_ulongest (y, *eff_type_y, value_as_long (arg2)); else target_float_from_longest (y, *eff_type_y, value_as_long (arg2)); } else error (_("Don't know how to convert from %s to %s."), TYPE_NAME (type1), TYPE_NAME (type2)); }
CORE_ADDR lookup_child_selector (struct gdbarch *gdbarch, char *selname) { struct type *char_type = builtin_type (gdbarch)->builtin_char; struct value * function, *selstring; if (! target_has_execution) { /* Can't call into inferior to lookup selector. */ return 0; } if (lookup_minimal_symbol("sel_getUid", 0, 0).minsym) function = find_function_in_inferior("sel_getUid", NULL); else if (lookup_minimal_symbol ("sel_get_any_uid", 0, 0).minsym) function = find_function_in_inferior("sel_get_any_uid", NULL); else { complaint (&symfile_complaints, _("no way to lookup Objective-C selectors")); return 0; } selstring = value_coerce_array (value_string (selname, strlen (selname) + 1, char_type)); return value_as_long (call_function_by_hand (function, 1, &selstring)); }
/* Use inferior's dlopen() to bring in some helper functions: */ void load_helpers(void) { struct value *dlfn, *args[2], *val; long rslt; args[0] = value_string(LIBCHECKPOINT_NAME, (strlen(LIBCHECKPOINT_NAME) + 1UL)); args[0] = value_coerce_array(args[0]); args[1] = value_from_longest(builtin_type_int, (LONGEST)RTLD_NOW); if (lookup_minimal_symbol("dlopen", 0, 0) && (dlfn = find_function_in_inferior("dlopen", builtin_type_int))) { val = call_function_by_hand_expecting_type(dlfn, builtin_type_int, 2, args, 1); rslt = (long)value_as_long(val); if (rslt == 0) warning("dlopen of checkpoint library returned NULL"); } else { warning("dlopen not found, libcheckpoint functions not loaded"); } }
CORE_ADDR lookup_objc_class (struct gdbarch *gdbarch, char *classname) { struct type *char_type = builtin_type (gdbarch)->builtin_char; struct value * function, *classval; if (! target_has_execution) { /* Can't call into inferior to lookup class. */ return 0; } if (lookup_minimal_symbol("objc_lookUpClass", 0, 0).minsym) function = find_function_in_inferior("objc_lookUpClass", NULL); else if (lookup_minimal_symbol ("objc_lookup_class", 0, 0).minsym) function = find_function_in_inferior("objc_lookup_class", NULL); else { complaint (&symfile_complaints, _("no way to lookup Objective-C classes")); return 0; } classval = value_string (classname, strlen (classname) + 1, char_type); classval = value_coerce_array (classval); return (CORE_ADDR) value_as_long (call_function_by_hand (function, 1, &classval)); }
static struct value * m88k_frame_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct m88k_frame_cache *cache = m88k_frame_cache (this_frame, this_cache); if (regnum == M88K_SNIP_REGNUM || regnum == M88K_SFIP_REGNUM) { struct value *value; CORE_ADDR pc; value = trad_frame_get_prev_register (this_frame, cache->saved_regs, M88K_SXIP_REGNUM); pc = value_as_long (value); release_value (value); value_free (value); if (regnum == M88K_SFIP_REGNUM) pc += 4; return frame_unwind_got_constant (this_frame, regnum, pc + 4); } return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum); }
char * get_java_utf8_name (struct obstack *obstack, struct value *name) { char *chrs; struct value *temp = name; int name_length; CORE_ADDR data_addr; temp = value_struct_elt (&temp, NULL, "length", NULL, "structure"); name_length = (int) value_as_long (temp); data_addr = value_address (temp) + TYPE_LENGTH (value_type (temp)); chrs = obstack_alloc (obstack, name_length + 1); chrs[name_length] = '\0'; read_memory (data_addr, (gdb_byte *) chrs, name_length); return chrs; }
static int gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr, int embedded_offset, CORE_ADDR address, const struct value *val) { struct gdbarch *gdbarch; struct type *ptr_type; struct value *vtable; struct value *vbase_array; long int cur_base_offset, base_offset; /* Determine architecture. */ gdbarch = get_type_arch (type); ptr_type = builtin_type (gdbarch)->builtin_data_ptr; /* If it isn't a virtual base, this is easy. The offset is in the type definition. Likewise for Java, which doesn't really have virtual inheritance in the C++ sense. */ if (!BASETYPE_VIA_VIRTUAL (type, index) || TYPE_CPLUS_REALLY_JAVA (type)) return TYPE_BASECLASS_BITPOS (type, index) / 8; /* To access a virtual base, we need to use the vbase offset stored in our vtable. Recent GCC versions provide this information. If it isn't available, we could get what we needed from RTTI, or from drawing the complete inheritance graph based on the debug info. Neither is worthwhile. */ cur_base_offset = TYPE_BASECLASS_BITPOS (type, index) / 8; if (cur_base_offset >= - vtable_address_point_offset (gdbarch)) error (_("Expected a negative vbase offset (old compiler?)")); cur_base_offset = cur_base_offset + vtable_address_point_offset (gdbarch); if ((- cur_base_offset) % TYPE_LENGTH (ptr_type) != 0) error (_("Misaligned vbase offset.")); cur_base_offset = cur_base_offset / ((int) TYPE_LENGTH (ptr_type)); vtable = gnuv3_get_vtable (gdbarch, type, address + embedded_offset); gdb_assert (vtable != NULL); vbase_array = value_field (vtable, vtable_field_vcall_and_vbase_offsets); base_offset = value_as_long (value_subscript (vbase_array, cur_base_offset)); return base_offset; }
static bfd_vma call_target_sbrk (int sbrk_arg) { struct objfile *sbrk_objf; struct gdbarch *gdbarch; bfd_vma top_of_heap; struct value *target_sbrk_arg; struct value *sbrk_fn, *ret; bfd_vma tmp; if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL) { sbrk_fn = find_function_in_inferior ("sbrk", &sbrk_objf); if (sbrk_fn == NULL) return (bfd_vma) 0; } else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL) { sbrk_fn = find_function_in_inferior ("_sbrk", &sbrk_objf); if (sbrk_fn == NULL) return (bfd_vma) 0; } else return (bfd_vma) 0; gdbarch = get_objfile_arch (sbrk_objf); target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int, sbrk_arg); gdb_assert (target_sbrk_arg); ret = call_function_by_hand (sbrk_fn, 1, &target_sbrk_arg); if (ret == NULL) return (bfd_vma) 0; tmp = value_as_long (ret); if ((LONGEST) tmp <= 0 || (LONGEST) tmp == 0xffffffff) return (bfd_vma) 0; top_of_heap = tmp; return top_of_heap; }
static int derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top) { bfd_vma top_of_data_memory = 0; bfd_vma top_of_heap = 0; bfd_size_type sec_size; struct value *zero, *sbrk; bfd_vma sec_vaddr; asection *sec; gdb_assert (bottom); gdb_assert (top); /* This function depends on being able to call a function in the inferior. */ if (!target_has_execution) return 0; /* The following code assumes that the link map is arranged as follows (low to high addresses): --------------------------------- | text sections | --------------------------------- | data sections (including bss) | --------------------------------- | heap | --------------------------------- */ for (sec = abfd->sections; sec; sec = sec->next) { if (bfd_get_section_flags (abfd, sec) & SEC_DATA || strcmp (".bss", bfd_section_name (abfd, sec)) == 0) { sec_vaddr = bfd_get_section_vma (abfd, sec); sec_size = bfd_get_section_size (sec); if (sec_vaddr + sec_size > top_of_data_memory) top_of_data_memory = sec_vaddr + sec_size; } } /* Now get the top-of-heap by calling sbrk in the inferior. */ if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL) { sbrk = find_function_in_inferior ("sbrk"); if (sbrk == NULL) return 0; } else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL) { sbrk = find_function_in_inferior ("_sbrk"); if (sbrk == NULL) return 0; } else return 0; zero = value_from_longest (builtin_type_int, 0); gdb_assert (zero); sbrk = call_function_by_hand (sbrk, 1, &zero); if (sbrk == NULL) return 0; top_of_heap = value_as_long (sbrk); /* Return results. */ if (top_of_heap > top_of_data_memory) { *bottom = top_of_data_memory; *top = top_of_heap; return 1; } /* No additional heap space needs to be saved. */ return 0; }
static void parse_find_args (char *args, ULONGEST *max_countp, char **pattern_bufp, ULONGEST *pattern_lenp, CORE_ADDR *start_addrp, ULONGEST *search_space_lenp, bfd_boolean big_p) { /* Default to using the specified type. */ char size = '\0'; ULONGEST max_count = ~(ULONGEST) 0; /* Buffer to hold the search pattern. */ char *pattern_buf; /* Current size of search pattern buffer. We realloc space as needed. */ #define INITIAL_PATTERN_BUF_SIZE 100 ULONGEST pattern_buf_size = INITIAL_PATTERN_BUF_SIZE; /* Pointer to one past the last in-use part of pattern_buf. */ char *pattern_buf_end; ULONGEST pattern_len; CORE_ADDR start_addr; ULONGEST search_space_len; char *s = args; struct cleanup *old_cleanups; struct value *v; if (args == NULL) error (_("Missing search parameters.")); pattern_buf = xmalloc (pattern_buf_size); pattern_buf_end = pattern_buf; old_cleanups = make_cleanup (free_current_contents, &pattern_buf); /* Get search granularity and/or max count if specified. They may be specified in either order, together or separately. */ while (*s == '/') { ++s; while (*s != '\0' && *s != '/' && !isspace (*s)) { if (isdigit (*s)) { max_count = atoi (s); while (isdigit (*s)) ++s; continue; } switch (*s) { case 'b': case 'h': case 'w': case 'g': size = *s++; break; default: error (_("Invalid size granularity.")); } } while (isspace (*s)) ++s; } /* Get the search range. */ v = parse_to_comma_and_eval (&s); start_addr = value_as_address (v); if (*s == ',') ++s; while (isspace (*s)) ++s; if (*s == '+') { LONGEST len; ++s; v = parse_to_comma_and_eval (&s); len = value_as_long (v); if (len == 0) { printf_filtered (_("Empty search range.\n")); return; } if (len < 0) error (_("Invalid length.")); /* Watch for overflows. */ if (len > CORE_ADDR_MAX || (start_addr + len - 1) < start_addr) error (_("Search space too large.")); search_space_len = len; } else { CORE_ADDR end_addr; v = parse_to_comma_and_eval (&s); end_addr = value_as_address (v); if (start_addr > end_addr) error (_("Invalid search space, end preceeds start.")); search_space_len = end_addr - start_addr + 1; /* We don't support searching all of memory (i.e. start=0, end = 0xff..ff). Bail to avoid overflows later on. */ if (search_space_len == 0) error (_("Overflow in address range computation, choose smaller range.")); } if (*s == ',') ++s; /* Fetch the search string. */ while (*s != '\0') { LONGEST x; int val_bytes; while (isspace (*s)) ++s; v = parse_to_comma_and_eval (&s); val_bytes = TYPE_LENGTH (value_type (v)); /* Keep it simple and assume size == 'g' when watching for when we need to grow the pattern buf. */ if ((pattern_buf_end - pattern_buf + max (val_bytes, sizeof (int64_t))) > pattern_buf_size) { size_t current_offset = pattern_buf_end - pattern_buf; pattern_buf_size *= 2; pattern_buf = xrealloc (pattern_buf, pattern_buf_size); pattern_buf_end = pattern_buf + current_offset; } if (size != '\0') { x = value_as_long (v); switch (size) { case 'b': *pattern_buf_end++ = x; break; case 'h': put_bits (x, pattern_buf_end, 16, big_p); pattern_buf_end += sizeof (int16_t); break; case 'w': put_bits (x, pattern_buf_end, 32, big_p); pattern_buf_end += sizeof (int32_t); break; case 'g': put_bits (x, pattern_buf_end, 64, big_p); pattern_buf_end += sizeof (int64_t); break; } } else { memcpy (pattern_buf_end, value_contents_raw (v), val_bytes); pattern_buf_end += val_bytes; } if (*s == ',') ++s; while (isspace (*s)) ++s; } if (pattern_buf_end == pattern_buf) error (_("Missing search pattern.")); pattern_len = pattern_buf_end - pattern_buf; if (search_space_len < pattern_len) error (_("Search space too small to contain pattern.")); *max_countp = max_count; *pattern_bufp = pattern_buf; *pattern_lenp = pattern_len; *start_addrp = start_addr; *search_space_lenp = search_space_len; /* We successfully parsed the arguments, leave the freeing of PATTERN_BUF to the caller now. */ discard_cleanups (old_cleanups); }
static int get_number_trailer (char **pp, int trailer) { int retval = 0; /* default */ char *p = *pp; if (*p == '$') { struct value *val = value_from_history_ref (p, &p); if (val) /* Value history reference */ { if (TYPE_CODE (value_type (val)) == TYPE_CODE_INT) retval = value_as_long (val); else { printf_filtered (_("History value must have integer type.")); retval = 0; } } else /* Convenience variable */ { /* Internal variable. Make a copy of the name, so we can null-terminate it to pass to lookup_internalvar(). */ char *varname; char *start = ++p; LONGEST val; while (isalnum (*p) || *p == '_') p++; varname = (char *) alloca (p - start + 1); strncpy (varname, start, p - start); varname[p - start] = '\0'; if (get_internalvar_integer (lookup_internalvar (varname), &val)) retval = (int) val; else { printf_filtered (_("Convenience variable must " "have integer value.\n")); retval = 0; } } } else { if (*p == '-') ++p; while (*p >= '0' && *p <= '9') ++p; if (p == *pp) /* There is no number here. (e.g. "cond a == b"). */ { /* Skip non-numeric token. */ while (*p && !isspace((int) *p)) ++p; /* Return zero, which caller must interpret as error. */ retval = 0; } else retval = atoi (*pp); } if (!(isspace (*p) || *p == '\0' || *p == trailer)) { /* Trailing junk: return 0 and let caller print error msg. */ while (!(isspace (*p) || *p == '\0' || *p == trailer)) ++p; retval = 0; } p = skip_spaces (p); *pp = p; return retval; }
static struct value * scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) { struct value *val; struct type *type1, *type2, *result_type; arg1 = coerce_ref (arg1); arg2 = coerce_ref (arg2); type1 = check_typedef (value_type (arg1)); type2 = check_typedef (value_type (arg2)); if ((!is_floating_value (arg1) && !is_integral_type (type1)) || (!is_floating_value (arg2) && !is_integral_type (type2))) error (_("Argument to arithmetic operation not a number or boolean.")); if (is_floating_type (type1) || is_floating_type (type2)) { /* If only one type is floating-point, use its type. Otherwise use the bigger type. */ if (!is_floating_type (type1)) result_type = type2; else if (!is_floating_type (type2)) result_type = type1; else if (TYPE_LENGTH (type2) > TYPE_LENGTH (type1)) result_type = type2; else result_type = type1; val = allocate_value (result_type); struct type *eff_type_v1, *eff_type_v2; gdb::byte_vector v1, v2; v1.resize (TYPE_LENGTH (result_type)); v2.resize (TYPE_LENGTH (result_type)); value_args_as_target_float (arg1, arg2, v1.data (), &eff_type_v1, v2.data (), &eff_type_v2); target_float_binop (op, v1.data (), eff_type_v1, v2.data (), eff_type_v2, value_contents_raw (val), result_type); } else if (TYPE_CODE (type1) == TYPE_CODE_BOOL || TYPE_CODE (type2) == TYPE_CODE_BOOL) { LONGEST v1, v2, v = 0; v1 = value_as_long (arg1); v2 = value_as_long (arg2); switch (op) { case BINOP_BITWISE_AND: v = v1 & v2; break; case BINOP_BITWISE_IOR: v = v1 | v2; break; case BINOP_BITWISE_XOR: v = v1 ^ v2; break; case BINOP_EQUAL: v = v1 == v2; break; case BINOP_NOTEQUAL: v = v1 != v2; break; default: error (_("Invalid operation on booleans.")); } result_type = type1; val = allocate_value (result_type); store_signed_integer (value_contents_raw (val), TYPE_LENGTH (result_type), gdbarch_byte_order (get_type_arch (result_type)), v); } else /* Integral operations here. */ { /* Determine type length of the result, and if the operation should be done unsigned. For exponentiation and shift operators, use the length and type of the left operand. Otherwise, use the signedness of the operand with the greater length. If both operands are of equal length, use unsigned operation if one of the operands is unsigned. */ if (op == BINOP_RSH || op == BINOP_LSH || op == BINOP_EXP) result_type = type1; else if (TYPE_LENGTH (type1) > TYPE_LENGTH (type2)) result_type = type1; else if (TYPE_LENGTH (type2) > TYPE_LENGTH (type1)) result_type = type2; else if (TYPE_UNSIGNED (type1)) result_type = type1; else if (TYPE_UNSIGNED (type2)) result_type = type2; else result_type = type1; if (TYPE_UNSIGNED (result_type)) { LONGEST v2_signed = value_as_long (arg2); ULONGEST v1, v2, v = 0; v1 = (ULONGEST) value_as_long (arg1); v2 = (ULONGEST) v2_signed; switch (op) { case BINOP_ADD: v = v1 + v2; break; case BINOP_SUB: v = v1 - v2; break; case BINOP_MUL: v = v1 * v2; break; case BINOP_DIV: case BINOP_INTDIV: if (v2 != 0) v = v1 / v2; else error (_("Division by zero")); break; case BINOP_EXP: v = uinteger_pow (v1, v2_signed); break; case BINOP_REM: if (v2 != 0) v = v1 % v2; else error (_("Division by zero")); break; case BINOP_MOD: /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, v1 mod 0 has a defined value, v1. */ if (v2 == 0) { v = v1; } else { v = v1 / v2; /* Note floor(v1/v2) == v1/v2 for unsigned. */ v = v1 - (v2 * v); } break; case BINOP_LSH: v = v1 << v2; break; case BINOP_RSH: v = v1 >> v2; break; case BINOP_BITWISE_AND: v = v1 & v2; break; case BINOP_BITWISE_IOR: v = v1 | v2; break; case BINOP_BITWISE_XOR: v = v1 ^ v2; break; case BINOP_LOGICAL_AND: v = v1 && v2; break; case BINOP_LOGICAL_OR: v = v1 || v2; break; case BINOP_MIN: v = v1 < v2 ? v1 : v2; break; case BINOP_MAX: v = v1 > v2 ? v1 : v2; break; case BINOP_EQUAL: v = v1 == v2; break; case BINOP_NOTEQUAL: v = v1 != v2; break; case BINOP_LESS: v = v1 < v2; break; case BINOP_GTR: v = v1 > v2; break; case BINOP_LEQ: v = v1 <= v2; break; case BINOP_GEQ: v = v1 >= v2; break; default: error (_("Invalid binary operation on numbers.")); } val = allocate_value (result_type); store_unsigned_integer (value_contents_raw (val), TYPE_LENGTH (value_type (val)), gdbarch_byte_order (get_type_arch (result_type)), v); } else { LONGEST v1, v2, v = 0; v1 = value_as_long (arg1); v2 = value_as_long (arg2); switch (op) { case BINOP_ADD: v = v1 + v2; break; case BINOP_SUB: v = v1 - v2; break; case BINOP_MUL: v = v1 * v2; break; case BINOP_DIV: case BINOP_INTDIV: if (v2 != 0) v = v1 / v2; else error (_("Division by zero")); break; case BINOP_EXP: v = integer_pow (v1, v2); break; case BINOP_REM: if (v2 != 0) v = v1 % v2; else error (_("Division by zero")); break; case BINOP_MOD: /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, X mod 0 has a defined value, X. */ if (v2 == 0) { v = v1; } else { v = v1 / v2; /* Compute floor. */ if (TRUNCATION_TOWARDS_ZERO && (v < 0) && ((v1 % v2) != 0)) { v--; } v = v1 - (v2 * v); } break; case BINOP_LSH: v = v1 << v2; break; case BINOP_RSH: v = v1 >> v2; break; case BINOP_BITWISE_AND: v = v1 & v2; break; case BINOP_BITWISE_IOR: v = v1 | v2; break; case BINOP_BITWISE_XOR: v = v1 ^ v2; break; case BINOP_LOGICAL_AND: v = v1 && v2; break; case BINOP_LOGICAL_OR: v = v1 || v2; break; case BINOP_MIN: v = v1 < v2 ? v1 : v2; break; case BINOP_MAX: v = v1 > v2 ? v1 : v2; break; case BINOP_EQUAL: v = v1 == v2; break; case BINOP_NOTEQUAL: v = v1 != v2; break; case BINOP_LESS: v = v1 < v2; break; case BINOP_GTR: v = v1 > v2; break; case BINOP_LEQ: v = v1 <= v2; break; case BINOP_GEQ: v = v1 >= v2; break; default: error (_("Invalid binary operation on numbers.")); } val = allocate_value (result_type); store_signed_integer (value_contents_raw (val), TYPE_LENGTH (value_type (val)), gdbarch_byte_order (get_type_arch (result_type)), v); } }
struct type * type_from_class (struct gdbarch *gdbarch, struct value *clas) { struct type *type; char *name; struct value *temp; struct objfile *objfile; struct value *utf8_name; char *nptr; CORE_ADDR addr; type = check_typedef (value_type (clas)); if (TYPE_CODE (type) == TYPE_CODE_PTR) { if (value_logical_not (clas)) return NULL; clas = value_ind (clas); } addr = value_address (clas); objfile = get_dynamics_objfile (gdbarch); if (java_class_is_primitive (clas)) { struct value *sig; temp = clas; sig = value_struct_elt (&temp, NULL, "method_count", NULL, "structure"); return java_primitive_type (gdbarch, value_as_long (sig)); } /* Get Class name. */ /* If clasloader non-null, prepend loader address. FIXME */ temp = clas; utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure"); name = get_java_utf8_name (&objfile->objfile_obstack, utf8_name); for (nptr = name; *nptr != 0; nptr++) { if (*nptr == '/') *nptr = '.'; } type = java_lookup_class (name); if (type != NULL) return type; type = alloc_type (objfile); TYPE_CODE (type) = TYPE_CODE_STRUCT; INIT_CPLUS_SPECIFIC (type); if (name[0] == '[') { char *signature = name; int namelen = java_demangled_signature_length (signature); if (namelen > strlen (name)) name = obstack_alloc (&objfile->objfile_obstack, namelen + 1); java_demangled_signature_copy (name, signature); name[namelen] = '\0'; temp = clas; /* Set array element type. */ temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure"); deprecated_set_value_type (temp, lookup_pointer_type (value_type (clas))); TYPE_TARGET_TYPE (type) = type_from_class (gdbarch, temp); } ALLOCATE_CPLUS_STRUCT_TYPE (type); TYPE_TAG_NAME (type) = name; add_class_symtab_symbol (add_class_symbol (type, addr)); return java_link_class_type (gdbarch, type, clas); }
static void execute_stack_op (struct dwarf_expr_context *ctx, gdb_byte *op_ptr, gdb_byte *op_end) { enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch); ctx->location = DWARF_VALUE_MEMORY; ctx->initialized = 1; /* Default is initialized. */ if (ctx->recursion_depth > ctx->max_recursion_depth) error (_("DWARF-2 expression error: Loop detected (%d)."), ctx->recursion_depth); ctx->recursion_depth++; while (op_ptr < op_end) { enum dwarf_location_atom op = *op_ptr++; CORE_ADDR result; /* Assume the value is not in stack memory. Code that knows otherwise sets this to 1. Some arithmetic on stack addresses can probably be assumed to still be a stack address, but we skip this complication for now. This is just an optimization, so it's always ok to punt and leave this as 0. */ int in_stack_memory = 0; ULONGEST uoffset, reg; LONGEST offset; switch (op) { case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: result = op - DW_OP_lit0; break; case DW_OP_addr: result = dwarf2_read_address (ctx->gdbarch, op_ptr, op_end, ctx->addr_size); op_ptr += ctx->addr_size; break; case DW_OP_const1u: result = extract_unsigned_integer (op_ptr, 1, byte_order); op_ptr += 1; break; case DW_OP_const1s: result = extract_signed_integer (op_ptr, 1, byte_order); op_ptr += 1; break; case DW_OP_const2u: result = extract_unsigned_integer (op_ptr, 2, byte_order); op_ptr += 2; break; case DW_OP_const2s: result = extract_signed_integer (op_ptr, 2, byte_order); op_ptr += 2; break; case DW_OP_const4u: result = extract_unsigned_integer (op_ptr, 4, byte_order); op_ptr += 4; break; case DW_OP_const4s: result = extract_signed_integer (op_ptr, 4, byte_order); op_ptr += 4; break; case DW_OP_const8u: result = extract_unsigned_integer (op_ptr, 8, byte_order); op_ptr += 8; break; case DW_OP_const8s: result = extract_signed_integer (op_ptr, 8, byte_order); op_ptr += 8; break; case DW_OP_constu: op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); result = uoffset; break; case DW_OP_consts: op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = offset; break; /* The DW_OP_reg operations are required to occur alone in location expressions. */ case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: if (op_ptr != op_end && *op_ptr != DW_OP_piece && *op_ptr != DW_OP_GNU_uninit) error (_("DWARF-2 expression error: DW_OP_reg operations must be " "used either alone or in conjuction with DW_OP_piece.")); result = op - DW_OP_reg0; ctx->location = DWARF_VALUE_REGISTER; break; case DW_OP_regx: op_ptr = read_uleb128 (op_ptr, op_end, ®); require_composition (op_ptr, op_end, "DW_OP_regx"); result = reg; ctx->location = DWARF_VALUE_REGISTER; break; case DW_OP_implicit_value: { ULONGEST len; op_ptr = read_uleb128 (op_ptr, op_end, &len); if (op_ptr + len > op_end) error (_("DW_OP_implicit_value: too few bytes available.")); ctx->len = len; ctx->data = op_ptr; ctx->location = DWARF_VALUE_LITERAL; op_ptr += len; require_composition (op_ptr, op_end, "DW_OP_implicit_value"); } goto no_push; case DW_OP_stack_value: ctx->location = DWARF_VALUE_STACK; require_composition (op_ptr, op_end, "DW_OP_stack_value"); goto no_push; case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: { op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0); result += offset; } break; case DW_OP_bregx: { op_ptr = read_uleb128 (op_ptr, op_end, ®); op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = (ctx->read_reg) (ctx->baton, reg); result += offset; } break; case DW_OP_fbreg: { gdb_byte *datastart; size_t datalen; unsigned int before_stack_len; op_ptr = read_sleb128 (op_ptr, op_end, &offset); /* Rather than create a whole new context, we simply record the stack length before execution, then reset it afterwards, effectively erasing whatever the recursive call put there. */ before_stack_len = ctx->stack_len; /* FIXME: cagney/2003-03-26: This code should be using get_frame_base_address(), and then implement a dwarf2 specific this_base method. */ (ctx->get_frame_base) (ctx->baton, &datastart, &datalen); dwarf_expr_eval (ctx, datastart, datalen); if (ctx->location == DWARF_VALUE_LITERAL || ctx->location == DWARF_VALUE_STACK) error (_("Not implemented: computing frame base using explicit value operator")); result = dwarf_expr_fetch (ctx, 0); if (ctx->location == DWARF_VALUE_REGISTER) result = (ctx->read_reg) (ctx->baton, result); result = result + offset; in_stack_memory = 1; ctx->stack_len = before_stack_len; ctx->location = DWARF_VALUE_MEMORY; } break; case DW_OP_dup: result = dwarf_expr_fetch (ctx, 0); in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); break; case DW_OP_drop: dwarf_expr_pop (ctx); goto no_push; case DW_OP_pick: offset = *op_ptr++; result = dwarf_expr_fetch (ctx, offset); in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, offset); break; case DW_OP_swap: { struct dwarf_stack_value t1, t2; if (ctx->stack_len < 2) error (_("Not enough elements for DW_OP_swap. Need 2, have %d."), ctx->stack_len); t1 = ctx->stack[ctx->stack_len - 1]; t2 = ctx->stack[ctx->stack_len - 2]; ctx->stack[ctx->stack_len - 1] = t2; ctx->stack[ctx->stack_len - 2] = t1; goto no_push; } case DW_OP_over: result = dwarf_expr_fetch (ctx, 1); in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 1); break; case DW_OP_rot: { struct dwarf_stack_value t1, t2, t3; if (ctx->stack_len < 3) error (_("Not enough elements for DW_OP_rot. Need 3, have %d."), ctx->stack_len); t1 = ctx->stack[ctx->stack_len - 1]; t2 = ctx->stack[ctx->stack_len - 2]; t3 = ctx->stack[ctx->stack_len - 3]; ctx->stack[ctx->stack_len - 1] = t2; ctx->stack[ctx->stack_len - 2] = t3; ctx->stack[ctx->stack_len - 3] = t1; goto no_push; } case DW_OP_deref: case DW_OP_deref_size: case DW_OP_abs: case DW_OP_neg: case DW_OP_not: case DW_OP_plus_uconst: /* Unary operations. */ result = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); switch (op) { case DW_OP_deref: { gdb_byte *buf = alloca (ctx->addr_size); (ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size); result = dwarf2_read_address (ctx->gdbarch, buf, buf + ctx->addr_size, ctx->addr_size); } break; case DW_OP_deref_size: { int addr_size = *op_ptr++; gdb_byte *buf = alloca (addr_size); (ctx->read_mem) (ctx->baton, buf, result, addr_size); result = dwarf2_read_address (ctx->gdbarch, buf, buf + addr_size, addr_size); } break; case DW_OP_abs: if ((signed int) result < 0) result = -result; break; case DW_OP_neg: result = -result; break; case DW_OP_not: result = ~result; break; case DW_OP_plus_uconst: op_ptr = read_uleb128 (op_ptr, op_end, ®); result += reg; break; } break; case DW_OP_and: case DW_OP_div: case DW_OP_minus: case DW_OP_mod: case DW_OP_mul: case DW_OP_or: case DW_OP_plus: case DW_OP_shl: case DW_OP_shr: case DW_OP_shra: case DW_OP_xor: case DW_OP_le: case DW_OP_ge: case DW_OP_eq: case DW_OP_lt: case DW_OP_gt: case DW_OP_ne: { /* Binary operations. Use the value engine to do computations in the right width. */ CORE_ADDR first, second; enum exp_opcode binop; struct value *val1 = NULL, *val2 = NULL; struct type *stype, *utype; second = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); first = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); utype = unsigned_address_type (ctx->gdbarch, ctx->addr_size); stype = signed_address_type (ctx->gdbarch, ctx->addr_size); switch (op) { case DW_OP_and: binop = BINOP_BITWISE_AND; break; case DW_OP_div: binop = BINOP_DIV; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_minus: binop = BINOP_SUB; break; case DW_OP_mod: binop = BINOP_MOD; break; case DW_OP_mul: binop = BINOP_MUL; break; case DW_OP_or: binop = BINOP_BITWISE_IOR; break; case DW_OP_plus: binop = BINOP_ADD; break; case DW_OP_shl: binop = BINOP_LSH; break; case DW_OP_shr: binop = BINOP_RSH; break; case DW_OP_shra: binop = BINOP_RSH; val1 = value_from_longest (stype, first); break; case DW_OP_xor: binop = BINOP_BITWISE_XOR; break; case DW_OP_le: binop = BINOP_LEQ; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_ge: binop = BINOP_GEQ; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_eq: binop = BINOP_EQUAL; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_lt: binop = BINOP_LESS; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_gt: binop = BINOP_GTR; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_ne: binop = BINOP_NOTEQUAL; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; default: internal_error (__FILE__, __LINE__, _("Can't be reached.")); } /* We use unsigned operands by default. */ if (val1 == NULL) val1 = value_from_longest (utype, first); if (val2 == NULL) val2 = value_from_longest (utype, second); result = value_as_long (value_binop (val1, val2, binop)); } break; case DW_OP_call_frame_cfa: result = (ctx->get_frame_cfa) (ctx->baton); in_stack_memory = 1; break; case DW_OP_GNU_push_tls_address: /* Variable is at a constant offset in the thread-local storage block into the objfile for the current thread and the dynamic linker module containing this expression. Here we return returns the offset from that base. The top of the stack has the offset from the beginning of the thread control block at which the variable is located. Nothing should follow this operator, so the top of stack would be returned. */ result = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); result = (ctx->get_tls_address) (ctx->baton, result); break; case DW_OP_skip: offset = extract_signed_integer (op_ptr, 2, byte_order); op_ptr += 2; op_ptr += offset; goto no_push; case DW_OP_bra: offset = extract_signed_integer (op_ptr, 2, byte_order); op_ptr += 2; if (dwarf_expr_fetch (ctx, 0) != 0) op_ptr += offset; dwarf_expr_pop (ctx); goto no_push; case DW_OP_nop: goto no_push; case DW_OP_piece: { ULONGEST size; /* Record the piece. */ op_ptr = read_uleb128 (op_ptr, op_end, &size); add_piece (ctx, size); /* Pop off the address/regnum, and reset the location type. */ if (ctx->location != DWARF_VALUE_LITERAL) dwarf_expr_pop (ctx); ctx->location = DWARF_VALUE_MEMORY; } goto no_push; case DW_OP_GNU_uninit: if (op_ptr != op_end) error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always " "be the very last op.")); ctx->initialized = 0; goto no_push; default: error (_("Unhandled dwarf expression opcode 0x%x"), op); } /* Most things push a result value. */ dwarf_expr_push (ctx, result, in_stack_memory); no_push:; } ctx->recursion_depth--; gdb_assert (ctx->recursion_depth >= 0); }
static struct value * scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) { struct value *val; struct type *type1, *type2, *result_type; arg1 = coerce_ref (arg1); arg2 = coerce_ref (arg2); type1 = check_typedef (value_type (arg1)); type2 = check_typedef (value_type (arg2)); if ((TYPE_CODE (type1) != TYPE_CODE_FLT && TYPE_CODE (type1) != TYPE_CODE_DECFLOAT && !is_integral_type (type1)) || (TYPE_CODE (type2) != TYPE_CODE_FLT && TYPE_CODE (type2) != TYPE_CODE_DECFLOAT && !is_integral_type (type2))) error (_("Argument to arithmetic operation not a number or boolean.")); if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT || TYPE_CODE (type2) == TYPE_CODE_DECFLOAT) { int len_v1, len_v2, len_v; enum bfd_endian byte_order_v1, byte_order_v2, byte_order_v; gdb_byte v1[16], v2[16]; gdb_byte v[16]; /* If only one type is decimal float, use its type. Otherwise use the bigger type. */ if (TYPE_CODE (type1) != TYPE_CODE_DECFLOAT) result_type = type2; else if (TYPE_CODE (type2) != TYPE_CODE_DECFLOAT) result_type = type1; else if (TYPE_LENGTH (type2) > TYPE_LENGTH (type1)) result_type = type2; else result_type = type1; len_v = TYPE_LENGTH (result_type); byte_order_v = gdbarch_byte_order (get_type_arch (result_type)); value_args_as_decimal (arg1, arg2, v1, &len_v1, &byte_order_v1, v2, &len_v2, &byte_order_v2); switch (op) { case BINOP_ADD: case BINOP_SUB: case BINOP_MUL: case BINOP_DIV: case BINOP_EXP: decimal_binop (op, v1, len_v1, byte_order_v1, v2, len_v2, byte_order_v2, v, len_v, byte_order_v); break; default: error (_("Operation not valid for decimal floating point number.")); } val = value_from_decfloat (result_type, v); } else if (TYPE_CODE (type1) == TYPE_CODE_FLT || TYPE_CODE (type2) == TYPE_CODE_FLT) { /* FIXME-if-picky-about-floating-accuracy: Should be doing this in target format. real.c in GCC probably has the necessary code. */ DOUBLEST v1, v2, v = 0; v1 = value_as_double (arg1); v2 = value_as_double (arg2); switch (op) { case BINOP_ADD: v = v1 + v2; break; case BINOP_SUB: v = v1 - v2; break; case BINOP_MUL: v = v1 * v2; break; case BINOP_DIV: v = v1 / v2; break; case BINOP_EXP: errno = 0; v = pow (v1, v2); if (errno) error (_("Cannot perform exponentiation: %s"), safe_strerror (errno)); break; case BINOP_MIN: v = v1 < v2 ? v1 : v2; break; case BINOP_MAX: v = v1 > v2 ? v1 : v2; break; default: error (_("Integer-only operation on floating point number.")); } /* If only one type is float, use its type. Otherwise use the bigger type. */ if (TYPE_CODE (type1) != TYPE_CODE_FLT) result_type = type2; else if (TYPE_CODE (type2) != TYPE_CODE_FLT) result_type = type1; else if (TYPE_LENGTH (type2) > TYPE_LENGTH (type1)) result_type = type2; else result_type = type1; val = allocate_value (result_type); store_typed_floating (value_contents_raw (val), value_type (val), v); } else if (TYPE_CODE (type1) == TYPE_CODE_BOOL || TYPE_CODE (type2) == TYPE_CODE_BOOL) { LONGEST v1, v2, v = 0; v1 = value_as_long (arg1); v2 = value_as_long (arg2); switch (op) { case BINOP_BITWISE_AND: v = v1 & v2; break; case BINOP_BITWISE_IOR: v = v1 | v2; break; case BINOP_BITWISE_XOR: v = v1 ^ v2; break; case BINOP_EQUAL: v = v1 == v2; break; case BINOP_NOTEQUAL: v = v1 != v2; break; default: error (_("Invalid operation on booleans.")); } result_type = type1; val = allocate_value (result_type); store_signed_integer (value_contents_raw (val), TYPE_LENGTH (result_type), gdbarch_byte_order (get_type_arch (result_type)), v); } else /* Integral operations here. */ { /* Determine type length of the result, and if the operation should be done unsigned. For exponentiation and shift operators, use the length and type of the left operand. Otherwise, use the signedness of the operand with the greater length. If both operands are of equal length, use unsigned operation if one of the operands is unsigned. */ if (op == BINOP_RSH || op == BINOP_LSH || op == BINOP_EXP) result_type = type1; else if (TYPE_LENGTH (type1) > TYPE_LENGTH (type2)) result_type = type1; else if (TYPE_LENGTH (type2) > TYPE_LENGTH (type1)) result_type = type2; else if (TYPE_UNSIGNED (type1)) result_type = type1; else if (TYPE_UNSIGNED (type2)) result_type = type2; else result_type = type1; if (TYPE_UNSIGNED (result_type)) { LONGEST v2_signed = value_as_long (arg2); ULONGEST v1, v2, v = 0; v1 = (ULONGEST) value_as_long (arg1); v2 = (ULONGEST) v2_signed; switch (op) { case BINOP_ADD: v = v1 + v2; break; case BINOP_SUB: v = v1 - v2; break; case BINOP_MUL: v = v1 * v2; break; case BINOP_DIV: case BINOP_INTDIV: if (v2 != 0) v = v1 / v2; else error (_("Division by zero")); break; case BINOP_EXP: v = uinteger_pow (v1, v2_signed); break; case BINOP_REM: if (v2 != 0) v = v1 % v2; else error (_("Division by zero")); break; case BINOP_MOD: /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, v1 mod 0 has a defined value, v1. */ if (v2 == 0) { v = v1; } else { v = v1 / v2; /* Note floor(v1/v2) == v1/v2 for unsigned. */ v = v1 - (v2 * v); } break; case BINOP_LSH: v = v1 << v2; break; case BINOP_RSH: v = v1 >> v2; break; case BINOP_BITWISE_AND: v = v1 & v2; break; case BINOP_BITWISE_IOR: v = v1 | v2; break; case BINOP_BITWISE_XOR: v = v1 ^ v2; break; case BINOP_LOGICAL_AND: v = v1 && v2; break; case BINOP_LOGICAL_OR: v = v1 || v2; break; case BINOP_MIN: v = v1 < v2 ? v1 : v2; break; case BINOP_MAX: v = v1 > v2 ? v1 : v2; break; case BINOP_EQUAL: v = v1 == v2; break; case BINOP_NOTEQUAL: v = v1 != v2; break; case BINOP_LESS: v = v1 < v2; break; case BINOP_GTR: v = v1 > v2; break; case BINOP_LEQ: v = v1 <= v2; break; case BINOP_GEQ: v = v1 >= v2; break; default: error (_("Invalid binary operation on numbers.")); } val = allocate_value (result_type); store_unsigned_integer (value_contents_raw (val), TYPE_LENGTH (value_type (val)), gdbarch_byte_order (get_type_arch (result_type)), v); } else { LONGEST v1, v2, v = 0; v1 = value_as_long (arg1); v2 = value_as_long (arg2); switch (op) { case BINOP_ADD: v = v1 + v2; break; case BINOP_SUB: v = v1 - v2; break; case BINOP_MUL: v = v1 * v2; break; case BINOP_DIV: case BINOP_INTDIV: if (v2 != 0) v = v1 / v2; else error (_("Division by zero")); break; case BINOP_EXP: v = integer_pow (v1, v2); break; case BINOP_REM: if (v2 != 0) v = v1 % v2; else error (_("Division by zero")); break; case BINOP_MOD: /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, X mod 0 has a defined value, X. */ if (v2 == 0) { v = v1; } else { v = v1 / v2; /* Compute floor. */ if (TRUNCATION_TOWARDS_ZERO && (v < 0) && ((v1 % v2) != 0)) { v--; } v = v1 - (v2 * v); } break; case BINOP_LSH: v = v1 << v2; break; case BINOP_RSH: v = v1 >> v2; break; case BINOP_BITWISE_AND: v = v1 & v2; break; case BINOP_BITWISE_IOR: v = v1 | v2; break; case BINOP_BITWISE_XOR: v = v1 ^ v2; break; case BINOP_LOGICAL_AND: v = v1 && v2; break; case BINOP_LOGICAL_OR: v = v1 || v2; break; case BINOP_MIN: v = v1 < v2 ? v1 : v2; break; case BINOP_MAX: v = v1 > v2 ? v1 : v2; break; case BINOP_EQUAL: v = v1 == v2; break; case BINOP_NOTEQUAL: v = v1 != v2; break; case BINOP_LESS: v = v1 < v2; break; case BINOP_GTR: v = v1 > v2; break; case BINOP_LEQ: v = v1 <= v2; break; case BINOP_GEQ: v = v1 >= v2; break; default: error (_("Invalid binary operation on numbers.")); } val = allocate_value (result_type); store_signed_integer (value_contents_raw (val), TYPE_LENGTH (value_type (val)), gdbarch_byte_order (get_type_arch (result_type)), v); } }
struct value * value_concat (struct value *arg1, struct value *arg2) { struct value *inval1; struct value *inval2; struct value *outval = NULL; int inval1len, inval2len; int count, idx; char *ptr; char inchar; struct type *type1 = check_typedef (value_type (arg1)); struct type *type2 = check_typedef (value_type (arg2)); struct type *char_type; /* First figure out if we are dealing with two values to be concatenated or a repeat count and a value to be repeated. INVAL1 is set to the first of two concatenated values, or the repeat count. INVAL2 is set to the second of the two concatenated values or the value to be repeated. */ if (TYPE_CODE (type2) == TYPE_CODE_INT) { struct type *tmp = type1; type1 = tmp; tmp = type2; inval1 = arg2; inval2 = arg1; } else { inval1 = arg1; inval2 = arg2; } /* Now process the input values. */ if (TYPE_CODE (type1) == TYPE_CODE_INT) { /* We have a repeat count. Validate the second value and then construct a value repeated that many times. */ if (TYPE_CODE (type2) == TYPE_CODE_STRING || TYPE_CODE (type2) == TYPE_CODE_CHAR) { count = longest_to_int (value_as_long (inval1)); inval2len = TYPE_LENGTH (type2); ptr = (char *) alloca (count * inval2len); if (TYPE_CODE (type2) == TYPE_CODE_CHAR) { char_type = type2; inchar = (char) unpack_long (type2, value_contents (inval2)); for (idx = 0; idx < count; idx++) { *(ptr + idx) = inchar; } } else { char_type = TYPE_TARGET_TYPE (type2); for (idx = 0; idx < count; idx++) { memcpy (ptr + (idx * inval2len), value_contents (inval2), inval2len); } } outval = value_string (ptr, count * inval2len, char_type); } else if (TYPE_CODE (type2) == TYPE_CODE_BITSTRING || TYPE_CODE (type2) == TYPE_CODE_BOOL) { error (_("unimplemented support for bitstring/boolean repeats")); } else { error (_("can't repeat values of that type")); } } else if (TYPE_CODE (type1) == TYPE_CODE_STRING || TYPE_CODE (type1) == TYPE_CODE_CHAR) { /* We have two character strings to concatenate. */ if (TYPE_CODE (type2) != TYPE_CODE_STRING && TYPE_CODE (type2) != TYPE_CODE_CHAR) { error (_("Strings can only be concatenated with other strings.")); } inval1len = TYPE_LENGTH (type1); inval2len = TYPE_LENGTH (type2); ptr = (char *) alloca (inval1len + inval2len); if (TYPE_CODE (type1) == TYPE_CODE_CHAR) { char_type = type1; *ptr = (char) unpack_long (type1, value_contents (inval1)); } else { char_type = TYPE_TARGET_TYPE (type1); memcpy (ptr, value_contents (inval1), inval1len); } if (TYPE_CODE (type2) == TYPE_CODE_CHAR) { *(ptr + inval1len) = (char) unpack_long (type2, value_contents (inval2)); } else { memcpy (ptr + inval1len, value_contents (inval2), inval2len); } outval = value_string (ptr, inval1len + inval2len, char_type); } else if (TYPE_CODE (type1) == TYPE_CODE_BITSTRING || TYPE_CODE (type1) == TYPE_CODE_BOOL) { /* We have two bitstrings to concatenate. */ if (TYPE_CODE (type2) != TYPE_CODE_BITSTRING && TYPE_CODE (type2) != TYPE_CODE_BOOL) { error (_("Bitstrings or booleans can only be concatenated " "with other bitstrings or booleans.")); } error (_("unimplemented support for bitstring/boolean concatenation.")); } else { /* We don't know how to concatenate these operands. */ error (_("illegal operands for concatenation.")); } return (outval); }
static struct type * gnuv3_rtti_type (struct value *value, int *full_p, int *top_p, int *using_enc_p) { struct gdbarch *gdbarch; struct type *vtable_type; struct type *values_type = check_typedef (value_type (value)); CORE_ADDR vtable_address; struct value *vtable; struct minimal_symbol *vtable_symbol; const char *vtable_symbol_name; const char *class_name; struct type *run_time_type; struct type *base_type; LONGEST offset_to_top; struct type *values_type_vptr_basetype; int values_type_vptr_fieldno; /* We only have RTTI for class objects. */ if (TYPE_CODE (values_type) != TYPE_CODE_CLASS) return NULL; /* This routine may be called for Java types that do not have a proper objfile. Just return NULL for those. */ if (!TYPE_OBJFILE (values_type) || !TYPE_OBJFILE (values_type)->obfd) return NULL; /* Determine architecture. */ gdbarch = get_class_arch (values_type); vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data); /* If we can't find the virtual table pointer for values_type, we can't find the RTTI. */ values_type_vptr_fieldno = get_vptr_fieldno (values_type, &values_type_vptr_basetype); if (values_type_vptr_fieldno == -1) return NULL; if (using_enc_p) *using_enc_p = 0; /* Fetch VALUE's virtual table pointer, and tweak it to point at an instance of our imaginary gdb_gnu_v3_abi_vtable structure. */ base_type = check_typedef (values_type_vptr_basetype); if (values_type != base_type) { value = value_cast (base_type, value); if (using_enc_p) *using_enc_p = 1; } vtable_address = value_as_address (value_field (value, values_type_vptr_fieldno)); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset (gdbarch)); /* Find the linker symbol for this vtable. */ vtable_symbol = lookup_minimal_symbol_by_pc (value_address (vtable) + value_embedded_offset (vtable)); if (! vtable_symbol) return NULL; /* The symbol's demangled name should be something like "vtable for CLASS", where CLASS is the name of the run-time type of VALUE. If we didn't like this approach, we could instead look in the type_info object itself to get the class name. But this way should work just as well, and doesn't read target memory. */ vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol); if (vtable_symbol_name == NULL || strncmp (vtable_symbol_name, "vtable for ", 11)) { warning (_("can't find linker symbol for virtual table for `%s' value"), TYPE_NAME (values_type)); if (vtable_symbol_name) warning (_(" found `%s' instead"), vtable_symbol_name); return NULL; } class_name = vtable_symbol_name + 11; /* Try to look up the class name as a type name. */ /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */ run_time_type = cp_lookup_rtti_type (class_name, NULL); if (run_time_type == NULL) return NULL; /* Get the offset from VALUE to the top of the complete object. NOTE: this is the reverse of the meaning of *TOP_P. */ offset_to_top = value_as_long (value_field (vtable, vtable_field_offset_to_top)); if (full_p) *full_p = (- offset_to_top == value_embedded_offset (value) && (TYPE_LENGTH (value_enclosing_type (value)) >= TYPE_LENGTH (run_time_type))); if (top_p) *top_p = - offset_to_top; return run_time_type; }
static struct value * evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp, int *pos, enum noside noside) { enum exp_opcode op = exp->elts[*pos].opcode; struct value *arg1; struct value *arg2; struct type *type; switch (op) { case UNOP_HIGH: (*pos)++; arg1 = evaluate_subexp_with_coercion (exp, pos, noside); if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; else { arg1 = coerce_ref (arg1); type = check_typedef (value_type (arg1)); if (m2_is_unbounded_array (type)) { struct value *temp = arg1; type = TYPE_FIELD_TYPE (type, 1); /* i18n: Do not translate the "_m2_high" part! */ arg1 = value_struct_elt (&temp, NULL, "_m2_high", NULL, _("unbounded structure " "missing _m2_high field")); if (value_type (arg1) != type) arg1 = value_cast (type, arg1); } } return arg1; case BINOP_SUBSCRIPT: (*pos)++; arg1 = evaluate_subexp_with_coercion (exp, pos, noside); arg2 = evaluate_subexp_with_coercion (exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; /* If the user attempts to subscript something that is not an array or pointer type (like a plain int variable for example), then report this as an error. */ arg1 = coerce_ref (arg1); type = check_typedef (value_type (arg1)); if (m2_is_unbounded_array (type)) { struct value *temp = arg1; type = TYPE_FIELD_TYPE (type, 0); if (type == NULL || (TYPE_CODE (type) != TYPE_CODE_PTR)) { warning (_("internal error: unbounded " "array structure is unknown")); return evaluate_subexp_standard (expect_type, exp, pos, noside); } /* i18n: Do not translate the "_m2_contents" part! */ arg1 = value_struct_elt (&temp, NULL, "_m2_contents", NULL, _("unbounded structure " "missing _m2_contents field")); if (value_type (arg1) != type) arg1 = value_cast (type, arg1); check_typedef (value_type (arg1)); return value_ind (value_ptradd (arg1, value_as_long (arg2))); } else if (TYPE_CODE (type) != TYPE_CODE_ARRAY) { if (TYPE_NAME (type)) error (_("cannot subscript something of type `%s'"), TYPE_NAME (type)); else error (_("cannot subscript requested type")); } if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1)); else return value_subscript (arg1, value_as_long (arg2)); default: return evaluate_subexp_standard (expect_type, exp, pos, noside); } nosideret: return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1); }
static struct type * gnuv3_rtti_type (struct value *value, int *full_p, int *top_p, int *using_enc_p) { struct gdbarch *gdbarch; struct type *values_type = check_typedef (value_type (value)); struct value *vtable; struct minimal_symbol *vtable_symbol; const char *vtable_symbol_name; const char *class_name; struct type *run_time_type; LONGEST offset_to_top; char *atsign; /* We only have RTTI for class objects. */ if (TYPE_CODE (values_type) != TYPE_CODE_CLASS) return NULL; /* Java doesn't have RTTI following the C++ ABI. */ if (TYPE_CPLUS_REALLY_JAVA (values_type)) return NULL; /* Determine architecture. */ gdbarch = get_type_arch (values_type); if (using_enc_p) *using_enc_p = 0; vtable = gnuv3_get_vtable (gdbarch, value_type (value), value_as_address (value_addr (value))); if (vtable == NULL) return NULL; /* Find the linker symbol for this vtable. */ vtable_symbol = lookup_minimal_symbol_by_pc (value_address (vtable) + value_embedded_offset (vtable)).minsym; if (! vtable_symbol) return NULL; /* The symbol's demangled name should be something like "vtable for CLASS", where CLASS is the name of the run-time type of VALUE. If we didn't like this approach, we could instead look in the type_info object itself to get the class name. But this way should work just as well, and doesn't read target memory. */ vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol); if (vtable_symbol_name == NULL || strncmp (vtable_symbol_name, "vtable for ", 11)) { warning (_("can't find linker symbol for virtual table for `%s' value"), TYPE_SAFE_NAME (values_type)); if (vtable_symbol_name) warning (_(" found `%s' instead"), vtable_symbol_name); return NULL; } class_name = vtable_symbol_name + 11; /* Strip off @plt and version suffixes. */ atsign = strchr (class_name, '@'); if (atsign != NULL) { char *copy; copy = alloca (atsign - class_name + 1); memcpy (copy, class_name, atsign - class_name); copy[atsign - class_name] = '\0'; class_name = copy; } /* Try to look up the class name as a type name. */ /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */ run_time_type = cp_lookup_rtti_type (class_name, NULL); if (run_time_type == NULL) return NULL; /* Get the offset from VALUE to the top of the complete object. NOTE: this is the reverse of the meaning of *TOP_P. */ offset_to_top = value_as_long (value_field (vtable, vtable_field_offset_to_top)); if (full_p) *full_p = (- offset_to_top == value_embedded_offset (value) && (TYPE_LENGTH (value_enclosing_type (value)) >= TYPE_LENGTH (run_time_type))); if (top_p) *top_p = - offset_to_top; return run_time_type; }
static struct value * evaluate_subexp_java (struct type *expect_type, struct expression *exp, int *pos, enum noside noside) { int pc = *pos; int i; const char *name; enum exp_opcode op = exp->elts[*pos].opcode; struct value *arg1; struct value *arg2; struct type *type; switch (op) { case UNOP_IND: if (noside == EVAL_SKIP) goto standard; (*pos)++; arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL); if (is_object_type (value_type (arg1))) { struct type *type; type = type_from_class (exp->gdbarch, java_class_from_object (arg1)); arg1 = value_cast (lookup_pointer_type (type), arg1); } return value_ind (arg1); case BINOP_SUBSCRIPT: (*pos)++; arg1 = evaluate_subexp_with_coercion (exp, pos, noside); arg2 = evaluate_subexp_with_coercion (exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; /* If the user attempts to subscript something that is not an array or pointer type (like a plain int variable for example), then report this as an error. */ arg1 = coerce_ref (arg1); type = check_typedef (value_type (arg1)); if (TYPE_CODE (type) == TYPE_CODE_PTR) type = check_typedef (TYPE_TARGET_TYPE (type)); name = TYPE_NAME (type); if (name == NULL) name = TYPE_TAG_NAME (type); i = name == NULL ? 0 : strlen (name); if (TYPE_CODE (type) == TYPE_CODE_STRUCT && i > 2 && name[i - 1] == ']') { enum bfd_endian byte_order = gdbarch_byte_order (exp->gdbarch); CORE_ADDR address; long length, index; struct type *el_type; gdb_byte buf4[4]; struct value *clas = java_class_from_object (arg1); struct value *temp = clas; /* Get CLASS_ELEMENT_TYPE of the array type. */ temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure"); deprecated_set_value_type (temp, value_type (clas)); el_type = type_from_class (exp->gdbarch, temp); if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT) el_type = lookup_pointer_type (el_type); if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (el_type, VALUE_LVAL (arg1)); address = value_as_address (arg1); address += get_java_object_header_size (exp->gdbarch); read_memory (address, buf4, 4); length = (long) extract_signed_integer (buf4, 4, byte_order); index = (long) value_as_long (arg2); if (index >= length || index < 0) error (_("array index (%ld) out of bounds (length: %ld)"), index, length); address = (address + 4) + index * TYPE_LENGTH (el_type); return value_at (el_type, address); } else if (TYPE_CODE (type) == TYPE_CODE_ARRAY) { if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1)); else return value_subscript (arg1, value_as_long (arg2)); } if (name) error (_("cannot subscript something of type `%s'"), name); else error (_("cannot subscript requested type")); case OP_STRING: (*pos)++; i = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1); if (noside == EVAL_SKIP) goto nosideret; return java_value_string (&exp->elts[pc + 2].string, i); case STRUCTOP_PTR: arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside); /* Convert object field (such as TYPE.class) to reference. */ if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_STRUCT) arg1 = value_addr (arg1); return arg1; default: break; } standard: return evaluate_subexp_standard (expect_type, exp, pos, noside); nosideret: return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1); }
static struct type * hpacc_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) { struct type *known_type; struct type *rtti_type; CORE_ADDR coreptr; struct value *vp; int using_enclosing = 0; long top_offset = 0; char rtti_type_name[256]; if (full) *full = 0; if (top) *top = -1; if (using_enc) *using_enc = 0; /* Get declared type */ known_type = value_type (v); CHECK_TYPEDEF (known_type); /* RTTI works only or class objects */ if (TYPE_CODE (known_type) != TYPE_CODE_CLASS) return NULL; /* If neither the declared type nor the enclosing type of the * value structure has a HP ANSI C++ style virtual table, * we can't do anything. */ if (!TYPE_HAS_VTABLE (known_type)) { known_type = value_enclosing_type (v); CHECK_TYPEDEF (known_type); if ((TYPE_CODE (known_type) != TYPE_CODE_CLASS) || !TYPE_HAS_VTABLE (known_type)) return NULL; /* No RTTI, or not HP-compiled types */ CHECK_TYPEDEF (known_type); using_enclosing = 1; } if (using_enclosing && using_enc) *using_enc = 1; /* First get the virtual table address */ coreptr = *(CORE_ADDR *) ((value_contents_all (v)) + value_offset (v) + (using_enclosing ? 0 : value_embedded_offset (v))); if (coreptr == 0) /* return silently -- maybe called on gdb-generated value */ return NULL; /* Fetch the top offset of the object */ /* FIXME possible 32x64 problem with pointer size & arithmetic */ vp = value_at (builtin_type_int, coreptr + 4 * HP_ACC_TOP_OFFSET_OFFSET); top_offset = value_as_long (vp); if (top) *top = top_offset; /* Fetch the typeinfo pointer */ /* FIXME possible 32x64 problem with pointer size & arithmetic */ vp = value_at (builtin_type_int, coreptr + 4 * HP_ACC_TYPEINFO_OFFSET); /* Indirect through the typeinfo pointer and retrieve the pointer * to the string name */ coreptr = *(CORE_ADDR *) (value_contents (vp)); if (!coreptr) error (_("Retrieved null typeinfo pointer in trying to determine " "run-time type")); /* 4 -> offset of name field */ vp = value_at (builtin_type_int, coreptr + 4); /* FIXME possible 32x64 problem */ coreptr = *(CORE_ADDR *) (value_contents (vp)); read_memory_string (coreptr, rtti_type_name, 256); if (strlen (rtti_type_name) == 0) error (_("Retrieved null type name from typeinfo")); /* search for type */ rtti_type = lookup_typename (rtti_type_name, (struct block *) 0, 1); if (!rtti_type) error (_("Could not find run-time type: invalid type name %s in typeinfo??"), rtti_type_name); CHECK_TYPEDEF (rtti_type); #if 0 printf ("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type), TYPE_TAG_NAME (rtti_type), full ? *full : -1); #endif /* Check whether we have the entire object */ if (full /* Non-null pointer passed */ && /* Either we checked on the whole object in hand and found the top offset to be zero */ (((top_offset == 0) && using_enclosing && TYPE_LENGTH (known_type) == TYPE_LENGTH (rtti_type)) || /* Or we checked on the embedded object and top offset was the same as the embedded offset */ ((top_offset == value_embedded_offset (v)) && !using_enclosing && TYPE_LENGTH (value_enclosing_type (v)) == TYPE_LENGTH (rtti_type)))) *full = 1; return rtti_type; }
CORE_ADDR find_function_addr (struct value *function, struct type **retval_type) { struct type *ftype = check_typedef (value_type (function)); struct gdbarch *gdbarch = get_type_arch (ftype); struct type *value_type = NULL; /* Initialize it just to avoid a GCC false warning. */ CORE_ADDR funaddr = 0; /* If it's a member function, just look at the function part of it. */ /* Determine address to call. */ if (TYPE_CODE (ftype) == TYPE_CODE_FUNC || TYPE_CODE (ftype) == TYPE_CODE_METHOD) funaddr = value_address (function); else if (TYPE_CODE (ftype) == TYPE_CODE_PTR) { funaddr = value_as_address (function); ftype = check_typedef (TYPE_TARGET_TYPE (ftype)); if (TYPE_CODE (ftype) == TYPE_CODE_FUNC || TYPE_CODE (ftype) == TYPE_CODE_METHOD) funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr, ¤t_target); } if (TYPE_CODE (ftype) == TYPE_CODE_FUNC || TYPE_CODE (ftype) == TYPE_CODE_METHOD) { value_type = TYPE_TARGET_TYPE (ftype); if (TYPE_GNU_IFUNC (ftype)) { funaddr = gnu_ifunc_resolve_addr (gdbarch, funaddr); /* Skip querying the function symbol if no RETVAL_TYPE has been asked for. */ if (retval_type) value_type = find_function_return_type (funaddr); } } else if (TYPE_CODE (ftype) == TYPE_CODE_INT) { /* Handle the case of functions lacking debugging info. Their values are characters since their addresses are char. */ if (TYPE_LENGTH (ftype) == 1) funaddr = value_as_address (value_addr (function)); else { /* Handle function descriptors lacking debug info. */ int found_descriptor = 0; funaddr = 0; /* pacify "gcc -Werror" */ if (VALUE_LVAL (function) == lval_memory) { CORE_ADDR nfunaddr; funaddr = value_as_address (value_addr (function)); nfunaddr = funaddr; funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr, ¤t_target); if (funaddr != nfunaddr) found_descriptor = 1; } if (!found_descriptor) /* Handle integer used as address of a function. */ funaddr = (CORE_ADDR) value_as_long (function); } } else error (_("Invalid data type for function to be called.")); if (retval_type != NULL) *retval_type = value_type; return funaddr + gdbarch_deprecated_function_start_offset (gdbarch); }
static struct type * java_link_class_type (struct gdbarch *gdbarch, struct type *type, struct value *clas) { struct value *temp; const char *unqualified_name; const char *name = TYPE_TAG_NAME (type); int ninterfaces, nfields, nmethods; int type_is_object = 0; struct fn_field *fn_fields; struct fn_fieldlist *fn_fieldlists; struct value *fields; struct value *methods; struct value *method = NULL; struct value *field = NULL; int i, j; struct objfile *objfile = get_dynamics_objfile (gdbarch); struct type *tsuper; gdb_assert (name != NULL); unqualified_name = strrchr (name, '.'); if (unqualified_name == NULL) unqualified_name = name; temp = clas; temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure"); if (strcmp (name, "java.lang.Object") == 0) { tsuper = get_java_object_type (); if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR) tsuper = TYPE_TARGET_TYPE (tsuper); type_is_object = 1; } else tsuper = type_from_class (gdbarch, temp); #if 1 ninterfaces = 0; #else temp = clas; ninterfaces = value_as_long (value_struct_elt (&temp, NULL, "interface_len", NULL, "structure")); #endif TYPE_N_BASECLASSES (type) = (tsuper == NULL ? 0 : 1) + ninterfaces; temp = clas; nfields = value_as_long (value_struct_elt (&temp, NULL, "field_count", NULL, "structure")); nfields += TYPE_N_BASECLASSES (type); nfields++; /* Add one for dummy "class" field. */ TYPE_NFIELDS (type) = nfields; TYPE_FIELDS (type) = (struct field *) TYPE_ALLOC (type, sizeof (struct field) * nfields); memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields); TYPE_FIELD_PRIVATE_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields); TYPE_FIELD_PROTECTED_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields); TYPE_FIELD_IGNORE_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields); TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type))); B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type)); if (tsuper != NULL) { TYPE_BASECLASS (type, 0) = tsuper; if (type_is_object) SET_TYPE_FIELD_PRIVATE (type, 0); } i = strlen (name); if (i > 2 && name[i - 1] == ']' && tsuper != NULL) { /* FIXME */ TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4; /* size with "length" */ } else { temp = clas; temp = value_struct_elt (&temp, NULL, "size_in_bytes", NULL, "structure"); TYPE_LENGTH (type) = value_as_long (temp); } fields = NULL; nfields--; /* First set up dummy "class" field. */ SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields), value_address (clas)); TYPE_FIELD_NAME (type, nfields) = "class"; TYPE_FIELD_TYPE (type, nfields) = value_type (clas); SET_TYPE_FIELD_PRIVATE (type, nfields); for (i = TYPE_N_BASECLASSES (type); i < nfields; i++) { int accflags; int boffset; if (fields == NULL) { temp = clas; fields = value_struct_elt (&temp, NULL, "fields", NULL, "structure"); field = value_ind (fields); } else { /* Re-use field value for next field. */ CORE_ADDR addr = value_address (field) + TYPE_LENGTH (value_type (field)); set_value_address (field, addr); set_value_lazy (field, 1); } temp = field; temp = value_struct_elt (&temp, NULL, "name", NULL, "structure"); TYPE_FIELD_NAME (type, i) = get_java_utf8_name (&objfile->objfile_obstack, temp); temp = field; accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags", NULL, "structure")); temp = field; temp = value_struct_elt (&temp, NULL, "info", NULL, "structure"); boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset", NULL, "structure")); if (accflags & 0x0001) /* public access */ { /* ??? */ } if (accflags & 0x0002) /* private access */ { SET_TYPE_FIELD_PRIVATE (type, i); } if (accflags & 0x0004) /* protected access */ { SET_TYPE_FIELD_PROTECTED (type, i); } if (accflags & 0x0008) /* ACC_STATIC */ SET_FIELD_PHYSADDR (TYPE_FIELD (type, i), boffset); else SET_FIELD_BITPOS (TYPE_FIELD (type, i), 8 * boffset); if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */ { TYPE_FIELD_TYPE (type, i) = get_java_object_type (); /* FIXME */ } else { struct type *ftype; temp = field; temp = value_struct_elt (&temp, NULL, "type", NULL, "structure"); ftype = type_from_class (gdbarch, temp); if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT) ftype = lookup_pointer_type (ftype); TYPE_FIELD_TYPE (type, i) = ftype; } } temp = clas; nmethods = value_as_long (value_struct_elt (&temp, NULL, "method_count", NULL, "structure")); j = nmethods * sizeof (struct fn_field); fn_fields = (struct fn_field *) obstack_alloc (&objfile->objfile_obstack, j); memset (fn_fields, 0, j); fn_fieldlists = (struct fn_fieldlist *) alloca (nmethods * sizeof (struct fn_fieldlist)); methods = NULL; for (i = 0; i < nmethods; i++) { const char *mname; int k; if (methods == NULL) { temp = clas; methods = value_struct_elt (&temp, NULL, "methods", NULL, "structure"); method = value_ind (methods); } else { /* Re-use method value for next method. */ CORE_ADDR addr = value_address (method) + TYPE_LENGTH (value_type (method)); set_value_address (method, addr); set_value_lazy (method, 1); } /* Get method name. */ temp = method; temp = value_struct_elt (&temp, NULL, "name", NULL, "structure"); mname = get_java_utf8_name (&objfile->objfile_obstack, temp); if (strcmp (mname, "<init>") == 0) mname = unqualified_name; /* Check for an existing method with the same name. * This makes building the fn_fieldslists an O(nmethods**2) * operation. That could be using hashing, but I doubt it * is worth it. Note that we do maintain the order of methods * in the inferior's Method table (as long as that is grouped * by method name), which I think is desirable. --PB */ for (k = 0, j = TYPE_NFN_FIELDS (type);;) { if (--j < 0) { /* No match - new method name. */ j = TYPE_NFN_FIELDS (type)++; fn_fieldlists[j].name = mname; fn_fieldlists[j].length = 1; fn_fieldlists[j].fn_fields = &fn_fields[i]; k = i; break; } if (strcmp (mname, fn_fieldlists[j].name) == 0) { /* Found an existing method with the same name. */ int l; if (mname != unqualified_name) obstack_free (&objfile->objfile_obstack, mname); mname = fn_fieldlists[j].name; fn_fieldlists[j].length++; k = i - k; /* Index of new slot. */ /* Shift intervening fn_fields (between k and i) down. */ for (l = i; l > k; l--) fn_fields[l] = fn_fields[l - 1]; for (l = TYPE_NFN_FIELDS (type); --l > j;) fn_fieldlists[l].fn_fields++; break; } k += fn_fieldlists[j].length; } fn_fields[k].physname = ""; fn_fields[k].is_stub = 1; /* FIXME */ fn_fields[k].type = lookup_function_type (builtin_java_type (gdbarch)->builtin_void); TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD; } j = TYPE_NFN_FIELDS (type) * sizeof (struct fn_fieldlist); TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) obstack_alloc (&objfile->objfile_obstack, j); memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j); return type; }
/* Compute the offset of the baseclass which is the INDEXth baseclass of class TYPE, for value at VALADDR (in host) at ADDRESS (in target). The result is the offset of the baseclass value relative to (the address of)(ARG) + OFFSET. -1 is returned on error. */ static int gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr, CORE_ADDR address) { struct gdbarch *gdbarch; struct type *vtable_type; struct type *ptr_type; struct value *vtable; struct type *vbasetype; struct value *offset_val, *vbase_array; CORE_ADDR vtable_address; long int cur_base_offset, base_offset; int vbasetype_vptr_fieldno; /* Determine architecture. */ gdbarch = get_class_arch (type); vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data); ptr_type = builtin_type (gdbarch)->builtin_data_ptr; /* If it isn't a virtual base, this is easy. The offset is in the type definition. */ if (!BASETYPE_VIA_VIRTUAL (type, index)) return TYPE_BASECLASS_BITPOS (type, index) / 8; /* To access a virtual base, we need to use the vbase offset stored in our vtable. Recent GCC versions provide this information. If it isn't available, we could get what we needed from RTTI, or from drawing the complete inheritance graph based on the debug info. Neither is worthwhile. */ cur_base_offset = TYPE_BASECLASS_BITPOS (type, index) / 8; if (cur_base_offset >= - vtable_address_point_offset (gdbarch)) error (_("Expected a negative vbase offset (old compiler?)")); cur_base_offset = cur_base_offset + vtable_address_point_offset (gdbarch); if ((- cur_base_offset) % TYPE_LENGTH (ptr_type) != 0) error (_("Misaligned vbase offset.")); cur_base_offset = cur_base_offset / ((int) TYPE_LENGTH (ptr_type)); /* We're now looking for the cur_base_offset'th entry (negative index) in the vcall_and_vbase_offsets array. We used to cast the object to its TYPE_VPTR_BASETYPE, and reference the vtable as TYPE_VPTR_FIELDNO; however, that cast can not be done without calling baseclass_offset again if the TYPE_VPTR_BASETYPE is a virtual base class, as described in the v3 C++ ABI Section 2.4.I.2.b. Fortunately the ABI guarantees that the vtable pointer will be located at the beginning of the object, so we can bypass the casting. Verify that the TYPE_VPTR_FIELDNO is in fact at the start of whichever baseclass it resides in, as a sanity measure - iff we have debugging information for that baseclass. */ vbasetype = check_typedef (TYPE_VPTR_BASETYPE (type)); vbasetype_vptr_fieldno = get_vptr_fieldno (vbasetype, NULL); if (vbasetype_vptr_fieldno >= 0 && TYPE_FIELD_BITPOS (vbasetype, vbasetype_vptr_fieldno) != 0) error (_("Illegal vptr offset in class %s"), TYPE_NAME (vbasetype) ? TYPE_NAME (vbasetype) : "<unknown>"); vtable_address = value_as_address (value_at_lazy (ptr_type, address)); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset (gdbarch)); offset_val = value_from_longest (builtin_type_int32, cur_base_offset); vbase_array = value_field (vtable, vtable_field_vcall_and_vbase_offsets); base_offset = value_as_long (value_subscript (vbase_array, offset_val)); return base_offset; }
/* Return a virtual function as a value. ARG1 is the object which provides the virtual function table pointer. *ARG1P is side-effected in calling this function. F is the list of member functions which contains the desired virtual function. J is an index into F which provides the desired virtual function. TYPE is the type in which F is located. */ static struct value * gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j, struct type * type, int offset) { struct value *arg1 = *arg1p; struct type *type1 = check_typedef (value_type (arg1)); struct type *entry_type; /* First, get the virtual function table pointer. That comes with a strange type, so cast it to type `pointer to long' (which should serve just fine as a function type). Then, index into the table, and convert final value to appropriate function type. */ struct value *entry; struct value *vfn; struct value *vtbl; struct value *vi = value_from_longest (builtin_type_int, (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j)); struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j); struct type *context; if (fcontext == NULL) /* We don't have an fcontext (e.g. the program was compiled with g++ version 1). Try to get the vtbl from the TYPE_VPTR_BASETYPE. This won't work right for multiple inheritance, but at least we should do as well as GDB 3.x did. */ fcontext = TYPE_VPTR_BASETYPE (type); context = lookup_pointer_type (fcontext); /* Now context is a pointer to the basetype containing the vtbl. */ if (TYPE_TARGET_TYPE (context) != type1) { struct value *tmp = value_cast (context, value_addr (arg1)); arg1 = value_ind (tmp); type1 = check_typedef (value_type (arg1)); } context = type1; /* Now context is the basetype containing the vtbl. */ /* This type may have been defined before its virtual function table was. If so, fill in the virtual function table entry for the type now. */ if (TYPE_VPTR_FIELDNO (context) < 0) fill_in_vptr_fieldno (context); /* The virtual function table is now an array of structures which have the form { int16 offset, delta; void *pfn; }. */ vtbl = value_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context), TYPE_VPTR_BASETYPE (context)); /* With older versions of g++, the vtbl field pointed to an array of structures. Nowadays it points directly to the structure. */ if (TYPE_CODE (value_type (vtbl)) == TYPE_CODE_PTR && TYPE_CODE (TYPE_TARGET_TYPE (value_type (vtbl))) == TYPE_CODE_ARRAY) { /* Handle the case where the vtbl field points to an array of structures. */ vtbl = value_ind (vtbl); /* Index into the virtual function table. This is hard-coded because looking up a field is not cheap, and it may be important to save time, e.g. if the user has set a conditional breakpoint calling a virtual function. */ entry = value_subscript (vtbl, vi); } else { /* Handle the case where the vtbl field points directly to a structure. */ vtbl = value_add (vtbl, vi); entry = value_ind (vtbl); } entry_type = check_typedef (value_type (entry)); if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT) { /* Move the `this' pointer according to the virtual function table. */ set_value_offset (arg1, value_offset (arg1) + value_as_long (value_field (entry, 0))); if (!value_lazy (arg1)) { set_value_lazy (arg1, 1); value_fetch_lazy (arg1); } vfn = value_field (entry, 2); } else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR) vfn = entry; else error (_("I'm confused: virtual function table has bad type")); /* Reinstantiate the function pointer with the correct type. */ deprecated_set_value_type (vfn, lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j))); *arg1p = arg1; return vfn; }
static void execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr, unsigned char *op_end) { ctx->in_reg = 0; while (op_ptr < op_end) { enum dwarf_location_atom op = *op_ptr++; CORE_ADDR result; ULONGEST uoffset, reg; LONGEST offset; int bytes_read; switch (op) { case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: result = op - DW_OP_lit0; break; case DW_OP_addr: result = dwarf2_read_address (op_ptr, op_end, &bytes_read); op_ptr += bytes_read; break; case DW_OP_const1u: result = extract_unsigned_integer (op_ptr, 1); op_ptr += 1; break; case DW_OP_const1s: result = extract_signed_integer (op_ptr, 1); op_ptr += 1; break; case DW_OP_const2u: result = extract_unsigned_integer (op_ptr, 2); op_ptr += 2; break; case DW_OP_const2s: result = extract_signed_integer (op_ptr, 2); op_ptr += 2; break; case DW_OP_const4u: result = extract_unsigned_integer (op_ptr, 4); op_ptr += 4; break; case DW_OP_const4s: result = extract_signed_integer (op_ptr, 4); op_ptr += 4; break; case DW_OP_const8u: result = extract_unsigned_integer (op_ptr, 8); op_ptr += 8; break; case DW_OP_const8s: result = extract_signed_integer (op_ptr, 8); op_ptr += 8; break; case DW_OP_constu: op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); result = uoffset; break; case DW_OP_consts: op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = offset; break; /* The DW_OP_reg operations are required to occur alone in location expressions. */ case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: if (op_ptr != op_end && *op_ptr != DW_OP_piece) error ("DWARF-2 expression error: DW_OP_reg operations must be " "used either alone or in conjuction with DW_OP_piece."); result = op - DW_OP_reg0; ctx->in_reg = 1; break; case DW_OP_regx: op_ptr = read_uleb128 (op_ptr, op_end, ®); if (op_ptr != op_end && *op_ptr != DW_OP_piece) error ("DWARF-2 expression error: DW_OP_reg operations must be " "used either alone or in conjuction with DW_OP_piece."); result = reg; ctx->in_reg = 1; break; case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: { op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0); result += offset; } break; case DW_OP_bregx: { op_ptr = read_uleb128 (op_ptr, op_end, ®); op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = (ctx->read_reg) (ctx->baton, reg); result += offset; } break; case DW_OP_fbreg: { unsigned char *datastart; size_t datalen; unsigned int before_stack_len; op_ptr = read_sleb128 (op_ptr, op_end, &offset); /* Rather than create a whole new context, we simply record the stack length before execution, then reset it afterwards, effectively erasing whatever the recursive call put there. */ before_stack_len = ctx->stack_len; /* FIXME: cagney/2003-03-26: This code should be using get_frame_base_address(), and then implement a dwarf2 specific this_base method. */ (ctx->get_frame_base) (ctx->baton, &datastart, &datalen); dwarf_expr_eval (ctx, datastart, datalen); result = dwarf_expr_fetch (ctx, 0); if (ctx->in_reg) result = (ctx->read_reg) (ctx->baton, result); result = result + offset; ctx->stack_len = before_stack_len; ctx->in_reg = 0; } break; case DW_OP_dup: result = dwarf_expr_fetch (ctx, 0); break; case DW_OP_drop: dwarf_expr_pop (ctx); goto no_push; case DW_OP_pick: offset = *op_ptr++; result = dwarf_expr_fetch (ctx, offset); break; case DW_OP_over: result = dwarf_expr_fetch (ctx, 1); break; case DW_OP_rot: { CORE_ADDR t1, t2, t3; if (ctx->stack_len < 3) error ("Not enough elements for DW_OP_rot. Need 3, have %d\n", ctx->stack_len); t1 = ctx->stack[ctx->stack_len - 1]; t2 = ctx->stack[ctx->stack_len - 2]; t3 = ctx->stack[ctx->stack_len - 3]; ctx->stack[ctx->stack_len - 1] = t2; ctx->stack[ctx->stack_len - 2] = t3; ctx->stack[ctx->stack_len - 3] = t1; goto no_push; } case DW_OP_deref: case DW_OP_deref_size: case DW_OP_abs: case DW_OP_neg: case DW_OP_not: case DW_OP_plus_uconst: /* Unary operations. */ result = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); switch (op) { case DW_OP_deref: { char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT); int bytes_read; (ctx->read_mem) (ctx->baton, buf, result, TARGET_ADDR_BIT / TARGET_CHAR_BIT); result = dwarf2_read_address (buf, buf + (TARGET_ADDR_BIT / TARGET_CHAR_BIT), &bytes_read); } break; case DW_OP_deref_size: { char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT); int bytes_read; (ctx->read_mem) (ctx->baton, buf, result, *op_ptr++); result = dwarf2_read_address (buf, buf + (TARGET_ADDR_BIT / TARGET_CHAR_BIT), &bytes_read); } break; case DW_OP_abs: if ((signed int) result < 0) result = -result; break; case DW_OP_neg: result = -result; break; case DW_OP_not: result = ~result; break; case DW_OP_plus_uconst: op_ptr = read_uleb128 (op_ptr, op_end, ®); result += reg; break; } break; case DW_OP_and: case DW_OP_div: case DW_OP_minus: case DW_OP_mod: case DW_OP_mul: case DW_OP_or: case DW_OP_plus: case DW_OP_shl: case DW_OP_shr: case DW_OP_shra: case DW_OP_xor: case DW_OP_le: case DW_OP_ge: case DW_OP_eq: case DW_OP_lt: case DW_OP_gt: case DW_OP_ne: { /* Binary operations. Use the value engine to do computations in the right width. */ CORE_ADDR first, second; enum exp_opcode binop; struct value *val1, *val2; second = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); first = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); val1 = value_from_longest (unsigned_address_type (), first); val2 = value_from_longest (unsigned_address_type (), second); switch (op) { case DW_OP_and: binop = BINOP_BITWISE_AND; break; case DW_OP_div: binop = BINOP_DIV; break; case DW_OP_minus: binop = BINOP_SUB; break; case DW_OP_mod: binop = BINOP_MOD; break; case DW_OP_mul: binop = BINOP_MUL; break; case DW_OP_or: binop = BINOP_BITWISE_IOR; break; case DW_OP_plus: binop = BINOP_ADD; break; case DW_OP_shl: binop = BINOP_LSH; break; case DW_OP_shr: binop = BINOP_RSH; break; case DW_OP_shra: binop = BINOP_RSH; val1 = value_from_longest (signed_address_type (), first); break; case DW_OP_xor: binop = BINOP_BITWISE_XOR; break; case DW_OP_le: binop = BINOP_LEQ; break; case DW_OP_ge: binop = BINOP_GEQ; break; case DW_OP_eq: binop = BINOP_EQUAL; break; case DW_OP_lt: binop = BINOP_LESS; break; case DW_OP_gt: binop = BINOP_GTR; break; case DW_OP_ne: binop = BINOP_NOTEQUAL; break; default: internal_error (__FILE__, __LINE__, "Can't be reached."); } result = value_as_long (value_binop (val1, val2, binop)); } break; case DW_OP_GNU_push_tls_address: /* Variable is at a constant offset in the thread-local storage block into the objfile for the current thread and the dynamic linker module containing this expression. Here we return returns the offset from that base. The top of the stack has the offset from the beginning of the thread control block at which the variable is located. Nothing should follow this operator, so the top of stack would be returned. */ result = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); result = (ctx->get_tls_address) (ctx->baton, result); break; case DW_OP_skip: offset = extract_signed_integer (op_ptr, 2); op_ptr += 2; op_ptr += offset; goto no_push; case DW_OP_bra: offset = extract_signed_integer (op_ptr, 2); op_ptr += 2; if (dwarf_expr_fetch (ctx, 0) != 0) op_ptr += offset; dwarf_expr_pop (ctx); goto no_push; case DW_OP_nop: goto no_push; case DW_OP_piece: { ULONGEST size; CORE_ADDR addr_or_regnum; /* Record the piece. */ op_ptr = read_uleb128 (op_ptr, op_end, &size); addr_or_regnum = dwarf_expr_fetch (ctx, 0); add_piece (ctx, ctx->in_reg, addr_or_regnum, size); /* Pop off the address/regnum, and clear the in_reg flag. */ dwarf_expr_pop (ctx); ctx->in_reg = 0; } goto no_push; default: error ("Unhandled dwarf expression opcode 0x%x", op); } /* Most things push a result value. */ dwarf_expr_push (ctx, result); no_push:; } }