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