static void mips_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { enum mips_abi abi = mips_abi (gdbarch); /* Generic FreeBSD support. */ fbsd_init_abi (info, gdbarch); set_gdbarch_software_single_step (gdbarch, mips_software_single_step); switch (abi) { case MIPS_ABI_O32: tramp_frame_prepend_unwinder (gdbarch, &mips_fbsd_sigframe); break; case MIPS_ABI_N32: tramp_frame_prepend_unwinder (gdbarch, &mipsn32_fbsd_sigframe); break; case MIPS_ABI_N64: tramp_frame_prepend_unwinder (gdbarch, &mips64_fbsd_sigframe); break; } set_gdbarch_iterate_over_regset_sections (gdbarch, mips_fbsd_iterate_over_regset_sections); /* FreeBSD/mips has SVR4-style shared libraries. */ set_solib_svr4_fetch_link_map_offsets (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ? mips_fbsd_ilp32_fetch_link_map_offsets : mips_fbsd_lp64_fetch_link_map_offsets)); }
void amd64_supply_native_gregset (struct regcache *regcache, const void *gregs, int regnum) { const char *regs = gregs; struct gdbarch *gdbarch = get_regcache_arch (regcache); int num_regs = amd64_native_gregset64_num_regs; int i; if (gdbarch_ptr_bit (gdbarch) == 32) num_regs = amd64_native_gregset32_num_regs; if (num_regs > gdbarch_num_regs (gdbarch)) num_regs = gdbarch_num_regs (gdbarch); for (i = 0; i < num_regs; i++) { if (regnum == -1 || regnum == i) { int offset = amd64_native_gregset_reg_offset (gdbarch, i); if (offset != -1) regcache_raw_supply (regcache, i, regs + offset); } } }
void sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum) { int offset = 0; char buf[8]; int i; if (sp & 1) { /* Registers are 64-bit. */ sp += BIAS; for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) { if (regnum == i || regnum == -1) { target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8); regcache_raw_supply (regcache, i, buf); } } } else { /* Registers are 32-bit. Toss any sign-extension of the stack pointer. */ sp &= 0xffffffffUL; /* Clear out the top half of the temporary buffer, and put the register value in the bottom half if we're in 64-bit mode. */ if (gdbarch_ptr_bit (current_gdbarch) == 64) { memset (buf, 0, 4); offset = 4; } for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) { if (regnum == i || regnum == -1) { target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 4), buf + offset, 4); /* Handle StackGhost. */ if (i == SPARC_I7_REGNUM) { ULONGEST wcookie = sparc_fetch_wcookie (); ULONGEST i7 = extract_unsigned_integer (buf + offset, 4); store_unsigned_integer (buf + offset, 4, i7 ^ wcookie); } regcache_raw_supply (regcache, i, buf); } } } }
int get_java_object_header_size (struct gdbarch *gdbarch) { struct type *objtype = get_java_object_type (); if (objtype == NULL) return (2 * gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); else return TYPE_LENGTH (objtype); }
static void sparc64nbsd_supply_fpregset (struct regcache *regcache, int regnum, const void *fpregs) { int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32); if (sparc32) sparc32_supply_fpregset (regcache, regnum, fpregs); else sparc64_supply_fpregset (regcache, regnum, fpregs); }
static void sparc64nbsd_collect_fpregset (const struct regcache *regcache, int regnum, void *fpregs) { int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32); if (sparc32) sparc32_collect_fpregset (regcache, regnum, fpregs); else sparc64_collect_fpregset (regcache, regnum, fpregs); }
static int mips_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) { CORE_ADDR jb_addr; char buf[gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT]; jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM); if (target_read_memory (jb_addr + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE, buf, gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT)) return 0; *pc = extract_unsigned_integer (buf, gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT); return 1; }
static int mips64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) { CORE_ADDR jb_addr; void *buf = alloca (gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT); int element_size = gdbarch_ptr_bit (current_gdbarch) == 32 ? 4 : 8; jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM); if (target_read_memory (jb_addr + MIPS64_LINUX_JB_PC * element_size, buf, gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT)) return 0; *pc = extract_unsigned_integer (buf, gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT); return 1; }
ps_err_e ps_get_thread_area (const struct ps_prochandle *ph, lwpid_t lwpid, int idx, void **base) { if (gdbarch_ptr_bit (current_gdbarch) == 32) { /* The full structure is found in <asm-i386/ldt.h>. The second integer is the LDT's base_address and that is used to locate the thread's local storage. See i386-linux-nat.c more info. */ unsigned int desc[4]; /* This code assumes that "int" is 32 bits and that GET_THREAD_AREA returns no more than 4 int values. */ gdb_assert (sizeof (int) == 4); #ifndef PTRACE_GET_THREAD_AREA #define PTRACE_GET_THREAD_AREA 25 #endif if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, (void *) (long) idx, (unsigned long) &desc) < 0) return PS_ERR; /* Extend the value to 64 bits. Here it's assumed that a "long" and a "void *" are the same. */ (*base) = (void *) (long) desc[1]; return PS_OK; } else { /* This definition comes from prctl.h, but some kernels may not have it. */ #ifndef PTRACE_ARCH_PRCTL #define PTRACE_ARCH_PRCTL 30 #endif /* FIXME: ezannoni-2003-07-09 see comment above about include file order. We could be getting bogus values for these two. */ gdb_assert (FS < ELF_NGREG); gdb_assert (GS < ELF_NGREG); switch (idx) { case FS: if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0) return PS_OK; break; case GS: if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0) return PS_OK; break; default: /* Should not happen. */ return PS_BADADDR; } } return PS_ERR; /* ptrace failed. */ }
void sparc_collect_rwindow (const struct regcache *regcache, CORE_ADDR sp, int regnum) { int offset = 0; char buf[8]; int i; if (sp & 1) { /* Registers are 64-bit. */ sp += BIAS; for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) { if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i) { regcache_raw_collect (regcache, i, buf); target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8); } } } else { /* Registers are 32-bit. Toss any sign-extension of the stack pointer. */ sp &= 0xffffffffUL; /* Only use the bottom half if we're in 64-bit mode. */ if (gdbarch_ptr_bit (current_gdbarch) == 64) offset = 4; for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) { if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i) { regcache_raw_collect (regcache, i, buf); /* Handle StackGhost. */ if (i == SPARC_I7_REGNUM) { ULONGEST wcookie = sparc_fetch_wcookie (); ULONGEST i7 = extract_unsigned_integer (buf + offset, 4); store_unsigned_integer (buf + offset, 4, i7 ^ wcookie); } target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 4), buf + offset, 4); } } } }
static void sparc64nbsd_collect_gregset (const struct sparc_gregmap *gregmap, const struct regcache *regcache, int regnum, void *gregs) { int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32); if (sparc32) sparc32_collect_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs); else sparc64_collect_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs); }
static void sparc64nbsd_collect_gregset (const struct sparc_gregset *gregset, const struct regcache *regcache, int regnum, void *gregs) { int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32); if (sparc32) sparc32_collect_gregset (&sparc32nbsd_gregset, regcache, regnum, gregs); else sparc64_collect_gregset (&sparc64nbsd_gregset, regcache, regnum, gregs); }
static void sparc64nbsd_supply_gregset (const struct sparc_gregset *gregset, struct regcache *regcache, int regnum, const void *gregs) { int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32); if (sparc32) sparc32_supply_gregset (&sparc32nbsd_gregset, regcache, regnum, gregs); else sparc64_supply_gregset (&sparc64nbsd_gregset, regcache, regnum, gregs); }
static int mips_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) { CORE_ADDR jb_addr; struct gdbarch *gdbarch = get_frame_arch (frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); char buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT]; jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM); if (target_read_memory (jb_addr + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE, buf, gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT)) return 0; *pc = extract_unsigned_integer (buf, gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT, byte_order); return 1; }
void amd64_supply_fxsave(struct regcache *regcache, int regnum, const void *fxsave) { i387_supply_fxsave(regcache, regnum, fxsave); if (fxsave && (gdbarch_ptr_bit(get_regcache_arch(regcache)) == 64)) { const gdb_byte *regs = (const gdb_byte *)fxsave; if ((regnum == -1) || (regnum == I387_FISEG_REGNUM)) regcache_raw_supply(regcache, I387_FISEG_REGNUM, regs + 12); if ((regnum == -1) || (regnum == I387_FOSEG_REGNUM)) regcache_raw_supply(regcache, I387_FOSEG_REGNUM, regs + 20); } }
void amd64_collect_fxsave(const struct regcache *regcache, int regnum, void *fxsave) { gdb_byte *regs = (gdb_byte *)fxsave; i387_collect_fxsave(regcache, regnum, fxsave); if (gdbarch_ptr_bit(get_regcache_arch(regcache)) == 64) { if ((regnum == -1) || (regnum == I387_FISEG_REGNUM)) regcache_raw_collect(regcache, I387_FISEG_REGNUM, regs + 12); if ((regnum == -1) || (regnum == I387_FOSEG_REGNUM)) regcache_raw_collect(regcache, I387_FOSEG_REGNUM, regs + 20); } }
static void * build_go_types (struct gdbarch *gdbarch) { struct builtin_go_type *builtin_go_type = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_go_type); builtin_go_type->builtin_void = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void"); builtin_go_type->builtin_char = arch_character_type (gdbarch, 8, 1, "char"); builtin_go_type->builtin_bool = arch_boolean_type (gdbarch, 8, 0, "bool"); builtin_go_type->builtin_int = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0, "int"); builtin_go_type->builtin_uint = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 1, "uint"); builtin_go_type->builtin_uintptr = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "uintptr"); builtin_go_type->builtin_int8 = arch_integer_type (gdbarch, 8, 0, "int8"); builtin_go_type->builtin_int16 = arch_integer_type (gdbarch, 16, 0, "int16"); builtin_go_type->builtin_int32 = arch_integer_type (gdbarch, 32, 0, "int32"); builtin_go_type->builtin_int64 = arch_integer_type (gdbarch, 64, 0, "int64"); builtin_go_type->builtin_uint8 = arch_integer_type (gdbarch, 8, 1, "uint8"); builtin_go_type->builtin_uint16 = arch_integer_type (gdbarch, 16, 1, "uint16"); builtin_go_type->builtin_uint32 = arch_integer_type (gdbarch, 32, 1, "uint32"); builtin_go_type->builtin_uint64 = arch_integer_type (gdbarch, 64, 1, "uint64"); builtin_go_type->builtin_float32 = arch_float_type (gdbarch, 32, "float32", floatformats_ieee_single); builtin_go_type->builtin_float64 = arch_float_type (gdbarch, 64, "float64", floatformats_ieee_double); builtin_go_type->builtin_complex64 = arch_complex_type (gdbarch, "complex64", builtin_go_type->builtin_float32); builtin_go_type->builtin_complex128 = arch_complex_type (gdbarch, "complex128", builtin_go_type->builtin_float64); return builtin_go_type; }
static int sparc64nbsd_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum) { if (gdbarch_ptr_bit (gdbarch) == 32) return sparc32_fpregset_supplies_p (gdbarch, regnum); /* Floating-point registers. */ if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM)) return 1; /* Control registers. */ if (regnum == SPARC64_FSR_REGNUM) return 1; return 0; }
static struct btrace_target_info * amd64_linux_enable_btrace (struct target_ops *self, ptid_t ptid) { struct btrace_target_info *tinfo; struct gdbarch *gdbarch; errno = 0; tinfo = linux_enable_btrace (ptid); if (tinfo == NULL) error (_("Could not enable branch tracing for %s: %s."), target_pid_to_str (ptid), safe_strerror (errno)); /* Fill in the size of a pointer in bits. */ gdbarch = target_thread_architecture (ptid); tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch); return tinfo; }
void amd64_collect_native_gregset (const struct regcache *regcache, void *gregs, int regnum) { char *regs = gregs; struct gdbarch *gdbarch = get_regcache_arch (regcache); int num_regs = amd64_native_gregset64_num_regs; int i; if (gdbarch_ptr_bit (gdbarch) == 32) { num_regs = amd64_native_gregset32_num_regs; /* Make sure %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and %eip get zero-extended to 64 bits. */ for (i = 0; i <= I386_EIP_REGNUM; i++) { if (regnum == -1 || regnum == i) memset (regs + amd64_native_gregset_reg_offset (gdbarch, i), 0, 8); } /* Ditto for %cs, %ss, %ds, %es, %fs, and %gs. */ for (i = I386_CS_REGNUM; i <= I386_GS_REGNUM; i++) { if (regnum == -1 || regnum == i) memset (regs + amd64_native_gregset_reg_offset (gdbarch, i), 0, 8); } } if (num_regs > gdbarch_num_regs (gdbarch)) num_regs = gdbarch_num_regs (gdbarch); for (i = 0; i < num_regs; i++) { if (regnum == -1 || regnum == i) { int offset = amd64_native_gregset_reg_offset (gdbarch, i); if (offset != -1) regcache_raw_collect (regcache, i, regs + offset); } } }
static void mipsnbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { set_gdbarch_regset_from_core_section (gdbarch, mipsnbsd_regset_from_core_section); set_gdbarch_get_longjmp_target (gdbarch, mipsnbsd_get_longjmp_target); set_gdbarch_cannot_fetch_register (gdbarch, mipsnbsd_cannot_fetch_register); set_gdbarch_cannot_store_register (gdbarch, mipsnbsd_cannot_store_register); set_gdbarch_software_single_step (gdbarch, mips_software_single_step); /* NetBSD/mips has SVR4-style shared libraries. */ set_solib_svr4_fetch_link_map_offsets (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ? mipsnbsd_ilp32_fetch_link_map_offsets : mipsnbsd_lp64_fetch_link_map_offsets)); }
static int sparc64nbsd_gregset_supplies_p (struct gdbarch *gdbarch, int regnum) { if (gdbarch_ptr_bit (gdbarch) == 32) return sparc32_gregset_supplies_p (gdbarch, regnum); /* Integer registers. */ if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM) || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM) || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM)) return 1; /* Control registers. */ if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM || regnum == SPARC64_STATE_REGNUM || regnum == SPARC64_Y_REGNUM) return 1; return 0; }
static int amd64_native_gregset_reg_offset (int regnum) { int *reg_offset = amd64_native_gregset64_reg_offset; int num_regs = amd64_native_gregset64_num_regs; gdb_assert (regnum >= 0); if (gdbarch_ptr_bit (current_gdbarch) == 32) { reg_offset = amd64_native_gregset32_reg_offset; num_regs = amd64_native_gregset32_num_regs; } if (num_regs > NUM_REGS) num_regs = NUM_REGS; if (regnum < num_regs && regnum < NUM_REGS) return reg_offset[regnum]; return -1; }
static int amd64_native_gregset_reg_offset (struct gdbarch *gdbarch, int regnum) { int *reg_offset = amd64_native_gregset64_reg_offset; int num_regs = amd64_native_gregset64_num_regs; gdb_assert (regnum >= 0); if (gdbarch_ptr_bit (gdbarch) == 32) { reg_offset = amd64_native_gregset32_reg_offset; num_regs = amd64_native_gregset32_num_regs; } if (num_regs > gdbarch_num_regs (gdbarch)) num_regs = gdbarch_num_regs (gdbarch); if (regnum < num_regs && regnum < gdbarch_num_regs (gdbarch)) return reg_offset[regnum]; return -1; }
/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. Return 0 if *READPTR is already at the end of the buffer. Return -1 if there is insufficient buffer for a whole entry. Return 1 if an entry was read into *TYPEP and *VALP. */ static int default_auxv_parse (struct target_ops *ops, gdb_byte **readptr, gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) { const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT; const enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); gdb_byte *ptr = *readptr; if (endptr == ptr) return 0; if (endptr - ptr < sizeof_auxv_field * 2) return -1; *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); ptr += sizeof_auxv_field; *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); ptr += sizeof_auxv_field; *readptr = ptr; return 1; }
int java_value_print (struct value *val, struct ui_file *stream, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (value_type (val)); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct type *type; CORE_ADDR address; int i; char *name; struct value_print_options opts; type = value_type (val); address = value_address (val); if (is_object_type (type)) { CORE_ADDR obj_addr; /* Get the run-time type, and cast the object into that */ obj_addr = unpack_pointer (type, value_contents (val)); if (obj_addr != 0) { type = type_from_class (gdbarch, java_class_from_object (val)); type = lookup_pointer_type (type); val = value_at (type, address); } } if (TYPE_CODE (type) == TYPE_CODE_PTR && !value_logical_not (val)) type_print (TYPE_TARGET_TYPE (type), "", stream, -1); name = TYPE_TAG_NAME (type); if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL && (i = strlen (name), name[i - 1] == ']')) { gdb_byte buf4[4]; long length; unsigned int things_printed = 0; int reps; struct type *el_type = java_primitive_type_from_name (gdbarch, name, i - 2); i = 0; read_memory (address + get_java_object_header_size (gdbarch), buf4, 4); length = (long) extract_signed_integer (buf4, 4, byte_order); fprintf_filtered (stream, "{length: %ld", length); if (el_type == NULL) { CORE_ADDR element; CORE_ADDR next_element = -1; /* dummy initial value */ /* Skip object header and length. */ address += get_java_object_header_size (gdbarch) + 4; while (i < length && things_printed < options->print_max) { gdb_byte *buf; buf = alloca (gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT); fputs_filtered (", ", stream); wrap_here (n_spaces (2)); if (i > 0) element = next_element; else { read_memory (address, buf, sizeof (buf)); address += gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT; /* FIXME: cagney/2003-05-24: Bogus or what. It pulls a host sized pointer out of the target and then extracts that as an address (while assuming that the address is unsigned)! */ element = extract_unsigned_integer (buf, sizeof (buf), byte_order); } for (reps = 1; i + reps < length; reps++) { read_memory (address, buf, sizeof (buf)); address += gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT; /* FIXME: cagney/2003-05-24: Bogus or what. It pulls a host sized pointer out of the target and then extracts that as an address (while assuming that the address is unsigned)! */ next_element = extract_unsigned_integer (buf, sizeof (buf), byte_order); if (next_element != element) break; } if (reps == 1) fprintf_filtered (stream, "%d: ", i); else fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); if (element == 0) fprintf_filtered (stream, "null"); else fprintf_filtered (stream, "@%s", paddress (gdbarch, element)); things_printed++; i += reps; } } else { struct value *v = allocate_value (el_type); struct value *next_v = allocate_value (el_type); set_value_address (v, (address + get_java_object_header_size (gdbarch) + 4)); set_value_address (next_v, value_raw_address (v)); while (i < length && things_printed < options->print_max) { fputs_filtered (", ", stream); wrap_here (n_spaces (2)); if (i > 0) { struct value *tmp; tmp = next_v; next_v = v; v = tmp; } else { set_value_lazy (v, 1); set_value_offset (v, 0); } set_value_offset (next_v, value_offset (v)); for (reps = 1; i + reps < length; reps++) { set_value_lazy (next_v, 1); set_value_offset (next_v, value_offset (next_v) + TYPE_LENGTH (el_type)); if (memcmp (value_contents (v), value_contents (next_v), TYPE_LENGTH (el_type)) != 0) break; } if (reps == 1) fprintf_filtered (stream, "%d: ", i); else fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); opts = *options; opts.deref_ref = 1; common_val_print (v, stream, 1, &opts, current_language); things_printed++; i += reps; } } if (i < length) fprintf_filtered (stream, "..."); fprintf_filtered (stream, "}"); return 0; } /* If it's type String, print it */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_TARGET_TYPE (type) && TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)) && strcmp (TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0 && (options->format == 0 || options->format == 's') && address != 0 && value_as_address (val) != 0) { struct type *char_type; struct value *data_val; CORE_ADDR data; struct value *boffset_val; unsigned long boffset; struct value *count_val; unsigned long count; struct value *mark; mark = value_mark (); /* Remember start of new values */ data_val = value_struct_elt (&val, NULL, "data", NULL, NULL); data = value_as_address (data_val); boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL); boffset = value_as_address (boffset_val); count_val = value_struct_elt (&val, NULL, "count", NULL, NULL); count = value_as_address (count_val); value_free_to_mark (mark); /* Release unnecessary values */ char_type = builtin_java_type (gdbarch)->builtin_char; val_print_string (char_type, data + boffset, count, stream, options); return 0; } opts = *options; opts.deref_ref = 1; return common_val_print (val, stream, 0, &opts, current_language); }
static void i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); const struct target_desc *tdesc = info.target_desc; struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info; const struct tdesc_feature *feature; int valid_p; gdb_assert (tdesc_data); linux_init_abi (info, gdbarch); /* GNU/Linux uses ELF. */ i386_elf_init_abi (info, gdbarch); /* Reserve a number for orig_eax. */ set_gdbarch_num_regs (gdbarch, I386_LINUX_NUM_REGS); if (! tdesc_has_registers (tdesc)) tdesc = tdesc_i386_linux; tdep->tdesc = tdesc; feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); if (feature == NULL) return; valid_p = tdesc_numbered_register (feature, tdesc_data, I386_LINUX_ORIG_EAX_REGNUM, "orig_eax"); if (!valid_p) return; /* Add the %orig_eax register used for syscall restarting. */ set_gdbarch_write_pc (gdbarch, i386_linux_write_pc); tdep->register_reggroup_p = i386_linux_register_reggroup_p; tdep->gregset_reg_offset = i386_linux_gregset_reg_offset; tdep->gregset_num_regs = ARRAY_SIZE (i386_linux_gregset_reg_offset); tdep->sizeof_gregset = 17 * 4; tdep->jb_pc_offset = 20; /* From <bits/setjmp.h>. */ tdep->sigtramp_p = i386_linux_sigtramp_p; tdep->sigcontext_addr = i386_linux_sigcontext_addr; tdep->sc_reg_offset = i386_linux_sc_reg_offset; tdep->sc_num_regs = ARRAY_SIZE (i386_linux_sc_reg_offset); tdep->xsave_xcr0_offset = I386_LINUX_XSAVE_XCR0_OFFSET; set_gdbarch_process_record (gdbarch, i386_process_record); set_gdbarch_process_record_signal (gdbarch, i386_linux_record_signal); /* Initialize the i386_linux_record_tdep. */ /* These values are the size of the type that will be used in a system call. They are obtained from Linux Kernel source. */ i386_linux_record_tdep.size_pointer = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; i386_linux_record_tdep.size__old_kernel_stat = 32; i386_linux_record_tdep.size_tms = 16; i386_linux_record_tdep.size_loff_t = 8; i386_linux_record_tdep.size_flock = 16; i386_linux_record_tdep.size_oldold_utsname = 45; i386_linux_record_tdep.size_ustat = 20; i386_linux_record_tdep.size_old_sigaction = 140; i386_linux_record_tdep.size_old_sigset_t = 128; i386_linux_record_tdep.size_rlimit = 8; i386_linux_record_tdep.size_rusage = 72; i386_linux_record_tdep.size_timeval = 8; i386_linux_record_tdep.size_timezone = 8; i386_linux_record_tdep.size_old_gid_t = 2; i386_linux_record_tdep.size_old_uid_t = 2; i386_linux_record_tdep.size_fd_set = 128; i386_linux_record_tdep.size_dirent = 268; i386_linux_record_tdep.size_dirent64 = 276; i386_linux_record_tdep.size_statfs = 64; i386_linux_record_tdep.size_statfs64 = 84; i386_linux_record_tdep.size_sockaddr = 16; i386_linux_record_tdep.size_int = gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT; i386_linux_record_tdep.size_long = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT; i386_linux_record_tdep.size_ulong = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT; i386_linux_record_tdep.size_msghdr = 28; i386_linux_record_tdep.size_itimerval = 16; i386_linux_record_tdep.size_stat = 88; i386_linux_record_tdep.size_old_utsname = 325; i386_linux_record_tdep.size_sysinfo = 64; i386_linux_record_tdep.size_msqid_ds = 88; i386_linux_record_tdep.size_shmid_ds = 84; i386_linux_record_tdep.size_new_utsname = 390; i386_linux_record_tdep.size_timex = 128; i386_linux_record_tdep.size_mem_dqinfo = 24; i386_linux_record_tdep.size_if_dqblk = 68; i386_linux_record_tdep.size_fs_quota_stat = 68; i386_linux_record_tdep.size_timespec = 8; i386_linux_record_tdep.size_pollfd = 8; i386_linux_record_tdep.size_NFS_FHSIZE = 32; i386_linux_record_tdep.size_knfsd_fh = 132; i386_linux_record_tdep.size_TASK_COMM_LEN = 16; i386_linux_record_tdep.size_sigaction = 140; i386_linux_record_tdep.size_sigset_t = 8; i386_linux_record_tdep.size_siginfo_t = 128; i386_linux_record_tdep.size_cap_user_data_t = 12; i386_linux_record_tdep.size_stack_t = 12; i386_linux_record_tdep.size_off_t = i386_linux_record_tdep.size_long; i386_linux_record_tdep.size_stat64 = 96; i386_linux_record_tdep.size_gid_t = 2; i386_linux_record_tdep.size_uid_t = 2; i386_linux_record_tdep.size_PAGE_SIZE = 4096; i386_linux_record_tdep.size_flock64 = 24; i386_linux_record_tdep.size_user_desc = 16; i386_linux_record_tdep.size_io_event = 32; i386_linux_record_tdep.size_iocb = 64; i386_linux_record_tdep.size_epoll_event = 12; i386_linux_record_tdep.size_itimerspec = i386_linux_record_tdep.size_timespec * 2; i386_linux_record_tdep.size_mq_attr = 32; i386_linux_record_tdep.size_siginfo = 128; i386_linux_record_tdep.size_termios = 36; i386_linux_record_tdep.size_termios2 = 44; i386_linux_record_tdep.size_pid_t = 4; i386_linux_record_tdep.size_winsize = 8; i386_linux_record_tdep.size_serial_struct = 60; i386_linux_record_tdep.size_serial_icounter_struct = 80; i386_linux_record_tdep.size_hayes_esp_config = 12; i386_linux_record_tdep.size_size_t = 4; i386_linux_record_tdep.size_iovec = 8; /* These values are the second argument of system call "sys_ioctl". They are obtained from Linux Kernel source. */ i386_linux_record_tdep.ioctl_TCGETS = 0x5401; i386_linux_record_tdep.ioctl_TCSETS = 0x5402; i386_linux_record_tdep.ioctl_TCSETSW = 0x5403; i386_linux_record_tdep.ioctl_TCSETSF = 0x5404; i386_linux_record_tdep.ioctl_TCGETA = 0x5405; i386_linux_record_tdep.ioctl_TCSETA = 0x5406; i386_linux_record_tdep.ioctl_TCSETAW = 0x5407; i386_linux_record_tdep.ioctl_TCSETAF = 0x5408; i386_linux_record_tdep.ioctl_TCSBRK = 0x5409; i386_linux_record_tdep.ioctl_TCXONC = 0x540A; i386_linux_record_tdep.ioctl_TCFLSH = 0x540B; i386_linux_record_tdep.ioctl_TIOCEXCL = 0x540C; i386_linux_record_tdep.ioctl_TIOCNXCL = 0x540D; i386_linux_record_tdep.ioctl_TIOCSCTTY = 0x540E; i386_linux_record_tdep.ioctl_TIOCGPGRP = 0x540F; i386_linux_record_tdep.ioctl_TIOCSPGRP = 0x5410; i386_linux_record_tdep.ioctl_TIOCOUTQ = 0x5411; i386_linux_record_tdep.ioctl_TIOCSTI = 0x5412; i386_linux_record_tdep.ioctl_TIOCGWINSZ = 0x5413; i386_linux_record_tdep.ioctl_TIOCSWINSZ = 0x5414; i386_linux_record_tdep.ioctl_TIOCMGET = 0x5415; i386_linux_record_tdep.ioctl_TIOCMBIS = 0x5416; i386_linux_record_tdep.ioctl_TIOCMBIC = 0x5417; i386_linux_record_tdep.ioctl_TIOCMSET = 0x5418; i386_linux_record_tdep.ioctl_TIOCGSOFTCAR = 0x5419; i386_linux_record_tdep.ioctl_TIOCSSOFTCAR = 0x541A; i386_linux_record_tdep.ioctl_FIONREAD = 0x541B; i386_linux_record_tdep.ioctl_TIOCINQ = i386_linux_record_tdep.ioctl_FIONREAD; i386_linux_record_tdep.ioctl_TIOCLINUX = 0x541C; i386_linux_record_tdep.ioctl_TIOCCONS = 0x541D; i386_linux_record_tdep.ioctl_TIOCGSERIAL = 0x541E; i386_linux_record_tdep.ioctl_TIOCSSERIAL = 0x541F; i386_linux_record_tdep.ioctl_TIOCPKT = 0x5420; i386_linux_record_tdep.ioctl_FIONBIO = 0x5421; i386_linux_record_tdep.ioctl_TIOCNOTTY = 0x5422; i386_linux_record_tdep.ioctl_TIOCSETD = 0x5423; i386_linux_record_tdep.ioctl_TIOCGETD = 0x5424; i386_linux_record_tdep.ioctl_TCSBRKP = 0x5425; i386_linux_record_tdep.ioctl_TIOCTTYGSTRUCT = 0x5426; i386_linux_record_tdep.ioctl_TIOCSBRK = 0x5427; i386_linux_record_tdep.ioctl_TIOCCBRK = 0x5428; i386_linux_record_tdep.ioctl_TIOCGSID = 0x5429; i386_linux_record_tdep.ioctl_TCGETS2 = 0x802c542a; i386_linux_record_tdep.ioctl_TCSETS2 = 0x402c542b; i386_linux_record_tdep.ioctl_TCSETSW2 = 0x402c542c; i386_linux_record_tdep.ioctl_TCSETSF2 = 0x402c542d; i386_linux_record_tdep.ioctl_TIOCGPTN = 0x80045430; i386_linux_record_tdep.ioctl_TIOCSPTLCK = 0x40045431; i386_linux_record_tdep.ioctl_FIONCLEX = 0x5450; i386_linux_record_tdep.ioctl_FIOCLEX = 0x5451; i386_linux_record_tdep.ioctl_FIOASYNC = 0x5452; i386_linux_record_tdep.ioctl_TIOCSERCONFIG = 0x5453; i386_linux_record_tdep.ioctl_TIOCSERGWILD = 0x5454; i386_linux_record_tdep.ioctl_TIOCSERSWILD = 0x5455; i386_linux_record_tdep.ioctl_TIOCGLCKTRMIOS = 0x5456; i386_linux_record_tdep.ioctl_TIOCSLCKTRMIOS = 0x5457; i386_linux_record_tdep.ioctl_TIOCSERGSTRUCT = 0x5458; i386_linux_record_tdep.ioctl_TIOCSERGETLSR = 0x5459; i386_linux_record_tdep.ioctl_TIOCSERGETMULTI = 0x545A; i386_linux_record_tdep.ioctl_TIOCSERSETMULTI = 0x545B; i386_linux_record_tdep.ioctl_TIOCMIWAIT = 0x545C; i386_linux_record_tdep.ioctl_TIOCGICOUNT = 0x545D; i386_linux_record_tdep.ioctl_TIOCGHAYESESP = 0x545E; i386_linux_record_tdep.ioctl_TIOCSHAYESESP = 0x545F; i386_linux_record_tdep.ioctl_FIOQSIZE = 0x5460; /* These values are the second argument of system call "sys_fcntl" and "sys_fcntl64". They are obtained from Linux Kernel source. */ i386_linux_record_tdep.fcntl_F_GETLK = 5; i386_linux_record_tdep.fcntl_F_GETLK64 = 12; i386_linux_record_tdep.fcntl_F_SETLK64 = 13; i386_linux_record_tdep.fcntl_F_SETLKW64 = 14; i386_linux_record_tdep.arg1 = I386_EBX_REGNUM; i386_linux_record_tdep.arg2 = I386_ECX_REGNUM; i386_linux_record_tdep.arg3 = I386_EDX_REGNUM; i386_linux_record_tdep.arg4 = I386_ESI_REGNUM; i386_linux_record_tdep.arg5 = I386_EDI_REGNUM; i386_linux_record_tdep.arg6 = I386_EBP_REGNUM; tdep->i386_intx80_record = i386_linux_intx80_sysenter_syscall_record; tdep->i386_sysenter_record = i386_linux_intx80_sysenter_syscall_record; tdep->i386_syscall_record = i386_linux_intx80_sysenter_syscall_record; /* N_FUN symbols in shared libaries have 0 for their values and need to be relocated. */ set_gdbarch_sofun_address_maybe_missing (gdbarch, 1); /* GNU/Linux uses SVR4-style shared libraries. */ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); /* GNU/Linux uses the dynamic linker included in the GNU C Library. */ set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); dwarf2_frame_set_signal_frame_p (gdbarch, i386_linux_dwarf_signal_frame_p); /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); /* Install supported register note sections. */ if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx")) set_gdbarch_core_regset_sections (gdbarch, i386_linux_avx_regset_sections); else if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.sse")) set_gdbarch_core_regset_sections (gdbarch, i386_linux_sse_regset_sections); else set_gdbarch_core_regset_sections (gdbarch, i386_linux_regset_sections); set_gdbarch_core_read_description (gdbarch, i386_linux_core_read_description); /* Displaced stepping. */ set_gdbarch_displaced_step_copy_insn (gdbarch, i386_linux_displaced_step_copy_insn); set_gdbarch_displaced_step_fixup (gdbarch, i386_displaced_step_fixup); set_gdbarch_displaced_step_free_closure (gdbarch, simple_displaced_step_free_closure); set_gdbarch_displaced_step_location (gdbarch, displaced_step_at_entry_point); /* Functions for 'catch syscall'. */ set_xml_syscall_file_name (XML_SYSCALL_FILENAME_I386); set_gdbarch_get_syscall_number (gdbarch, i386_linux_get_syscall_number); set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type); }
static struct gdbarch * tilegx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch *gdbarch; int arch_size = 64; /* Handle arch_size == 32 or 64. Default to 64. */ if (info.abfd) arch_size = bfd_get_arch_size (info.abfd); /* Try to find a pre-existing architecture. */ for (arches = gdbarch_list_lookup_by_info (arches, &info); arches != NULL; arches = gdbarch_list_lookup_by_info (arches->next, &info)) { /* We only have two flavors -- just make sure arch_size matches. */ if (gdbarch_ptr_bit (arches->gdbarch) == arch_size) return (arches->gdbarch); } gdbarch = gdbarch_alloc (&info, NULL); /* Basic register fields and methods, datatype sizes and stuff. */ /* There are 64 physical registers which can be referenced by instructions (although only 56 of them can actually be debugged) and 1 magic register (the PC). The other three magic registers (ex1, syscall, orig_r0) which are known to "ptrace" are ignored by "gdb". Note that we simply pretend that there are 65 registers, and no "pseudo registers". */ set_gdbarch_num_regs (gdbarch, TILEGX_NUM_REGS); set_gdbarch_num_pseudo_regs (gdbarch, 0); set_gdbarch_sp_regnum (gdbarch, TILEGX_SP_REGNUM); set_gdbarch_pc_regnum (gdbarch, TILEGX_PC_REGNUM); set_gdbarch_register_name (gdbarch, tilegx_register_name); set_gdbarch_register_type (gdbarch, tilegx_register_type); set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT); set_gdbarch_long_bit (gdbarch, arch_size); set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT); set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT); set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); set_gdbarch_ptr_bit (gdbarch, arch_size); set_gdbarch_addr_bit (gdbarch, arch_size); set_gdbarch_cannot_fetch_register (gdbarch, tilegx_cannot_reference_register); set_gdbarch_cannot_store_register (gdbarch, tilegx_cannot_reference_register); /* Stack grows down. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); /* Frame Info. */ set_gdbarch_unwind_sp (gdbarch, tilegx_unwind_sp); set_gdbarch_unwind_pc (gdbarch, tilegx_unwind_pc); set_gdbarch_dummy_id (gdbarch, tilegx_unwind_dummy_id); set_gdbarch_frame_align (gdbarch, tilegx_frame_align); frame_base_set_default (gdbarch, &tilegx_frame_base); set_gdbarch_skip_prologue (gdbarch, tilegx_skip_prologue); set_gdbarch_stack_frame_destroyed_p (gdbarch, tilegx_stack_frame_destroyed_p); /* Map debug registers into internal register numbers. */ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, tilegx_dwarf2_reg_to_regnum); /* These values and methods are used when gdb calls a target function. */ set_gdbarch_push_dummy_call (gdbarch, tilegx_push_dummy_call); set_gdbarch_get_longjmp_target (gdbarch, tilegx_get_longjmp_target); set_gdbarch_write_pc (gdbarch, tilegx_write_pc); set_gdbarch_breakpoint_from_pc (gdbarch, tilegx_breakpoint_from_pc); set_gdbarch_return_value (gdbarch, tilegx_return_value); set_gdbarch_print_insn (gdbarch, print_insn_tilegx); gdbarch_init_osabi (info, gdbarch); dwarf2_append_unwinders (gdbarch); frame_unwind_append_unwinder (gdbarch, &tilegx_frame_unwind); return gdbarch; }
/* Return a GDB type representing `struct gdb_gnu_v3_abi_vtable', described above, laid out appropriately for ARCH. We use this function as the gdbarch per-architecture data initialization function. */ static void * build_gdb_vtable_type (struct gdbarch *arch) { struct type *t; struct field *field_list, *field; int offset; struct type *void_ptr_type = builtin_type (arch)->builtin_data_ptr; struct type *ptr_to_void_fn_type = builtin_type (arch)->builtin_func_ptr; /* ARCH can't give us the true ptrdiff_t type, so we guess. */ struct type *ptrdiff_type = arch_integer_type (arch, gdbarch_ptr_bit (arch), 0, "ptrdiff_t"); /* We assume no padding is necessary, since GDB doesn't know anything about alignment at the moment. If this assumption bites us, we should add a gdbarch method which, given a type, returns the alignment that type requires, and then use that here. */ /* Build the field list. */ field_list = xmalloc (sizeof (struct field [4])); memset (field_list, 0, sizeof (struct field [4])); field = &field_list[0]; offset = 0; /* ptrdiff_t vcall_and_vbase_offsets[0]; */ FIELD_NAME (*field) = "vcall_and_vbase_offsets"; FIELD_TYPE (*field) = lookup_array_range_type (ptrdiff_type, 0, -1); SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* ptrdiff_t offset_to_top; */ FIELD_NAME (*field) = "offset_to_top"; FIELD_TYPE (*field) = ptrdiff_type; SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* void *type_info; */ FIELD_NAME (*field) = "type_info"; FIELD_TYPE (*field) = void_ptr_type; SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* void (*virtual_functions[0]) (); */ FIELD_NAME (*field) = "virtual_functions"; FIELD_TYPE (*field) = lookup_array_range_type (ptr_to_void_fn_type, 0, -1); SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* We assumed in the allocation above that there were four fields. */ gdb_assert (field == (field_list + 4)); t = arch_type (arch, TYPE_CODE_STRUCT, offset, NULL); TYPE_NFIELDS (t) = field - field_list; TYPE_FIELDS (t) = field_list; TYPE_TAG_NAME (t) = "gdb_gnu_v3_abi_vtable"; INIT_CPLUS_SPECIFIC (t); return t; }
static CORE_ADDR hppa_hpux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) { struct gdbarch *gdbarch = get_frame_arch (frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int word_size = gdbarch_ptr_bit (gdbarch) / 8; long orig_pc = pc; long prev_inst, curr_inst, loc; struct minimal_symbol *msym; struct unwind_table_entry *u; /* Addresses passed to dyncall may *NOT* be the actual address of the function. So we may have to do something special. */ if (pc == hppa_symbol_address("$$dyncall")) { pc = (CORE_ADDR) get_frame_register_unsigned (frame, 22); /* If bit 30 (counting from the left) is on, then pc is the address of the PLT entry for this function, not the address of the function itself. Bit 31 has meaning too, but only for MPE. */ if (pc & 0x2) pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, word_size, byte_order); } if (pc == hppa_symbol_address("$$dyncall_external")) { pc = (CORE_ADDR) get_frame_register_unsigned (frame, 22); pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, word_size, byte_order); } else if (pc == hppa_symbol_address("_sr4export")) pc = (CORE_ADDR) get_frame_register_unsigned (frame, 22); /* Get the unwind descriptor corresponding to PC, return zero if no unwind was found. */ u = find_unwind_entry (pc); if (!u) return 0; /* If this isn't a linker stub, then return now. */ /* elz: attention here! (FIXME) because of a compiler/linker error, some stubs which should have a non zero stub_unwind.stub_type have unfortunately a value of zero. So this function would return here as if we were not in a trampoline. To fix this, we go look at the partial symbol information, which reports this guy as a stub. (FIXME): Unfortunately, we are not that lucky: it turns out that the partial symbol information is also wrong sometimes. This is because when it is entered (somread.c::som_symtab_read()) it can happen that if the type of the symbol (from the som) is Entry, and the symbol is in a shared library, then it can also be a trampoline. This would be OK, except that I believe the way they decide if we are ina shared library does not work. SOOOO..., even if we have a regular function w/o trampolines its minimal symbol can be assigned type mst_solib_trampoline. Also, if we find that the symbol is a real stub, then we fix the unwind descriptor, and define the stub type to be EXPORT. Hopefully this is correct most of the times. */ if (u->stub_unwind.stub_type == 0) { /* elz: NOTE (FIXME!) once the problem with the unwind information is fixed we can delete all the code which appears between the lines. */ /*--------------------------------------------------------------------------*/ msym = lookup_minimal_symbol_by_pc (pc); if (msym == NULL || MSYMBOL_TYPE (msym) != mst_solib_trampoline) return orig_pc == pc ? 0 : pc & ~0x3; else if (msym != NULL && MSYMBOL_TYPE (msym) == mst_solib_trampoline) { struct objfile *objfile; struct minimal_symbol *msymbol; int function_found = 0; /* Go look if there is another minimal symbol with the same name as this one, but with type mst_text. This would happen if the msym is an actual trampoline, in which case there would be another symbol with the same name corresponding to the real function. */ ALL_MSYMBOLS (objfile, msymbol) { if (MSYMBOL_TYPE (msymbol) == mst_text && strcmp (SYMBOL_LINKAGE_NAME (msymbol), SYMBOL_LINKAGE_NAME (msym)) == 0) { function_found = 1; break; } } if (function_found) /* The type of msym is correct (mst_solib_trampoline), but the unwind info is wrong, so set it to the correct value. */ u->stub_unwind.stub_type = EXPORT; else /* The stub type info in the unwind is correct (this is not a trampoline), but the msym type information is wrong, it should be mst_text. So we need to fix the msym, and also get out of this function. */ { MSYMBOL_TYPE (msym) = mst_text; return orig_pc == pc ? 0 : pc & ~0x3; } } /*--------------------------------------------------------------------------*/ }