xref: /openbsd-src/gnu/usr.bin/binutils/gdb/bfd-target.c (revision b725ae7711052a2233e31a66fefb8a752c388d7a)
1*b725ae77Skettenis /* Very simple "bfd" target, for GDB, the GNU debugger.
2*b725ae77Skettenis 
3*b725ae77Skettenis    Copyright 2003 Free Software Foundation, Inc.
4*b725ae77Skettenis 
5*b725ae77Skettenis    This file is part of GDB.
6*b725ae77Skettenis 
7*b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
8*b725ae77Skettenis    it under the terms of the GNU General Public License as published by
9*b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
10*b725ae77Skettenis    (at your option) any later version.
11*b725ae77Skettenis 
12*b725ae77Skettenis    This program is distributed in the hope that it will be useful,
13*b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*b725ae77Skettenis    GNU General Public License for more details.
16*b725ae77Skettenis 
17*b725ae77Skettenis    You should have received a copy of the GNU General Public License
18*b725ae77Skettenis    along with this program; if not, write to the Free Software
19*b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20*b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
21*b725ae77Skettenis 
22*b725ae77Skettenis #include "defs.h"
23*b725ae77Skettenis #include "target.h"
24*b725ae77Skettenis #include "bfd-target.h"
25*b725ae77Skettenis #include "gdb_assert.h"
26*b725ae77Skettenis #include "gdb_string.h"
27*b725ae77Skettenis 
28*b725ae77Skettenis /* Locate all mappable sections of a BFD file, filling in a target
29*b725ae77Skettenis    section for each.  */
30*b725ae77Skettenis 
31*b725ae77Skettenis struct section_closure
32*b725ae77Skettenis {
33*b725ae77Skettenis   struct section_table *end;
34*b725ae77Skettenis };
35*b725ae77Skettenis 
36*b725ae77Skettenis static void
add_to_section_table(struct bfd * abfd,struct bfd_section * asect,void * closure)37*b725ae77Skettenis add_to_section_table (struct bfd *abfd, struct bfd_section *asect,
38*b725ae77Skettenis 		      void *closure)
39*b725ae77Skettenis {
40*b725ae77Skettenis   struct section_closure *pp = closure;
41*b725ae77Skettenis   flagword aflag;
42*b725ae77Skettenis 
43*b725ae77Skettenis   /* NOTE: cagney/2003-10-22: Is this pruning useful?  */
44*b725ae77Skettenis   aflag = bfd_get_section_flags (abfd, asect);
45*b725ae77Skettenis   if (!(aflag & SEC_ALLOC))
46*b725ae77Skettenis     return;
47*b725ae77Skettenis   if (bfd_section_size (abfd, asect) == 0)
48*b725ae77Skettenis     return;
49*b725ae77Skettenis   pp->end->bfd = abfd;
50*b725ae77Skettenis   pp->end->the_bfd_section = asect;
51*b725ae77Skettenis   pp->end->addr = bfd_section_vma (abfd, asect);
52*b725ae77Skettenis   pp->end->endaddr = pp->end->addr + bfd_section_size (abfd, asect);
53*b725ae77Skettenis   pp->end++;
54*b725ae77Skettenis }
55*b725ae77Skettenis 
56*b725ae77Skettenis void
build_target_sections_from_bfd(struct target_ops * targ,struct bfd * abfd)57*b725ae77Skettenis build_target_sections_from_bfd (struct target_ops *targ, struct bfd *abfd)
58*b725ae77Skettenis {
59*b725ae77Skettenis   unsigned count;
60*b725ae77Skettenis   struct section_table *start;
61*b725ae77Skettenis   struct section_closure cl;
62*b725ae77Skettenis 
63*b725ae77Skettenis   count = bfd_count_sections (abfd);
64*b725ae77Skettenis   target_resize_to_sections (targ, count);
65*b725ae77Skettenis   start = targ->to_sections;
66*b725ae77Skettenis   cl.end = targ->to_sections;
67*b725ae77Skettenis   bfd_map_over_sections (abfd, add_to_section_table, &cl);
68*b725ae77Skettenis   gdb_assert (cl.end - start <= count);
69*b725ae77Skettenis }
70*b725ae77Skettenis 
71*b725ae77Skettenis LONGEST
target_bfd_xfer_partial(struct target_ops * ops,enum target_object object,const char * annex,void * readbuf,const void * writebuf,ULONGEST offset,LONGEST len)72*b725ae77Skettenis target_bfd_xfer_partial (struct target_ops *ops,
73*b725ae77Skettenis 			 enum target_object object,
74*b725ae77Skettenis 			 const char *annex, void *readbuf,
75*b725ae77Skettenis 			 const void *writebuf, ULONGEST offset, LONGEST len)
76*b725ae77Skettenis {
77*b725ae77Skettenis   switch (object)
78*b725ae77Skettenis     {
79*b725ae77Skettenis     case TARGET_OBJECT_MEMORY:
80*b725ae77Skettenis       {
81*b725ae77Skettenis 	struct section_table *s = target_section_by_addr (ops, offset);
82*b725ae77Skettenis 	if (s == NULL)
83*b725ae77Skettenis 	  return -1;
84*b725ae77Skettenis 	/* If the length extends beyond the section, truncate it.  Be
85*b725ae77Skettenis            careful to not suffer from overflow (wish S contained a
86*b725ae77Skettenis            length).  */
87*b725ae77Skettenis 	if ((offset - s->addr + len) > (s->endaddr - s->addr))
88*b725ae77Skettenis 	  len = (s->endaddr - s->addr) - (offset - s->addr);
89*b725ae77Skettenis 	if (readbuf != NULL
90*b725ae77Skettenis 	    && !bfd_get_section_contents (s->bfd, s->the_bfd_section,
91*b725ae77Skettenis 					  readbuf, offset - s->addr, len))
92*b725ae77Skettenis 	  return -1;
93*b725ae77Skettenis #if 1
94*b725ae77Skettenis 	if (writebuf != NULL)
95*b725ae77Skettenis 	  return -1;
96*b725ae77Skettenis #else
97*b725ae77Skettenis 	/* FIXME: cagney/2003-10-31: The BFD interface doesn't yet
98*b725ae77Skettenis            take a const buffer.  */
99*b725ae77Skettenis 	if (writebuf != NULL
100*b725ae77Skettenis 	    && !bfd_set_section_contents (s->bfd, s->the_bfd_section,
101*b725ae77Skettenis 					  writebuf, offset - s->addr, len))
102*b725ae77Skettenis 	  return -1;
103*b725ae77Skettenis #endif
104*b725ae77Skettenis 	return len;
105*b725ae77Skettenis       }
106*b725ae77Skettenis     default:
107*b725ae77Skettenis       return -1;
108*b725ae77Skettenis     }
109*b725ae77Skettenis }
110*b725ae77Skettenis 
111*b725ae77Skettenis void
target_bfd_xclose(struct target_ops * t,int quitting)112*b725ae77Skettenis target_bfd_xclose (struct target_ops *t, int quitting)
113*b725ae77Skettenis {
114*b725ae77Skettenis   bfd_close (t->to_data);
115*b725ae77Skettenis   xfree (t->to_sections);
116*b725ae77Skettenis   xfree (t);
117*b725ae77Skettenis }
118*b725ae77Skettenis 
119*b725ae77Skettenis struct target_ops *
target_bfd_reopen(struct bfd * bfd)120*b725ae77Skettenis target_bfd_reopen (struct bfd *bfd)
121*b725ae77Skettenis {
122*b725ae77Skettenis   struct target_ops *t = XZALLOC (struct target_ops);
123*b725ae77Skettenis   t->to_shortname = "bfd";
124*b725ae77Skettenis   t->to_longname = "BFD backed target";
125*b725ae77Skettenis   t->to_doc = "You should never see this";
126*b725ae77Skettenis   t->to_xfer_partial = target_bfd_xfer_partial;
127*b725ae77Skettenis   t->to_xclose = target_bfd_xclose;
128*b725ae77Skettenis   t->to_data = bfd;
129*b725ae77Skettenis   build_target_sections_from_bfd (t, bfd);
130*b725ae77Skettenis   return t;
131*b725ae77Skettenis }
132