/* NOTE: 1999-04-30 This is the asynchronous version of the command_loop function. The command_loop function will be obsolete when we switch to use the event loop at every execution of gdb. */ static void command_handler (char *command) { struct cleanup *old_chain; int stdin_is_tty = ISATTY (stdin); struct continuation_arg *arg1; struct continuation_arg *arg2; long time_at_cmd_start; #ifdef HAVE_SBRK long space_at_cmd_start = 0; #endif extern int display_time; extern int display_space; quit_flag = 0; if (instream == stdin && stdin_is_tty) reinitialize_more_filter (); old_chain = make_cleanup (null_cleanup, 0); /* If readline returned a NULL command, it means that the connection with the terminal is gone. This happens at the end of a testsuite run, after Expect has hung up but GDB is still alive. In such a case, we just quit gdb killing the inferior program too. */ if (command == 0) quit_command ((char *) 0, stdin == instream); time_at_cmd_start = get_run_time (); if (display_space) { #ifdef HAVE_SBRK char *lim = (char *) sbrk (0); space_at_cmd_start = lim - lim_at_start; #endif } execute_command (command, instream == stdin); /* Set things up for this function to be compete later, once the execution has completed, if we are doing an execution command, otherwise, just go ahead and finish. */ if (target_can_async_p () && target_executing) { arg1 = (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); arg2 = (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); arg1->next = arg2; arg2->next = NULL; arg1->data.longint = time_at_cmd_start; #ifdef HAVE_SBRK arg2->data.longint = space_at_cmd_start; #endif add_continuation (command_line_handler_continuation, arg1); } /* Do any commands attached to breakpoint we stopped at. Only if we are always running synchronously. Or if we have just executed a command that doesn't start the target. */ if (!target_can_async_p () || !target_executing) { bpstat_do_actions (&stop_bpstat); do_cleanups (old_chain); if (display_time) { long cmd_time = get_run_time () - time_at_cmd_start; printf_unfiltered ("Command execution time: %ld.%06ld\n", cmd_time / 1000000, cmd_time % 1000000); } if (display_space) { #ifdef HAVE_SBRK char *lim = (char *) sbrk (0); long space_now = lim - lim_at_start; long space_diff = space_now - space_at_cmd_start; printf_unfiltered ("Space used: %ld (%c%ld for this command)\n", space_now, (space_diff >= 0 ? '+' : '-'), space_diff); #endif } } }
/* Expand a call to a macro named ID, whose definition is DEF. Append its expansion to DEST. SRC is the input text following the ID token. We are currently rescanning the expansions of the macros named in NO_LOOP; don't re-expand them. Use LOOKUP_FUNC and LOOKUP_BATON to find definitions for any nested macro references. Return 1 if we decided to expand it, zero otherwise. (If it's a function-like macro name that isn't followed by an argument list, we don't expand it.) If we return zero, leave SRC unchanged. */ static int expand (const char *id, struct macro_definition *def, struct macro_buffer *dest, struct macro_buffer *src, struct macro_name_list *no_loop, macro_lookup_ftype *lookup_func, void *lookup_baton) { struct macro_name_list new_no_loop; /* Create a new node to be added to the front of the no-expand list. This list is appropriate for re-scanning replacement lists, but it is *not* appropriate for scanning macro arguments; invocations of the macro whose arguments we are gathering *do* get expanded there. */ new_no_loop.name = id; new_no_loop.next = no_loop; /* What kind of macro are we expanding? */ if (def->kind == macro_object_like) { struct macro_buffer replacement_list; init_shared_buffer (&replacement_list, (char *) def->replacement, strlen (def->replacement)); scan (dest, &replacement_list, &new_no_loop, lookup_func, lookup_baton); return 1; } else if (def->kind == macro_function_like) { struct cleanup *back_to = make_cleanup (null_cleanup, 0); int argc; struct macro_buffer *argv = NULL; struct macro_buffer substituted; struct macro_buffer substituted_src; if (def->argc >= 1 && strcmp (def->argv[def->argc - 1], "...") == 0) error ("Varargs macros not implemented yet."); make_cleanup (free_current_contents, &argv); argv = gather_arguments (id, src, &argc); /* If we couldn't find any argument list, then we don't expand this macro. */ if (! argv) { do_cleanups (back_to); return 0; } /* Check that we're passing an acceptable number of arguments for this macro. */ if (argc != def->argc) { /* Remember that a sequence of tokens like "foo()" is a valid invocation of a macro expecting either zero or one arguments. */ if (! (argc == 1 && argv[0].len == 0 && def->argc == 0)) error ("Wrong number of arguments to macro `%s' " "(expected %d, got %d).", id, def->argc, argc); } /* Note that we don't expand macro invocations in the arguments yet --- we let subst_args take care of that. Parameters that appear as operands of the stringifying operator "#" or the splicing operator "##" don't get macro references expanded, so we can't really tell whether it's appropriate to macro- expand an argument until we see how it's being used. */ init_buffer (&substituted, 0); make_cleanup (cleanup_macro_buffer, &substituted); substitute_args (&substituted, def, argc, argv, no_loop, lookup_func, lookup_baton); /* Now `substituted' is the macro's replacement list, with all argument values substituted into it properly. Re-scan it for macro references, but don't expand invocations of this macro. We create a new buffer, `substituted_src', which points into `substituted', and scan that. We can't scan `substituted' itself, since the tokenization process moves the buffer's text pointer around, and we still need to be able to find `substituted's original text buffer after scanning it so we can free it. */ init_shared_buffer (&substituted_src, substituted.text, substituted.len); scan (dest, &substituted_src, &new_no_loop, lookup_func, lookup_baton); do_cleanups (back_to); return 1; } else internal_error (__FILE__, __LINE__, "bad macro definition kind"); }
void c_type_print_base (struct type *type, struct ui_file *stream, int show, int level, const struct type_print_options *flags) { int i; int len, real_len; enum { s_none, s_public, s_private, s_protected } section_type; int need_access_label = 0; int j, len2; QUIT; if (type == NULL) { fputs_filtered (_("<type unknown>"), stream); return; } /* When SHOW is zero or less, and there is a valid type name, then always just print the type name directly from the type. */ /* If we have "typedef struct foo {. . .} bar;" do we want to print it as "struct foo" or as "bar"? Pick the latter, because C++ folk tend to expect things like "class5 *foo" rather than "struct class5 *foo". */ if (show <= 0 && TYPE_NAME (type) != NULL) { c_type_print_modifier (type, stream, 0, 1); print_name_maybe_canonical (TYPE_NAME (type), flags, stream); return; } type = check_typedef (type); switch (TYPE_CODE (type)) { case TYPE_CODE_TYPEDEF: /* If we get here, the typedef doesn't have a name, and we couldn't resolve TYPE_TARGET_TYPE. Not much we can do. */ gdb_assert (TYPE_NAME (type) == NULL); gdb_assert (TYPE_TARGET_TYPE (type) == NULL); fprintf_filtered (stream, _("<unnamed typedef>")); break; case TYPE_CODE_ARRAY: case TYPE_CODE_PTR: case TYPE_CODE_MEMBERPTR: case TYPE_CODE_REF: case TYPE_CODE_FUNC: case TYPE_CODE_METHOD: case TYPE_CODE_METHODPTR: c_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level, flags); break; case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: { struct type_print_options local_flags = *flags; struct type_print_options semi_local_flags = *flags; struct cleanup *local_cleanups = make_cleanup (null_cleanup, NULL); local_flags.local_typedefs = NULL; semi_local_flags.local_typedefs = NULL; if (!flags->raw) { if (flags->local_typedefs) local_flags.local_typedefs = copy_typedef_hash (flags->local_typedefs); else local_flags.local_typedefs = create_typedef_hash (); make_cleanup_free_typedef_hash (local_flags.local_typedefs); } c_type_print_modifier (type, stream, 0, 1); if (TYPE_CODE (type) == TYPE_CODE_UNION) fprintf_filtered (stream, "union "); else if (TYPE_DECLARED_CLASS (type)) fprintf_filtered (stream, "class "); else fprintf_filtered (stream, "struct "); /* Print the tag if it exists. The HP aCC compiler emits a spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}" tag for unnamed struct/union/enum's, which we don't want to print. */ if (TYPE_TAG_NAME (type) != NULL && !startswith (TYPE_TAG_NAME (type), "{unnamed")) { /* When printing the tag name, we are still effectively printing in the outer context, hence the use of FLAGS here. */ print_name_maybe_canonical (TYPE_TAG_NAME (type), flags, stream); if (show > 0) fputs_filtered (" ", stream); } if (show < 0) { /* If we just printed a tag name, no need to print anything else. */ if (TYPE_TAG_NAME (type) == NULL) fprintf_filtered (stream, "{...}"); } else if (show > 0 || TYPE_TAG_NAME (type) == NULL) { struct type *basetype; int vptr_fieldno; c_type_print_template_args (&local_flags, type, stream); /* Add in template parameters when printing derivation info. */ add_template_parameters (local_flags.local_typedefs, type); cp_type_print_derivation_info (stream, type, &local_flags); /* This holds just the global typedefs and the template parameters. */ semi_local_flags.local_typedefs = copy_typedef_hash (local_flags.local_typedefs); if (semi_local_flags.local_typedefs) make_cleanup_free_typedef_hash (semi_local_flags.local_typedefs); /* Now add in the local typedefs. */ recursively_update_typedef_hash (local_flags.local_typedefs, type); fprintf_filtered (stream, "{\n"); if (TYPE_NFIELDS (type) == 0 && TYPE_NFN_FIELDS (type) == 0 && TYPE_TYPEDEF_FIELD_COUNT (type) == 0) { if (TYPE_STUB (type)) fprintfi_filtered (level + 4, stream, _("<incomplete type>\n")); else fprintfi_filtered (level + 4, stream, _("<no data fields>\n")); } /* Start off with no specific section type, so we can print one for the first field we find, and use that section type thereafter until we find another type. */ section_type = s_none; /* For a class, if all members are private, there's no need for a "private:" label; similarly, for a struct or union masquerading as a class, if all members are public, there's no need for a "public:" label. */ if (TYPE_DECLARED_CLASS (type)) { QUIT; len = TYPE_NFIELDS (type); for (i = TYPE_N_BASECLASSES (type); i < len; i++) if (!TYPE_FIELD_PRIVATE (type, i)) { need_access_label = 1; break; } QUIT; if (!need_access_label) { len2 = TYPE_NFN_FIELDS (type); for (j = 0; j < len2; j++) { len = TYPE_FN_FIELDLIST_LENGTH (type, j); for (i = 0; i < len; i++) if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i)) { need_access_label = 1; break; } if (need_access_label) break; } } } else { QUIT; len = TYPE_NFIELDS (type); for (i = TYPE_N_BASECLASSES (type); i < len; i++) if (TYPE_FIELD_PRIVATE (type, i) || TYPE_FIELD_PROTECTED (type, i)) { need_access_label = 1; break; } QUIT; if (!need_access_label) { len2 = TYPE_NFN_FIELDS (type); for (j = 0; j < len2; j++) { QUIT; len = TYPE_FN_FIELDLIST_LENGTH (type, j); for (i = 0; i < len; i++) if (TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type, j), i) || TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i)) { need_access_label = 1; break; } if (need_access_label) break; } } } /* If there is a base class for this type, do not print the field that it occupies. */ len = TYPE_NFIELDS (type); vptr_fieldno = get_vptr_fieldno (type, &basetype); for (i = TYPE_N_BASECLASSES (type); i < len; i++) { QUIT; /* If we have a virtual table pointer, omit it. Even if virtual table pointers are not specifically marked in the debug info, they should be artificial. */ if ((i == vptr_fieldno && type == basetype) || TYPE_FIELD_ARTIFICIAL (type, i)) continue; if (need_access_label) { if (TYPE_FIELD_PROTECTED (type, i)) { if (section_type != s_protected) { section_type = s_protected; fprintfi_filtered (level + 2, stream, "protected:\n"); } } else if (TYPE_FIELD_PRIVATE (type, i)) { if (section_type != s_private) { section_type = s_private; fprintfi_filtered (level + 2, stream, "private:\n"); } } else { if (section_type != s_public) { section_type = s_public; fprintfi_filtered (level + 2, stream, "public:\n"); } } } print_spaces_filtered (level + 4, stream); if (field_is_static (&TYPE_FIELD (type, i))) fprintf_filtered (stream, "static "); c_print_type (TYPE_FIELD_TYPE (type, i), TYPE_FIELD_NAME (type, i), stream, show - 1, level + 4, &local_flags); if (!field_is_static (&TYPE_FIELD (type, i)) && TYPE_FIELD_PACKED (type, i)) { /* It is a bitfield. This code does not attempt to look at the bitpos and reconstruct filler, unnamed fields. This would lead to misleading results if the compiler does not put out fields for such things (I don't know what it does). */ fprintf_filtered (stream, " : %d", TYPE_FIELD_BITSIZE (type, i)); } fprintf_filtered (stream, ";\n"); } /* If there are both fields and methods, put a blank line between them. Make sure to count only method that we will display; artificial methods will be hidden. */ len = TYPE_NFN_FIELDS (type); if (!flags->print_methods) len = 0; real_len = 0; for (i = 0; i < len; i++) { struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); int len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); int j; for (j = 0; j < len2; j++) if (!TYPE_FN_FIELD_ARTIFICIAL (f, j)) real_len++; } if (real_len > 0 && section_type != s_none) fprintf_filtered (stream, "\n"); /* C++: print out the methods. */ for (i = 0; i < len; i++) { struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); const char *method_name = TYPE_FN_FIELDLIST_NAME (type, i); const char *name = type_name_no_tag (type); int is_constructor = name && strcmp (method_name, name) == 0; for (j = 0; j < len2; j++) { const char *mangled_name; char *demangled_name; struct cleanup *inner_cleanup; const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); int is_full_physname_constructor = TYPE_FN_FIELD_CONSTRUCTOR (f, j) || is_constructor_name (physname) || is_destructor_name (physname) || method_name[0] == '~'; /* Do not print out artificial methods. */ if (TYPE_FN_FIELD_ARTIFICIAL (f, j)) continue; inner_cleanup = make_cleanup (null_cleanup, NULL); QUIT; if (TYPE_FN_FIELD_PROTECTED (f, j)) { if (section_type != s_protected) { section_type = s_protected; fprintfi_filtered (level + 2, stream, "protected:\n"); } } else if (TYPE_FN_FIELD_PRIVATE (f, j)) { if (section_type != s_private) { section_type = s_private; fprintfi_filtered (level + 2, stream, "private:\n"); } } else { if (section_type != s_public) { section_type = s_public; fprintfi_filtered (level + 2, stream, "public:\n"); } } print_spaces_filtered (level + 4, stream); if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) fprintf_filtered (stream, "virtual "); else if (TYPE_FN_FIELD_STATIC_P (f, j)) fprintf_filtered (stream, "static "); if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0) { /* Keep GDB from crashing here. */ fprintf_filtered (stream, _("<undefined type> %s;\n"), TYPE_FN_FIELD_PHYSNAME (f, j)); break; } else if (!is_constructor /* Constructors don't have declared types. */ && !is_full_physname_constructor /* " " */ && !is_type_conversion_operator (type, i, j)) { c_print_type (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), "", stream, -1, 0, &local_flags); fputs_filtered (" ", stream); } if (TYPE_FN_FIELD_STUB (f, j)) { char *tem; /* Build something we can demangle. */ tem = gdb_mangle_name (type, i, j); make_cleanup (xfree, tem); mangled_name = tem; } else mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j); demangled_name = gdb_demangle (mangled_name, DMGL_ANSI | DMGL_PARAMS); if (demangled_name == NULL) { /* In some cases (for instance with the HP demangling), if a function has more than 10 arguments, the demangling will fail. Let's try to reconstruct the function signature from the symbol information. */ if (!TYPE_FN_FIELD_STUB (f, j)) { int staticp = TYPE_FN_FIELD_STATIC_P (f, j); struct type *mtype = TYPE_FN_FIELD_TYPE (f, j); cp_type_print_method_args (mtype, "", method_name, staticp, stream, &local_flags); } else fprintf_filtered (stream, _("<badly mangled name '%s'>"), mangled_name); } else { char *p; char *demangled_no_class = remove_qualifiers (demangled_name); /* Get rid of the `static' appended by the demangler. */ p = strstr (demangled_no_class, " static"); if (p != NULL) { int length = p - demangled_no_class; char *demangled_no_static; demangled_no_static = (char *) xmalloc (length + 1); strncpy (demangled_no_static, demangled_no_class, length); *(demangled_no_static + length) = '\0'; fputs_filtered (demangled_no_static, stream); xfree (demangled_no_static); } else fputs_filtered (demangled_no_class, stream); xfree (demangled_name); } do_cleanups (inner_cleanup); fprintf_filtered (stream, ";\n"); } } /* Print typedefs defined in this class. */ if (TYPE_TYPEDEF_FIELD_COUNT (type) != 0 && flags->print_typedefs) { if (TYPE_NFIELDS (type) != 0 || TYPE_NFN_FIELDS (type) != 0) fprintf_filtered (stream, "\n"); for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++) { struct type *target = TYPE_TYPEDEF_FIELD_TYPE (type, i); /* Dereference the typedef declaration itself. */ gdb_assert (TYPE_CODE (target) == TYPE_CODE_TYPEDEF); target = TYPE_TARGET_TYPE (target); print_spaces_filtered (level + 4, stream); fprintf_filtered (stream, "typedef "); /* We want to print typedefs with substitutions from the template parameters or globally-known typedefs but not local typedefs. */ c_print_type (target, TYPE_TYPEDEF_FIELD_NAME (type, i), stream, show - 1, level + 4, &semi_local_flags); fprintf_filtered (stream, ";\n"); } } fprintfi_filtered (level, stream, "}"); } do_cleanups (local_cleanups); } break; case TYPE_CODE_ENUM: c_type_print_modifier (type, stream, 0, 1); fprintf_filtered (stream, "enum "); if (TYPE_DECLARED_CLASS (type)) fprintf_filtered (stream, "class "); /* Print the tag name if it exists. The aCC compiler emits a spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}" tag for unnamed struct/union/enum's, which we don't want to print. */ if (TYPE_TAG_NAME (type) != NULL && !startswith (TYPE_TAG_NAME (type), "{unnamed")) { print_name_maybe_canonical (TYPE_TAG_NAME (type), flags, stream); if (show > 0) fputs_filtered (" ", stream); } wrap_here (" "); if (show < 0) { /* If we just printed a tag name, no need to print anything else. */ if (TYPE_TAG_NAME (type) == NULL) fprintf_filtered (stream, "{...}"); } else if (show > 0 || TYPE_TAG_NAME (type) == NULL) { LONGEST lastval = 0; /* We can't handle this case perfectly, as DWARF does not tell us whether or not the underlying type was specified in the source (and other debug formats don't provide this at all). We choose to print the underlying type, if it has a name, when in C++ on the theory that it's better to print too much than too little; but conversely not to print something egregiously outside the current language's syntax. */ if (current_language->la_language == language_cplus && TYPE_TARGET_TYPE (type) != NULL) { struct type *underlying = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_NAME (underlying) != NULL) fprintf_filtered (stream, ": %s ", TYPE_NAME (underlying)); } fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); for (i = 0; i < len; i++) { QUIT; if (i) fprintf_filtered (stream, ", "); wrap_here (" "); fputs_filtered (TYPE_FIELD_NAME (type, i), stream); if (lastval != TYPE_FIELD_ENUMVAL (type, i)) { fprintf_filtered (stream, " = %s", plongest (TYPE_FIELD_ENUMVAL (type, i))); lastval = TYPE_FIELD_ENUMVAL (type, i); } lastval++; } fprintf_filtered (stream, "}"); } break; case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_UNDEF: fprintf_filtered (stream, _("struct <unknown>")); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type)); break; case TYPE_CODE_RANGE: /* This should not occur. */ fprintf_filtered (stream, _("<range type>")); break; case TYPE_CODE_NAMESPACE: fputs_filtered ("namespace ", stream); fputs_filtered (TYPE_TAG_NAME (type), stream); break; default: /* Handle types not explicitly handled by the other cases, such as fundamental types. For these, just print whatever the type name is, as recorded in the type itself. If there is no type name, then complain. */ if (TYPE_NAME (type) != NULL) { c_type_print_modifier (type, stream, 0, 1); print_name_maybe_canonical (TYPE_NAME (type), flags, stream); } else { /* At least for dump_symtab, it is important that this not be an error (). */ fprintf_filtered (stream, _("<invalid type code %d>"), TYPE_CODE (type)); } break; } }
/* 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; if (argc == 0) { xasprintf (&mi_error_message, "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) { xasprintf (&mi_error_message, "mi_cmd_data_write_register_values: No registers."); return MI_CMD_ERROR; } if (!(argc - 1)) { xasprintf (&mi_error_message, "mi_cmd_data_write_register_values: No regs and values specified."); return MI_CMD_ERROR; } if ((argc - 1) % 2) { xasprintf (&mi_error_message, "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, DEPRECATED_REGISTER_RAW_SIZE (regnum)); /* Free the buffer. */ do_cleanups (old_chain); } else { xasprintf (&mi_error_message, "bad register number"); return MI_CMD_ERROR; } } return MI_CMD_DONE; }
void exec_file_attach (char *filename, int from_tty) { /* Remove any previous exec file. */ unpush_target (&exec_ops); /* Now open and digest the file the user requested, if any. */ if (!filename) { if (from_tty) printf_unfiltered (_("No executable file now.\n")); set_gdbarch_from_file (NULL); } else { char *scratch_pathname; int scratch_chan; scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, 0, &scratch_pathname); #if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__) if (scratch_chan < 0) { char *exename = alloca (strlen (filename) + 5); strcat (strcpy (exename, filename), ".exe"); scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, 0, &scratch_pathname); } #endif if (scratch_chan < 0) perror_with_name (filename); exec_bfd = bfd_fopen (scratch_pathname, gnutarget, write_files ? FOPEN_RUB : FOPEN_RB, scratch_chan); if (!exec_bfd) error (_("\"%s\": could not open as an executable file: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); /* At this point, scratch_pathname and exec_bfd->name both point to the same malloc'd string. However exec_close() will attempt to free it via the exec_bfd->name pointer, so we need to make another copy and leave exec_bfd as the new owner of the original copy. */ scratch_pathname = xstrdup (scratch_pathname); make_cleanup (xfree, scratch_pathname); if (!bfd_check_format (exec_bfd, bfd_object)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (0); error (_("\"%s\": not in executable format: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } /* FIXME - This should only be run for RS6000, but the ifdef is a poor way to accomplish. */ #ifdef DEPRECATED_IBM6000_TARGET /* Setup initial vmap. */ map_vmap (exec_bfd, 0); if (vmap == NULL) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (0); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } #endif /* DEPRECATED_IBM6000_TARGET */ if (build_section_table (exec_bfd, &exec_ops.to_sections, &exec_ops.to_sections_end)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (0); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } validate_files (); set_gdbarch_from_file (exec_bfd); push_target (&exec_ops); /* Tell display code (if any) about the changed file name. */ if (deprecated_exec_file_display_hook) (*deprecated_exec_file_display_hook) (filename); } bfd_cache_close_all (); observer_notify_executable_changed (NULL); }
struct cleanup * make_cleanup_py_decref (PyObject *py) { return make_cleanup (py_decref, (void *) py); }
/* 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) { xasprintf (&mi_error_message, "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; }
static void macro_define_command (char *exp, int from_tty) { struct macro_definition new_macro; char *name = NULL; struct cleanup *cleanup_chain; if (!exp) error (_("usage: macro define NAME[(ARGUMENT-LIST)] [REPLACEMENT-LIST]")); cleanup_chain = make_cleanup (free_macro_definition_ptr, &new_macro); make_cleanup (free_current_contents, &name); memset (&new_macro, 0, sizeof (struct macro_definition)); skip_ws (&exp); name = extract_identifier (&exp, 0); if (! name) error (_("Invalid macro name.")); if (*exp == '(') { /* Function-like macro. */ int alloced = 5; char **argv = XNEWVEC (char *, alloced); new_macro.kind = macro_function_like; new_macro.argc = 0; new_macro.argv = (const char * const *) argv; /* Skip the '(' and whitespace. */ ++exp; skip_ws (&exp); while (*exp != ')') { int i; if (new_macro.argc == alloced) { alloced *= 2; argv = (char **) xrealloc (argv, alloced * sizeof (char *)); /* Must update new_macro as well... */ new_macro.argv = (const char * const *) argv; } argv[new_macro.argc] = extract_identifier (&exp, 1); if (! argv[new_macro.argc]) error (_("Macro is missing an argument.")); ++new_macro.argc; for (i = new_macro.argc - 2; i >= 0; --i) { if (! strcmp (argv[i], argv[new_macro.argc - 1])) error (_("Two macro arguments with identical names.")); } skip_ws (&exp); if (*exp == ',') { ++exp; skip_ws (&exp); } else if (*exp != ')') error (_("',' or ')' expected at end of macro arguments.")); } /* Skip the closing paren. */ ++exp; skip_ws (&exp); macro_define_function (macro_main (macro_user_macros), -1, name, new_macro.argc, (const char **) new_macro.argv, exp); }
void switch_thru_all_uis_init (struct switch_thru_all_uis *state) { state->iter = ui_list; state->old_chain = make_cleanup (restore_ui_cleanup, current_ui); }
struct cleanup * make_cleanup_dlclose (void *handle) { return make_cleanup (do_dlclose_cleanup, handle); }
/* The implementation of the `info macro' command. */ static void info_macro_command (char *args, int from_tty) { struct macro_scope *ms = NULL; struct cleanup *cleanup_chain; char *name; int show_all_macros_named = 0; char *arg_start = args; int processing_args = 1; while (processing_args && arg_start && *arg_start == '-' && *arg_start != '\0') { char *p = skip_to_space (arg_start); if (strncmp (arg_start, "-a", p - arg_start) == 0 || strncmp (arg_start, "-all", p - arg_start) == 0) show_all_macros_named = 1; else if (strncmp (arg_start, "--", p - arg_start) == 0) /* Our macro support seems rather C specific but this would seem necessary for languages allowing - in macro names. e.g. Scheme's (defmacro ->foo () "bar\n") */ processing_args = 0; else { /* Relies on modified 'args' not making it in to history */ *p = '\0'; error (_("Unrecognized option '%s' to info macro command. " "Try \"help info macro\"."), arg_start); } arg_start = skip_spaces (p); } name = arg_start; if (! name || ! *name) error (_("You must follow the `info macro' command with the name" " of the macro\n" "whose definition you want to see.")); ms = default_macro_scope (); cleanup_chain = make_cleanup (free_current_contents, &ms); if (! ms) macro_inform_no_debuginfo (); else if (show_all_macros_named) macro_for_each (ms->file->table, print_macro_callback, name); else { struct macro_definition *d; d = macro_lookup_definition (ms->file, ms->line, name); if (d) { int line; struct macro_source_file *file = macro_definition_location (ms->file, ms->line, name, &line); print_macro_definition (name, d, file, line); } else { fprintf_filtered (gdb_stdout, "The symbol `%s' has no definition as a C/C++" " preprocessor macro\n" "at ", name); show_pp_source_pos (gdb_stdout, ms->file, ms->line); } } do_cleanups (cleanup_chain); }
void xcoff_relocate_core (struct target_ops *target) { struct bfd_section *ldinfo_sec; int offset = 0; LdInfo *ldi; struct vmap *vp; int arch64 = ARCH64 (); /* Size of a struct ld_info except for the variable-length filename. */ int nonfilesz = (int)LDI_FILENAME ((LdInfo *)0, arch64); /* Allocated size of buffer. */ int buffer_size = nonfilesz; char *buffer = xmalloc (buffer_size); struct cleanup *old = make_cleanup (free_current_contents, &buffer); ldinfo_sec = bfd_get_section_by_name (core_bfd, ".ldinfo"); if (ldinfo_sec == NULL) { bfd_err: fprintf_filtered (gdb_stderr, "Couldn't get ldinfo from core file: %s\n", bfd_errmsg (bfd_get_error ())); do_cleanups (old); return; } do { int i; int names_found = 0; /* Read in everything but the name. */ if (bfd_get_section_contents (core_bfd, ldinfo_sec, buffer, offset, nonfilesz) == 0) goto bfd_err; /* Now the name. */ i = nonfilesz; do { if (i == buffer_size) { buffer_size *= 2; buffer = xrealloc (buffer, buffer_size); } if (bfd_get_section_contents (core_bfd, ldinfo_sec, &buffer[i], offset + i, 1) == 0) goto bfd_err; if (buffer[i++] == '\0') ++names_found; } while (names_found < 2); ldi = (LdInfo *) buffer; /* Can't use a file descriptor from the core file; need to open it. */ if (arch64) ldi->l64.ldinfo_fd = -1; else ldi->l32.ldinfo_fd = -1; /* The first ldinfo is for the exec file, allocated elsewhere. */ if (offset == 0 && vmap != NULL) vp = vmap; else vp = add_vmap (ldi); /* Process next shared library upon error. */ offset += LDI_NEXT (ldi, arch64); if (vp == NULL) continue; vmap_secs (vp, ldi, arch64); /* Unless this is the exec file, add our sections to the section table for the core target. */ if (vp != vmap) { struct section_table *stp; target_resize_to_sections (target, 2); stp = target->to_sections_end - 2; stp->bfd = vp->bfd; stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".text"); stp->addr = vp->tstart; stp->endaddr = vp->tend; stp++; stp->bfd = vp->bfd; stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".data"); stp->addr = vp->dstart; stp->endaddr = vp->dend; } vmap_symtab (vp); if (deprecated_target_new_objfile_hook && vp != vmap && vp->objfile) deprecated_target_new_objfile_hook (vp->objfile); } while (LDI_NEXT (ldi, arch64) != 0); vmap_exec (); breakpoint_re_set (); do_cleanups (old); }
void convert_between_encodings (const char *from, const char *to, const gdb_byte *bytes, unsigned int num_bytes, int width, struct obstack *output, enum transliterations translit) { iconv_t desc; struct cleanup *cleanups; size_t inleft; ICONV_CONST char *inp; unsigned int space_request; /* Often, the host and target charsets will be the same. */ if (!strcmp (from, to)) { obstack_grow (output, bytes, num_bytes); return; } desc = iconv_open (to, from); if (desc == (iconv_t) -1) perror_with_name (_("Converting character sets")); cleanups = make_cleanup (cleanup_iconv, &desc); inleft = num_bytes; inp = (ICONV_CONST char *) bytes; space_request = num_bytes; while (inleft > 0) { char *outp; size_t outleft, r; int old_size; old_size = obstack_object_size (output); obstack_blank (output, space_request); outp = obstack_base (output) + old_size; outleft = space_request; r = iconv (desc, &inp, &inleft, &outp, &outleft); /* Now make sure that the object on the obstack only includes bytes we have converted. */ obstack_blank (output, - (int) outleft); if (r == (size_t) -1) { switch (errno) { case EILSEQ: { int i; /* Invalid input sequence. */ if (translit == translit_none) error (_("Could not convert character " "to `%s' character set"), to); /* We emit escape sequence for the bytes, skip them, and try again. */ for (i = 0; i < width; ++i) { char octal[5]; xsnprintf (octal, sizeof (octal), "\\%.3o", *inp & 0xff); obstack_grow_str (output, octal); ++inp; --inleft; } } break; case E2BIG: /* We ran out of space in the output buffer. Make it bigger next time around. */ space_request *= 2; break; case EINVAL: /* Incomplete input sequence. FIXME: ought to report this to the caller somehow. */ inleft = 0; break; default: perror_with_name (_("Internal error while " "converting character sets")); } } } do_cleanups (cleanups); }
static void core_open (char *filename, int from_tty) { const char *p; int siggy; struct cleanup *old_chain; char *temp; bfd *temp_bfd; int scratch_chan; int flags; volatile struct gdb_exception except; target_preopen (from_tty); if (!filename) { if (core_bfd) error (_("No core file specified. (Use `detach' " "to stop debugging a core file.)")); else error (_("No core file specified.")); } filename = tilde_expand (filename); if (!IS_ABSOLUTE_PATH (filename)) { temp = concat (current_directory, "/", filename, (char *) NULL); xfree (filename); filename = temp; } old_chain = make_cleanup (xfree, filename); flags = O_BINARY | O_LARGEFILE; if (write_files) flags |= O_RDWR; else flags |= O_RDONLY; scratch_chan = gdb_open_cloexec (filename, flags, 0); if (scratch_chan < 0) perror_with_name (filename); temp_bfd = gdb_bfd_fopen (filename, gnutarget, write_files ? FOPEN_RUB : FOPEN_RB, scratch_chan); if (temp_bfd == NULL) perror_with_name (filename); if (!bfd_check_format (temp_bfd, bfd_core) && !gdb_check_format (temp_bfd)) { /* Do it after the err msg */ /* FIXME: should be checking for errors from bfd_close (for one thing, on error it does not free all the storage associated with the bfd). */ make_cleanup_bfd_unref (temp_bfd); error (_("\"%s\" is not a core dump: %s"), filename, bfd_errmsg (bfd_get_error ())); } /* Looks semi-reasonable. Toss the old core file and work on the new. */ do_cleanups (old_chain); unpush_target (&core_ops); core_bfd = temp_bfd; old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/); core_gdbarch = gdbarch_from_bfd (core_bfd); /* Find a suitable core file handler to munch on core_bfd */ core_vec = sniff_core_bfd (core_bfd); validate_files (); core_data = XZALLOC (struct target_section_table); /* Find the data section */ if (build_section_table (core_bfd, &core_data->sections, &core_data->sections_end)) error (_("\"%s\": Can't find sections: %s"), bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ())); /* If we have no exec file, try to set the architecture from the core file. We don't do this unconditionally since an exec file typically contains more information that helps us determine the architecture than a core file. */ if (!exec_bfd) set_gdbarch_from_file (core_bfd); push_target (&core_ops); discard_cleanups (old_chain); /* Do this before acknowledging the inferior, so if post_create_inferior throws (can happen easilly if you're loading a core file with the wrong exec), we aren't left with threads from the previous inferior. */ init_thread_list (); inferior_ptid = null_ptid; /* Need to flush the register cache (and the frame cache) from a previous debug session. If inferior_ptid ends up the same as the last debug session --- e.g., b foo; run; gcore core1; step; gcore core2; core core1; core core2 --- then there's potential for get_current_regcache to return the cached regcache of the previous session, and the frame cache being stale. */ registers_changed (); /* Build up thread list from BFD sections, and possibly set the current thread to the .reg/NN section matching the .reg section. */ bfd_map_over_sections (core_bfd, add_to_thread_list, bfd_get_section_by_name (core_bfd, ".reg")); if (ptid_equal (inferior_ptid, null_ptid)) { /* Either we found no .reg/NN section, and hence we have a non-threaded core (single-threaded, from gdb's perspective), or for some reason add_to_thread_list couldn't determine which was the "main" thread. The latter case shouldn't usually happen, but we're dealing with input here, which can always be broken in different ways. */ struct thread_info *thread = first_thread_of_process (-1); if (thread == NULL) { inferior_appeared (current_inferior (), CORELOW_PID); inferior_ptid = pid_to_ptid (CORELOW_PID); add_thread_silent (inferior_ptid); } else switch_to_thread (thread->ptid); } post_create_inferior (&core_ops, from_tty); /* Now go through the target stack looking for threads since there may be a thread_stratum target loaded on top of target core by now. The layer above should claim threads found in the BFD sections. */ TRY_CATCH (except, RETURN_MASK_ERROR) { target_find_new_threads (); } if (except.reason < 0) exception_print (gdb_stderr, except); p = bfd_core_file_failing_command (core_bfd); if (p) printf_filtered (_("Core was generated by `%s'.\n"), p); siggy = bfd_core_file_failing_signal (core_bfd); if (siggy > 0) { /* If we don't have a CORE_GDBARCH to work with, assume a native core (map gdb_signal from host signals). If we do have CORE_GDBARCH to work with, but no gdb_signal_from_target implementation for that gdbarch, as a fallback measure, assume the host signal mapping. It'll be correct for native cores, but most likely incorrect for cross-cores. */ enum gdb_signal sig = (core_gdbarch != NULL && gdbarch_gdb_signal_from_target_p (core_gdbarch) ? gdbarch_gdb_signal_from_target (core_gdbarch, siggy) : gdb_signal_from_host (siggy)); printf_filtered (_("Program terminated with signal %d, %s.\n"), siggy, gdb_signal_to_string (sig)); } /* Fetch all registers from core file. */ target_fetch_registers (get_current_regcache (), -1); /* Now, set up the frame cache, and print the top of stack. */ reinit_frame_cache (); print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); }
/* The arguments to be passed on the command line and parsed here are: either: START-ADDRESS: address to start the disassembly at. END-ADDRESS: address to end the disassembly at. or: FILENAME: The name of the file where we want disassemble from. LINE: The line around which we want to disassemble. It will disassemble the function that contins that line. HOW_MANY: Number of disassembly lines to display. With source, it is the number of disassembly lines only, not counting the source lines. always required: MODE: 0 -- disassembly. 1 -- disassembly and source. 2 -- disassembly and opcodes. 3 -- disassembly, source and opcodes. */ void mi_cmd_disassemble (char *command, char **argv, int argc) { struct gdbarch *gdbarch = get_current_arch (); CORE_ADDR start; int mode, disasm_flags; struct symtab *s; /* Which options have we processed ... */ int file_seen = 0; int line_seen = 0; int num_seen = 0; int start_seen = 0; int end_seen = 0; /* ... and their corresponding value. */ char *file_string = NULL; int line_num = -1; int how_many = -1; CORE_ADDR low = 0; CORE_ADDR high = 0; struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); /* Options processing stuff. */ int optind = 0; char *optarg; enum opt { FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT }; static struct mi_opt opts[] = { {"f", FILE_OPT, 1}, {"l", LINE_OPT, 1}, {"n", NUM_OPT, 1}, {"s", START_OPT, 1}, {"e", END_OPT, 1}, { 0, 0, 0 } }; /* Get the options with their arguments. Keep track of what we encountered. */ while (1) { int opt = mi_getopt ("-data-disassemble", argc, argv, opts, &optind, &optarg); if (opt < 0) break; switch ((enum opt) opt) { case FILE_OPT: file_string = xstrdup (optarg); file_seen = 1; make_cleanup (xfree, file_string); break; case LINE_OPT: line_num = atoi (optarg); line_seen = 1; break; case NUM_OPT: how_many = atoi (optarg); num_seen = 1; break; case START_OPT: low = parse_and_eval_address (optarg); start_seen = 1; break; case END_OPT: high = parse_and_eval_address (optarg); end_seen = 1; break; } } argv += optind; argc -= optind; /* Allow only filename + linenum (with how_many which is not required) OR start_addr + and_addr */ if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen) || (line_seen && file_seen && !num_seen && !start_seen && !end_seen) || (!line_seen && !file_seen && !num_seen && start_seen && end_seen))) error (_("-data-disassemble: Usage: ( [-f filename -l linenum [-n " "howmany]] | [-s startaddr -e endaddr]) [--] mode.")); if (argc != 1) error (_("-data-disassemble: Usage: [-f filename -l linenum " "[-n howmany]] [-s startaddr -e endaddr] [--] mode.")); mode = atoi (argv[0]); if (mode < 0 || mode > 3) error (_("-data-disassemble: Mode argument must be 0, 1, 2, or 3.")); /* Convert the mode into a set of disassembly flags */ disasm_flags = 0; if (mode & 0x1) disasm_flags |= DISASSEMBLY_SOURCE; if (mode & 0x2) disasm_flags |= DISASSEMBLY_RAW_INSN; /* We must get the function beginning and end where line_num is contained. */ if (line_seen && file_seen) { s = lookup_symtab (file_string); if (s == NULL) error (_("-data-disassemble: Invalid filename.")); if (!find_line_pc (s, line_num, &start)) error (_("-data-disassemble: Invalid line number")); if (find_pc_partial_function (start, NULL, &low, &high) == 0) error (_("-data-disassemble: " "No function contains specified address")); } gdb_disassembly (gdbarch, uiout, file_string, disasm_flags, how_many, low, high); do_cleanups (cleanups); }
void exec_file_attach (const char *filename, int from_tty) { struct cleanup *cleanups; /* First, acquire a reference to the current exec_bfd. We release this at the end of the function; but acquiring it now lets the BFD cache return it if this call refers to the same file. */ gdb_bfd_ref (exec_bfd); cleanups = make_cleanup_bfd_unref (exec_bfd); /* Remove any previous exec file. */ exec_close (); /* Now open and digest the file the user requested, if any. */ if (!filename) { if (from_tty) printf_unfiltered (_("No executable file now.\n")); set_gdbarch_from_file (NULL); } else { int load_via_target = 0; char *scratch_pathname, *canonical_pathname; int scratch_chan; struct target_section *sections = NULL, *sections_end = NULL; char **matching; if (is_target_filename (filename)) { if (target_filesystem_is_local ()) filename += strlen (TARGET_SYSROOT_PREFIX); else load_via_target = 1; } if (load_via_target) { /* gdb_bfd_fopen does not support "target:" filenames. */ if (write_files) warning (_("writing into executable files is " "not supported for %s sysroots"), TARGET_SYSROOT_PREFIX); scratch_pathname = xstrdup (filename); make_cleanup (xfree, scratch_pathname); scratch_chan = -1; canonical_pathname = scratch_pathname; } else { scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &scratch_pathname); #if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__) if (scratch_chan < 0) { char *exename = alloca (strlen (filename) + 5); strcat (strcpy (exename, filename), ".exe"); scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &scratch_pathname); } #endif if (scratch_chan < 0) perror_with_name (filename); make_cleanup (xfree, scratch_pathname); /* gdb_bfd_open (and its variants) prefers canonicalized pathname for better BFD caching. */ canonical_pathname = gdb_realpath (scratch_pathname); make_cleanup (xfree, canonical_pathname); } if (write_files && !load_via_target) exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget, FOPEN_RUB, scratch_chan); else exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan); if (!exec_bfd) { error (_("\"%s\": could not open as an executable file: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } /* gdb_realpath_keepfile resolves symlinks on the local filesystem and so cannot be used for "target:" files. */ gdb_assert (exec_filename == NULL); if (load_via_target) exec_filename = xstrdup (bfd_get_filename (exec_bfd)); else exec_filename = gdb_realpath_keepfile (scratch_pathname); if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": not in executable format: %s"), scratch_pathname, gdb_bfd_errmsg (bfd_get_error (), matching)); } if (build_section_table (exec_bfd, §ions, §ions_end)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } exec_bfd_mtime = bfd_get_mtime (exec_bfd); validate_files (); set_gdbarch_from_file (exec_bfd); /* Add the executable's sections to the current address spaces' list of sections. This possibly pushes the exec_ops target. */ add_target_sections (&exec_bfd, sections, sections_end); xfree (sections); /* Tell display code (if any) about the changed file name. */ if (deprecated_exec_file_display_hook) (*deprecated_exec_file_display_hook) (filename); } do_cleanups (cleanups); bfd_cache_close_all (); observer_notify_executable_changed (); }
static void kgdb_trgt_open(char *filename, int from_tty) { struct cleanup *old_chain; struct thread_info *ti; struct kthr *kt; kvm_t *nkvm; char *temp; int ontop; target_preopen (from_tty); if (!filename) error ("No vmcore file specified."); if (!exec_bfd) error ("Can't open a vmcore without a kernel"); filename = tilde_expand (filename); if (filename[0] != '/') { temp = concat (current_directory, "/", filename, NULL); xfree(filename); filename = temp; } old_chain = make_cleanup (xfree, filename); nkvm = kvm_openfiles(bfd_get_filename(exec_bfd), filename, NULL, write_files ? O_RDWR : O_RDONLY, kvm_err); if (nkvm == NULL) error ("Failed to open vmcore: %s", kvm_err); /* Don't free the filename now and close any previous vmcore. */ discard_cleanups(old_chain); unpush_target(&kgdb_trgt_ops); kvm = nkvm; vmcore = filename; old_chain = make_cleanup(kgdb_core_cleanup, NULL); ontop = !push_target (&kgdb_trgt_ops); discard_cleanups (old_chain); kgdb_dmesg(); init_thread_list(); kt = kgdb_thr_init(); while (kt != NULL) { ti = add_thread(pid_to_ptid(kt->tid)); kt = kgdb_thr_next(kt); } if (curkthr != 0) inferior_ptid = pid_to_ptid(curkthr->tid); if (ontop) { /* XXX: fetch registers? */ kld_init(); flush_cached_frames(); select_frame (get_current_frame()); print_stack_frame(get_selected_frame(), frame_relative_level(get_selected_frame()), 1); } else warning( "you won't be able to access this vmcore until you terminate\n\ your %s; do ``info files''", target_longname); }
/* Read inferior memory at ADDR to find the header of a loaded object file and read its in-core symbols out of inferior memory. SIZE, if non-zero, is the known size of the object. TEMPL is a bfd representing the target's format. NAME is the name to use for this symbol file in messages; it can be NULL or a malloc-allocated string which will be attached to the BFD. */ static struct objfile * symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, size_t size, char *name, int from_tty) { struct objfile *objf; struct bfd *nbfd; struct bfd_section *sec; bfd_vma loadbase; struct section_addr_info *sai; unsigned int i; struct cleanup *cleanup; symfile_add_flags add_flags = 0; if (bfd_get_flavour (templ) != bfd_target_elf_flavour) error (_("add-symbol-file-from-memory not supported for this target")); nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, size, &loadbase, target_read_memory_bfd); if (nbfd == NULL) error (_("Failed to read a valid object file image from memory.")); /* Manage the new reference for the duration of this function. */ gdb_bfd_ref_ptr nbfd_holder = new_bfd_ref (nbfd); xfree (bfd_get_filename (nbfd)); if (name == NULL) nbfd->filename = xstrdup ("shared object read from target memory"); else nbfd->filename = name; if (!bfd_check_format (nbfd, bfd_object)) error (_("Got object file from memory but can't read symbols: %s."), bfd_errmsg (bfd_get_error ())); sai = alloc_section_addr_info (bfd_count_sections (nbfd)); cleanup = make_cleanup (xfree, sai); i = 0; for (sec = nbfd->sections; sec != NULL; sec = sec->next) if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0) { sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase; sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec); sai->other[i].sectindex = sec->index; ++i; } sai->num_sections = i; if (from_tty) add_flags |= SYMFILE_VERBOSE; objf = symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd), add_flags, sai, OBJF_SHARED, NULL); add_target_sections_of_objfile (objf); /* This might change our ideas about frames already looked at. */ reinit_frame_cache (); do_cleanups (cleanup); return objf; }
void read_pe_exported_syms(struct objfile *objfile) { bfd *dll = objfile->obfd; unsigned long pe_header_offset, opthdr_ofs, num_entries, i; unsigned long export_rva, export_size, nsections, secptr, expptr; unsigned long exp_funcbase; unsigned char *expdata, *erva; unsigned long name_rvas, ordinals, nexp, ordbase; char *dll_name; /* Array elements are for text, data and bss in that order Initialization with start_rva > end_rva guarantees that unused sections will NOT be matched. */ struct read_pe_section_data section_data[PE_SECTION_TABLE_SIZE] = { { 0, 1, 0, mst_text }, { 0, 1, 0, mst_data }, { 0, 1, 0, mst_bss } }; struct cleanup *back_to = 0; char const *target = bfd_get_target(objfile->obfd); if ((strcmp(target, "pe-i386") != 0) && (strcmp(target, "pei-i386") != 0)) { /* This is not an i386 format file. Abort now, because the code is untested on anything else. *FIXME* test on further architectures and loosen or remove this test. */ return; } /* Get pe_header, optional header and numbers of export entries: */ pe_header_offset = pe_get32(dll, 0x3c); opthdr_ofs = (pe_header_offset + 4 + 20); num_entries = pe_get32(dll, opthdr_ofs + 92); if (num_entries < 1) /* No exports. */ { return; } export_rva = pe_get32(dll, opthdr_ofs + 96); export_size = pe_get32(dll, opthdr_ofs + 100); nsections = pe_get16(dll, pe_header_offset + 4 + 2); secptr = (pe_header_offset + 4 + 20 + pe_get16(dll, pe_header_offset + 4 + 16)); expptr = 0; /* Get the rva and size of the export section: */ for (i = 0; i < nsections; i++) { char sname[8]; unsigned long secptr1 = (secptr + 40 * i); unsigned long vaddr = pe_get32(dll, secptr1 + 12); unsigned long vsize = pe_get32(dll, secptr1 + 16); unsigned long fptr = pe_get32(dll, secptr1 + 20); bfd_seek(dll, (file_ptr)secptr1, SEEK_SET); bfd_bread(sname, (bfd_size_type)8UL, dll); if ((vaddr <= export_rva) && ((vaddr + vsize) > export_rva)) { expptr = fptr + (export_rva - vaddr); if ((export_rva + export_size) > (vaddr + vsize)) export_size = (vsize - (export_rva - vaddr)); break; } } if (export_size == 0) { /* Empty export table: */ return; } /* Scan sections and store the base and size of the relevant sections: */ for (i = 0; i < nsections; i++) { unsigned long secptr1 = (secptr + 40 * i); unsigned long vsize = pe_get32(dll, secptr1 + 8); unsigned long vaddr = pe_get32(dll, secptr1 + 12); char sec_name[9]; int sectix; sec_name[8] = '\0'; bfd_seek(dll, ((file_ptr)secptr1 + 0L), SEEK_SET); bfd_bread(sec_name, (bfd_size_type)8UL, dll); sectix = read_pe_section_index (sec_name); if (sectix != PE_SECTION_INDEX_INVALID) { section_data[sectix].rva_start = vaddr; section_data[sectix].rva_end = (vaddr + vsize); } } expdata = (unsigned char *)xmalloc(export_size); back_to = make_cleanup(xfree, expdata); bfd_seek(dll, (file_ptr)expptr, SEEK_SET); bfd_bread(expdata, (bfd_size_type)export_size, dll); erva = (expdata - export_rva); nexp = pe_as32(expdata + 24); name_rvas = pe_as32(expdata + 32); ordinals = pe_as32(expdata + 36); ordbase = pe_as32(expdata + 16); exp_funcbase = pe_as32(expdata + 28); if (ordinals == ordbase) { ; /* ??? */ } /* Use internal dll name instead of full pathname: */ dll_name = (char *)(pe_as32(expdata + 12) + erva); bfd_map_over_sections(dll, get_section_vmas, section_data); /* Adjust the vma_offsets in case this PE got relocated. This assumes that *all* sections share the same relocation offset as the text section. */ for (i = 0; i < PE_SECTION_TABLE_SIZE; i++) { section_data[i].vma_offset += objfile_text_section_offset(objfile); } printf_filtered(_("Minimal symbols from %s..."), dll_name); wrap_here(""); /* Truncate name at first dot. Should maybe also convert to all lower case for convenience on Windows. */ read_pe_truncate_name(dll_name); /* Iterate through the list of symbols. */ for (i = 0; i < nexp; i++) { /* Pointer to the names vector: */ unsigned long name_rva = pe_as32(erva + name_rvas + i * 4); /* Pointer to the function address vector: */ unsigned long func_rva = pe_as32(erva + exp_funcbase + i * 4); /* Find this symbol's section in our own array. */ int sectix = 0; for (sectix = 0; sectix < PE_SECTION_TABLE_SIZE; ++sectix) { if ((func_rva >= section_data[sectix].rva_start) && (func_rva < section_data[sectix].rva_end)) { add_pe_exported_sym((char *)(erva + name_rva), func_rva, section_data + sectix, dll_name, objfile); break; } } } /* discard expdata. */ do_cleanups (back_to); }
struct cleanup * make_cleanup_free_agent_expr (struct agent_expr *x) { return make_cleanup (do_free_agent_expr_cleanup, x); }
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, "&"); xasprintf (&run, "%s %s", mi, async_args); make_exec_cleanup (free, run); add_continuation (mi_exec_async_cli_cmd_continuation, NULL); old_cleanups = NULL; } else { xasprintf (&run, "%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; }
void display_gdb_prompt (const char *new_prompt) { char *actual_gdb_prompt = NULL; struct cleanup *old_chain; annotate_display_prompt (); /* Reset the nesting depth used when trace-commands is set. */ reset_command_nest_depth (); old_chain = make_cleanup (free_current_contents, &actual_gdb_prompt); /* Do not call the python hook on an explicit prompt change as passed to this function, as this forms a secondary/local prompt, IE, displayed but not set. */ if (! new_prompt) { struct ui *ui = current_ui; if (ui->prompt_state == PROMPTED) internal_error (__FILE__, __LINE__, _("double prompt")); else if (ui->prompt_state == PROMPT_BLOCKED) { /* This is to trick readline into not trying to display the prompt. Even though we display the prompt using this function, readline still tries to do its own display if we don't call rl_callback_handler_install and rl_callback_handler_remove (which readline detects because a global variable is not set). If readline did that, it could mess up gdb signal handlers for SIGINT. Readline assumes that between calls to rl_set_signals and rl_clear_signals gdb doesn't do anything with the signal handlers. Well, that's not the case, because when the target executes we change the SIGINT signal handler. If we allowed readline to display the prompt, the signal handler change would happen exactly between the calls to the above two functions. Calling rl_callback_handler_remove(), does the job. */ if (current_ui->command_editing) gdb_rl_callback_handler_remove (); do_cleanups (old_chain); return; } else if (ui->prompt_state == PROMPT_NEEDED) { /* Display the top level prompt. */ actual_gdb_prompt = top_level_prompt (); ui->prompt_state = PROMPTED; } } else actual_gdb_prompt = xstrdup (new_prompt); if (current_ui->command_editing) { gdb_rl_callback_handler_remove (); gdb_rl_callback_handler_install (actual_gdb_prompt); } /* new_prompt at this point can be the top of the stack or the one passed in. It can't be NULL. */ else { /* Don't use a _filtered function here. It causes the assumed character position to be off, since the newline we read from the user is not accounted for. */ fputs_unfiltered (actual_gdb_prompt, gdb_stdout); gdb_flush (gdb_stdout); } do_cleanups (old_chain); }
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; char *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) { xasprintf (&mi_error_message, "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) { xasprintf (&mi_error_message, "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) { xasprintf (&mi_error_message, "mi_cmd_data_read_memory: invalid number of columns."); } /* 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); if (mbuf == NULL) { xasprintf (&mi_error_message, "mi_cmd_data_read_memory: out of memory."); return MI_CMD_ERROR; } nr_bytes = 0; while (nr_bytes < total_bytes) { int error; long num = target_read_memory_partial (addr + nr_bytes, mbuf + nr_bytes, total_bytes - nr_bytes, &error); if (num <= 0) break; nr_bytes += num; } /* 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 CORE_ADDR tilegx_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR stack_dest = sp; int argreg = TILEGX_R0_REGNUM; int i, j; int typelen, slacklen, alignlen; static const gdb_byte four_zero_words[16] = { 0 }; /* If struct_return is 1, then the struct return address will consume one argument-passing register. */ if (struct_return) regcache_cooked_write_unsigned (regcache, argreg++, struct_addr); /* Arguments are passed in R0 - R9, and as soon as an argument will not fit completely in the remaining registers, then it, and all remaining arguments, are put on the stack. */ for (i = 0; i < nargs && argreg <= TILEGX_R9_REGNUM; i++) { const gdb_byte *val; typelen = TYPE_LENGTH (value_enclosing_type (args[i])); if (typelen > (TILEGX_R9_REGNUM - argreg + 1) * tilegx_reg_size) break; /* Put argument into registers wordwise. */ val = value_contents (args[i]); for (j = 0; j < typelen; j += tilegx_reg_size) { /* ISSUE: Why special handling for "typelen = 4x + 1"? I don't ever see "typelen" values except 4 and 8. */ int n = (typelen - j == 1) ? 1 : tilegx_reg_size; ULONGEST w = extract_unsigned_integer (val + j, n, byte_order); regcache_cooked_write_unsigned (regcache, argreg++, w); } } /* Align SP. */ stack_dest = tilegx_frame_align (gdbarch, stack_dest); /* Loop backwards through remaining arguments and push them on the stack, word aligned. */ for (j = nargs - 1; j >= i; j--) { gdb_byte *val; struct cleanup *back_to; const gdb_byte *contents = value_contents (args[j]); typelen = TYPE_LENGTH (value_enclosing_type (args[j])); slacklen = align_up (typelen, 8) - typelen; val = xmalloc (typelen + slacklen); back_to = make_cleanup (xfree, val); memcpy (val, contents, typelen); memset (val + typelen, 0, slacklen); /* Now write data to the stack. The stack grows downwards. */ stack_dest -= typelen + slacklen; write_memory (stack_dest, val, typelen + slacklen); do_cleanups (back_to); } /* Add 16 bytes for linkage space to the stack. */ stack_dest = stack_dest - 16; write_memory (stack_dest, four_zero_words, 16); /* Update stack pointer. */ regcache_cooked_write_unsigned (regcache, TILEGX_SP_REGNUM, stack_dest); /* Set the return address register to point to the entry point of the program, where a breakpoint lies in wait. */ regcache_cooked_write_unsigned (regcache, TILEGX_LR_REGNUM, bp_addr); return stack_dest; }
static struct macro_buffer * gather_arguments (const char *name, struct macro_buffer *src, int *argc_p) { struct macro_buffer tok; int args_len, args_size; struct macro_buffer *args = NULL; struct cleanup *back_to = make_cleanup (free_current_contents, &args); /* Does SRC start with an opening paren token? Read from a copy of SRC, so SRC itself is unaffected if we don't find an opening paren. */ { struct macro_buffer temp; init_shared_buffer (&temp, src->text, src->len); if (! get_token (&tok, &temp) || tok.len != 1 || tok.text[0] != '(') { discard_cleanups (back_to); return 0; } } /* Consume SRC's opening paren. */ get_token (&tok, src); args_len = 0; args_size = 1; /* small for initial testing */ args = (struct macro_buffer *) xmalloc (sizeof (*args) * args_size); for (;;) { struct macro_buffer *arg; int depth; /* Make sure we have room for the next argument. */ if (args_len >= args_size) { args_size *= 2; args = xrealloc (args, sizeof (*args) * args_size); } /* Initialize the next argument. */ arg = &args[args_len++]; set_token (arg, src->text, src->text); /* Gather the argument's tokens. */ depth = 0; for (;;) { char *start = src->text; if (! get_token (&tok, src)) error ("Malformed argument list for macro `%s'.", name); /* Is tok an opening paren? */ if (tok.len == 1 && tok.text[0] == '(') depth++; /* Is tok is a closing paren? */ else if (tok.len == 1 && tok.text[0] == ')') { /* If it's a closing paren at the top level, then that's the end of the argument list. */ if (depth == 0) { discard_cleanups (back_to); *argc_p = args_len; return args; } depth--; } /* If tok is a comma at top level, then that's the end of the current argument. */ else if (tok.len == 1 && tok.text[0] == ',' && depth == 0) break; /* Extend the current argument to enclose this token. If this is the current argument's first token, leave out any leading whitespace, just for aesthetics. */ if (arg->len == 0) { arg->text = tok.text; arg->len = tok.len; arg->last_token = 0; } else { arg->len = (tok.text + tok.len) - arg->text; arg->last_token = tok.text - arg->text; } } } }
static void som_symtab_read (bfd *abfd, struct objfile *objfile, struct section_offsets *section_offsets) { struct gdbarch *gdbarch = get_objfile_arch (objfile); unsigned int number_of_symbols; int val, dynamic; char *stringtab; asection *shlib_info; struct symbol_dictionary_record *buf, *bufp, *endbufp; char *symname; CONST int symsize = sizeof (struct symbol_dictionary_record); CORE_ADDR text_offset, data_offset; text_offset = ANOFFSET (section_offsets, 0); data_offset = ANOFFSET (section_offsets, 1); number_of_symbols = bfd_get_symcount (abfd); /* Allocate a buffer to read in the debug info. We avoid using alloca because the memory size could be so large that we could hit the stack size limit. */ buf = xmalloc (symsize * number_of_symbols); make_cleanup (xfree, buf); bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET); val = bfd_bread (buf, symsize * number_of_symbols, abfd); if (val != symsize * number_of_symbols) error (_("Couldn't read symbol dictionary!")); /* Allocate a buffer to read in the som stringtab section of the debugging info. Again, we avoid using alloca because the data could be so large that we could potentially hit the stack size limitat. */ stringtab = xmalloc (obj_som_stringtab_size (abfd)); make_cleanup (xfree, stringtab); bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET); val = bfd_bread (stringtab, obj_som_stringtab_size (abfd), abfd); if (val != obj_som_stringtab_size (abfd)) error (_("Can't read in HP string table.")); /* We need to determine if objfile is a dynamic executable (so we can do the right thing for ST_ENTRY vs ST_CODE symbols). There's nothing in the header which easily allows us to do this. This code used to rely upon the existence of a $SHLIB_INFO$ section to make this determination. HP claims that it is more accurate to check for a nonzero text offset, but they have not provided any information about why that test is more accurate. */ dynamic = (text_offset != 0); endbufp = buf + number_of_symbols; for (bufp = buf; bufp < endbufp; ++bufp) { enum minimal_symbol_type ms_type; QUIT; switch (bufp->symbol_scope) { case SS_UNIVERSAL: case SS_EXTERNAL: switch (bufp->symbol_type) { case ST_SYM_EXT: case ST_ARG_EXT: continue; case ST_CODE: case ST_PRI_PROG: case ST_SEC_PROG: case ST_MILLICODE: symname = bufp->name.n_strx + stringtab; ms_type = mst_text; bufp->symbol_value += text_offset; bufp->symbol_value = gdbarch_smash_text_address (gdbarch, bufp->symbol_value); break; case ST_ENTRY: symname = bufp->name.n_strx + stringtab; /* For a dynamic executable, ST_ENTRY symbols are the stubs, while the ST_CODE symbol is the real function. */ if (dynamic) ms_type = mst_solib_trampoline; else ms_type = mst_text; bufp->symbol_value += text_offset; bufp->symbol_value = gdbarch_smash_text_address (gdbarch, bufp->symbol_value); break; case ST_STUB: symname = bufp->name.n_strx + stringtab; ms_type = mst_solib_trampoline; bufp->symbol_value += text_offset; bufp->symbol_value = gdbarch_smash_text_address (gdbarch, bufp->symbol_value); break; case ST_DATA: symname = bufp->name.n_strx + stringtab; bufp->symbol_value += data_offset; ms_type = mst_data; break; default: continue; } break; #if 0 /* SS_GLOBAL and SS_LOCAL are two names for the same thing (!). */ case SS_GLOBAL: #endif case SS_LOCAL: switch (bufp->symbol_type) { case ST_SYM_EXT: case ST_ARG_EXT: continue; case ST_CODE: symname = bufp->name.n_strx + stringtab; ms_type = mst_file_text; bufp->symbol_value += text_offset; bufp->symbol_value = gdbarch_smash_text_address (gdbarch, bufp->symbol_value); check_strange_names: /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local label prefixes for stabs, constant data, etc. So we need only filter out L$ symbols which are left in due to limitations in how GAS generates SOM relocations. When linking in the HPUX C-library the HP linker has the nasty habit of placing section symbols from the literal subspaces in the middle of the program's text. Filter those out as best we can. Check for first and last character being '$'. And finally, the newer HP compilers emit crud like $PIC_foo$N in some circumstance (PIC code I guess). It's also claimed that they emit D$ symbols too. What stupidity. */ if ((symname[0] == 'L' && symname[1] == '$') || (symname[0] == '$' && symname[strlen (symname) - 1] == '$') || (symname[0] == 'D' && symname[1] == '$') || (strncmp (symname, "L0\001", 3) == 0) || (strncmp (symname, "$PIC", 4) == 0)) continue; break; case ST_PRI_PROG: case ST_SEC_PROG: case ST_MILLICODE: symname = bufp->name.n_strx + stringtab; ms_type = mst_file_text; bufp->symbol_value += text_offset; bufp->symbol_value = gdbarch_smash_text_address (gdbarch, bufp->symbol_value); break; case ST_ENTRY: symname = bufp->name.n_strx + stringtab; /* SS_LOCAL symbols in a shared library do not have export stubs, so we do not have to worry about using mst_file_text vs mst_solib_trampoline here like we do for SS_UNIVERSAL and SS_EXTERNAL symbols above. */ ms_type = mst_file_text; bufp->symbol_value += text_offset; bufp->symbol_value = gdbarch_smash_text_address (gdbarch, bufp->symbol_value); break; case ST_STUB: symname = bufp->name.n_strx + stringtab; ms_type = mst_solib_trampoline; bufp->symbol_value += text_offset; bufp->symbol_value = gdbarch_smash_text_address (gdbarch, bufp->symbol_value); break; case ST_DATA: symname = bufp->name.n_strx + stringtab; bufp->symbol_value += data_offset; ms_type = mst_file_data; goto check_strange_names; default: continue; } break; /* This can happen for common symbols when -E is passed to the final link. No idea _why_ that would make the linker force common symbols to have an SS_UNSAT scope, but it does. This also happens for weak symbols, but their type is ST_DATA. */ case SS_UNSAT: switch (bufp->symbol_type) { case ST_STORAGE: case ST_DATA: symname = bufp->name.n_strx + stringtab; bufp->symbol_value += data_offset; ms_type = mst_data; break; default: continue; } break; default: continue; } if (bufp->name.n_strx > obj_som_stringtab_size (abfd)) error (_("Invalid symbol data; bad HP string table offset: %d"), bufp->name.n_strx); prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type, objfile); } }
struct cleanup * make_cleanup_cp_demangled_name_parse_free (struct demangle_parse_info *info) { return make_cleanup (do_demangled_name_parse_free_cleanup, info); }
static void read_alphacoff_dynamic_symtab (minimal_symbol_reader &reader, struct section_offsets *section_offsets, struct objfile *objfile) { bfd *abfd = objfile->obfd; struct alphacoff_dynsecinfo si; char *sym_secptr; char *str_secptr; char *dyninfo_secptr; char *got_secptr; bfd_size_type sym_secsize; bfd_size_type str_secsize; bfd_size_type dyninfo_secsize; bfd_size_type got_secsize; int sym_count; int i; int stripped; Elfalpha_External_Sym *x_symp; char *dyninfo_p; char *dyninfo_end; int got_entry_size = 8; int dt_mips_local_gotno = -1; int dt_mips_gotsym = -1; struct cleanup *cleanups; /* We currently only know how to handle alpha dynamic symbols. */ if (bfd_get_arch (abfd) != bfd_arch_alpha) return; /* Locate the dynamic symbols sections and read them in. */ memset ((char *) &si, 0, sizeof (si)); bfd_map_over_sections (abfd, alphacoff_locate_sections, (void *) & si); if (si.sym_sect == NULL || si.str_sect == NULL || si.dyninfo_sect == NULL || si.got_sect == NULL) return; sym_secsize = bfd_get_section_size (si.sym_sect); str_secsize = bfd_get_section_size (si.str_sect); dyninfo_secsize = bfd_get_section_size (si.dyninfo_sect); got_secsize = bfd_get_section_size (si.got_sect); sym_secptr = (char *) xmalloc (sym_secsize); cleanups = make_cleanup (xfree, sym_secptr); str_secptr = (char *) xmalloc (str_secsize); make_cleanup (xfree, str_secptr); dyninfo_secptr = (char *) xmalloc (dyninfo_secsize); make_cleanup (xfree, dyninfo_secptr); got_secptr = (char *) xmalloc (got_secsize); make_cleanup (xfree, got_secptr); if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr, (file_ptr) 0, sym_secsize)) { do_cleanups (cleanups); return; } if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr, (file_ptr) 0, str_secsize)) { do_cleanups (cleanups); return; } if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr, (file_ptr) 0, dyninfo_secsize)) { do_cleanups (cleanups); return; } if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr, (file_ptr) 0, got_secsize)) { do_cleanups (cleanups); return; } /* Find the number of local GOT entries and the index for the first dynamic symbol in the GOT. */ for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize; dyninfo_p < dyninfo_end; dyninfo_p += sizeof (Elfalpha_External_Dyn)) { Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *) dyninfo_p; long dyn_tag; dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag); if (dyn_tag == DT_NULL) break; else if (dyn_tag == DT_MIPS_LOCAL_GOTNO) { if (dt_mips_local_gotno < 0) dt_mips_local_gotno = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val); } else if (dyn_tag == DT_MIPS_GOTSYM) { if (dt_mips_gotsym < 0) dt_mips_gotsym = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val); } } if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0) { do_cleanups (cleanups); return; } /* Scan all dynamic symbols and enter them into the minimal symbol table if appropriate. */ sym_count = sym_secsize / sizeof (Elfalpha_External_Sym); stripped = (bfd_get_symcount (abfd) == 0); /* Skip first symbol, which is a null dummy. */ for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1; i < sym_count; i++, x_symp++) { unsigned long strx; char *name; bfd_vma sym_value; unsigned char sym_info; unsigned int sym_shndx; int isglobal; enum minimal_symbol_type ms_type; strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name); if (strx >= str_secsize) continue; name = str_secptr + strx; if (*name == '\0' || *name == '.') continue; sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value); sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info); sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx); if (sym_shndx >= (SHN_LORESERVE & 0xffff)) sym_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff); isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL); if (sym_shndx == SHN_UNDEF) { /* Handle undefined functions which are defined in a shared library. */ if (ELF_ST_TYPE (sym_info) != STT_FUNC || ELF_ST_BIND (sym_info) != STB_GLOBAL) continue; ms_type = mst_solib_trampoline; /* If sym_value is nonzero, it points to the shared library trampoline entry, which is what we are looking for. If sym_value is zero, then we have to get the GOT entry for the symbol. If the GOT entry is nonzero, it represents the quickstart address of the function and we use that as the symbol value. If the GOT entry is zero, the function address has to be resolved by the runtime loader before the executable is started. We are unable to find any meaningful address for these functions in the executable file, so we skip them. */ if (sym_value == 0) { int got_entry_offset = (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size; if (got_entry_offset < 0 || got_entry_offset >= got_secsize) continue; sym_value = bfd_h_get_64 (abfd, (bfd_byte *) (got_secptr + got_entry_offset)); if (sym_value == 0) continue; } } else { /* Symbols defined in the executable itself. We only care about them if this is a stripped executable, otherwise they have been retrieved from the normal symbol table already. */ if (!stripped) continue; if (sym_shndx == SHN_MIPS_TEXT) { if (isglobal) ms_type = mst_text; else ms_type = mst_file_text; } else if (sym_shndx == SHN_MIPS_DATA) { if (isglobal) ms_type = mst_data; else ms_type = mst_file_data; } else if (sym_shndx == SHN_MIPS_ACOMMON) { if (isglobal) ms_type = mst_bss; else ms_type = mst_file_bss; } else if (sym_shndx == SHN_ABS) { ms_type = mst_abs; } else { continue; } } reader.record (name, sym_value, ms_type); } do_cleanups (cleanups); }
static enum string_repr_result print_string_repr (PyObject *printer, const char *hint, struct ui_file *stream, int recurse, const struct value_print_options *options, const struct language_defn *language, struct gdbarch *gdbarch) { struct value *replacement = NULL; PyObject *py_str = NULL; enum string_repr_result result = string_repr_ok; py_str = pretty_print_one_value (printer, &replacement); if (py_str) { struct cleanup *cleanup = make_cleanup_py_decref (py_str); if (py_str == Py_None) result = string_repr_none; else if (gdbpy_is_lazy_string (py_str)) { CORE_ADDR addr; long length; struct type *type; char *encoding = NULL; struct value_print_options local_opts = *options; make_cleanup (free_current_contents, &encoding); gdbpy_extract_lazy_string (py_str, &addr, &type, &length, &encoding); local_opts.addressprint = 0; val_print_string (type, encoding, addr, (int) length, stream, &local_opts); } else { PyObject *string; string = python_string_to_target_python_string (py_str); if (string) { char *output; long length; struct type *type; make_cleanup_py_decref (string); #ifdef IS_PY3K output = PyBytes_AS_STRING (string); length = PyBytes_GET_SIZE (string); #else output = PyString_AsString (string); length = PyString_Size (string); #endif type = builtin_type (gdbarch)->builtin_char; if (hint && !strcmp (hint, "string")) LA_PRINT_STRING (stream, type, (gdb_byte *) output, length, NULL, 0, options); else fputs_filtered (output, stream); } else { result = string_repr_error; print_stack_unless_memory_error (stream); } } do_cleanups (cleanup); } else if (replacement) { struct value_print_options opts = *options; opts.addressprint = 0; common_val_print (replacement, stream, recurse, &opts, language); } else { result = string_repr_error; print_stack_unless_memory_error (stream); } return result; }
static void tfile_open (const char *arg, int from_tty) { char *temp; struct cleanup *old_chain; int flags; int scratch_chan; char header[TRACE_HEADER_SIZE]; char linebuf[1000]; /* Should be max remote packet size or so. */ gdb_byte byte; int bytes, i; struct trace_status *ts; struct uploaded_tp *uploaded_tps = NULL; struct uploaded_tsv *uploaded_tsvs = NULL; char *filename; target_preopen (from_tty); if (!arg) error (_("No trace file specified.")); filename = tilde_expand (arg); if (!IS_ABSOLUTE_PATH(filename)) { temp = concat (current_directory, "/", filename, (char *) NULL); xfree (filename); filename = temp; } old_chain = make_cleanup (xfree, filename); flags = O_BINARY | O_LARGEFILE; flags |= O_RDONLY; scratch_chan = gdb_open_cloexec (filename, flags, 0); if (scratch_chan < 0) perror_with_name (filename); /* Looks semi-reasonable. Toss the old trace file and work on the new. */ discard_cleanups (old_chain); /* Don't free filename any more. */ unpush_target (&tfile_ops); trace_filename = xstrdup (filename); trace_fd = scratch_chan; /* Make sure this is clear. */ buffer_free (&trace_tdesc); bytes = 0; /* Read the file header and test for validity. */ tfile_read ((gdb_byte *) &header, TRACE_HEADER_SIZE); bytes += TRACE_HEADER_SIZE; if (!(header[0] == 0x7f && (startswith (header + 1, "TRACE0\n")))) error (_("File is not a valid trace file.")); push_target (&tfile_ops); trace_regblock_size = 0; ts = current_trace_status (); /* We know we're working with a file. Record its name. */ ts->filename = trace_filename; /* Set defaults in case there is no status line. */ ts->running_known = 0; ts->stop_reason = trace_stop_reason_unknown; ts->traceframe_count = -1; ts->buffer_free = 0; ts->disconnected_tracing = 0; ts->circular_buffer = 0; TRY { /* Read through a section of newline-terminated lines that define things like tracepoints. */ i = 0; while (1) { tfile_read (&byte, 1); ++bytes; if (byte == '\n') { /* Empty line marks end of the definition section. */ if (i == 0) break; linebuf[i] = '\0'; i = 0; tfile_interp_line (linebuf, &uploaded_tps, &uploaded_tsvs); } else linebuf[i++] = byte; if (i >= 1000) error (_("Excessively long lines in trace file")); } /* By now, tdesc lines have been read from tfile - let's parse them. */ target_find_description (); /* Record the starting offset of the binary trace data. */ trace_frames_offset = bytes; /* If we don't have a blocksize, we can't interpret the traceframes. */ if (trace_regblock_size == 0) error (_("No register block size recorded in trace file")); } CATCH (ex, RETURN_MASK_ALL) { /* Remove the partially set up target. */ unpush_target (&tfile_ops); throw_exception (ex); }