gdb/testsuite: gdb.base/args.exp: add KFAIL for native-extended-gdbserver
[binutils-gdb.git] / gdb / bfd-target.c
index 82080d4a4c9ec1943ae5a2fbeb30e375d53c26ea..b23cf2cd5ccb63c303db1c43d60903bcdc88c1a4 100644 (file)
@@ -1,12 +1,12 @@
 /* Very simple "bfd" target, for GDB, the GNU debugger.
 
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "target.h"
 #include "bfd-target.h"
-#include "gdb_assert.h"
-#include "gdb_string.h"
+#include "exec.h"
+#include "gdb_bfd.h"
 
-/* Locate all mappable sections of a BFD file, filling in a target
-   section for each.  */
+/* A target that wraps a BFD.  */
 
-struct section_closure
-{
-  struct section_table *end;
+static const target_info target_bfd_target_info = {
+  "bfd",
+  N_("BFD backed target"),
+  N_("You should never see this")
 };
 
-static void
-add_to_section_table (struct bfd *abfd, struct bfd_section *asect,
-                     void *closure)
+class target_bfd : public target_ops
 {
-  struct section_closure *pp = closure;
-  flagword aflag;
-
-  /* NOTE: cagney/2003-10-22: Is this pruning useful?  */
-  aflag = bfd_get_section_flags (abfd, asect);
-  if (!(aflag & SEC_ALLOC))
-    return;
-  if (bfd_section_size (abfd, asect) == 0)
-    return;
-  pp->end->bfd = abfd;
-  pp->end->the_bfd_section = asect;
-  pp->end->addr = bfd_section_vma (abfd, asect);
-  pp->end->endaddr = pp->end->addr + bfd_section_size (abfd, asect);
-  pp->end++;
-}
+public:
+  explicit target_bfd (const gdb_bfd_ref_ptr &bfd);
 
-void
-build_target_sections_from_bfd (struct target_ops *targ, struct bfd *abfd)
-{
-  unsigned count;
-  struct section_table *start;
-  struct section_closure cl;
-
-  count = bfd_count_sections (abfd);
-  target_resize_to_sections (targ, count);
-  start = targ->to_sections;
-  cl.end = targ->to_sections;
-  bfd_map_over_sections (abfd, add_to_section_table, &cl);
-  gdb_assert (cl.end - start <= count);
-}
+  const target_info &info () const override
+  { return target_bfd_target_info; }
+
+  strata stratum () const override { return file_stratum; }
+
+  void close () override;
+
+  target_xfer_status
+    xfer_partial (target_object object,
+                 const char *annex, gdb_byte *readbuf,
+                 const gdb_byte *writebuf,
+                 ULONGEST offset, ULONGEST len,
+                 ULONGEST *xfered_len) override;
+
+  const target_section_table *get_section_table () override;
+
+private:
+  /* The BFD we're wrapping.  */
+  gdb_bfd_ref_ptr m_bfd;
 
-LONGEST
-target_bfd_xfer_partial (struct target_ops *ops,
-                        enum target_object object,
-                        const char *annex, gdb_byte *readbuf,
-                        const gdb_byte *writebuf,
-                        ULONGEST offset, LONGEST len)
+  /* The section table build from the ALLOC sections in BFD.  Note
+     that we can't rely on extracting the BFD from a random section in
+     the table, since the table can be legitimately empty.  */
+  target_section_table m_table;
+};
+
+target_xfer_status
+target_bfd::xfer_partial (target_object object,
+                         const char *annex, gdb_byte *readbuf,
+                         const gdb_byte *writebuf,
+                         ULONGEST offset, ULONGEST len,
+                         ULONGEST *xfered_len)
 {
   switch (object)
     {
     case TARGET_OBJECT_MEMORY:
       {
-       struct section_table *s = target_section_by_addr (ops, offset);
-       if (s == NULL)
-         return -1;
-       /* If the length extends beyond the section, truncate it.  Be
-           careful to not suffer from overflow (wish S contained a
-           length).  */
-       if ((offset - s->addr + len) > (s->endaddr - s->addr))
-         len = (s->endaddr - s->addr) - (offset - s->addr);
-       if (readbuf != NULL
-           && !bfd_get_section_contents (s->bfd, s->the_bfd_section,
-                                         readbuf, offset - s->addr, len))
-         return -1;
-#if 1
-       if (writebuf != NULL)
-         return -1;
-#else
-       /* FIXME: cagney/2003-10-31: The BFD interface doesn't yet
-           take a const buffer.  */
-       if (writebuf != NULL
-           && !bfd_set_section_contents (s->bfd, s->the_bfd_section,
-                                         writebuf, offset - s->addr, len))
-         return -1;
-#endif
-       return len;
+       return section_table_xfer_memory_partial (readbuf, writebuf,
+                                                 offset, len, xfered_len,
+                                                 m_table);
       }
     default:
-      return -1;
+      return TARGET_XFER_E_IO;
     }
 }
 
-void
-target_bfd_xclose (struct target_ops *t, int quitting)
+const target_section_table *
+target_bfd::get_section_table ()
+{
+  return &m_table;
+}
+
+target_bfd::target_bfd (const gdb_bfd_ref_ptr &abfd)
+  : m_bfd (abfd),
+    m_table (build_section_table (abfd.get ()))
 {
-  bfd_close (t->to_data);
-  xfree (t->to_sections);
-  xfree (t);
 }
 
-struct target_ops *
-target_bfd_reopen (struct bfd *bfd)
+target_ops *
+target_bfd_reopen (const gdb_bfd_ref_ptr &abfd)
+{
+  return new target_bfd (abfd);
+}
+
+void
+target_bfd::close ()
 {
-  struct target_ops *t = XZALLOC (struct target_ops);
-  t->to_shortname = "bfd";
-  t->to_longname = _("BFD backed target");
-  t->to_doc = _("You should never see this");
-  t->to_xfer_partial = target_bfd_xfer_partial;
-  t->to_xclose = target_bfd_xclose;
-  t->to_data = bfd;
-  build_target_sections_from_bfd (t, bfd);
-  return t;
+  delete this;
 }