X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fexec.c;h=b849533e0c456d8f0483e8852842408ab1ebab32;hb=b9cd6d0b0dc85f23a41f4bb9ce42bbfb5b31cc2d;hp=2f9e46e509e5577139e9dec2509235791c1fb9fa;hpb=ed288bb597072176e84fc8279707a3f2f475779b;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/exec.c b/gdb/exec.c index 2f9e46e509..b849533e0c 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -1,6 +1,8 @@ /* Work with executable files, for GDB. - Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1997, 1998 - Free Software Foundation, Inc. + + Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, + 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. This file is part of GDB. @@ -27,12 +29,16 @@ #include "language.h" #include "symfile.h" #include "objfiles.h" +#include "completer.h" +#include "value.h" +#include "exec.h" #ifdef USG #include #endif #include +#include #include "gdb_string.h" #include "gdbcore.h" @@ -45,31 +51,25 @@ #include "xcoffsolib.h" -struct vmap *map_vmap PARAMS ((bfd *, bfd *)); +struct vmap *map_vmap (bfd *, bfd *); -void (*file_changed_hook) PARAMS ((char *)); +void (*file_changed_hook) (char *); /* Prototypes for local functions */ -static void add_to_section_table PARAMS ((bfd *, sec_ptr, PTR)); - -static void exec_close PARAMS ((int)); - -static void file_command PARAMS ((char *, int)); +static void exec_close (int); -static void set_section_command PARAMS ((char *, int)); +static void file_command (char *, int); -static void exec_files_info PARAMS ((struct target_ops *)); +static void set_section_command (char *, int); -static void bfdsec_to_vmap PARAMS ((bfd *, sec_ptr, PTR)); +static void exec_files_info (struct target_ops *); -static int ignore PARAMS ((CORE_ADDR, char *)); +static int ignore (CORE_ADDR, char *); -static void init_exec_ops PARAMS ((void)); +static void init_exec_ops (void); -void _initialize_exec PARAMS ((void)); - -extern int info_verbose; +void _initialize_exec (void); /* The target vector for executable files. */ @@ -83,20 +83,17 @@ bfd *exec_bfd = NULL; int write_files = 0; -/* Text start and end addresses (KLUDGE) if needed */ - -#ifndef NEED_TEXT_START_END -#define NEED_TEXT_START_END (0) -#endif -CORE_ADDR text_start = 0; -CORE_ADDR text_end = 0; - struct vmap *vmap; -/* ARGSUSED */ +void +exec_open (char *args, int from_tty) +{ + target_preopen (from_tty); + exec_file_attach (args, from_tty); +} + static void -exec_close (quitting) - int quitting; +exec_close (int quitting) { int need_symtab_cleanup = 0; struct vmap *vp, *nxt; @@ -126,7 +123,7 @@ exec_close (quitting) FIXME-as-well: free_objfile already free'd vp->name, so it isn't valid here. */ free_named_symtabs (vp->name); - free (vp); + xfree (vp); } vmap = NULL; @@ -138,18 +135,28 @@ exec_close (quitting) if (!bfd_close (exec_bfd)) warning ("cannot close \"%s\": %s", name, bfd_errmsg (bfd_get_error ())); - free (name); + xfree (name); exec_bfd = NULL; } if (exec_ops.to_sections) { - free ((PTR) exec_ops.to_sections); + xfree (exec_ops.to_sections); exec_ops.to_sections = NULL; exec_ops.to_sections_end = NULL; } } +void +exec_file_clear (int from_tty) +{ + /* Remove exec file. */ + unpush_target (&exec_ops); + + if (from_tty) + printf_unfiltered ("No executable file now.\n"); +} + /* Process the first arg in ARGS as the new exec file. This function is intended to be behave essentially the same @@ -165,48 +172,32 @@ exec_close (quitting) given a pid but not a exec pathname, and the attach command could figure out the pathname from the pid. (In this case, we shouldn't ask the user whether the current target should be shut down -- - we're supplying the exec pathname late for good reason.) */ + we're supplying the exec pathname late for good reason.) + + ARGS is assumed to be the filename. */ void -exec_file_attach (args, from_tty) - char *args; - int from_tty; +exec_file_attach (char *filename, int from_tty) { - char **argv; - char *filename; - /* Remove any previous exec file. */ unpush_target (&exec_ops); /* Now open and digest the file the user requested, if any. */ - if (args) + if (!filename) + { + if (from_tty) + printf_unfiltered ("No executable file now.\n"); + } + else { char *scratch_pathname; int scratch_chan; - /* Scan through the args and pick up the first non option arg - as the filename. */ - - argv = buildargv (args); - if (argv == NULL) - nomem (0); - - make_cleanup_freeargv (argv); - - for (; (*argv != NULL) && (**argv == '-'); argv++) - {; - } - if (*argv == NULL) - error ("no exec file name was specified"); - - filename = tilde_expand (*argv); - make_cleanup (free, filename); - scratch_chan = openp (getenv ("PATH"), 1, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, 0, &scratch_pathname); -#if defined(__GO32__) || defined(_WIN32) +#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__) if (scratch_chan < 0) { char *exename = alloca (strlen (filename) + 5); @@ -227,8 +218,8 @@ exec_file_attach (args, from_tty) 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 = strdup (scratch_pathname); - make_cleanup (free, scratch_pathname); + scratch_pathname = xstrdup (scratch_pathname); + make_cleanup (xfree, scratch_pathname); if (!bfd_check_format (exec_bfd, bfd_object)) { @@ -241,7 +232,7 @@ exec_file_attach (args, from_tty) /* FIXME - This should only be run for RS6000, but the ifdef is a poor way to accomplish. */ -#ifdef IBM6000_TARGET +#ifdef DEPRECATED_IBM6000_TARGET /* Setup initial vmap. */ map_vmap (exec_bfd, 0); @@ -253,7 +244,7 @@ exec_file_attach (args, from_tty) error ("\"%s\": can't find the file sections: %s", scratch_pathname, bfd_errmsg (bfd_get_error ())); } -#endif /* IBM6000_TARGET */ +#endif /* DEPRECATED_IBM6000_TARGET */ if (build_section_table (exec_bfd, &exec_ops.to_sections, &exec_ops.to_sections_end)) @@ -265,30 +256,9 @@ exec_file_attach (args, from_tty) scratch_pathname, bfd_errmsg (bfd_get_error ())); } - /* text_end is sometimes used for where to put call dummies. A - few ports use these for other purposes too. */ - if (NEED_TEXT_START_END) - { - struct section_table *p; - - /* Set text_start to the lowest address of the start of any - readonly code section and set text_end to the highest - address of the end of any readonly code section. */ - /* FIXME: The comment above does not match the code. The - code checks for sections with are either code *or* - readonly. */ - text_start = ~(CORE_ADDR) 0; - text_end = (CORE_ADDR) 0; - for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++) - if (bfd_get_section_flags (p->bfd, p->the_bfd_section) - & (SEC_CODE | SEC_READONLY)) - { - if (text_start > p->addr) - text_start = p->addr; - if (text_end < p->endaddr) - text_end = p->endaddr; - } - } +#ifdef DEPRECATED_HPUX_TEXT_END + DEPRECATED_HPUX_TEXT_END (&exec_ops); +#endif validate_files (); @@ -300,27 +270,47 @@ exec_file_attach (args, from_tty) if (exec_file_display_hook) (*exec_file_display_hook) (filename); } - else if (from_tty) - printf_unfiltered ("No executable file now.\n"); } /* Process the first arg in ARGS as the new exec file. Note that we have to explicitly ignore additional args, since we can be called from file_command(), which also calls symbol_file_command() - which can take multiple args. */ + which can take multiple args. + + If ARGS is NULL, we just want to close the exec file. */ -void -exec_file_command (args, from_tty) - char *args; - int from_tty; +static void +exec_file_command (char *args, int from_tty) { char **argv; char *filename; - + target_preopen (from_tty); - exec_file_attach (args, from_tty); + if (args) + { + /* Scan through the args and pick up the first non option arg + as the filename. */ + + argv = buildargv (args); + if (argv == NULL) + nomem (0); + + make_cleanup_freeargv (argv); + + for (; (*argv != NULL) && (**argv == '-'); argv++) + {; + } + if (*argv == NULL) + error ("No executable file name was specified"); + + filename = tilde_expand (*argv); + make_cleanup (xfree, filename); + exec_file_attach (filename, from_tty); + } + else + exec_file_attach (NULL, from_tty); } /* Set both the exec file and the symbol file, in one command. @@ -328,9 +318,7 @@ exec_file_command (args, from_tty) command was added? */ static void -file_command (arg, from_tty) - char *arg; - int from_tty; +file_command (char *arg, int from_tty) { /* FIXME, if we lose on reading the symbol file, we should revert the exec file, but that's rough. */ @@ -346,10 +334,8 @@ file_command (arg, from_tty) we cast it back to its proper type. */ static void -add_to_section_table (abfd, asect, table_pp_char) - bfd *abfd; - sec_ptr asect; - PTR table_pp_char; +add_to_section_table (bfd *abfd, struct bfd_section *asect, + void *table_pp_char) { struct section_table **table_pp = (struct section_table **) table_pp_char; flagword aflag; @@ -370,29 +356,25 @@ add_to_section_table (abfd, asect, table_pp_char) Returns 0 if OK, 1 on error. */ int -build_section_table (some_bfd, start, end) - bfd *some_bfd; - struct section_table **start, **end; +build_section_table (struct bfd *some_bfd, struct section_table **start, + struct section_table **end) { unsigned count; count = bfd_count_sections (some_bfd); if (*start) - free ((PTR) * start); + xfree (* start); *start = (struct section_table *) xmalloc (count * sizeof (**start)); *end = *start; bfd_map_over_sections (some_bfd, add_to_section_table, (char *) end); if (*end > *start + count) - abort (); + internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* We could realloc the table, but it probably loses for most files. */ return 0; } static void -bfdsec_to_vmap (abfd, sect, arg3) - bfd *abfd; - sec_ptr sect; - PTR arg3; +bfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3) { struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3; struct vmap *vp; @@ -402,14 +384,14 @@ bfdsec_to_vmap (abfd, sect, arg3) if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0) return; - if (STREQ (bfd_section_name (abfd, sect), ".text")) + if (DEPRECATED_STREQ (bfd_section_name (abfd, sect), ".text")) { vp->tstart = bfd_section_vma (abfd, sect); vp->tend = vp->tstart + bfd_section_size (abfd, sect); vp->tvma = bfd_section_vma (abfd, sect); vp->toffs = sect->filepos; } - else if (STREQ (bfd_section_name (abfd, sect), ".data")) + else if (DEPRECATED_STREQ (bfd_section_name (abfd, sect), ".data")) { vp->dstart = bfd_section_vma (abfd, sect); vp->dend = vp->dstart + bfd_section_size (abfd, sect); @@ -422,9 +404,7 @@ bfdsec_to_vmap (abfd, sect, arg3) Return the new vmap. */ struct vmap * -map_vmap (abfd, arch) - bfd *abfd; - bfd *arch; +map_vmap (bfd *abfd, bfd *arch) { struct vmap_and_bfd vmap_bfd; struct vmap *vp, **vpp; @@ -467,21 +447,17 @@ map_vmap (abfd, arch) we just tail-call it with more arguments to select between them. */ int -xfer_memory (memaddr, myaddr, len, write, target) - CORE_ADDR memaddr; - char *myaddr; - int len; - int write; - struct target_ops *target; +xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, + struct mem_attrib *attrib, + struct target_ops *target) { - boolean res; + int res; struct section_table *p; CORE_ADDR nextsectaddr, memend; - boolean (*xfer_fn) PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); - asection *section; + asection *section = NULL; if (len <= 0) - abort (); + internal_error (__FILE__, __LINE__, "failed internal consistency check"); if (overlay_debugging) { @@ -491,78 +467,48 @@ xfer_memory (memaddr, myaddr, len, write, target) } memend = memaddr + len; - xfer_fn = write ? bfd_set_section_contents : bfd_get_section_contents; nextsectaddr = memend; -#if 0 /* Stu's implementation */ -/* If a section has been specified, try to use it. Note that we cannot use the - specified section directly. This is because it usually comes from the - symbol file, which may be different from the exec or core file. Instead, we - have to lookup the specified section by name in the bfd associated with - to_sections. */ - - if (target_memory_bfd_section) - { - asection *s; - bfd *abfd; - asection *target_section; - bfd *target_bfd; - - s = target_memory_bfd_section; - abfd = s->owner; - - target_bfd = target->to_sections->bfd; - target_section = bfd_get_section_by_name (target_bfd, bfd_section_name (abfd, s)); - - if (target_section) - { - bfd_vma sec_addr; - bfd_size_type sec_size; - - sec_addr = bfd_section_vma (target_bfd, target_section); - sec_size = target_section->_raw_size; - - /* Make sure the requested memory starts inside the section. */ - - if (memaddr >= sec_addr - && memaddr < sec_addr + sec_size) - { - /* Cut back length in case request overflows the end of the section. */ - len = min (len, sec_addr + sec_size - memaddr); - - res = xfer_fn (target_bfd, target_section, myaddr, memaddr - sec_addr, len); - - return res ? len : 0; - } - } - } -#endif /* 0, Stu's implementation */ for (p = target->to_sections; p < target->to_sections_end; p++) { if (overlay_debugging && section && p->the_bfd_section && strcmp (section->name, p->the_bfd_section->name) != 0) continue; /* not the section we need */ if (memaddr >= p->addr) - if (memend <= p->endaddr) - { - /* Entire transfer is within this section. */ - res = xfer_fn (p->bfd, p->the_bfd_section, myaddr, - memaddr - p->addr, len); - return (res != 0) ? len : 0; - } - else if (memaddr >= p->endaddr) - { - /* This section ends before the transfer starts. */ - continue; - } - else - { - /* This section overlaps the transfer. Just do half. */ - len = p->endaddr - memaddr; - res = xfer_fn (p->bfd, p->the_bfd_section, myaddr, - memaddr - p->addr, len); - return (res != 0) ? len : 0; - } + { + if (memend <= p->endaddr) + { + /* Entire transfer is within this section. */ + if (write) + res = bfd_set_section_contents (p->bfd, p->the_bfd_section, + myaddr, memaddr - p->addr, + len); + else + res = bfd_get_section_contents (p->bfd, p->the_bfd_section, + myaddr, memaddr - p->addr, + len); + return (res != 0) ? len : 0; + } + else if (memaddr >= p->endaddr) + { + /* This section ends before the transfer starts. */ + continue; + } + else + { + /* This section overlaps the transfer. Just do half. */ + len = p->endaddr - memaddr; + if (write) + res = bfd_set_section_contents (p->bfd, p->the_bfd_section, + myaddr, memaddr - p->addr, + len); + else + res = bfd_get_section_contents (p->bfd, p->the_bfd_section, + myaddr, memaddr - p->addr, + len); + return (res != 0) ? len : 0; + } + } else nextsectaddr = min (nextsectaddr, p->addr); } @@ -575,11 +521,11 @@ xfer_memory (memaddr, myaddr, len, write, target) void -print_section_info (t, abfd) - struct target_ops *t; - bfd *abfd; +print_section_info (struct target_ops *t, bfd *abfd) { struct section_table *p; + /* FIXME: "016l" is not wide enough when TARGET_ADDR_BIT > 64. */ + char *fmt = TARGET_ADDR_BIT <= 32 ? "08l" : "016l"; printf_filtered ("\t`%s', ", bfd_get_filename (abfd)); wrap_here (" "); @@ -592,12 +538,17 @@ print_section_info (t, abfd) } for (p = t->to_sections; p < t->to_sections_end; p++) { - /* FIXME-32x64 need a print_address_numeric with field width */ - printf_filtered ("\t%s", local_hex_string_custom ((unsigned long) p->addr, "08l")); - printf_filtered (" - %s", local_hex_string_custom ((unsigned long) p->endaddr, "08l")); + printf_filtered ("\t%s", local_hex_string_custom (p->addr, fmt)); + printf_filtered (" - %s", local_hex_string_custom (p->endaddr, fmt)); + + /* FIXME: A format of "08l" is not wide enough for file offsets + larger than 4GB. OTOH, making it "016l" isn't desirable either + since most output will then be much wider than necessary. It + may make sense to test the size of the file and choose the + format string accordingly. */ if (info_verbose) printf_filtered (" @ %s", - local_hex_string_custom ((unsigned long) p->the_bfd_section->filepos, "08l")); + local_hex_string_custom (p->the_bfd_section->filepos, "08l")); printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section)); if (p->bfd != abfd) { @@ -608,8 +559,7 @@ print_section_info (t, abfd) } static void -exec_files_info (t) - struct target_ops *t; +exec_files_info (struct target_ops *t) { print_section_info (t, exec_bfd); @@ -618,13 +568,21 @@ exec_files_info (t) struct vmap *vp; printf_unfiltered ("\tMapping info for file `%s'.\n", vmap->name); - printf_unfiltered ("\t %8.8s %8.8s %8.8s %8.8s %8.8s %s\n", - "tstart", "tend", "dstart", "dend", "section", + printf_unfiltered ("\t %*s %*s %*s %*s %8.8s %s\n", + strlen_paddr (), "tstart", + strlen_paddr (), "tend", + strlen_paddr (), "dstart", + strlen_paddr (), "dend", + "section", "file(member)"); for (vp = vmap; vp; vp = vp->nxt) - printf_unfiltered ("\t0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x %s%s%s%s\n", - vp->tstart, vp->tend, vp->dstart, vp->dend, vp->name, + printf_unfiltered ("\t0x%s 0x%s 0x%s 0x%s %s%s%s%s\n", + paddr (vp->tstart), + paddr (vp->tend), + paddr (vp->dstart), + paddr (vp->dend), + vp->name, *vp->member ? "(" : "", vp->member, *vp->member ? ")" : ""); } @@ -635,10 +593,8 @@ exec_files_info (t) in the exec objfile. */ void -exec_set_section_offsets (text_off, data_off, bss_off) - bfd_signed_vma text_off; - bfd_signed_vma data_off; - bfd_signed_vma bss_off; +exec_set_section_offsets (bfd_signed_vma text_off, bfd_signed_vma data_off, + bfd_signed_vma bss_off) { struct section_table *sect; @@ -669,9 +625,7 @@ exec_set_section_offsets (text_off, data_off, bss_off) } static void -set_section_command (args, from_tty) - char *args; - int from_tty; +set_section_command (char *args, int from_tty) { struct section_table *p; char *secname; @@ -715,41 +669,51 @@ set_section_command (args, from_tty) breakpoint_init_inferior). */ static int -ignore (addr, contents) - CORE_ADDR addr; - char *contents; +ignore (CORE_ADDR addr, char *contents) { return 0; } +/* Find mapped memory. */ + +extern void +exec_set_find_memory_regions (int (*func) (int (*) (CORE_ADDR, + unsigned long, + int, int, int, + void *), + void *)) +{ + exec_ops.to_find_memory_regions = func; +} + +static char *exec_make_note_section (bfd *, int *); + /* Fill in the exec file target vector. Very few entries need to be defined. */ -void -init_exec_ops () +static void +init_exec_ops (void) { exec_ops.to_shortname = "exec"; exec_ops.to_longname = "Local exec file"; exec_ops.to_doc = "Use an executable file as a target.\n\ Specify the filename of the executable file."; - exec_ops.to_open = exec_file_command; + exec_ops.to_open = exec_open; exec_ops.to_close = exec_close; exec_ops.to_attach = find_default_attach; - exec_ops.to_require_attach = find_default_require_attach; - exec_ops.to_require_detach = find_default_require_detach; exec_ops.to_xfer_memory = xfer_memory; exec_ops.to_files_info = exec_files_info; exec_ops.to_insert_breakpoint = ignore; exec_ops.to_remove_breakpoint = ignore; exec_ops.to_create_inferior = find_default_create_inferior; - exec_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior; exec_ops.to_stratum = file_stratum; exec_ops.to_has_memory = 1; + exec_ops.to_make_corefile_notes = exec_make_note_section; exec_ops.to_magic = OPS_MAGIC; } void -_initialize_exec () +_initialize_exec (void) { struct cmd_list_element *c; @@ -764,7 +728,7 @@ and it is the program executed when you use the `run' command.\n\ If FILE cannot be found as specified, your execution directory path\n\ ($PATH) is searched for a command of that name.\n\ No arg means to have no executable file and no symbols.", &cmdlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); } c = add_cmd ("exec-file", class_files, exec_file_command, @@ -772,7 +736,7 @@ No arg means to have no executable file and no symbols.", &cmdlist); If FILE cannot be found as specified, your execution directory path\n\ is searched for a command of that name.\n\ No arg means have no executable file.", &cmdlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); add_com ("section", class_files, set_section_command, "Change the base address of section SECTION of the exec file to ADDR.\n\ @@ -789,3 +753,9 @@ file itself are wrong. Each section must be changed separately. The\n\ add_target (&exec_ops); } + +static char * +exec_make_note_section (bfd *obfd, int *note_size) +{ + error ("Can't create a corefile"); +}