static void exec_reverse_once (char *cmd, char *args, int from_tty) { char *reverse_command; enum exec_direction_kind dir = execution_direction; struct cleanup *old_chain; if (dir == EXEC_REVERSE) error (_("Already in reverse mode. Use '%s' or 'set exec-dir forward'."), cmd); if (!target_can_execute_reverse) error (_("Target %s does not support this command."), target_shortname); reverse_command = xstrprintf ("%s %s", cmd, args ? args : ""); old_chain = make_cleanup (exec_direction_default, NULL); make_cleanup (xfree, reverse_command); execution_direction = EXEC_REVERSE; execute_command (reverse_command, from_tty); do_cleanups (old_chain); }
void mi_execute_cli_command (const char *cmd, int args_p, const char *args) { if (cmd != 0) { struct cleanup *old_cleanups; char *run; if (args_p) run = xstrprintf ("%s %s", cmd, args); else run = xstrdup (cmd); if (mi_debug_p) /* FIXME: gdb_???? */ fprintf_unfiltered (gdb_stdout, "cli=%s run=%s\n", cmd, run); old_cleanups = make_cleanup (xfree, run); execute_command ( /*ui */ run, 0 /*from_tty */ ); do_cleanups (old_cleanups); return; } }
/* Assign a value to a variable. The expression argument must be in the form A=2 or "A = 2" (I.e. if there are spaces it needs to be quoted. */ enum mi_cmd_result mi_cmd_data_assign (char *command, char **argv, int argc) { struct expression *expr; struct cleanup *old_chain; if (argc != 1) { mi_error_message = xstrprintf ("mi_cmd_data_assign: Usage: -data-assign expression"); return MI_CMD_ERROR; } /* NOTE what follows is a clone of set_command(). FIXME: ezannoni 01-12-1999: Need to decide what to do with this for libgdb purposes. */ expr = parse_expression (argv[0]); old_chain = make_cleanup (free_current_contents, &expr); evaluate_expression (expr); do_cleanups (old_chain); return MI_CMD_DONE; }
static void add_vsyscall_page (struct target_ops *target, int from_tty) { struct mem_range vsyscall_range; if (gdbarch_vsyscall_range (target_gdbarch (), &vsyscall_range)) { struct bfd *bfd; struct symbol_file_add_from_memory_args args; if (core_bfd != NULL) bfd = core_bfd; else if (exec_bfd != NULL) bfd = exec_bfd; else /* FIXME: cagney/2004-05-06: Should not require an existing BFD when trying to create a run-time BFD of the VSYSCALL page in the inferior. Unfortunately that's the current interface so for the moment bail. Introducing a ``bfd_runtime'' (a BFD created using the loaded image) file format should fix this. */ { warning (_("Could not load vsyscall page " "because no executable was specified")); return; } args.bfd = bfd; args.sysinfo_ehdr = vsyscall_range.start; args.size = vsyscall_range.length; args.name = xstrprintf ("system-supplied DSO at %s", paddress (target_gdbarch (), vsyscall_range.start)); /* Pass zero for FROM_TTY, because the action of loading the vsyscall DSO was not triggered by the user, even if the user typed "run" at the TTY. */ args.from_tty = 0; catch_exceptions (current_uiout, symbol_file_add_from_memory_wrapper, &args, RETURN_MASK_ALL); } }
enum mi_cmd_result mi_cmd_thread_select (char *command, char **argv, int argc) { enum gdb_rc rc; if (argc != 1) { mi_error_message = xstrprintf ("mi_cmd_thread_select: USAGE: threadnum."); return MI_CMD_ERROR; } else rc = gdb_thread_select (uiout, argv[0], &mi_error_message); /* RC is enum gdb_rc if it is successful (>=0) enum return_reason if not (<0). */ if ((int) rc < 0 && (enum return_reason) rc == RETURN_ERROR) return MI_CMD_ERROR; else if ((int) rc >= 0 && rc == GDB_RC_FAIL) return MI_CMD_ERROR; else return MI_CMD_DONE; }
static PyObject * salpy_str (PyObject *self) { char *s, *filename; sal_object *sal_obj; PyObject *result; struct symtab_and_line *sal = NULL; SALPY_REQUIRE_VALID (self, sal); sal_obj = (sal_object *) self; filename = (sal_obj->symtab == (symtab_object *) Py_None) ? "<unknown>" : sal_obj->symtab->symtab->filename; s = xstrprintf ("symbol and line for %s, line %d", filename, sal->line); result = PyString_FromString (s); xfree (s); return result; }
/* Interrupt the execution of the target. Note how we must play around with the token varialbes, in order to display the current token in the result of the interrupt command, and the previous execution token when the target finally stops. See comments in mi_cmd_execute. */ enum mi_cmd_result mi_cmd_exec_interrupt (char *args, int from_tty) { if (!target_executing) { mi_error_message = xstrprintf ("mi_cmd_exec_interrupt: Inferior not executing."); return MI_CMD_ERROR; } interrupt_target_command (args, from_tty); if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("^done", raw_stdout); xfree (last_async_command); if (previous_async_command) last_async_command = xstrdup (previous_async_command); xfree (previous_async_command); previous_async_command = NULL; mi_out_put (uiout, raw_stdout); mi_out_rewind (uiout); fputs_unfiltered ("\n", raw_stdout); return MI_CMD_QUIET; }
static LONGEST get_core_siginfo (bfd *abfd, gdb_byte *readbuf, ULONGEST offset, LONGEST len) { asection *section; char *section_name; const char *name = ".note.linuxcore.siginfo"; if (ptid_get_lwp (inferior_ptid)) section_name = xstrprintf ("%s/%ld", name, ptid_get_lwp (inferior_ptid)); else section_name = xstrdup (name); section = bfd_get_section_by_name (abfd, section_name); xfree (section_name); if (section == NULL) return -1; if (!bfd_get_section_contents (abfd, section, readbuf, offset, len)) return -1; return len; }
static enum target_xfer_status procfs_xfer_auxv (gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { char *pathname; int fd; ssize_t l; pathname = xstrprintf ("/proc/%d/auxv", ptid_get_pid (inferior_ptid)); fd = gdb_open_cloexec (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY, 0); xfree (pathname); if (fd < 0) return TARGET_XFER_E_IO; if (offset != (ULONGEST) 0 && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset) l = -1; else if (readbuf != NULL) l = read (fd, readbuf, (size_t) len); else l = write (fd, writebuf, (size_t) len); (void) close (fd); if (l < 0) return TARGET_XFER_E_IO; else if (l == 0) return TARGET_XFER_EOF; else { *xfered_len = (ULONGEST) l; return TARGET_XFER_OK; } }
static varobj_item * py_varobj_iter_next (struct varobj_iter *self) { struct py_varobj_iter *t = (struct py_varobj_iter *) self; struct cleanup *back_to; PyObject *item; PyObject *py_v; varobj_item *vitem; const char *name = NULL; if (!gdb_python_initialized) return NULL; back_to = varobj_ensure_python_env (self->var); item = PyIter_Next (t->iter); if (item == NULL) { /* Normal end of iteration. */ if (!PyErr_Occurred ()) return NULL; /* If we got a memory error, just use the text as the item. */ if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error)) { PyObject *type, *value, *trace; char *name_str, *value_str; PyErr_Fetch (&type, &value, &trace); value_str = gdbpy_exception_to_string (type, value); Py_XDECREF (type); Py_XDECREF (value); Py_XDECREF (trace); if (value_str == NULL) { gdbpy_print_stack (); return NULL; } name_str = xstrprintf ("<error at %d>", self->next_raw_index++); item = Py_BuildValue ("(ss)", name_str, value_str); xfree (name_str); xfree (value_str); if (item == NULL) { gdbpy_print_stack (); return NULL; } } else { /* Any other kind of error. */ gdbpy_print_stack (); return NULL; } } if (!PyArg_ParseTuple (item, "sO", &name, &py_v)) { gdbpy_print_stack (); error (_("Invalid item from the child list")); } vitem = XNEW (struct varobj_item); vitem->value = convert_value_from_python (py_v); if (vitem->value == NULL) gdbpy_print_stack (); vitem->name = xstrdup (name); self->next_raw_index++; do_cleanups (back_to); return vitem; }
static void ada_varobj_describe_struct_child (struct value *parent_value, struct type *parent_type, const char *parent_name, const char *parent_path_expr, int child_index, char **child_name, struct value **child_value, struct type **child_type, char **child_path_expr) { int fieldno; int childno = 0; gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT); for (fieldno = 0; fieldno < TYPE_NFIELDS (parent_type); fieldno++) { if (ada_is_ignored_field (parent_type, fieldno)) continue; if (ada_is_wrapper_field (parent_type, fieldno)) { struct value *elt_value; struct type *elt_type; int elt_n_children; ada_varobj_struct_elt (parent_value, parent_type, fieldno, &elt_value, &elt_type); if (ada_is_tagged_type (elt_type, 0)) { /* Same as in ada_varobj_get_struct_number_of_children: For tagged types, we must be careful to not call ada_varobj_get_number_of_children, to prevent our element from being fixed back into the parent. */ elt_n_children = ada_varobj_get_struct_number_of_children (elt_value, elt_type); } else elt_n_children = ada_varobj_get_number_of_children (elt_value, elt_type); /* Is the child we're looking for one of the children of this wrapper field? */ if (child_index - childno < elt_n_children) { if (ada_is_tagged_type (elt_type, 0)) { /* Same as in ada_varobj_get_struct_number_of_children: For tagged types, we must be careful to not call ada_varobj_describe_child, to prevent our element from being fixed back into the parent. */ ada_varobj_describe_struct_child (elt_value, elt_type, parent_name, parent_path_expr, child_index - childno, child_name, child_value, child_type, child_path_expr); } else ada_varobj_describe_child (elt_value, elt_type, parent_name, parent_path_expr, child_index - childno, child_name, child_value, child_type, child_path_expr); return; } /* The child we're looking for is beyond this wrapper field, so skip all its children. */ childno += elt_n_children; continue; } else if (ada_is_variant_part (parent_type, fieldno)) { /* In normal situations, the variant part of the record should have been "fixed". Or, in other words, it should have been replaced by the branch of the variant part that is relevant for our value. But there are still situations where this can happen, however (Eg. when our parent is a NULL pointer). We do not support showing this part of the record for now, so just pretend this field does not exist. */ continue; } if (childno == child_index) { if (child_name) { /* The name of the child is none other than the field's name, except that we need to strip suffixes from it. For instance, fields with alignment constraints will have an __XVA suffix added to them. */ const char *field_name = TYPE_FIELD_NAME (parent_type, fieldno); int child_name_len = ada_name_prefix_len (field_name); *child_name = xstrprintf ("%.*s", child_name_len, field_name); } if (child_value && parent_value) ada_varobj_struct_elt (parent_value, parent_type, fieldno, child_value, NULL); if (child_type) ada_varobj_struct_elt (parent_value, parent_type, fieldno, NULL, child_type); if (child_path_expr) { /* The name of the child is none other than the field's name, except that we need to strip suffixes from it. For instance, fields with alignment constraints will have an __XVA suffix added to them. */ const char *field_name = TYPE_FIELD_NAME (parent_type, fieldno); int child_name_len = ada_name_prefix_len (field_name); *child_path_expr = xstrprintf ("(%s).%.*s", parent_path_expr, child_name_len, field_name); } return; } childno++; } /* Something went wrong. Either we miscounted the number of children, or CHILD_INDEX was too high. But we should never reach here. We don't have enough information to recover nicely, so just raise an assertion failure. */ gdb_assert_not_reached ("unexpected code path"); }
static LONGEST linux_xfer_osdata_fds (gdb_byte *readbuf, ULONGEST offset, LONGEST len) { /* We make the process list snapshot when the object starts to be read. */ static const char *buf; static LONGEST len_avail = -1; static struct buffer buffer; if (offset == 0) { DIR *dirp; if (len_avail != -1 && len_avail != 0) buffer_free (&buffer); len_avail = 0; buf = NULL; buffer_init (&buffer); buffer_grow_str (&buffer, "<osdata type=\"files\">\n"); dirp = opendir ("/proc"); if (dirp) { struct dirent *dp; while ((dp = readdir (dirp)) != NULL) { struct stat statbuf; char procentry[sizeof ("/proc/4294967295")]; if (!isdigit (dp->d_name[0]) || NAMELEN (dp) > sizeof ("4294967295") - 1) continue; sprintf (procentry, "/proc/%s", dp->d_name); if (stat (procentry, &statbuf) == 0 && S_ISDIR (statbuf.st_mode)) { char *pathname; DIR *dirp2; PID_T pid; char command[32]; pid = atoi (dp->d_name); command_from_pid (command, sizeof (command), pid); pathname = xstrprintf ("/proc/%s/fd", dp->d_name); dirp2 = opendir (pathname); if (dirp2) { struct dirent *dp2; while ((dp2 = readdir (dirp2)) != NULL) { char *fdname; char buf[1000]; ssize_t rslt; if (!isdigit (dp2->d_name[0])) continue; fdname = xstrprintf ("%s/%s", pathname, dp2->d_name); rslt = readlink (fdname, buf, sizeof (buf) - 1); if (rslt >= 0) buf[rslt] = '\0'; buffer_xml_printf ( &buffer, "<item>" "<column name=\"pid\">%s</column>" "<column name=\"command\">%s</column>" "<column name=\"file descriptor\">%s</column>" "<column name=\"name\">%s</column>" "</item>", dp->d_name, command, dp2->d_name, (rslt >= 0 ? buf : dp2->d_name)); } closedir (dirp2); } xfree (pathname); } } closedir (dirp); } buffer_grow_str0 (&buffer, "</osdata>\n"); buf = buffer_finish (&buffer); len_avail = strlen (buf); } if (offset >= len_avail) { /* Done. Get rid of the buffer. */ buffer_free (&buffer); buf = NULL; len_avail = 0; return 0; } if (len > len_avail - offset) len = len_avail - offset; memcpy (readbuf, buf + offset, len); return len; }
static int add_pe_forwarded_sym (const char *sym_name, const char *forward_dll_name, const char *forward_func_name, int ordinal, const char *dll_name, struct objfile *objfile) { CORE_ADDR vma; struct bound_minimal_symbol msymbol; enum minimal_symbol_type msymtype; char *qualified_name, *bare_name; int forward_dll_name_len = strlen (forward_dll_name); int forward_func_name_len = strlen (forward_func_name); int forward_len = forward_dll_name_len + forward_func_name_len + 2; char *forward_qualified_name = alloca (forward_len); xsnprintf (forward_qualified_name, forward_len, "%s!%s", forward_dll_name, forward_func_name); msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name); if (!msymbol.minsym) { int i; for (i = 0; i < forward_dll_name_len; i++) forward_qualified_name[i] = tolower (forward_qualified_name[i]); msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name); } if (!msymbol.minsym) { if (debug_coff_pe_read) fprintf_unfiltered (gdb_stdlog, _("Unable to find function \"%s\" in" " dll \"%s\", forward of \"%s\" in dll \"%s\"\n"), forward_func_name, forward_dll_name, sym_name, dll_name); return 0; } if (debug_coff_pe_read > 1) fprintf_unfiltered (gdb_stdlog, _("Adding forwarded exported symbol" " \"%s\" in dll \"%s\", pointing to \"%s\"\n"), sym_name, dll_name, forward_qualified_name); vma = SYMBOL_VALUE_ADDRESS (msymbol.minsym); msymtype = MSYMBOL_TYPE (msymbol.minsym); /* Generate a (hopefully unique) qualified name using the first part of the dll name, e.g. KERNEL32!AddAtomA. This matches the style used by windbg from the "Microsoft Debugging Tools for Windows". */ if (sym_name == NULL || *sym_name == '\0') bare_name = xstrprintf ("#%d", ordinal); else bare_name = xstrdup (sym_name); qualified_name = xstrprintf ("%s!%s", dll_name, bare_name); prim_record_minimal_symbol (qualified_name, vma, msymtype, objfile); /* Enter the plain name as well, which might not be unique. */ prim_record_minimal_symbol (bare_name, vma, msymtype, objfile); xfree (qualified_name); xfree (bare_name); return 1; }
char * c_get_range_decl_name (const struct dynamic_prop *prop) { return xstrprintf ("__gdb_prop_%s", host_address_to_string (prop)); }
static LONGEST linux_xfer_osdata_threads (gdb_byte *readbuf, ULONGEST offset, LONGEST len) { /* We make the process list snapshot when the object starts to be read. */ static const char *buf; static LONGEST len_avail = -1; static struct buffer buffer; if (offset == 0) { DIR *dirp; if (len_avail != -1 && len_avail != 0) buffer_free (&buffer); len_avail = 0; buf = NULL; buffer_init (&buffer); buffer_grow_str (&buffer, "<osdata type=\"threads\">\n"); dirp = opendir ("/proc"); if (dirp) { struct dirent *dp; while ((dp = readdir (dirp)) != NULL) { struct stat statbuf; char procentry[sizeof ("/proc/4294967295")]; if (!isdigit (dp->d_name[0]) || NAMELEN (dp) > sizeof ("4294967295") - 1) continue; sprintf (procentry, "/proc/%s", dp->d_name); if (stat (procentry, &statbuf) == 0 && S_ISDIR (statbuf.st_mode)) { DIR *dirp2; char *pathname; PID_T pid; char command[32]; pathname = xstrprintf ("/proc/%s/task", dp->d_name); pid = atoi (dp->d_name); command_from_pid (command, sizeof (command), pid); dirp2 = opendir (pathname); if (dirp2) { struct dirent *dp2; while ((dp2 = readdir (dirp2)) != NULL) { PID_T tid; int core; if (!isdigit (dp2->d_name[0]) || NAMELEN (dp2) > sizeof ("4294967295") - 1) continue; tid = atoi (dp2->d_name); core = linux_common_core_of_thread (ptid_build (pid, tid, 0)); buffer_xml_printf ( &buffer, "<item>" "<column name=\"pid\">%lld</column>" "<column name=\"command\">%s</column>" "<column name=\"tid\">%lld</column>" "<column name=\"core\">%d</column>" "</item>", pid, command, tid, core); } closedir (dirp2); } xfree (pathname); } } closedir (dirp); } buffer_grow_str0 (&buffer, "</osdata>\n"); buf = buffer_finish (&buffer); len_avail = strlen (buf); } if (offset >= len_avail) { /* Done. Get rid of the buffer. */ buffer_free (&buffer); buf = NULL; len_avail = 0; return 0; } if (len > len_avail - offset) len = len_avail - offset; memcpy (readbuf, buf + offset, len); return len; }
/* Allocate a new variant structure, and set up default values for all the fields. */ static struct gdbarch_tdep * new_variant (void) { struct gdbarch_tdep *var; int r; var = XCNEW (struct gdbarch_tdep); var->frv_abi = FRV_ABI_EABI; var->num_gprs = 64; var->num_fprs = 64; var->num_hw_watchpoints = 0; var->num_hw_breakpoints = 0; /* By default, don't supply any general-purpose or floating-point register names. */ var->register_names = (char **) xmalloc ((frv_num_regs + frv_num_pseudo_regs) * sizeof (char *)); for (r = 0; r < frv_num_regs + frv_num_pseudo_regs; r++) var->register_names[r] = ""; /* Do, however, supply default names for the known special-purpose registers. */ var->register_names[pc_regnum] = "pc"; var->register_names[lr_regnum] = "lr"; var->register_names[lcr_regnum] = "lcr"; var->register_names[psr_regnum] = "psr"; var->register_names[ccr_regnum] = "ccr"; var->register_names[cccr_regnum] = "cccr"; var->register_names[tbr_regnum] = "tbr"; /* Debug registers. */ var->register_names[brr_regnum] = "brr"; var->register_names[dbar0_regnum] = "dbar0"; var->register_names[dbar1_regnum] = "dbar1"; var->register_names[dbar2_regnum] = "dbar2"; var->register_names[dbar3_regnum] = "dbar3"; /* iacc0 (Only found on MB93405.) */ var->register_names[iacc0h_regnum] = "iacc0h"; var->register_names[iacc0l_regnum] = "iacc0l"; var->register_names[iacc0_regnum] = "iacc0"; /* fsr0 (Found on FR555 and FR501.) */ var->register_names[fsr0_regnum] = "fsr0"; /* acc0 - acc7. The architecture provides for the possibility of many more (up to 64 total), but we don't want to make that big of a hole in the G packet. If we need more in the future, we'll add them elsewhere. */ for (r = acc0_regnum; r <= acc7_regnum; r++) { char *buf; buf = xstrprintf ("acc%d", r - acc0_regnum); var->register_names[r] = buf; } /* accg0 - accg7: These are one byte registers. The remote protocol provides the raw values packed four into a slot. accg0123 and accg4567 correspond to accg0 - accg3 and accg4-accg7 respectively. We don't provide names for accg0123 and accg4567 since the user will likely not want to see these raw values. */ for (r = accg0_regnum; r <= accg7_regnum; r++) { char *buf; buf = xstrprintf ("accg%d", r - accg0_regnum); var->register_names[r] = buf; } /* msr0 and msr1. */ var->register_names[msr0_regnum] = "msr0"; var->register_names[msr1_regnum] = "msr1"; /* gner and fner registers. */ var->register_names[gner0_regnum] = "gner0"; var->register_names[gner1_regnum] = "gner1"; var->register_names[fner0_regnum] = "fner0"; var->register_names[fner1_regnum] = "fner1"; return var; }
enum mi_cmd_result mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) { int regnum, numregs, changed; int i; struct cleanup *cleanup; /* Note that the test for a valid register must include checking the REGISTER_NAME because NUM_REGS may be allocated for the union of the register sets within a family of related processors. In this case, some entries of REGISTER_NAME will change depending upon the particular processor being debugged. */ numregs = NUM_REGS + NUM_PSEUDO_REGS; cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changed-registers"); if (argc == 0) /* No args, just do all the regs */ { for (regnum = 0; regnum < numregs; regnum++) { if (REGISTER_NAME (regnum) == NULL || *(REGISTER_NAME (regnum)) == '\0') continue; changed = register_changed_p (regnum); if (changed < 0) { do_cleanups (cleanup); mi_error_message = xstrprintf ("mi_cmd_data_list_changed_registers: Unable to read register contents."); return MI_CMD_ERROR; } else if (changed) ui_out_field_int (uiout, NULL, regnum); } } /* Else, list of register #s, just do listed regs */ for (i = 0; i < argc; i++) { regnum = atoi (argv[i]); if (regnum >= 0 && regnum < numregs && REGISTER_NAME (regnum) != NULL && *REGISTER_NAME (regnum) != '\000') { changed = register_changed_p (regnum); if (changed < 0) { do_cleanups (cleanup); mi_error_message = xstrprintf ("mi_cmd_data_list_register_change: Unable to read register contents."); return MI_CMD_ERROR; } else if (changed) ui_out_field_int (uiout, NULL, regnum); } else { do_cleanups (cleanup); mi_error_message = xstrprintf ("bad register number"); return MI_CMD_ERROR; } } do_cleanups (cleanup); return MI_CMD_DONE; }
static void get_core_register_section (struct regcache *regcache, const char *name, int which, const char *human_name, int required) { static char *section_name = NULL; struct bfd_section *section; bfd_size_type size; char *contents; xfree (section_name); if (ptid_get_lwp (inferior_ptid)) section_name = xstrprintf ("%s/%ld", name, ptid_get_lwp (inferior_ptid)); else section_name = xstrdup (name); section = bfd_get_section_by_name (core_bfd, section_name); if (! section) { if (required) warning (_("Couldn't find %s registers in core file."), human_name); return; } size = bfd_section_size (core_bfd, section); contents = alloca (size); if (! bfd_get_section_contents (core_bfd, section, contents, (file_ptr) 0, size)) { warning (_("Couldn't read %s registers from `%s' section in core file."), human_name, name); return; } if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) { const struct regset *regset; regset = gdbarch_regset_from_core_section (core_gdbarch, name, size); if (regset == NULL) { if (required) warning (_("Couldn't recognize %s registers in core file."), human_name); return; } regset->supply_regset (regset, regcache, -1, contents, size); return; } gdb_assert (core_vec); core_vec->core_read_registers (regcache, contents, size, which, ((CORE_ADDR) bfd_section_vma (core_bfd, section))); }
int cf_flag_name( int *vp, char *str, long extra, dbref player, char *cmd ) { char *numstr, *namestr, *tokst; FLAGENT *fp; int flagnum = -1; char *flagstr, *cp; numstr = strtok_r( str, " \t=,", &tokst ); namestr = strtok_r( NULL, " \t=,", &tokst ); if( numstr && ( strlen( numstr ) == 1 ) ) { flagnum = ( int ) strtol( numstr, ( char ** ) NULL, 10 ); } if( ( flagnum < 0 ) || ( flagnum > 9 ) ) { cf_log_notfound( player, cmd, "Not a marker flag", numstr ); return -1; } if( ( fp = letter_to_flag( *numstr ) ) == NULL ) { cf_log_notfound( player, cmd, "Marker flag", numstr ); return -1; } /* * Our conditions: The flag name MUST start with an underscore. It * must not conflict with the name of any existing flag. There is a * KNOWN MEMORY LEAK here -- if you name the flag and rename it * later, the old bit of memory for the name won't get freed. This * should pretty much never happen, since you're not going to run * around arbitrarily giving your flags new names all the time. */ flagstr = xstrprintf( "cf_flag_name", "_%s", namestr ); if( strlen( flagstr ) > 31 ) { cf_log_syntax( player, cmd, "Marker flag name too long: %s", namestr ); XFREE( flagstr, "cf_flag_name" ); } for( cp = flagstr; cp && *cp; cp++ ) { if( !isalnum( *cp ) && ( *cp != '_' ) ) { cf_log_syntax( player, cmd, "Illegal marker flag name: %s", namestr ); XFREE( flagstr, "cf_flag_name" ); return -1; } *cp = tolower( *cp ); } if( hashfind( flagstr, &mudstate.flags_htab ) ) { XFREE( flagstr, "cf_flag_name" ); cf_log_syntax( player, cmd, "Marker flag name in use: %s", namestr ); return -1; } for( cp = flagstr; cp && *cp; cp++ ) { *cp = toupper( *cp ); } fp->flagname = ( const char * ) flagstr; hashadd( ( char * ) fp->flagname, ( int * ) fp, &mudstate.flags_htab, 0 ); return 0; }
char * target_waitstatus_to_string (const struct target_waitstatus *ws) { const char *kind_str = "status->kind = "; switch (ws->kind) { case TARGET_WAITKIND_EXITED: return xstrprintf ("%sexited, status = %d", kind_str, ws->value.integer); case TARGET_WAITKIND_STOPPED: return xstrprintf ("%sstopped, signal = %s", kind_str, gdb_signal_to_symbol_string (ws->value.sig)); case TARGET_WAITKIND_SIGNALLED: return xstrprintf ("%ssignalled, signal = %s", kind_str, gdb_signal_to_symbol_string (ws->value.sig)); case TARGET_WAITKIND_LOADED: return xstrprintf ("%sloaded", kind_str); case TARGET_WAITKIND_FORKED: return xstrprintf ("%sforked", kind_str); case TARGET_WAITKIND_VFORKED: return xstrprintf ("%svforked", kind_str); case TARGET_WAITKIND_EXECD: return xstrprintf ("%sexecd", kind_str); case TARGET_WAITKIND_VFORK_DONE: return xstrprintf ("%svfork-done", kind_str); case TARGET_WAITKIND_SYSCALL_ENTRY: return xstrprintf ("%sentered syscall", kind_str); case TARGET_WAITKIND_SYSCALL_RETURN: return xstrprintf ("%sexited syscall", kind_str); case TARGET_WAITKIND_SPURIOUS: return xstrprintf ("%sspurious", kind_str); case TARGET_WAITKIND_IGNORE: return xstrprintf ("%signore", kind_str); case TARGET_WAITKIND_NO_HISTORY: return xstrprintf ("%sno-history", kind_str); case TARGET_WAITKIND_NO_RESUMED: return xstrprintf ("%sno-resumed", kind_str); case TARGET_WAITKIND_THREAD_CREATED: return xstrprintf ("%sthread created", kind_str); case TARGET_WAITKIND_THREAD_EXITED: return xstrprintf ("%sthread exited, status = %d", kind_str, ws->value.integer); default: return xstrprintf ("%sunknown???", kind_str); } }
/* Write given values into registers. The registers and values are given as pairs. The corresponding MI command is -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]*/ enum mi_cmd_result mi_cmd_data_write_register_values (char *command, char **argv, int argc) { int regnum; int i; int numregs; LONGEST value; char format; /* Note that the test for a valid register must include checking the REGISTER_NAME because NUM_REGS may be allocated for the union of the register sets within a family of related processors. In this case, some entries of REGISTER_NAME will change depending upon the particular processor being debugged. */ numregs = NUM_REGS + NUM_PSEUDO_REGS; if (argc == 0) { mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: Usage: -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]"); return MI_CMD_ERROR; } format = (int) argv[0][0]; if (!target_has_registers) { mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No registers."); return MI_CMD_ERROR; } if (!(argc - 1)) { mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No regs and values specified."); return MI_CMD_ERROR; } if ((argc - 1) % 2) { mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: Regs and vals are not in pairs."); return MI_CMD_ERROR; } for (i = 1; i < argc; i = i + 2) { regnum = atoi (argv[i]); if (regnum >= 0 && regnum < numregs && REGISTER_NAME (regnum) != NULL && *REGISTER_NAME (regnum) != '\000') { void *buffer; struct cleanup *old_chain; /* Get the value as a number */ value = parse_and_eval_address (argv[i + 1]); /* Get the value into an array */ buffer = xmalloc (DEPRECATED_REGISTER_SIZE); old_chain = make_cleanup (xfree, buffer); store_signed_integer (buffer, DEPRECATED_REGISTER_SIZE, value); /* Write it down */ deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (regnum), buffer, register_size (current_gdbarch, regnum)); /* Free the buffer. */ do_cleanups (old_chain); } else { mi_error_message = xstrprintf ("bad register number"); return MI_CMD_ERROR; } } return MI_CMD_DONE; }
/* Return a list of register number and value pairs. The valid arguments expected are: a letter indicating the format in which to display the registers contents. This can be one of: x (hexadecimal), d (decimal), N (natural), t (binary), o (octal), r (raw). After the format argumetn there can be a sequence of numbers, indicating which registers to fetch the content of. If the format is the only argument, a list of all the registers with their values is returned. */ enum mi_cmd_result mi_cmd_data_list_register_values (char *command, char **argv, int argc) { int regnum, numregs, format, result; int i; struct cleanup *list_cleanup, *tuple_cleanup; /* Note that the test for a valid register must include checking the REGISTER_NAME because NUM_REGS may be allocated for the union of the register sets within a family of related processors. In this case, some entries of REGISTER_NAME will change depending upon the particular processor being debugged. */ numregs = NUM_REGS + NUM_PSEUDO_REGS; if (argc == 0) { mi_error_message = xstrprintf ("mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> [<regnum1>...<regnumN>]"); return MI_CMD_ERROR; } format = (int) argv[0][0]; list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values"); if (argc == 1) /* No args, beside the format: do all the regs */ { for (regnum = 0; regnum < numregs; regnum++) { if (REGISTER_NAME (regnum) == NULL || *(REGISTER_NAME (regnum)) == '\0') continue; tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_int (uiout, "number", regnum); result = get_register (regnum, format); if (result == -1) { do_cleanups (list_cleanup); return MI_CMD_ERROR; } do_cleanups (tuple_cleanup); } } /* Else, list of register #s, just do listed regs */ for (i = 1; i < argc; i++) { regnum = atoi (argv[i]); if (regnum >= 0 && regnum < numregs && REGISTER_NAME (regnum) != NULL && *REGISTER_NAME (regnum) != '\000') { tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_int (uiout, "number", regnum); result = get_register (regnum, format); if (result == -1) { do_cleanups (list_cleanup); return MI_CMD_ERROR; } do_cleanups (tuple_cleanup); } else { do_cleanups (list_cleanup); mi_error_message = xstrprintf ("bad register number"); return MI_CMD_ERROR; } } do_cleanups (list_cleanup); return MI_CMD_DONE; }
static void ada_varobj_describe_simple_array_child (struct value *parent_value, struct type *parent_type, const char *parent_name, const char *parent_path_expr, int child_index, char **child_name, struct value **child_value, struct type **child_type, char **child_path_expr) { struct type *index_type; int real_index; gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_ARRAY); index_type = TYPE_INDEX_TYPE (parent_type); real_index = child_index + ada_discrete_type_low_bound (index_type); if (child_name) *child_name = ada_varobj_scalar_image (index_type, real_index); if (child_value && parent_value) ada_varobj_simple_array_elt (parent_value, parent_type, real_index, child_value, NULL); if (child_type) ada_varobj_simple_array_elt (parent_value, parent_type, real_index, NULL, child_type); if (child_path_expr) { char *index_img = ada_varobj_scalar_image (index_type, real_index); struct cleanup *cleanups = make_cleanup (xfree, index_img); /* Enumeration litterals by themselves are potentially ambiguous. For instance, consider the following package spec: package Pck is type Color is (Red, Green, Blue, White); type Blood_Cells is (White, Red); end Pck; In this case, the litteral "red" for instance, or even the fully-qualified litteral "pck.red" cannot be resolved by itself. Type qualification is needed to determine which enumeration litterals should be used. The following variable will be used to contain the name of the array index type when such type qualification is needed. */ const char *index_type_name = NULL; /* If the index type is a range type, find the base type. */ while (TYPE_CODE (index_type) == TYPE_CODE_RANGE) index_type = TYPE_TARGET_TYPE (index_type); if (TYPE_CODE (index_type) == TYPE_CODE_ENUM || TYPE_CODE (index_type) == TYPE_CODE_BOOL) { index_type_name = ada_type_name (index_type); if (index_type_name) index_type_name = ada_decode (index_type_name); } if (index_type_name != NULL) *child_path_expr = xstrprintf ("(%s)(%.*s'(%s))", parent_path_expr, ada_name_prefix_len (index_type_name), index_type_name, index_img); else *child_path_expr = xstrprintf ("(%s)(%s)", parent_path_expr, index_img); do_cleanups (cleanups); } }
char * default_gcc_target_options (struct gdbarch *gdbarch) { return xstrprintf ("-m%d%s", gdbarch_ptr_bit (gdbarch), gdbarch_ptr_bit (gdbarch) == 64 ? " -mcmodel=large" : ""); }
/* Compute the locations of init files that GDB should source and return them in SYSTEM_GDBINIT, HOME_GDBINIT, LOCAL_GDBINIT. If there is no system gdbinit (resp. home gdbinit and local gdbinit) to be loaded, then SYSTEM_GDBINIT (resp. HOME_GDBINIT and LOCAL_GDBINIT) is set to NULL. */ static void get_init_files (const char **system_gdbinit, const char **home_gdbinit, const char **local_gdbinit) { static const char *sysgdbinit = NULL; static char *homeinit = NULL; static const char *localinit = NULL; static int initialized = 0; if (!initialized) { struct stat homebuf, cwdbuf, s; char *homedir; if (SYSTEM_GDBINIT[0]) { int datadir_len = strlen (GDB_DATADIR); int sys_gdbinit_len = strlen (SYSTEM_GDBINIT); char *relocated_sysgdbinit; /* If SYSTEM_GDBINIT lives in data-directory, and data-directory has been provided, search for SYSTEM_GDBINIT there. */ if (gdb_datadir_provided && datadir_len < sys_gdbinit_len && filename_ncmp (SYSTEM_GDBINIT, GDB_DATADIR, datadir_len) == 0 && IS_DIR_SEPARATOR (SYSTEM_GDBINIT[datadir_len])) { /* Append the part of SYSTEM_GDBINIT that follows GDB_DATADIR to gdb_datadir. */ char *tmp_sys_gdbinit = xstrdup (SYSTEM_GDBINIT + datadir_len); char *p; for (p = tmp_sys_gdbinit; IS_DIR_SEPARATOR (*p); ++p) continue; relocated_sysgdbinit = concat (gdb_datadir, SLASH_STRING, p, (char *) NULL); xfree (tmp_sys_gdbinit); } else { relocated_sysgdbinit = relocate_path (gdb_program_name, SYSTEM_GDBINIT, SYSTEM_GDBINIT_RELOCATABLE); } if (relocated_sysgdbinit && stat (relocated_sysgdbinit, &s) == 0) sysgdbinit = relocated_sysgdbinit; else xfree (relocated_sysgdbinit); } homedir = getenv ("HOME"); /* If the .gdbinit file in the current directory is the same as the $HOME/.gdbinit file, it should not be sourced. homebuf and cwdbuf are used in that purpose. Make sure that the stats are zero in case one of them fails (this guarantees that they won't match if either exists). */ memset (&homebuf, 0, sizeof (struct stat)); memset (&cwdbuf, 0, sizeof (struct stat)); if (homedir) { homeinit = xstrprintf ("%s/%s", homedir, gdbinit); if (stat (homeinit, &homebuf) != 0) { xfree (homeinit); homeinit = NULL; } } if (stat (gdbinit, &cwdbuf) == 0) { if (!homeinit || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat))) localinit = gdbinit; } initialized = 1; } *system_gdbinit = sysgdbinit; *home_gdbinit = homeinit; *local_gdbinit = localinit; }
enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty) { struct cleanup *old_cleanups; char *run; char *async_args; if (target_can_async_p ()) { async_args = (char *) xmalloc (strlen (args) + 2); make_exec_cleanup (free, async_args); strcpy (async_args, args); strcat (async_args, "&"); run = xstrprintf ("%s %s", mi, async_args); make_exec_cleanup (free, run); add_continuation (mi_exec_async_cli_cmd_continuation, NULL); old_cleanups = NULL; } else { run = xstrprintf ("%s %s", mi, args); old_cleanups = make_cleanup (xfree, run); } if (!target_can_async_p ()) { /* NOTE: For synchronous targets asynchronous behavour is faked by printing out the GDB prompt before we even try to execute the command. */ if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("^running\n", raw_stdout); fputs_unfiltered ("(gdb) \n", raw_stdout); gdb_flush (raw_stdout); } else { /* FIXME: cagney/1999-11-29: Printing this message before calling execute_command is wrong. It should only be printed once gdb has confirmed that it really has managed to send a run command to the target. */ if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("^running\n", raw_stdout); } execute_command ( /*ui */ run, 0 /*from_tty */ ); if (!target_can_async_p ()) { /* Do this before doing any printing. It would appear that some print code leaves garbage around in the buffer. */ do_cleanups (old_cleanups); /* If the target was doing the operation synchronously we fake the stopped message. */ if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("*stopped", raw_stdout); mi_out_put (uiout, raw_stdout); mi_out_rewind (uiout); fputs_unfiltered ("\n", raw_stdout); return MI_CMD_QUIET; } return MI_CMD_DONE; }
static struct so_list * build_so_list_from_mapfile (int pid, long match_mask, long match_val) { char *mapbuf = NULL; struct prmap *prmap; int mapbuf_size; struct so_list *sos = NULL; { int mapbuf_allocation_size = 8192; char *map_pathname; int map_fd; /* Open the map file */ map_pathname = xstrprintf ("/proc/%d/map", pid); map_fd = open (map_pathname, O_RDONLY); xfree (map_pathname); if (map_fd < 0) return 0; /* Read the entire map file in */ do { if (mapbuf) { xfree (mapbuf); mapbuf_allocation_size *= 2; lseek (map_fd, 0, SEEK_SET); } mapbuf = xmalloc (mapbuf_allocation_size); mapbuf_size = read (map_fd, mapbuf, mapbuf_allocation_size); if (mapbuf_size < 0) { xfree (mapbuf); /* FIXME: This warrants an error or a warning of some sort */ return 0; } } while (mapbuf_size == mapbuf_allocation_size); close (map_fd); } for (prmap = (struct prmap *) mapbuf; (char *) prmap < mapbuf + mapbuf_size; prmap++) { char *mapname, *pathname, *membername; struct so_list *sop; int mapidx; if (prmap->pr_size == 0) break; /* Skip to the next entry if there's no path associated with the map, unless we're looking for the kernel text region, in which case it's okay if there's no path. */ if ((prmap->pr_pathoff == 0 || prmap->pr_pathoff >= mapbuf_size) && ((match_mask & MA_KERNTEXT) == 0)) continue; /* Skip to the next entry if our match conditions don't hold. */ if ((prmap->pr_mflags & match_mask) != match_val) continue; mapname = prmap->pr_mapname; if (prmap->pr_pathoff == 0) { pathname = ""; membername = ""; } else { pathname = mapbuf + prmap->pr_pathoff; membername = pathname + strlen (pathname) + 1; } for (sop = sos; sop != NULL; sop = sop->next) if (strcmp (pathname, sop->lm_info->pathname) == 0 && strcmp (membername, sop->lm_info->membername) == 0) break; if (sop == NULL) { sop = xcalloc (1, sizeof (struct so_list)); make_cleanup (xfree, sop); sop->lm_info = xcalloc (1, sizeof (struct lm_info)); make_cleanup (xfree, sop->lm_info); sop->lm_info->mapname = xstrdup (mapname); make_cleanup (xfree, sop->lm_info->mapname); /* FIXME: Eliminate the pathname field once length restriction is lifted on so_name and so_original_name. */ sop->lm_info->pathname = xstrdup (pathname); make_cleanup (xfree, sop->lm_info->pathname); sop->lm_info->membername = xstrdup (membername); make_cleanup (xfree, sop->lm_info->membername); strncpy (sop->so_name, pathname, SO_NAME_MAX_PATH_SIZE - 1); sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; strcpy (sop->so_original_name, sop->so_name); sop->next = sos; sos = sop; } mapidx = sop->lm_info->nmappings; sop->lm_info->nmappings += 1; sop->lm_info->mapping = xrealloc (sop->lm_info->mapping, sop->lm_info->nmappings * sizeof (struct lm_mapping)); sop->lm_info->mapping[mapidx].addr = (CORE_ADDR) prmap->pr_vaddr; sop->lm_info->mapping[mapidx].size = prmap->pr_size; sop->lm_info->mapping[mapidx].offset = prmap->pr_off; sop->lm_info->mapping[mapidx].flags = prmap->pr_mflags; sop->lm_info->mapping[mapidx].gp = (CORE_ADDR) prmap->pr_gp; } xfree (mapbuf); return sos; }
enum mi_cmd_result mi_cmd_data_read_memory (char *command, char **argv, int argc) { struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); CORE_ADDR addr; long total_bytes; long nr_cols; long nr_rows; char word_format; struct type *word_type; long word_size; char word_asize; char aschar; gdb_byte *mbuf; int nr_bytes; long offset = 0; int optind = 0; char *optarg; enum opt { OFFSET_OPT }; static struct mi_opt opts[] = { {"o", OFFSET_OPT, 1}, 0 }; while (1) { int opt = mi_getopt ("mi_cmd_data_read_memory", argc, argv, opts, &optind, &optarg); if (opt < 0) break; switch ((enum opt) opt) { case OFFSET_OPT: offset = atol (optarg); break; } } argv += optind; argc -= optind; if (argc < 5 || argc > 6) { mi_error_message = xstrprintf ("mi_cmd_data_read_memory: Usage: ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR]."); return MI_CMD_ERROR; } /* Extract all the arguments. */ /* Start address of the memory dump. */ addr = parse_and_eval_address (argv[0]) + offset; /* The format character to use when displaying a memory word. See the ``x'' command. */ word_format = argv[1][0]; /* The size of the memory word. */ word_size = atol (argv[2]); switch (word_size) { case 1: word_type = builtin_type_int8; word_asize = 'b'; break; case 2: word_type = builtin_type_int16; word_asize = 'h'; break; case 4: word_type = builtin_type_int32; word_asize = 'w'; break; case 8: word_type = builtin_type_int64; word_asize = 'g'; break; default: word_type = builtin_type_int8; word_asize = 'b'; } /* The number of rows */ nr_rows = atol (argv[3]); if (nr_rows <= 0) { mi_error_message = xstrprintf ("mi_cmd_data_read_memory: invalid number of rows."); return MI_CMD_ERROR; } /* number of bytes per row. */ nr_cols = atol (argv[4]); if (nr_cols <= 0) { mi_error_message = xstrprintf ("mi_cmd_data_read_memory: invalid number of columns."); return MI_CMD_ERROR; } /* The un-printable character when printing ascii. */ if (argc == 6) aschar = *argv[5]; else aschar = 0; /* create a buffer and read it in. */ total_bytes = word_size * nr_rows * nr_cols; mbuf = xcalloc (total_bytes, 1); make_cleanup (xfree, mbuf); nr_bytes = target_read (¤t_target, TARGET_OBJECT_MEMORY, NULL, mbuf, addr, total_bytes); if (nr_bytes <= 0) { do_cleanups (cleanups); mi_error_message = xstrdup ("Unable to read memory."); return MI_CMD_ERROR; } /* output the header information. */ ui_out_field_core_addr (uiout, "addr", addr); ui_out_field_int (uiout, "nr-bytes", nr_bytes); ui_out_field_int (uiout, "total-bytes", total_bytes); ui_out_field_core_addr (uiout, "next-row", addr + word_size * nr_cols); ui_out_field_core_addr (uiout, "prev-row", addr - word_size * nr_cols); ui_out_field_core_addr (uiout, "next-page", addr + total_bytes); ui_out_field_core_addr (uiout, "prev-page", addr - total_bytes); /* Build the result as a two dimentional table. */ { struct ui_stream *stream = ui_out_stream_new (uiout); struct cleanup *cleanup_list_memory; int row; int row_byte; cleanup_list_memory = make_cleanup_ui_out_list_begin_end (uiout, "memory"); for (row = 0, row_byte = 0; row < nr_rows; row++, row_byte += nr_cols * word_size) { int col; int col_byte; struct cleanup *cleanup_tuple; struct cleanup *cleanup_list_data; cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_core_addr (uiout, "addr", addr + row_byte); /* ui_out_field_core_addr_symbolic (uiout, "saddr", addr + row_byte); */ cleanup_list_data = make_cleanup_ui_out_list_begin_end (uiout, "data"); for (col = 0, col_byte = row_byte; col < nr_cols; col++, col_byte += word_size) { if (col_byte + word_size > nr_bytes) { ui_out_field_string (uiout, NULL, "N/A"); } else { ui_file_rewind (stream->stream); print_scalar_formatted (mbuf + col_byte, word_type, word_format, word_asize, stream->stream); ui_out_field_stream (uiout, NULL, stream); } } do_cleanups (cleanup_list_data); if (aschar) { int byte; ui_file_rewind (stream->stream); for (byte = row_byte; byte < row_byte + word_size * nr_cols; byte++) { if (byte >= nr_bytes) { fputc_unfiltered ('X', stream->stream); } else if (mbuf[byte] < 32 || mbuf[byte] > 126) { fputc_unfiltered (aschar, stream->stream); } else fputc_unfiltered (mbuf[byte], stream->stream); } ui_out_field_stream (uiout, "ascii", stream); } do_cleanups (cleanup_tuple); } ui_out_stream_delete (stream); do_cleanups (cleanup_list_memory); } do_cleanups (cleanups); return MI_CMD_DONE; }
static int add_pe_forwarded_sym (minimal_symbol_reader &reader, const char *sym_name, const char *forward_dll_name, const char *forward_func_name, int ordinal, const char *dll_name, struct objfile *objfile) { CORE_ADDR vma, baseaddr; struct bound_minimal_symbol msymbol; enum minimal_symbol_type msymtype; char *qualified_name, *bare_name; int forward_dll_name_len = strlen (forward_dll_name); int forward_func_name_len = strlen (forward_func_name); int forward_len = forward_dll_name_len + forward_func_name_len + 2; char *forward_qualified_name = (char *) alloca (forward_len); short section; xsnprintf (forward_qualified_name, forward_len, "%s!%s", forward_dll_name, forward_func_name); msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name); if (!msymbol.minsym) { int i; for (i = 0; i < forward_dll_name_len; i++) forward_qualified_name[i] = tolower (forward_qualified_name[i]); msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name); } if (!msymbol.minsym) { if (debug_coff_pe_read) fprintf_unfiltered (gdb_stdlog, _("Unable to find function \"%s\" in" " dll \"%s\", forward of \"%s\" in dll \"%s\"\n"), forward_func_name, forward_dll_name, sym_name, dll_name); return 0; } if (debug_coff_pe_read > 1) fprintf_unfiltered (gdb_stdlog, _("Adding forwarded exported symbol" " \"%s\" in dll \"%s\", pointing to \"%s\"\n"), sym_name, dll_name, forward_qualified_name); vma = BMSYMBOL_VALUE_ADDRESS (msymbol); msymtype = MSYMBOL_TYPE (msymbol.minsym); section = MSYMBOL_SECTION (msymbol.minsym); /* Generate a (hopefully unique) qualified name using the first part of the dll name, e.g. KERNEL32!AddAtomA. This matches the style used by windbg from the "Microsoft Debugging Tools for Windows". */ if (sym_name == NULL || *sym_name == '\0') bare_name = xstrprintf ("#%d", ordinal); else bare_name = xstrdup (sym_name); qualified_name = xstrprintf ("%s!%s", dll_name, bare_name); /* Note that this code makes a minimal symbol whose value may point outside of any section in this objfile. These symbols can't really be relocated properly, but nevertheless we make a stab at it, choosing an approach consistent with the history of this code. */ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); reader.record_with_info (qualified_name, vma - baseaddr, msymtype, section); /* Enter the plain name as well, which might not be unique. */ reader.record_with_info (bare_name, vma - baseaddr, msymtype, section); xfree (qualified_name); xfree (bare_name); return 1; }
/* DATA-MEMORY-WRITE: COLUMN_OFFSET: optional argument. Must be preceeded by '-o'. The offset from the beginning of the memory grid row where the cell to be written is. ADDR: start address of the row in the memory grid where the memory cell is, if OFFSET_COLUMN is specified. Otherwise, the address of the location to write to. FORMAT: a char indicating format for the ``word''. See the ``x'' command. WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes VALUE: value to be written into the memory address. Writes VALUE into ADDR + (COLUMN_OFFSET * WORD_SIZE). Prints nothing. */ enum mi_cmd_result mi_cmd_data_write_memory (char *command, char **argv, int argc) { CORE_ADDR addr; char word_format; long word_size; /* FIXME: ezannoni 2000-02-17 LONGEST could possibly not be big enough when using a compiler other than GCC. */ LONGEST value; void *buffer; struct cleanup *old_chain; long offset = 0; int optind = 0; char *optarg; enum opt { OFFSET_OPT }; static struct mi_opt opts[] = { {"o", OFFSET_OPT, 1}, 0 }; while (1) { int opt = mi_getopt ("mi_cmd_data_write_memory", argc, argv, opts, &optind, &optarg); if (opt < 0) break; switch ((enum opt) opt) { case OFFSET_OPT: offset = atol (optarg); break; } } argv += optind; argc -= optind; if (argc != 4) { mi_error_message = xstrprintf ("mi_cmd_data_write_memory: Usage: [-o COLUMN_OFFSET] ADDR FORMAT WORD-SIZE VALUE."); return MI_CMD_ERROR; } /* Extract all the arguments. */ /* Start address of the memory dump. */ addr = parse_and_eval_address (argv[0]); /* The format character to use when displaying a memory word. See the ``x'' command. */ word_format = argv[1][0]; /* The size of the memory word. */ word_size = atol (argv[2]); /* Calculate the real address of the write destination. */ addr += (offset * word_size); /* Get the value as a number */ value = parse_and_eval_address (argv[3]); /* Get the value into an array */ buffer = xmalloc (word_size); old_chain = make_cleanup (xfree, buffer); store_signed_integer (buffer, word_size, value); /* Write it down to memory */ write_memory (addr, buffer, word_size); /* Free the buffer. */ do_cleanups (old_chain); return MI_CMD_DONE; }