void print_section_info (struct target_ops *t, bfd *abfd) { struct target_section *p; /* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64. */ int wid = gdbarch_addr_bit (gdbarch_from_bfd (abfd)) <= 32 ? 8 : 16; printf_filtered ("\t`%s', ", bfd_get_filename (abfd)); wrap_here (" "); printf_filtered (_("file type %s.\n"), bfd_get_target (abfd)); if (abfd == exec_bfd) printf_filtered (_("\tEntry point: %s\n"), paddress (bfd_get_start_address (abfd))); for (p = t->to_sections; p < t->to_sections_end; p++) { printf_filtered ("\t%s", hex_string_custom (p->addr, wid)); printf_filtered (" - %s", hex_string_custom (p->endaddr, wid)); /* FIXME: A format of "08l" is not wide enough for file offsets larger than 4GB. OTOH, making it "016l" isn't desirable either since most output will then be much wider than necessary. It may make sense to test the size of the file and choose the format string accordingly. */ /* FIXME: i18n: Need to rewrite this sentence. */ if (info_verbose) printf_filtered (" @ %s", hex_string_custom (p->the_bfd_section->filepos, 8)); printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section)); if (p->bfd != abfd) printf_filtered (" in %s", bfd_get_filename (p->bfd)); printf_filtered ("\n"); } }
static int amd64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction) { struct gdbarch *gdbarch = get_frame_arch (get_current_frame ()); /* Is the inferior 32-bit? If so, then do fixup the siginfo object. */ if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) { gdb_assert (sizeof (siginfo_t) == sizeof (compat_siginfo_t)); if (direction == 0) compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, native); else siginfo_from_compat_siginfo (native, (struct compat_siginfo *) inf); return 1; } /* No fixup for native x32 GDB. */ else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8) { gdb_assert (sizeof (siginfo_t) == sizeof (compat_x32_siginfo_t)); if (direction == 0) compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf, native); else siginfo_from_compat_x32_siginfo (native, (struct compat_x32_siginfo *) inf); return 1; } else return 0; }
static void tilegx_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { int arch_size = gdbarch_addr_bit (gdbarch); linux_init_abi (info, gdbarch); tramp_frame_prepend_unwinder (gdbarch, &tilegx_linux_rt_sigframe); set_gdbarch_iterate_over_regset_sections (gdbarch, tilegx_iterate_over_regset_sections); /* GNU/Linux uses SVR4-style shared libraries. */ if (arch_size == 32) set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); else set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_lp64_fetch_link_map_offsets); /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); /* Shared library handling. */ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); }
static gdb_byte * find_location_expression (struct dwarf2_loclist_baton *baton, size_t *locexpr_length, CORE_ADDR pc) { CORE_ADDR low, high; gdb_byte *loc_ptr, *buf_end; int length; unsigned int addr_size = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT; CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); /* Adjust base_address for relocatable objects. */ CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets, SECT_OFF_TEXT (baton->objfile)); CORE_ADDR base_address = baton->base_address + base_offset; loc_ptr = baton->data; buf_end = baton->data + baton->size; while (1) { low = dwarf2_read_address (loc_ptr, buf_end, &length); loc_ptr += length; high = dwarf2_read_address (loc_ptr, buf_end, &length); loc_ptr += length; /* An end-of-list entry. */ if (low == 0 && high == 0) return NULL; /* A base-address-selection entry. */ if ((low & base_mask) == base_mask) { base_address = high; continue; } /* Otherwise, a location expression entry. */ low += base_address; high += base_address; length = extract_unsigned_integer (loc_ptr, 2); loc_ptr += 2; if (pc >= low && pc < high) { *locexpr_length = length; return loc_ptr; } loc_ptr += length; } }
static void print_objfile_section_info (bfd *abfd, struct obj_section *asect, const char *string) { flagword flags = bfd_get_section_flags (abfd, asect->the_bfd_section); const char *name = bfd_section_name (abfd, asect->the_bfd_section); if (string == NULL || *string == '\0' || match_substring (string, name) || match_bfd_flags (string, flags)) { struct gdbarch *gdbarch = gdbarch_from_bfd (abfd); int addr_size = gdbarch_addr_bit (gdbarch) / 8; maint_print_section_info (name, flags, obj_section_addr (asect), obj_section_endaddr (asect), asect->the_bfd_section->filepos, addr_size); } }
static void print_bfd_section_info (bfd *abfd, asection *asect, void *arg) { flagword flags = bfd_get_section_flags (abfd, asect); const char *name = bfd_section_name (abfd, asect); if (arg == NULL || *((char *) arg) == '\0' || match_substring ((char *) arg, name) || match_bfd_flags ((char *) arg, flags)) { struct gdbarch *gdbarch = gdbarch_from_bfd (abfd); int addr_size = gdbarch_addr_bit (gdbarch) / 8; CORE_ADDR addr, endaddr; addr = bfd_section_vma (abfd, asect); endaddr = addr + bfd_section_size (abfd, asect); maint_print_section_info (name, flags, addr, endaddr, asect->filepos, addr_size); } }
static CORE_ADDR darwin_read_exec_load_addr_at_init (struct darwin_info *info) { struct gdbarch *gdbarch = target_gdbarch (); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int addr_size = gdbarch_addr_bit (gdbarch) / 8; ULONGEST load_ptr_addr; ULONGEST load_addr; gdb_byte buf[8]; /* Get SP. */ if (regcache_cooked_read_unsigned (get_current_regcache (), gdbarch_sp_regnum (gdbarch), &load_ptr_addr) != REG_VALID) return 0; /* Read value at SP (image load address). */ if (target_read_memory (load_ptr_addr, buf, addr_size)) return 0; load_addr = extract_unsigned_integer (buf, addr_size, byte_order); return darwin_validate_exec_header (load_addr); }
/* Analyze a prologue starting at START_PC, going no further than LIMIT_PC. Fill in RESULT as appropriate. */ static void rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc, struct rx_prologue *result) { CORE_ADDR pc, next_pc; int rn; pv_t reg[RX_NUM_REGS]; struct pv_area *stack; struct cleanup *back_to; CORE_ADDR after_last_frame_setup_insn = start_pc; memset (result, 0, sizeof (*result)); for (rn = 0; rn < RX_NUM_REGS; rn++) { reg[rn] = pv_register (rn, 0); result->reg_offset[rn] = 1; } stack = make_pv_area (RX_SP_REGNUM, gdbarch_addr_bit (target_gdbarch)); back_to = make_cleanup_free_pv_area (stack); /* The call instruction has saved the return address on the stack. */ reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4); pv_area_store (stack, reg[RX_SP_REGNUM], 4, reg[RX_PC_REGNUM]); pc = start_pc; while (pc < limit_pc) { int bytes_read; struct rx_get_opcode_byte_handle opcode_handle; RX_Opcode_Decoded opc; opcode_handle.pc = pc; bytes_read = rx_decode_opcode (pc, &opc, rx_get_opcode_byte, &opcode_handle); next_pc = pc + bytes_read; if (opc.id == RXO_pushm /* pushm r1, r2 */ && opc.op[1].type == RX_Operand_Register && opc.op[2].type == RX_Operand_Register) { int r1, r2; int r; r1 = opc.op[1].reg; r2 = opc.op[2].reg; for (r = r2; r >= r1; r--) { reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4); pv_area_store (stack, reg[RX_SP_REGNUM], 4, reg[r]); } after_last_frame_setup_insn = next_pc; } else if (opc.id == RXO_mov /* mov.l rdst, rsrc */ && opc.op[0].type == RX_Operand_Register && opc.op[1].type == RX_Operand_Register && opc.size == RX_Long) { int rdst, rsrc; rdst = opc.op[0].reg; rsrc = opc.op[1].reg; reg[rdst] = reg[rsrc]; if (rdst == RX_FP_REGNUM && rsrc == RX_SP_REGNUM) after_last_frame_setup_insn = next_pc; } else if (opc.id == RXO_mov /* mov.l rsrc, [-SP] */ && opc.op[0].type == RX_Operand_Predec && opc.op[0].reg == RX_SP_REGNUM && opc.op[1].type == RX_Operand_Register && opc.size == RX_Long) { int rsrc; rsrc = opc.op[1].reg; reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4); pv_area_store (stack, reg[RX_SP_REGNUM], 4, reg[rsrc]); after_last_frame_setup_insn = next_pc; } else if (opc.id == RXO_add /* add #const, rsrc, rdst */ && opc.op[0].type == RX_Operand_Register && opc.op[1].type == RX_Operand_Immediate && opc.op[2].type == RX_Operand_Register) { int rdst = opc.op[0].reg; int addend = opc.op[1].addend; int rsrc = opc.op[2].reg; reg[rdst] = pv_add_constant (reg[rsrc], addend); /* Negative adjustments to the stack pointer or frame pointer are (most likely) part of the prologue. */ if ((rdst == RX_SP_REGNUM || rdst == RX_FP_REGNUM) && addend < 0) after_last_frame_setup_insn = next_pc; } else if (opc.id == RXO_mov && opc.op[0].type == RX_Operand_Indirect && opc.op[1].type == RX_Operand_Register && opc.size == RX_Long && (opc.op[0].reg == RX_SP_REGNUM || opc.op[0].reg == RX_FP_REGNUM) && (RX_R1_REGNUM <= opc.op[1].reg && opc.op[1].reg <= RX_R4_REGNUM)) { /* This moves an argument register to the stack. Don't record it, but allow it to be a part of the prologue. */ } else if (opc.id == RXO_branch && opc.op[0].type == RX_Operand_Immediate && next_pc < opc.op[0].addend) { /* When a loop appears as the first statement of a function body, gcc 4.x will use a BRA instruction to branch to the loop condition checking code. This BRA instruction is marked as part of the prologue. We therefore set next_pc to this branch target and also stop the prologue scan. The instructions at and beyond the branch target should no longer be associated with the prologue. Note that we only consider forward branches here. We presume that a forward branch is being used to skip over a loop body. A backwards branch is covered by the default case below. If we were to encounter a backwards branch, that would most likely mean that we've scanned through a loop body. We definitely want to stop the prologue scan when this happens and that is precisely what is done by the default case below. */ after_last_frame_setup_insn = opc.op[0].addend; break; /* Scan no further if we hit this case. */ } else { /* Terminate the prologue scan. */ break; } pc = next_pc; } /* Is the frame size (offset, really) a known constant? */ if (pv_is_register (reg[RX_SP_REGNUM], RX_SP_REGNUM)) result->frame_size = reg[RX_SP_REGNUM].k; /* Was the frame pointer initialized? */ if (pv_is_register (reg[RX_FP_REGNUM], RX_SP_REGNUM)) { result->has_frame_ptr = 1; result->frame_ptr_offset = reg[RX_FP_REGNUM].k; } /* Record where all the registers were saved. */ pv_area_scan (stack, check_for_saved, (void *) result); result->prologue_end = after_last_frame_setup_insn; do_cleanups (back_to); }
static void msp430_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc, CORE_ADDR limit_pc, struct msp430_prologue *result) { CORE_ADDR pc, next_pc; int rn; pv_t reg[MSP430_NUM_TOTAL_REGS]; struct pv_area *stack; struct cleanup *back_to; CORE_ADDR after_last_frame_setup_insn = start_pc; int code_model = gdbarch_tdep (gdbarch)->code_model; int sz; memset (result, 0, sizeof (*result)); for (rn = 0; rn < MSP430_NUM_TOTAL_REGS; rn++) { reg[rn] = pv_register (rn, 0); result->reg_offset[rn] = 1; } stack = make_pv_area (MSP430_SP_REGNUM, gdbarch_addr_bit (gdbarch)); back_to = make_cleanup_free_pv_area (stack); /* The call instruction has saved the return address on the stack. */ sz = code_model == MSP_LARGE_CODE_MODEL ? 4 : 2; reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM], -sz); pv_area_store (stack, reg[MSP430_SP_REGNUM], sz, reg[MSP430_PC_REGNUM]); pc = start_pc; while (pc < limit_pc) { int bytes_read; struct msp430_get_opcode_byte_handle opcode_handle; MSP430_Opcode_Decoded opc; opcode_handle.pc = pc; bytes_read = msp430_decode_opcode (pc, &opc, msp430_get_opcode_byte, &opcode_handle); next_pc = pc + bytes_read; if (opc.id == MSO_push && opc.op[0].type == MSP430_Operand_Register) { int rsrc = opc.op[0].reg; reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM], -2); pv_area_store (stack, reg[MSP430_SP_REGNUM], 2, reg[rsrc]); after_last_frame_setup_insn = next_pc; } else if (opc.id == MSO_push /* PUSHM */ && opc.op[0].type == MSP430_Operand_None && opc.op[1].type == MSP430_Operand_Register) { int rsrc = opc.op[1].reg; int count = opc.repeats + 1; int size = opc.size == 16 ? 2 : 4; while (count > 0) { reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM], -size); pv_area_store (stack, reg[MSP430_SP_REGNUM], size, reg[rsrc]); rsrc--; count--; } after_last_frame_setup_insn = next_pc; } else if (opc.id == MSO_sub && opc.op[0].type == MSP430_Operand_Register && opc.op[0].reg == MSR_SP && opc.op[1].type == MSP430_Operand_Immediate) { int addend = opc.op[1].addend; reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM], -addend); after_last_frame_setup_insn = next_pc; } else if (opc.id == MSO_mov && opc.op[0].type == MSP430_Operand_Immediate && 12 <= opc.op[0].reg && opc.op[0].reg <= 15) after_last_frame_setup_insn = next_pc; else { /* Terminate the prologue scan. */ break; } pc = next_pc; } /* Is the frame size (offset, really) a known constant? */ if (pv_is_register (reg[MSP430_SP_REGNUM], MSP430_SP_REGNUM)) result->frame_size = reg[MSP430_SP_REGNUM].k; /* Record where all the registers were saved. */ pv_area_scan (stack, check_for_saved, result); result->prologue_end = after_last_frame_setup_insn; do_cleanups (back_to); }
static void darwin_debug_regions_recurse (task_t task) { mach_vm_address_t r_addr; mach_vm_address_t r_start; mach_vm_size_t r_size; natural_t r_depth; mach_msg_type_number_t r_info_size; vm_region_submap_short_info_data_64_t r_info; kern_return_t kret; int ret; struct cleanup *table_chain; struct ui_out *uiout = current_uiout; table_chain = make_cleanup_ui_out_table_begin_end (uiout, 9, -1, "regions"); if (gdbarch_addr_bit (target_gdbarch ()) <= 32) { ui_out_table_header (uiout, 10, ui_left, "start", "Start"); ui_out_table_header (uiout, 10, ui_left, "end", "End"); } else { ui_out_table_header (uiout, 18, ui_left, "start", "Start"); ui_out_table_header (uiout, 18, ui_left, "end", "End"); } ui_out_table_header (uiout, 3, ui_left, "min-prot", "Min"); ui_out_table_header (uiout, 3, ui_left, "max-prot", "Max"); ui_out_table_header (uiout, 5, ui_left, "inheritence", "Inh"); ui_out_table_header (uiout, 9, ui_left, "share-mode", "Shr"); ui_out_table_header (uiout, 1, ui_left, "depth", "D"); ui_out_table_header (uiout, 3, ui_left, "submap", "Sm"); ui_out_table_header (uiout, 0, ui_noalign, "tag", "Tag"); ui_out_table_body (uiout); r_start = 0; r_depth = 0; while (1) { const char *tag; struct cleanup *row_chain; r_info_size = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64; r_size = -1; kret = mach_vm_region_recurse (task, &r_start, &r_size, &r_depth, (vm_region_recurse_info_t) &r_info, &r_info_size); if (kret != KERN_SUCCESS) break; row_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "regions-row"); ui_out_field_core_addr (uiout, "start", target_gdbarch (), r_start); ui_out_field_core_addr (uiout, "end", target_gdbarch (), r_start + r_size); ui_out_field_string (uiout, "min-prot", unparse_protection (r_info.protection)); ui_out_field_string (uiout, "max-prot", unparse_protection (r_info.max_protection)); ui_out_field_string (uiout, "inheritence", unparse_inheritance (r_info.inheritance)); ui_out_field_string (uiout, "share-mode", unparse_share_mode (r_info.share_mode)); ui_out_field_int (uiout, "depth", r_depth); ui_out_field_string (uiout, "submap", r_info.is_submap ? _("sm ") : _("obj")); tag = unparse_user_tag (r_info.user_tag); if (tag) ui_out_field_string (uiout, "tag", tag); else ui_out_field_int (uiout, "tag", r_info.user_tag); do_cleanups (row_chain); if (!ui_out_is_mi_like_p (uiout)) ui_out_text (uiout, "\n"); if (r_info.is_submap) r_depth++; else r_start += r_size; } do_cleanups (table_chain); }
static void mem_info_command (char *args, int from_tty) { struct mem_region *m; struct mem_attrib *attrib; int ix; if (mem_use_target) printf_filtered (_("Using memory regions provided by the target.\n")); else printf_filtered (_("Using user-defined memory regions.\n")); require_target_regions (); if (!mem_region_list) { printf_unfiltered (_("There are no memory regions defined.\n")); return; } printf_filtered ("Num "); printf_filtered ("Enb "); printf_filtered ("Low Addr "); if (gdbarch_addr_bit (target_gdbarch ()) > 32) printf_filtered (" "); printf_filtered ("High Addr "); if (gdbarch_addr_bit (target_gdbarch ()) > 32) printf_filtered (" "); printf_filtered ("Attrs "); printf_filtered ("\n"); for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) { char *tmp; printf_filtered ("%-3d %-3c\t", m->number, m->enabled_p ? 'y' : 'n'); if (gdbarch_addr_bit (target_gdbarch ()) <= 32) tmp = hex_string_custom (m->lo, 8); else tmp = hex_string_custom (m->lo, 16); printf_filtered ("%s ", tmp); if (gdbarch_addr_bit (target_gdbarch ()) <= 32) { if (m->hi == 0) tmp = "0x100000000"; else tmp = hex_string_custom (m->hi, 8); } else { if (m->hi == 0) tmp = "0x10000000000000000"; else tmp = hex_string_custom (m->hi, 16); } printf_filtered ("%s ", tmp); /* Print a token for each attribute. * FIXME: Should we output a comma after each token? It may * make it easier for users to read, but we'd lose the ability * to cut-and-paste the list of attributes when defining a new * region. Perhaps that is not important. * * FIXME: If more attributes are added to GDB, the output may * become cluttered and difficult for users to read. At that * time, we may want to consider printing tokens only if they * are different from the default attribute. */ attrib = &m->attrib; switch (attrib->mode) { case MEM_RW: printf_filtered ("rw "); break; case MEM_RO: printf_filtered ("ro "); break; case MEM_WO: printf_filtered ("wo "); break; case MEM_FLASH: printf_filtered ("flash blocksize 0x%x ", attrib->blocksize); break; } switch (attrib->width) { case MEM_WIDTH_8: printf_filtered ("8 "); break; case MEM_WIDTH_16: printf_filtered ("16 "); break; case MEM_WIDTH_32: printf_filtered ("32 "); break; case MEM_WIDTH_64: printf_filtered ("64 "); break; case MEM_WIDTH_UNSPECIFIED: break; } #if 0 if (attrib->hwbreak) printf_filtered ("hwbreak"); else printf_filtered ("swbreak"); #endif if (attrib->cache) printf_filtered ("cache "); else printf_filtered ("nocache "); #if 0 if (attrib->verify) printf_filtered ("verify "); else printf_filtered ("noverify "); #endif printf_filtered ("\n"); gdb_flush (gdb_stdout); } }