forked from Imagelibrary/binutils-gdb
Use a std::vector in target_section_table
This changes target_section_table to wrap a std::vector. This simplifies some code, and also enables the simplifications coming in the subsequent patches. Note that for solib, I chose to have it use a pointer to a target_section_table. This is more convoluted than would be ideal, but I didn't want to convert solib to new/delete as a prerequisite for this series. gdb/ChangeLog 2020-10-12 Tom Tromey <tom@tromey.com> * target.c (target_section_by_addr, memory_xfer_partial_1): Update. * target-section.h (struct target_section_table): Use std::vector. * symfile.h (build_section_addr_info_from_section_table): Take a target_section_table. * symfile.c (build_section_addr_info_from_section_table): Take a target_section_table. * solist.h (struct so_list) <sections>: Change type. <sections_end>: Remove. * solib.c (solib_map_sections, clear_so, solib_read_symbols) (solib_contains_address_p): Update. * solib-svr4.c (scan_dyntag): Update. * solib-dsbt.c (scan_dyntag): Update. * remote.c (remote_target::remote_xfer_live_readonly_partial): Update. * record-full.c (record_full_core_start, record_full_core_end): Remove. (record_full_core_sections): New global. (record_full_core_open_1, record_full_core_target::xfer_partial): Update. * exec.h (build_section_table, section_table_xfer_memory_partial) (add_target_sections): Take a target_section_table. * exec.c (exec_file_attach, clear_section_table): Update. (resize_section_table): Remove. (build_section_table, add_target_sections): Take a target_section_table. (add_target_sections_of_objfile, remove_target_sections) (exec_on_vfork): Update. (section_table_available_memory): Take a target_section_table. (section_table_read_available_memory): Update. (section_table_xfer_memory_partial): Take a target_section_table. (print_section_info, set_section_command) (exec_set_section_address, exec_target::has_memory): Update. * corelow.c (class core_target) <m_core_section_table, m_core_file_mappings>: Remove braces. <~core_target>: Remove. (core_target::core_target): Update. (core_target::~core_target): Remove. (core_target::build_file_mappings) (core_target::xfer_memory_via_mappings) (core_target::xfer_partial, core_target::info_proc_mappings): Update. * bfd-target.c (target_bfd::xfer_partial): Update. (target_bfd::target_bfd): Update. (target_bfd::~target_bfd): Remove.
This commit is contained in:
245
gdb/exec.c
245
gdb/exec.c
@@ -413,7 +413,7 @@ exec_file_attach (const char *filename, int from_tty)
|
||||
int load_via_target = 0;
|
||||
const char *scratch_pathname, *canonical_pathname;
|
||||
int scratch_chan;
|
||||
struct target_section *sections = NULL, *sections_end = NULL;
|
||||
target_section_table sections;
|
||||
char **matching;
|
||||
|
||||
if (is_target_filename (filename))
|
||||
@@ -503,7 +503,7 @@ exec_file_attach (const char *filename, int from_tty)
|
||||
gdb_bfd_errmsg (bfd_get_error (), matching).c_str ());
|
||||
}
|
||||
|
||||
if (build_section_table (exec_bfd, §ions, §ions_end))
|
||||
if (build_section_table (exec_bfd, §ions))
|
||||
{
|
||||
/* Make sure to close exec_bfd, or else "run" might try to use
|
||||
it. */
|
||||
@@ -522,8 +522,7 @@ exec_file_attach (const char *filename, int from_tty)
|
||||
/* Add the executable's sections to the current address spaces'
|
||||
list of sections. This possibly pushes the exec_ops
|
||||
target. */
|
||||
add_target_sections (&exec_bfd, sections, sections_end);
|
||||
xfree (sections);
|
||||
add_target_sections (&exec_bfd, sections);
|
||||
|
||||
/* Tell display code (if any) about the changed file name. */
|
||||
if (deprecated_exec_file_display_hook)
|
||||
@@ -592,50 +591,16 @@ file_command (const char *arg, int from_tty)
|
||||
void
|
||||
clear_section_table (struct target_section_table *table)
|
||||
{
|
||||
xfree (table->sections);
|
||||
table->sections = table->sections_end = NULL;
|
||||
table->sections.clear ();
|
||||
}
|
||||
|
||||
/* Resize section table TABLE by ADJUSTMENT.
|
||||
ADJUSTMENT may be negative, in which case the caller must have already
|
||||
removed the sections being deleted.
|
||||
Returns the old size. */
|
||||
|
||||
static int
|
||||
resize_section_table (struct target_section_table *table, int adjustment)
|
||||
{
|
||||
int old_count;
|
||||
int new_count;
|
||||
|
||||
old_count = table->sections_end - table->sections;
|
||||
|
||||
new_count = adjustment + old_count;
|
||||
|
||||
if (new_count)
|
||||
{
|
||||
table->sections = XRESIZEVEC (struct target_section, table->sections,
|
||||
new_count);
|
||||
table->sections_end = table->sections + new_count;
|
||||
}
|
||||
else
|
||||
clear_section_table (table);
|
||||
|
||||
return old_count;
|
||||
}
|
||||
|
||||
/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
|
||||
/* Builds a section table, given args BFD, TABLE.
|
||||
Returns 0 if OK, 1 on error. */
|
||||
|
||||
int
|
||||
build_section_table (struct bfd *some_bfd, struct target_section **start,
|
||||
struct target_section **end)
|
||||
build_section_table (struct bfd *some_bfd, target_section_table *table)
|
||||
{
|
||||
unsigned count;
|
||||
|
||||
count = bfd_count_sections (some_bfd);
|
||||
xfree (*start);
|
||||
*start = XNEWVEC (struct target_section, count);
|
||||
*end = *start;
|
||||
table->sections.clear ();
|
||||
for (asection *asect : gdb_bfd_sections (some_bfd))
|
||||
{
|
||||
flagword aflag;
|
||||
@@ -650,15 +615,14 @@ build_section_table (struct bfd *some_bfd, struct target_section **start,
|
||||
if (!(aflag & SEC_ALLOC))
|
||||
continue;
|
||||
|
||||
(*end)->owner = NULL;
|
||||
(*end)->the_bfd_section = asect;
|
||||
(*end)->addr = bfd_section_vma (asect);
|
||||
(*end)->endaddr = (*end)->addr + bfd_section_size (asect);
|
||||
(*end)++;
|
||||
table->sections.emplace_back ();
|
||||
target_section § = table->sections.back ();
|
||||
sect.owner = NULL;
|
||||
sect.the_bfd_section = asect;
|
||||
sect.addr = bfd_section_vma (asect);
|
||||
sect.endaddr = sect.addr + bfd_section_size (asect);
|
||||
}
|
||||
|
||||
gdb_assert (*end <= *start + count);
|
||||
|
||||
/* We could realloc the table, but it probably loses for most files. */
|
||||
return 0;
|
||||
}
|
||||
@@ -668,23 +632,16 @@ build_section_table (struct bfd *some_bfd, struct target_section **start,
|
||||
|
||||
void
|
||||
add_target_sections (void *owner,
|
||||
struct target_section *sections,
|
||||
struct target_section *sections_end)
|
||||
const target_section_table §ions)
|
||||
{
|
||||
int count;
|
||||
struct target_section_table *table = current_target_sections;
|
||||
|
||||
count = sections_end - sections;
|
||||
|
||||
if (count > 0)
|
||||
if (!sections.sections.empty ())
|
||||
{
|
||||
int space = resize_section_table (table, count);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
for (const target_section &s : sections.sections)
|
||||
{
|
||||
table->sections[space + i] = sections[i];
|
||||
table->sections[space + i].owner = owner;
|
||||
table->sections.push_back (s);
|
||||
table->sections.back ().owner = owner;
|
||||
}
|
||||
|
||||
scoped_restore_current_pspace_and_thread restore_pspace_thread;
|
||||
@@ -714,9 +671,7 @@ add_target_sections_of_objfile (struct objfile *objfile)
|
||||
{
|
||||
struct target_section_table *table = current_target_sections;
|
||||
struct obj_section *osect;
|
||||
int space;
|
||||
unsigned count = 0;
|
||||
struct target_section *ts;
|
||||
|
||||
if (objfile == NULL)
|
||||
return;
|
||||
@@ -732,23 +687,17 @@ add_target_sections_of_objfile (struct objfile *objfile)
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
space = resize_section_table (table, count);
|
||||
|
||||
ts = table->sections + space;
|
||||
|
||||
ALL_OBJFILE_OSECTIONS (objfile, osect)
|
||||
{
|
||||
if (bfd_section_size (osect->the_bfd_section) == 0)
|
||||
continue;
|
||||
|
||||
gdb_assert (ts < table->sections + space + count);
|
||||
|
||||
ts->addr = obj_section_addr (osect);
|
||||
ts->endaddr = obj_section_endaddr (osect);
|
||||
ts->the_bfd_section = osect->the_bfd_section;
|
||||
ts->owner = (void *) objfile;
|
||||
|
||||
ts++;
|
||||
table->sections.emplace_back ();
|
||||
target_section &ts = table->sections.back ();
|
||||
ts.addr = obj_section_addr (osect);
|
||||
ts.endaddr = obj_section_endaddr (osect);
|
||||
ts.the_bfd_section = osect->the_bfd_section;
|
||||
ts.owner = (void *) objfile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,48 +707,36 @@ add_target_sections_of_objfile (struct objfile *objfile)
|
||||
void
|
||||
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->owner != owner)
|
||||
{
|
||||
/* Keep this section. */
|
||||
if (dest < src)
|
||||
*dest = *src;
|
||||
dest++;
|
||||
}
|
||||
auto it = std::remove_if (table->sections.begin (),
|
||||
table->sections.end (),
|
||||
[&] (target_section §)
|
||||
{
|
||||
return sect.owner == owner;
|
||||
});
|
||||
table->sections.erase (it, table->sections.end ());
|
||||
|
||||
/* If we've dropped any sections, resize the section table. */
|
||||
if (dest < src)
|
||||
/* If we don't have any more sections to read memory from,
|
||||
remove the file_stratum target from the stack of each
|
||||
inferior sharing the program space. */
|
||||
if (table->sections.empty ())
|
||||
{
|
||||
int old_count;
|
||||
scoped_restore_current_pspace_and_thread restore_pspace_thread;
|
||||
program_space *curr_pspace = current_program_space;
|
||||
|
||||
old_count = resize_section_table (table, dest - src);
|
||||
|
||||
/* If we don't have any more sections to read memory from,
|
||||
remove the file_stratum target from the stack of each
|
||||
inferior sharing the program space. */
|
||||
if (old_count + (dest - src) == 0)
|
||||
for (inferior *inf : all_inferiors ())
|
||||
{
|
||||
scoped_restore_current_pspace_and_thread restore_pspace_thread;
|
||||
program_space *curr_pspace = current_program_space;
|
||||
if (inf->pspace != curr_pspace)
|
||||
continue;
|
||||
|
||||
for (inferior *inf : all_inferiors ())
|
||||
{
|
||||
if (inf->pspace != curr_pspace)
|
||||
continue;
|
||||
if (!inf->pspace->target_sections.sections.empty ())
|
||||
continue;
|
||||
|
||||
if (inf->pspace->target_sections.sections
|
||||
!= inf->pspace->target_sections.sections_end)
|
||||
continue;
|
||||
|
||||
switch_to_inferior_no_thread (inf);
|
||||
unpush_target (&exec_ops);
|
||||
}
|
||||
switch_to_inferior_no_thread (inf);
|
||||
unpush_target (&exec_ops);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -809,8 +746,7 @@ remove_target_sections (void *owner)
|
||||
void
|
||||
exec_on_vfork ()
|
||||
{
|
||||
if (current_program_space->target_sections.sections
|
||||
!= current_program_space->target_sections.sections_end)
|
||||
if (!current_program_space->target_sections.sections.empty ())
|
||||
push_target (&exec_ops);
|
||||
}
|
||||
|
||||
@@ -869,26 +805,25 @@ exec_read_partial_read_only (gdb_byte *readbuf, ULONGEST offset,
|
||||
|
||||
static std::vector<mem_range>
|
||||
section_table_available_memory (CORE_ADDR memaddr, ULONGEST len,
|
||||
struct target_section *sections,
|
||||
struct target_section *sections_end)
|
||||
const target_section_table §ions)
|
||||
{
|
||||
std::vector<mem_range> memory;
|
||||
|
||||
for (target_section *p = sections; p < sections_end; p++)
|
||||
for (const target_section &p : sections.sections)
|
||||
{
|
||||
if ((bfd_section_flags (p->the_bfd_section) & SEC_READONLY) == 0)
|
||||
if ((bfd_section_flags (p.the_bfd_section) & SEC_READONLY) == 0)
|
||||
continue;
|
||||
|
||||
/* Copy the meta-data, adjusted. */
|
||||
if (mem_ranges_overlap (p->addr, p->endaddr - p->addr, memaddr, len))
|
||||
if (mem_ranges_overlap (p.addr, p.endaddr - p.addr, memaddr, len))
|
||||
{
|
||||
ULONGEST lo1, hi1, lo2, hi2;
|
||||
|
||||
lo1 = memaddr;
|
||||
hi1 = memaddr + len;
|
||||
|
||||
lo2 = p->addr;
|
||||
hi2 = p->endaddr;
|
||||
lo2 = p.addr;
|
||||
hi2 = p.endaddr;
|
||||
|
||||
CORE_ADDR start = std::max (lo1, lo2);
|
||||
int length = std::min (hi1, hi2) - start;
|
||||
@@ -906,8 +841,7 @@ section_table_read_available_memory (gdb_byte *readbuf, ULONGEST offset,
|
||||
{
|
||||
target_section_table *table = target_get_section_table (&exec_ops);
|
||||
std::vector<mem_range> available_memory
|
||||
= section_table_available_memory (offset, len,
|
||||
table->sections, table->sections_end);
|
||||
= section_table_available_memory (offset, len, *table);
|
||||
|
||||
normalize_mem_ranges (&available_memory);
|
||||
|
||||
@@ -944,37 +878,35 @@ enum target_xfer_status
|
||||
section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, ULONGEST len,
|
||||
ULONGEST *xfered_len,
|
||||
struct target_section *sections,
|
||||
struct target_section *sections_end,
|
||||
const target_section_table §ions,
|
||||
gdb::function_view<bool
|
||||
(const struct target_section *)> match_cb)
|
||||
{
|
||||
int res;
|
||||
struct target_section *p;
|
||||
ULONGEST memaddr = offset;
|
||||
ULONGEST memend = memaddr + len;
|
||||
|
||||
gdb_assert (len != 0);
|
||||
|
||||
for (p = sections; p < sections_end; p++)
|
||||
for (const target_section &p : sections.sections)
|
||||
{
|
||||
struct bfd_section *asect = p->the_bfd_section;
|
||||
struct bfd_section *asect = p.the_bfd_section;
|
||||
bfd *abfd = asect->owner;
|
||||
|
||||
if (match_cb != nullptr && !match_cb (p))
|
||||
if (match_cb != nullptr && !match_cb (&p))
|
||||
continue; /* not the section we need. */
|
||||
if (memaddr >= p->addr)
|
||||
if (memaddr >= p.addr)
|
||||
{
|
||||
if (memend <= p->endaddr)
|
||||
if (memend <= p.endaddr)
|
||||
{
|
||||
/* Entire transfer is within this section. */
|
||||
if (writebuf)
|
||||
res = bfd_set_section_contents (abfd, asect,
|
||||
writebuf, memaddr - p->addr,
|
||||
writebuf, memaddr - p.addr,
|
||||
len);
|
||||
else
|
||||
res = bfd_get_section_contents (abfd, asect,
|
||||
readbuf, memaddr - p->addr,
|
||||
readbuf, memaddr - p.addr,
|
||||
len);
|
||||
|
||||
if (res != 0)
|
||||
@@ -985,7 +917,7 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
else
|
||||
return TARGET_XFER_EOF;
|
||||
}
|
||||
else if (memaddr >= p->endaddr)
|
||||
else if (memaddr >= p.endaddr)
|
||||
{
|
||||
/* This section ends before the transfer starts. */
|
||||
continue;
|
||||
@@ -993,14 +925,14 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
else
|
||||
{
|
||||
/* This section overlaps the transfer. Just do half. */
|
||||
len = p->endaddr - memaddr;
|
||||
len = p.endaddr - memaddr;
|
||||
if (writebuf)
|
||||
res = bfd_set_section_contents (abfd, asect,
|
||||
writebuf, memaddr - p->addr,
|
||||
writebuf, memaddr - p.addr,
|
||||
len);
|
||||
else
|
||||
res = bfd_get_section_contents (abfd, asect,
|
||||
readbuf, memaddr - p->addr,
|
||||
readbuf, memaddr - p.addr,
|
||||
len);
|
||||
if (res != 0)
|
||||
{
|
||||
@@ -1033,8 +965,7 @@ exec_target::xfer_partial (enum target_object object,
|
||||
if (object == TARGET_OBJECT_MEMORY)
|
||||
return section_table_xfer_memory_partial (readbuf, writebuf,
|
||||
offset, len, xfered_len,
|
||||
table->sections,
|
||||
table->sections_end);
|
||||
*table);
|
||||
else
|
||||
return TARGET_XFER_E_IO;
|
||||
}
|
||||
@@ -1044,7 +975,6 @@ void
|
||||
print_section_info (struct target_section_table *t, bfd *abfd)
|
||||
{
|
||||
struct gdbarch *gdbarch = gdbarch_from_bfd (abfd);
|
||||
struct target_section *p;
|
||||
/* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64. */
|
||||
int wid = gdbarch_addr_bit (gdbarch) <= 32 ? 8 : 16;
|
||||
|
||||
@@ -1059,10 +989,11 @@ print_section_info (struct target_section_table *t, bfd *abfd)
|
||||
<p == t->sections_end>. */
|
||||
bfd_vma displacement = 0;
|
||||
bfd_vma entry_point;
|
||||
bool found = false;
|
||||
|
||||
for (p = t->sections; p < t->sections_end; p++)
|
||||
for (const target_section &p : t->sections)
|
||||
{
|
||||
struct bfd_section *psect = p->the_bfd_section;
|
||||
struct bfd_section *psect = p.the_bfd_section;
|
||||
|
||||
if ((bfd_section_flags (psect) & (SEC_ALLOC | SEC_LOAD))
|
||||
!= (SEC_ALLOC | SEC_LOAD))
|
||||
@@ -1072,11 +1003,12 @@ print_section_info (struct target_section_table *t, bfd *abfd)
|
||||
&& abfd->start_address < (bfd_section_vma (psect)
|
||||
+ bfd_section_size (psect)))
|
||||
{
|
||||
displacement = p->addr - bfd_section_vma (psect);
|
||||
displacement = p.addr - bfd_section_vma (psect);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p == t->sections_end)
|
||||
if (!found)
|
||||
warning (_("Cannot find section for the entry point of %ps."),
|
||||
styled_string (file_name_style.style (),
|
||||
bfd_get_filename (abfd)));
|
||||
@@ -1087,13 +1019,13 @@ print_section_info (struct target_section_table *t, bfd *abfd)
|
||||
printf_filtered (_("\tEntry point: %s\n"),
|
||||
paddress (gdbarch, entry_point));
|
||||
}
|
||||
for (p = t->sections; p < t->sections_end; p++)
|
||||
for (const target_section &p : t->sections)
|
||||
{
|
||||
struct bfd_section *psect = p->the_bfd_section;
|
||||
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));
|
||||
printf_filtered ("\t%s", hex_string_custom (p.addr, wid));
|
||||
printf_filtered (" - %s", hex_string_custom (p.endaddr, wid));
|
||||
|
||||
/* FIXME: A format of "08l" is not wide enough for file offsets
|
||||
larger than 4GB. OTOH, making it "016l" isn't desirable either
|
||||
@@ -1125,7 +1057,6 @@ exec_target::files_info ()
|
||||
static void
|
||||
set_section_command (const char *args, int from_tty)
|
||||
{
|
||||
struct target_section *p;
|
||||
const char *secname;
|
||||
unsigned seclen;
|
||||
unsigned long secaddr;
|
||||
@@ -1144,14 +1075,14 @@ set_section_command (const char *args, int from_tty)
|
||||
secaddr = parse_and_eval_address (args);
|
||||
|
||||
table = current_target_sections;
|
||||
for (p = table->sections; p < table->sections_end; p++)
|
||||
for (target_section &p : table->sections)
|
||||
{
|
||||
if (!strncmp (secname, bfd_section_name (p->the_bfd_section), seclen)
|
||||
&& bfd_section_name (p->the_bfd_section)[seclen] == '\0')
|
||||
if (!strncmp (secname, bfd_section_name (p.the_bfd_section), seclen)
|
||||
&& bfd_section_name (p.the_bfd_section)[seclen] == '\0')
|
||||
{
|
||||
offset = secaddr - p->addr;
|
||||
p->addr += offset;
|
||||
p->endaddr += offset;
|
||||
offset = secaddr - p.addr;
|
||||
p.addr += offset;
|
||||
p.endaddr += offset;
|
||||
if (from_tty)
|
||||
exec_ops.files_info ();
|
||||
return;
|
||||
@@ -1170,18 +1101,17 @@ set_section_command (const char *args, int from_tty)
|
||||
void
|
||||
exec_set_section_address (const char *filename, int index, CORE_ADDR address)
|
||||
{
|
||||
struct target_section *p;
|
||||
struct target_section_table *table;
|
||||
|
||||
table = current_target_sections;
|
||||
for (p = table->sections; p < table->sections_end; p++)
|
||||
for (target_section &p : table->sections)
|
||||
{
|
||||
if (filename_cmp (filename,
|
||||
bfd_get_filename (p->the_bfd_section->owner)) == 0
|
||||
&& index == p->the_bfd_section->index)
|
||||
bfd_get_filename (p.the_bfd_section->owner)) == 0
|
||||
&& index == p.the_bfd_section->index)
|
||||
{
|
||||
p->endaddr += address - p->addr;
|
||||
p->addr = address;
|
||||
p.endaddr += address - p.addr;
|
||||
p.addr = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1191,8 +1121,7 @@ exec_target::has_memory ()
|
||||
{
|
||||
/* We can provide memory if we have any file/target sections to read
|
||||
from. */
|
||||
return (current_target_sections->sections
|
||||
!= current_target_sections->sections_end);
|
||||
return !current_target_sections->sections.empty ();
|
||||
}
|
||||
|
||||
char *
|
||||
|
||||
Reference in New Issue
Block a user