X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fexec.c;h=3ec6c2f124eb110a9b1eab56d27d0c2a7f595c91;hb=ce6d08922f2875544f9ba461a849726ceff84528;hp=5b256ef01f1123bcbb5bcc663e4d660337242ab9;hpb=2b2848e211ef08d32b8427839b95b472d8fde337;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/exec.c b/gdb/exec.c index 5b256ef01f..3ec6c2f124 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -1,6 +1,6 @@ /* Work with executable files, for GDB. - Copyright (C) 1988-2013 Free Software Foundation, Inc. + Copyright (C) 1988-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -37,12 +37,12 @@ #include #include "readline/readline.h" -#include "gdb_string.h" +#include #include "gdbcore.h" #include -#include "gdb_stat.h" +#include void (*deprecated_file_changed_hook) (char *); @@ -101,7 +101,10 @@ exec_close (void) exec_bfd = NULL; exec_bfd_mtime = 0; - remove_target_sections (&exec_bfd, abfd); + remove_target_sections (&exec_bfd); + + xfree (exec_filename); + exec_filename = NULL; } } @@ -179,7 +182,7 @@ exec_file_attach (char *filename, int from_tty) else { struct cleanup *cleanups; - char *scratch_pathname; + char *scratch_pathname, *canonical_pathname; int scratch_chan; struct target_section *sections = NULL, *sections_end = NULL; char **matching; @@ -203,11 +206,16 @@ exec_file_attach (char *filename, int from_tty) cleanups = 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) - exec_bfd = gdb_bfd_fopen (scratch_pathname, gnutarget, + exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget, FOPEN_RUB, scratch_chan); else - exec_bfd = gdb_bfd_open (scratch_pathname, gnutarget, scratch_chan); + exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan); if (!exec_bfd) { @@ -215,6 +223,9 @@ exec_file_attach (char *filename, int from_tty) scratch_pathname, bfd_errmsg (bfd_get_error ())); } + gdb_assert (exec_filename == NULL); + 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 @@ -339,7 +350,7 @@ add_to_section_table (bfd *abfd, struct bfd_section *asect, if (!(aflag & SEC_ALLOC)) return; - (*table_pp)->key = NULL; + (*table_pp)->owner = NULL; (*table_pp)->the_bfd_section = asect; (*table_pp)->addr = bfd_section_vma (abfd, asect); (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect); @@ -397,7 +408,7 @@ build_section_table (struct bfd *some_bfd, struct target_section **start, current set of target sections. */ void -add_target_sections (void *key, +add_target_sections (void *owner, struct target_section *sections, struct target_section *sections_end) { @@ -414,7 +425,7 @@ add_target_sections (void *key, for (i = 0; i < count; ++i) { table->sections[space + i] = sections[i]; - table->sections[space + i].key = key; + table->sections[space + i].owner = owner; } /* If these are the first file sections we can provide memory @@ -427,17 +438,65 @@ add_target_sections (void *key, } } -/* Remove all target sections taken from ABFD. */ +/* Add the sections of OBJFILE to the current set of target sections. */ void -remove_target_sections (void *key, bfd *abfd) +add_target_sections_of_objfile (struct objfile *objfile) +{ + struct target_section_table *table = current_target_sections; + struct obj_section *osect; + int space; + unsigned count = 0; + struct target_section *ts; + + if (objfile == NULL) + return; + + /* Compute the number of sections to add. */ + ALL_OBJFILE_OSECTIONS (objfile, osect) + { + if (bfd_get_section_size (osect->the_bfd_section) == 0) + continue; + count++; + } + + if (count == 0) + return; + + space = resize_section_table (table, count); + + ts = table->sections + space; + + ALL_OBJFILE_OSECTIONS (objfile, osect) + { + if (bfd_get_section_size (osect->the_bfd_section) == 0) + continue; + + gdb_assert (ts < table->sections + space + count); + + ts->addr = obj_section_addr (osect); + ts->endaddr = obj_section_endaddr (osect); + ts->the_bfd_section = osect->the_bfd_section; + ts->owner = (void *) objfile; + + ts++; + } +} + +/* Remove all target sections owned by OWNER. + OWNER must be the same value passed to add_target_sections. */ + +void +remove_target_sections (void *owner) { struct target_section *src, *dest; struct target_section_table *table = current_target_sections; + gdb_assert (owner != NULL); + dest = table->sections; for (src = table->sections; src < table->sections_end; src++) - if (src->key != key || src->the_bfd_section->owner != abfd) + if (src->owner != owner) { /* Keep this section. */ if (dest < src) @@ -509,7 +568,7 @@ section_table_available_memory (VEC(mem_range_s) *memory, int section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf, - ULONGEST offset, LONGEST len, + ULONGEST offset, ULONGEST len, struct target_section *sections, struct target_section *sections_end, const char *section_name) @@ -519,7 +578,7 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST memaddr = offset; ULONGEST memend = memaddr + len; - if (len <= 0) + if (len == 0) internal_error (__FILE__, __LINE__, _("failed internal consistency check")); @@ -580,7 +639,7 @@ static LONGEST exec_xfer_partial (struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, - ULONGEST offset, LONGEST len) + ULONGEST offset, ULONGEST len) { struct target_section_table *table = target_get_section_table (ops); @@ -591,7 +650,7 @@ exec_xfer_partial (struct target_ops *ops, enum target_object object, table->sections_end, NULL); else - return -1; + return TARGET_XFER_E_IO; } @@ -742,7 +801,8 @@ exec_set_section_address (const char *filename, int index, CORE_ADDR address) breakpoint_init_inferior). */ static int -ignore (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) +ignore (struct target_ops *ops, struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) { return 0; }