1130803Smarcel/* Very simple "bfd" target, for GDB, the GNU debugger. 2130803Smarcel 3130803Smarcel Copyright 2003 Free Software Foundation, Inc. 4130803Smarcel 5130803Smarcel This file is part of GDB. 6130803Smarcel 7130803Smarcel This program is free software; you can redistribute it and/or modify 8130803Smarcel it under the terms of the GNU General Public License as published by 9130803Smarcel the Free Software Foundation; either version 2 of the License, or 10130803Smarcel (at your option) any later version. 11130803Smarcel 12130803Smarcel This program is distributed in the hope that it will be useful, 13130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 14130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130803Smarcel GNU General Public License for more details. 16130803Smarcel 17130803Smarcel You should have received a copy of the GNU General Public License 18130803Smarcel along with this program; if not, write to the Free Software 19130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130803Smarcel Boston, MA 02111-1307, USA. */ 21130803Smarcel 22130803Smarcel#include "defs.h" 23130803Smarcel#include "target.h" 24130803Smarcel#include "bfd-target.h" 25130803Smarcel#include "gdb_assert.h" 26130803Smarcel#include "gdb_string.h" 27130803Smarcel 28130803Smarcel/* Locate all mappable sections of a BFD file, filling in a target 29130803Smarcel section for each. */ 30130803Smarcel 31130803Smarcelstruct section_closure 32130803Smarcel{ 33130803Smarcel struct section_table *end; 34130803Smarcel}; 35130803Smarcel 36130803Smarcelstatic void 37130803Smarceladd_to_section_table (struct bfd *abfd, struct bfd_section *asect, 38130803Smarcel void *closure) 39130803Smarcel{ 40130803Smarcel struct section_closure *pp = closure; 41130803Smarcel flagword aflag; 42130803Smarcel 43130803Smarcel /* NOTE: cagney/2003-10-22: Is this pruning useful? */ 44130803Smarcel aflag = bfd_get_section_flags (abfd, asect); 45130803Smarcel if (!(aflag & SEC_ALLOC)) 46130803Smarcel return; 47130803Smarcel if (bfd_section_size (abfd, asect) == 0) 48130803Smarcel return; 49130803Smarcel pp->end->bfd = abfd; 50130803Smarcel pp->end->the_bfd_section = asect; 51130803Smarcel pp->end->addr = bfd_section_vma (abfd, asect); 52130803Smarcel pp->end->endaddr = pp->end->addr + bfd_section_size (abfd, asect); 53130803Smarcel pp->end++; 54130803Smarcel} 55130803Smarcel 56130803Smarcelvoid 57130803Smarcelbuild_target_sections_from_bfd (struct target_ops *targ, struct bfd *abfd) 58130803Smarcel{ 59130803Smarcel unsigned count; 60130803Smarcel struct section_table *start; 61130803Smarcel struct section_closure cl; 62130803Smarcel 63130803Smarcel count = bfd_count_sections (abfd); 64130803Smarcel target_resize_to_sections (targ, count); 65130803Smarcel start = targ->to_sections; 66130803Smarcel cl.end = targ->to_sections; 67130803Smarcel bfd_map_over_sections (abfd, add_to_section_table, &cl); 68130803Smarcel gdb_assert (cl.end - start <= count); 69130803Smarcel} 70130803Smarcel 71130803SmarcelLONGEST 72130803Smarceltarget_bfd_xfer_partial (struct target_ops *ops, 73130803Smarcel enum target_object object, 74130803Smarcel const char *annex, void *readbuf, 75130803Smarcel const void *writebuf, ULONGEST offset, LONGEST len) 76130803Smarcel{ 77130803Smarcel switch (object) 78130803Smarcel { 79130803Smarcel case TARGET_OBJECT_MEMORY: 80130803Smarcel { 81130803Smarcel struct section_table *s = target_section_by_addr (ops, offset); 82130803Smarcel if (s == NULL) 83130803Smarcel return -1; 84130803Smarcel /* If the length extends beyond the section, truncate it. Be 85130803Smarcel careful to not suffer from overflow (wish S contained a 86130803Smarcel length). */ 87130803Smarcel if ((offset - s->addr + len) > (s->endaddr - s->addr)) 88130803Smarcel len = (s->endaddr - s->addr) - (offset - s->addr); 89130803Smarcel if (readbuf != NULL 90130803Smarcel && !bfd_get_section_contents (s->bfd, s->the_bfd_section, 91130803Smarcel readbuf, offset - s->addr, len)) 92130803Smarcel return -1; 93130803Smarcel#if 1 94130803Smarcel if (writebuf != NULL) 95130803Smarcel return -1; 96130803Smarcel#else 97130803Smarcel /* FIXME: cagney/2003-10-31: The BFD interface doesn't yet 98130803Smarcel take a const buffer. */ 99130803Smarcel if (writebuf != NULL 100130803Smarcel && !bfd_set_section_contents (s->bfd, s->the_bfd_section, 101130803Smarcel writebuf, offset - s->addr, len)) 102130803Smarcel return -1; 103130803Smarcel#endif 104130803Smarcel return len; 105130803Smarcel } 106130803Smarcel default: 107130803Smarcel return -1; 108130803Smarcel } 109130803Smarcel} 110130803Smarcel 111130803Smarcelvoid 112130803Smarceltarget_bfd_xclose (struct target_ops *t, int quitting) 113130803Smarcel{ 114130803Smarcel bfd_close (t->to_data); 115130803Smarcel xfree (t->to_sections); 116130803Smarcel xfree (t); 117130803Smarcel} 118130803Smarcel 119130803Smarcelstruct target_ops * 120130803Smarceltarget_bfd_reopen (struct bfd *bfd) 121130803Smarcel{ 122130803Smarcel struct target_ops *t = XZALLOC (struct target_ops); 123130803Smarcel t->to_shortname = "bfd"; 124130803Smarcel t->to_longname = "BFD backed target"; 125130803Smarcel t->to_doc = "You should never see this"; 126130803Smarcel t->to_xfer_partial = target_bfd_xfer_partial; 127130803Smarcel t->to_xclose = target_bfd_xclose; 128130803Smarcel t->to_data = bfd; 129130803Smarcel build_target_sections_from_bfd (t, bfd); 130130803Smarcel return t; 131130803Smarcel} 132