const gdb_byte *writebuf,
ULONGEST offset, ULONGEST len,
ULONGEST *xfered_len) override;
- struct target_section_table *get_section_table () override;
+ target_section_table *get_section_table () override;
void files_info () override;
bool has_memory () override;
- char *make_corefile_notes (bfd *, int *) override;
+ gdb::unique_xmalloc_ptr<char> make_corefile_notes (bfd *, int *) override;
int find_memory_regions (find_memory_region_ftype func, void *data) override;
};
remove_target_sections (&exec_bfd);
- xfree (exec_filename);
- exec_filename = NULL;
+ current_program_space->exec_filename.reset (nullptr);
}
}
for (struct program_space *ss : program_spaces)
{
set_current_program_space (ss);
- clear_section_table (current_target_sections);
+ current_target_sections->clear ();
exec_close ();
}
}
exec_file_target = TARGET_SYSROOT_PREFIX + exec_file_target;
warning
- (_("Mismatch between current exec-file %ps\n"
+ (_("Build ID mismatch between current exec-file %ps\n"
"and automatically determined exec-file %ps\n"
"exec-file-mismatch handling is currently \"%s\""),
styled_string (file_name_style.style (), current_exec_file),
{
symfile_add_flags add_flags = SYMFILE_MAINLINE;
if (from_tty)
- add_flags |= SYMFILE_VERBOSE;
+ {
+ add_flags |= SYMFILE_VERBOSE;
+ add_flags |= SYMFILE_ALWAYS_CONFIRM;
+ }
try
{
symbol_file_add_main (exec_file_target.c_str (), add_flags);
int load_via_target = 0;
const char *scratch_pathname, *canonical_pathname;
int scratch_chan;
- struct target_section *sections = NULL, *sections_end = NULL;
char **matching;
if (is_target_filename (filename))
/* gdb_realpath_keepfile resolves symlinks on the local
filesystem and so cannot be used for "target:" files. */
- gdb_assert (exec_filename == NULL);
+ gdb_assert (current_program_space->exec_filename == nullptr);
if (load_via_target)
- exec_filename = xstrdup (bfd_get_filename (exec_bfd));
+ current_program_space->exec_filename
+ = make_unique_xstrdup (bfd_get_filename (exec_bfd));
else
- exec_filename = gdb_realpath_keepfile (scratch_pathname).release ();
+ current_program_space->exec_filename
+ = gdb_realpath_keepfile (scratch_pathname);
if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
{
gdb_bfd_errmsg (bfd_get_error (), matching).c_str ());
}
- if (build_section_table (exec_bfd, §ions, §ions_end))
- {
- /* Make sure to close exec_bfd, or else "run" might try to use
- it. */
- exec_close ();
- error (_("\"%ps\": can't find the file sections: %s"),
- styled_string (file_name_style.style (), scratch_pathname),
- bfd_errmsg (bfd_get_error ()));
- }
+ target_section_table sections = build_section_table (exec_bfd);
exec_bfd_mtime = bfd_get_mtime (exec_bfd);
/* 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)
static void
exec_file_command (const char *args, int from_tty)
{
- if (from_tty && target_has_execution
+ if (from_tty && target_has_execution ()
&& !query (_("A program is being debugged already.\n"
"Are you sure you want to change the file? ")))
error (_("File not changed."));
}
\f
-/* Locate all mappable sections of a BFD file.
- table_pp_char is a char * to get it through bfd_map_over_sections;
- we cast it back to its proper type. */
+/* Builds a section table, given args BFD, TABLE. */
-static void
-add_to_section_table (bfd *abfd, struct bfd_section *asect,
- void *table_pp_char)
+target_section_table
+build_section_table (struct bfd *some_bfd)
{
- struct target_section **table_pp = (struct target_section **) table_pp_char;
- flagword aflag;
-
- gdb_assert (abfd == asect->owner);
-
- /* Check the section flags, but do not discard zero-length sections, since
- some symbols may still be attached to this section. For instance, we
- encountered on sparc-solaris 2.10 a shared library with an empty .bss
- section to which a symbol named "_end" was attached. The address
- of this symbol still needs to be relocated. */
- aflag = bfd_section_flags (asect);
- if (!(aflag & SEC_ALLOC))
- return;
-
- (*table_pp)->owner = NULL;
- (*table_pp)->the_bfd_section = asect;
- (*table_pp)->addr = bfd_section_vma (asect);
- (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (asect);
- (*table_pp)++;
-}
-
-/* See exec.h. */
+ target_section_table table;
-void
-clear_section_table (struct target_section_table *table)
-{
- xfree (table->sections);
- table->sections = table->sections_end = NULL;
-}
-
-/* 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)
+ for (asection *asect : gdb_bfd_sections (some_bfd))
{
- 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.
- Returns 0 if OK, 1 on error. */
-
-int
-build_section_table (struct bfd *some_bfd, struct target_section **start,
- struct target_section **end)
-{
- unsigned count;
-
- count = bfd_count_sections (some_bfd);
- xfree (*start);
- *start = XNEWVEC (struct target_section, count);
- *end = *start;
- bfd_map_over_sections (some_bfd, add_to_section_table, (char *) end);
+ flagword aflag;
+
+ /* Check the section flags, but do not discard zero-length
+ sections, since some symbols may still be attached to this
+ section. For instance, we encountered on sparc-solaris 2.10
+ a shared library with an empty .bss section to which a symbol
+ named "_end" was attached. The address of this symbol still
+ needs to be relocated. */
+ aflag = bfd_section_flags (asect);
+ if (!(aflag & SEC_ALLOC))
+ continue;
- gdb_assert (*end <= *start + count);
+ table.emplace_back (bfd_section_vma (asect),
+ bfd_section_vma (asect) + bfd_section_size (asect),
+ asect);
+ }
- /* We could realloc the table, but it probably loses for most files. */
- return 0;
+ return table;
}
/* Add the sections array defined by [SECTIONS..SECTIONS_END[ to the
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;
+ target_section_table *table = current_target_sections;
- count = sections_end - sections;
-
- if (count > 0)
+ if (!sections.empty ())
{
- int space = resize_section_table (table, count);
- int i;
-
- for (i = 0; i < count; ++i)
+ for (const target_section &s : sections)
{
- table->sections[space + i] = sections[i];
- table->sections[space + i].owner = owner;
+ table->push_back (s);
+ table->back ().owner = owner;
}
scoped_restore_current_pspace_and_thread restore_pspace_thread;
void
add_target_sections_of_objfile (struct objfile *objfile)
{
- struct target_section_table *table = current_target_sections;
+ target_section_table *table = current_target_sections;
struct obj_section *osect;
- int space;
- unsigned count = 0;
- struct target_section *ts;
- if (objfile == NULL)
- return;
+ gdb_assert (objfile != nullptr);
/* Compute the number of sections to add. */
ALL_OBJFILE_OSECTIONS (objfile, osect)
{
if (bfd_section_size (osect->the_bfd_section) == 0)
continue;
- count++;
- }
- 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->emplace_back (obj_section_addr (osect),
+ obj_section_endaddr (osect),
+ osect->the_bfd_section, (void *) objfile);
}
}
void
remove_target_sections (void *owner)
{
- struct target_section *src, *dest;
- struct target_section_table *table = current_target_sections;
+ 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++;
- }
-
- /* If we've dropped any sections, resize the section table. */
- if (dest < src)
+ auto it = std::remove_if (table->begin (),
+ table->end (),
+ [&] (target_section §)
+ {
+ return sect.owner == owner;
+ });
+ table->erase (it, table->end ());
+
+ /* 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->empty ())
{
- int old_count;
-
- old_count = resize_section_table (table, dest - src);
+ scoped_restore_current_pspace_and_thread restore_pspace_thread;
+ program_space *curr_pspace = current_program_space;
- /* 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;
-
- for (inferior *inf : all_inferiors ())
- {
- if (inf->pspace != curr_pspace)
- continue;
+ if (inf->pspace != curr_pspace)
+ continue;
- if (inf->pspace->target_sections.sections
- != inf->pspace->target_sections.sections_end)
- continue;
+ if (!inf->pspace->target_sections.empty ())
+ continue;
- switch_to_inferior_no_thread (inf);
- unpush_target (&exec_ops);
- }
+ switch_to_inferior_no_thread (inf);
+ unpush_target (&exec_ops);
}
}
}
void
exec_on_vfork ()
{
- if (current_program_space->target_sections.sections
- != current_program_space->target_sections.sections_end)
+ if (!current_program_space->target_sections.empty ())
push_target (&exec_ops);
}
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)
{
- 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;
{
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);
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 char *section_name)
+ 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)
{
- struct bfd_section *asect = p->the_bfd_section;
+ struct bfd_section *asect = p.the_bfd_section;
bfd *abfd = asect->owner;
- if (section_name && strcmp (section_name, asect->name) != 0)
+ 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)
else
return TARGET_XFER_EOF;
}
- else if (memaddr >= p->endaddr)
+ else if (memaddr >= p.endaddr)
{
/* This section ends before the transfer starts. */
continue;
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)
{
return TARGET_XFER_EOF; /* We can't help. */
}
-struct target_section_table *
+target_section_table *
exec_target::get_section_table ()
{
return current_target_sections;
const gdb_byte *writebuf,
ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
{
- struct target_section_table *table = get_section_table ();
+ target_section_table *table = get_section_table ();
if (object == TARGET_OBJECT_MEMORY)
return section_table_xfer_memory_partial (readbuf, writebuf,
offset, len, xfered_len,
- table->sections,
- table->sections_end,
- NULL);
+ *table);
else
return TARGET_XFER_E_IO;
}
\f
void
-print_section_info (struct target_section_table *t, bfd *abfd)
+print_section_info (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;
<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)
{
- 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))
&& 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)));
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)
{
- 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
static void
set_section_command (const char *args, int from_tty)
{
- struct target_section *p;
const char *secname;
unsigned seclen;
unsigned long secaddr;
char secprint[100];
long offset;
- struct target_section_table *table;
if (args == 0)
error (_("Must specify section name and its virtual address"));
/* Parse out new virtual address. */
secaddr = parse_and_eval_address (args);
- table = current_target_sections;
- for (p = table->sections; p < table->sections_end; p++)
+ for (target_section &p : *current_target_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;
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 : *current_target_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;
}
}
}
{
/* 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->empty ();
}
-char *
+gdb::unique_xmalloc_ptr<char>
exec_target::make_corefile_notes (bfd *obfd, int *note_size)
{
error (_("Can't create a corefile"));
to a process:\n\n\
ask - warn the user and ask whether to load the determined exec-file.\n\
warn - warn the user, but do not change the exec-file.\n\
- off - do not check for mismatch."),
+ off - do not check for mismatch.\n\
+\n\
+GDB detects a mismatch by comparing the build IDs of the files.\n\
+If the user confirms loading the determined exec-file, then its symbols\n\
+will be loaded as well."),
set_exec_file_mismatch_command,
show_exec_file_mismatch_command,
&setlist, &showlist);