2013-08-30 Phil Muldoon <pmuldoon@redhat.com>
[deliverable/binutils-gdb.git] / gdb / exec.c
index e8605b961c83a8b06615d964dfd3f9dd32d20195..c61d5307521d75e08c5e5d9243aefd1f78abfbd9 100644 (file)
@@ -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,12 +182,13 @@ 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;
 
-      scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename,
+      scratch_chan = openp (getenv ("PATH"),
+                           OPF_TRY_CWD_FIRST | OPF_DISABLE_REALPATH, filename,
                   write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
                            &scratch_pathname);
 #if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
@@ -193,7 +197,9 @@ exec_file_attach (char *filename, int from_tty)
          char *exename = alloca (strlen (filename) + 5);
 
          strcat (strcpy (exename, filename), ".exe");
-         scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename,
+         scratch_chan = openp (getenv ("PATH"),
+                               OPF_TRY_CWD_FIRST | OPF_DISABLE_REALPATH,
+                               exename,
             write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
             &scratch_pathname);
        }
@@ -203,11 +209,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 +226,9 @@ exec_file_attach (char *filename, int from_tty)
                 scratch_pathname, bfd_errmsg (bfd_get_error ()));
        }
 
+      gdb_assert (exec_filename == NULL);
+      exec_filename = xstrdup (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
@@ -328,6 +342,8 @@ add_to_section_table (bfd *abfd, struct bfd_section *asect,
   struct target_section **table_pp = (struct target_section **) table_pp_char;
   flagword aflag;
 
+  gdb_assert (abfd == asect->owner);
+
   /* Check the section flags, but do not discard zero-length sections, since
      some symbols may still be attached to this section.  For instance, we
      encountered on sparc-solaris 2.10 a shared library with an empty .bss
@@ -337,8 +353,7 @@ add_to_section_table (bfd *abfd, struct bfd_section *asect,
   if (!(aflag & SEC_ALLOC))
     return;
 
-  (*table_pp)->key = NULL;
-  (*table_pp)->bfd = abfd;
+  (*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);
@@ -396,7 +411,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)
 {
@@ -413,7 +428,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
@@ -426,17 +441,20 @@ add_target_sections (void *key,
     }
 }
 
-/* Remove all target sections taken from ABFD.  */
+/* Remove all target sections owned by OWNER.
+   OWNER must be the same value passed to add_target_sections.  */
 
 void
-remove_target_sections (void *key, bfd *abfd)
+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->bfd != abfd)
+    if (src->owner != owner)
       {
        /* Keep this section.  */
        if (dest < src)
@@ -479,7 +497,8 @@ section_table_available_memory (VEC(mem_range_s) *memory,
 
   for (p = sections; p < sections_end; p++)
     {
-      if ((bfd_get_section_flags (p->bfd, p->the_bfd_section)
+      if ((bfd_get_section_flags (p->the_bfd_section->owner,
+                                 p->the_bfd_section)
           & SEC_READONLY) == 0)
        continue;
 
@@ -523,7 +542,10 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
 
   for (p = sections; p < sections_end; p++)
     {
-      if (section_name && strcmp (section_name, p->the_bfd_section->name) != 0)
+      struct bfd_section *asect = p->the_bfd_section;
+      bfd *abfd = asect->owner;
+
+      if (section_name && strcmp (section_name, asect->name) != 0)
        continue;               /* not the section we need.  */
       if (memaddr >= p->addr)
         {
@@ -531,11 +553,11 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
            {
              /* Entire transfer is within this section.  */
              if (writebuf)
-               res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
+               res = bfd_set_section_contents (abfd, asect,
                                                writebuf, memaddr - p->addr,
                                                len);
              else
-               res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
+               res = bfd_get_section_contents (abfd, asect,
                                                readbuf, memaddr - p->addr,
                                                len);
              return (res != 0) ? len : 0;
@@ -550,11 +572,11 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
              /* This section overlaps the transfer.  Just do half.  */
              len = p->endaddr - memaddr;
              if (writebuf)
-               res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
+               res = bfd_set_section_contents (abfd, asect,
                                                writebuf, memaddr - p->addr,
                                                len);
              else
-               res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
+               res = bfd_get_section_contents (abfd, asect,
                                                readbuf, memaddr - p->addr,
                                                len);
              return (res != 0) ? len : 0;
@@ -610,17 +632,18 @@ print_section_info (struct target_section_table *t, bfd *abfd)
 
       for (p = t->sections; p < t->sections_end; p++)
        {
-         asection *asect = p->the_bfd_section;
+         struct bfd_section *psect = p->the_bfd_section;
+         bfd *pbfd = psect->owner;
 
-         if ((bfd_get_section_flags (abfd, asect) & (SEC_ALLOC | SEC_LOAD))
+         if ((bfd_get_section_flags (pbfd, psect) & (SEC_ALLOC | SEC_LOAD))
              != (SEC_ALLOC | SEC_LOAD))
            continue;
 
-         if (bfd_get_section_vma (abfd, asect) <= abfd->start_address
-             && abfd->start_address < (bfd_get_section_vma (abfd, asect)
-                                       + bfd_get_section_size (asect)))
+         if (bfd_get_section_vma (pbfd, psect) <= abfd->start_address
+             && abfd->start_address < (bfd_get_section_vma (pbfd, psect)
+                                       + bfd_get_section_size (psect)))
            {
-             displacement = p->addr - bfd_get_section_vma (abfd, asect);
+             displacement = p->addr - bfd_get_section_vma (pbfd, psect);
              break;
            }
        }
@@ -636,6 +659,9 @@ print_section_info (struct target_section_table *t, bfd *abfd)
     }
   for (p = t->sections; p < t->sections_end; p++)
     {
+      struct bfd_section *psect = p->the_bfd_section;
+      bfd *pbfd = psect->owner;
+
       printf_filtered ("\t%s", hex_string_custom (p->addr, wid));
       printf_filtered (" - %s", hex_string_custom (p->endaddr, wid));
 
@@ -647,11 +673,10 @@ print_section_info (struct target_section_table *t, bfd *abfd)
       /* FIXME: i18n: Need to rewrite this sentence.  */
       if (info_verbose)
        printf_filtered (" @ %s",
-                        hex_string_custom (p->the_bfd_section->filepos, 8));
-      printf_filtered (" is %s", bfd_section_name (p->bfd,
-                                                  p->the_bfd_section));
-      if (p->bfd != abfd)
-       printf_filtered (" in %s", bfd_get_filename (p->bfd));
+                        hex_string_custom (psect->filepos, 8));
+      printf_filtered (" is %s", bfd_section_name (pbfd, psect));
+      if (pbfd != abfd)
+       printf_filtered (" in %s", bfd_get_filename (pbfd));
       printf_filtered ("\n");
     }
 }
@@ -720,7 +745,7 @@ exec_set_section_address (const char *filename, int index, CORE_ADDR address)
   table = current_target_sections;
   for (p = table->sections; p < table->sections_end; p++)
     {
-      if (filename_cmp (filename, p->bfd->filename) == 0
+      if (filename_cmp (filename, p->the_bfd_section->owner->filename) == 0
          && index == p->the_bfd_section->index)
        {
          p->endaddr += address - p->addr;
This page took 0.029089 seconds and 4 git commands to generate.