mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-06 00:34:26 +08:00
268a13a5a3
This is the next patch in the ongoing series to move gdbsever to the top level. This patch just renames the "common" directory. The idea is to do this move in two parts: first rename the directory (this patch), then move the directory to the top. This approach makes the patches a bit more tractable. I chose the name "gdbsupport" for the directory. However, as this patch was largely written by sed, we could pick a new name without too much difficulty. Tested by the buildbot. gdb/ChangeLog 2019-07-09 Tom Tromey <tom@tromey.com> * contrib/ari/gdb_ari.sh: Change common to gdbsupport. * configure: Rebuild. * configure.ac: Change common to gdbsupport. * gdbsupport: Rename from common. * acinclude.m4: Change common to gdbsupport. * Makefile.in (CONFIG_SRC_SUBDIR, COMMON_SFILES) (HFILES_NO_SRCDIR, stamp-version, ALLDEPFILES): Change common to gdbsupport. * aarch64-tdep.c, ada-lang.c, ada-lang.h, agent.c, alloc.c, amd64-darwin-tdep.c, amd64-dicos-tdep.c, amd64-fbsd-nat.c, amd64-fbsd-tdep.c, amd64-linux-nat.c, amd64-linux-tdep.c, amd64-nbsd-tdep.c, amd64-obsd-tdep.c, amd64-sol2-tdep.c, amd64-tdep.c, amd64-windows-tdep.c, arch-utils.c, arch/aarch64-insn.c, arch/aarch64.c, arch/aarch64.h, arch/amd64.c, arch/amd64.h, arch/arm-get-next-pcs.c, arch/arm-linux.c, arch/arm.c, arch/i386.c, arch/i386.h, arch/ppc-linux-common.c, arch/riscv.c, arch/riscv.h, arch/tic6x.c, arm-tdep.c, auto-load.c, auxv.c, ax-gdb.c, ax-general.c, ax.h, breakpoint.c, breakpoint.h, btrace.c, btrace.h, build-id.c, build-id.h, c-lang.h, charset.c, charset.h, cli/cli-cmds.c, cli/cli-cmds.h, cli/cli-decode.c, cli/cli-dump.c, cli/cli-option.h, cli/cli-script.c, coff-pe-read.c, command.h, compile/compile-c-support.c, compile/compile-c.h, compile/compile-cplus-symbols.c, compile/compile-cplus-types.c, compile/compile-cplus.h, compile/compile-loc2c.c, compile/compile.c, completer.c, completer.h, contrib/ari/gdb_ari.sh, corefile.c, corelow.c, cp-support.c, cp-support.h, cp-valprint.c, csky-tdep.c, ctf.c, darwin-nat.c, debug.c, defs.h, disasm-selftests.c, disasm.c, disasm.h, dtrace-probe.c, dwarf-index-cache.c, dwarf-index-cache.h, dwarf-index-write.c, dwarf2-frame.c, dwarf2expr.c, dwarf2loc.c, dwarf2read.c, event-loop.c, event-top.c, exceptions.c, exec.c, extension.h, fbsd-nat.c, features/aarch64-core.c, features/aarch64-fpu.c, features/aarch64-pauth.c, features/aarch64-sve.c, features/i386/32bit-avx.c, features/i386/32bit-avx512.c, features/i386/32bit-core.c, features/i386/32bit-linux.c, features/i386/32bit-mpx.c, features/i386/32bit-pkeys.c, features/i386/32bit-segments.c, features/i386/32bit-sse.c, features/i386/64bit-avx.c, features/i386/64bit-avx512.c, features/i386/64bit-core.c, features/i386/64bit-linux.c, features/i386/64bit-mpx.c, features/i386/64bit-pkeys.c, features/i386/64bit-segments.c, features/i386/64bit-sse.c, features/i386/x32-core.c, features/riscv/32bit-cpu.c, features/riscv/32bit-csr.c, features/riscv/32bit-fpu.c, features/riscv/64bit-cpu.c, features/riscv/64bit-csr.c, features/riscv/64bit-fpu.c, features/tic6x-c6xp.c, features/tic6x-core.c, features/tic6x-gp.c, filename-seen-cache.h, findcmd.c, findvar.c, fork-child.c, gcore.c, gdb_bfd.c, gdb_bfd.h, gdb_proc_service.h, gdb_regex.c, gdb_select.h, gdb_usleep.c, gdbarch-selftests.c, gdbthread.h, gdbtypes.h, gnu-nat.c, go32-nat.c, guile/guile.c, guile/scm-ports.c, guile/scm-safe-call.c, guile/scm-type.c, i386-fbsd-nat.c, i386-fbsd-tdep.c, i386-go32-tdep.c, i386-linux-nat.c, i386-linux-tdep.c, i386-tdep.c, i387-tdep.c, ia64-libunwind-tdep.c, ia64-linux-nat.c, inf-child.c, inf-ptrace.c, infcall.c, infcall.h, infcmd.c, inferior-iter.h, inferior.c, inferior.h, inflow.c, inflow.h, infrun.c, infrun.h, inline-frame.c, language.h, linespec.c, linux-fork.c, linux-nat.c, linux-tdep.c, linux-thread-db.c, location.c, machoread.c, macrotab.h, main.c, maint.c, maint.h, memattr.c, memrange.h, mi/mi-cmd-break.h, mi/mi-cmd-env.c, mi/mi-cmd-stack.c, mi/mi-cmd-var.c, mi/mi-interp.c, mi/mi-main.c, mi/mi-parse.h, minsyms.c, mips-linux-tdep.c, namespace.h, nat/aarch64-linux-hw-point.c, nat/aarch64-linux-hw-point.h, nat/aarch64-linux.c, nat/aarch64-sve-linux-ptrace.c, nat/amd64-linux-siginfo.c, nat/fork-inferior.c, nat/linux-btrace.c, nat/linux-btrace.h, nat/linux-namespaces.c, nat/linux-nat.h, nat/linux-osdata.c, nat/linux-personality.c, nat/linux-procfs.c, nat/linux-ptrace.c, nat/linux-ptrace.h, nat/linux-waitpid.c, nat/mips-linux-watch.c, nat/mips-linux-watch.h, nat/ppc-linux.c, nat/x86-dregs.c, nat/x86-dregs.h, nat/x86-linux-dregs.c, nat/x86-linux.c, nto-procfs.c, nto-tdep.c, objfile-flags.h, objfiles.c, objfiles.h, obsd-nat.c, observable.h, osdata.c, p-valprint.c, parse.c, parser-defs.h, ppc-linux-nat.c, printcmd.c, probe.c, proc-api.c, procfs.c, producer.c, progspace.h, psymtab.h, python/py-framefilter.c, python/py-inferior.c, python/py-ref.h, python/py-type.c, python/python.c, record-btrace.c, record-full.c, record.c, record.h, regcache-dump.c, regcache.c, regcache.h, remote-fileio.c, remote-fileio.h, remote-sim.c, remote.c, riscv-tdep.c, rs6000-aix-tdep.c, rust-exp.y, s12z-tdep.c, selftest-arch.c, ser-base.c, ser-event.c, ser-pipe.c, ser-tcp.c, ser-unix.c, skip.c, solib-aix.c, solib-target.c, solib.c, source-cache.c, source.c, source.h, sparc-nat.c, spu-linux-nat.c, stack.c, stap-probe.c, symfile-add-flags.h, symfile.c, symfile.h, symtab.c, symtab.h, target-descriptions.c, target-descriptions.h, target-memory.c, target.c, target.h, target/waitstatus.c, target/waitstatus.h, thread-iter.h, thread.c, tilegx-tdep.c, top.c, top.h, tracefile-tfile.c, tracefile.c, tracepoint.c, tracepoint.h, tui/tui-io.c, ui-file.c, ui-out.h, unittests/array-view-selftests.c, unittests/child-path-selftests.c, unittests/cli-utils-selftests.c, unittests/common-utils-selftests.c, unittests/copy_bitwise-selftests.c, unittests/environ-selftests.c, unittests/format_pieces-selftests.c, unittests/function-view-selftests.c, unittests/lookup_name_info-selftests.c, unittests/memory-map-selftests.c, unittests/memrange-selftests.c, unittests/mkdir-recursive-selftests.c, unittests/observable-selftests.c, unittests/offset-type-selftests.c, unittests/optional-selftests.c, unittests/parse-connection-spec-selftests.c, unittests/ptid-selftests.c, unittests/rsp-low-selftests.c, unittests/scoped_fd-selftests.c, unittests/scoped_mmap-selftests.c, unittests/scoped_restore-selftests.c, unittests/string_view-selftests.c, unittests/style-selftests.c, unittests/tracepoint-selftests.c, unittests/unpack-selftests.c, unittests/utils-selftests.c, unittests/xml-utils-selftests.c, utils.c, utils.h, valarith.c, valops.c, valprint.c, value.c, value.h, varobj.c, varobj.h, windows-nat.c, x86-linux-nat.c, xml-support.c, xml-support.h, xml-tdesc.h, xstormy16-tdep.c, xtensa-linux-nat.c, dwarf2read.h: Change common to gdbsupport. gdb/gdbserver/ChangeLog 2019-07-09 Tom Tromey <tom@tromey.com> * configure: Rebuild. * configure.ac: Change common to gdbsupport. * acinclude.m4: Change common to gdbsupport. * Makefile.in (SFILES, OBS, GDBREPLAY_OBS, IPA_OBJS) (version-generated.c, gdbsupport/%-ipa.o, gdbsupport/%.o): Change common to gdbsupport. * ax.c, event-loop.c, fork-child.c, gdb_proc_service.h, gdbreplay.c, gdbthread.h, hostio-errno.c, hostio.c, i387-fp.c, inferiors.c, inferiors.h, linux-aarch64-tdesc-selftest.c, linux-amd64-ipa.c, linux-i386-ipa.c, linux-low.c, linux-tic6x-low.c, linux-x86-low.c, linux-x86-tdesc-selftest.c, linux-x86-tdesc.c, lynx-i386-low.c, lynx-low.c, mem-break.h, nto-x86-low.c, regcache.c, regcache.h, remote-utils.c, server.c, server.h, spu-low.c, symbol.c, target.h, tdesc.c, tdesc.h, thread-db.c, tracepoint.c, win32-i386-low.c, win32-low.c: Change common to gdbsupport.
465 lines
13 KiB
C
465 lines
13 KiB
C
/* Definitions for targets which report shared library events.
|
|
|
|
Copyright (C) 2007-2019 Free Software Foundation, Inc.
|
|
|
|
This file is part of GDB.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#include "defs.h"
|
|
#include "objfiles.h"
|
|
#include "solist.h"
|
|
#include "symtab.h"
|
|
#include "symfile.h"
|
|
#include "target.h"
|
|
#include "gdbsupport/vec.h"
|
|
#include "solib-target.h"
|
|
#include <vector>
|
|
|
|
/* Private data for each loaded library. */
|
|
struct lm_info_target : public lm_info_base
|
|
{
|
|
/* The library's name. The name is normally kept in the struct
|
|
so_list; it is only here during XML parsing. */
|
|
std::string name;
|
|
|
|
/* The target can either specify segment bases or section bases, not
|
|
both. */
|
|
|
|
/* The base addresses for each independently relocatable segment of
|
|
this shared library. */
|
|
std::vector<CORE_ADDR> segment_bases;
|
|
|
|
/* The base addresses for each independently allocatable,
|
|
relocatable section of this shared library. */
|
|
std::vector<CORE_ADDR> section_bases;
|
|
|
|
/* The cached offsets for each section of this shared library,
|
|
determined from SEGMENT_BASES, or SECTION_BASES. */
|
|
section_offsets *offsets = NULL;
|
|
};
|
|
|
|
typedef std::vector<std::unique_ptr<lm_info_target>> lm_info_vector;
|
|
|
|
#if !defined(HAVE_LIBEXPAT)
|
|
|
|
static lm_info_vector
|
|
solib_target_parse_libraries (const char *library)
|
|
{
|
|
static int have_warned;
|
|
|
|
if (!have_warned)
|
|
{
|
|
have_warned = 1;
|
|
warning (_("Can not parse XML library list; XML support was disabled "
|
|
"at compile time"));
|
|
}
|
|
|
|
return lm_info_vector ();
|
|
}
|
|
|
|
#else /* HAVE_LIBEXPAT */
|
|
|
|
#include "xml-support.h"
|
|
|
|
/* Handle the start of a <segment> element. */
|
|
|
|
static void
|
|
library_list_start_segment (struct gdb_xml_parser *parser,
|
|
const struct gdb_xml_element *element,
|
|
void *user_data,
|
|
std::vector<gdb_xml_value> &attributes)
|
|
{
|
|
lm_info_vector *list = (lm_info_vector *) user_data;
|
|
lm_info_target *last = list->back ().get ();
|
|
ULONGEST *address_p
|
|
= (ULONGEST *) xml_find_attribute (attributes, "address")->value.get ();
|
|
CORE_ADDR address = (CORE_ADDR) *address_p;
|
|
|
|
if (!last->section_bases.empty ())
|
|
gdb_xml_error (parser,
|
|
_("Library list with both segments and sections"));
|
|
|
|
last->segment_bases.push_back (address);
|
|
}
|
|
|
|
static void
|
|
library_list_start_section (struct gdb_xml_parser *parser,
|
|
const struct gdb_xml_element *element,
|
|
void *user_data,
|
|
std::vector<gdb_xml_value> &attributes)
|
|
{
|
|
lm_info_vector *list = (lm_info_vector *) user_data;
|
|
lm_info_target *last = list->back ().get ();
|
|
ULONGEST *address_p
|
|
= (ULONGEST *) xml_find_attribute (attributes, "address")->value.get ();
|
|
CORE_ADDR address = (CORE_ADDR) *address_p;
|
|
|
|
if (!last->segment_bases.empty ())
|
|
gdb_xml_error (parser,
|
|
_("Library list with both segments and sections"));
|
|
|
|
last->section_bases.push_back (address);
|
|
}
|
|
|
|
/* Handle the start of a <library> element. */
|
|
|
|
static void
|
|
library_list_start_library (struct gdb_xml_parser *parser,
|
|
const struct gdb_xml_element *element,
|
|
void *user_data,
|
|
std::vector<gdb_xml_value> &attributes)
|
|
{
|
|
lm_info_vector *list = (lm_info_vector *) user_data;
|
|
lm_info_target *item = new lm_info_target;
|
|
item->name
|
|
= (const char *) xml_find_attribute (attributes, "name")->value.get ();
|
|
|
|
list->emplace_back (item);
|
|
}
|
|
|
|
static void
|
|
library_list_end_library (struct gdb_xml_parser *parser,
|
|
const struct gdb_xml_element *element,
|
|
void *user_data, const char *body_text)
|
|
{
|
|
lm_info_vector *list = (lm_info_vector *) user_data;
|
|
lm_info_target *lm_info = list->back ().get ();
|
|
|
|
if (lm_info->segment_bases.empty () && lm_info->section_bases.empty ())
|
|
gdb_xml_error (parser, _("No segment or section bases defined"));
|
|
}
|
|
|
|
|
|
/* Handle the start of a <library-list> element. */
|
|
|
|
static void
|
|
library_list_start_list (struct gdb_xml_parser *parser,
|
|
const struct gdb_xml_element *element,
|
|
void *user_data,
|
|
std::vector<gdb_xml_value> &attributes)
|
|
{
|
|
struct gdb_xml_value *version = xml_find_attribute (attributes, "version");
|
|
|
|
/* #FIXED attribute may be omitted, Expat returns NULL in such case. */
|
|
if (version != NULL)
|
|
{
|
|
const char *string = (const char *) version->value.get ();
|
|
|
|
if (strcmp (string, "1.0") != 0)
|
|
gdb_xml_error (parser,
|
|
_("Library list has unsupported version \"%s\""),
|
|
string);
|
|
}
|
|
}
|
|
|
|
/* The allowed elements and attributes for an XML library list.
|
|
The root element is a <library-list>. */
|
|
|
|
static const struct gdb_xml_attribute segment_attributes[] = {
|
|
{ "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
|
|
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
|
|
};
|
|
|
|
static const struct gdb_xml_attribute section_attributes[] = {
|
|
{ "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
|
|
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
|
|
};
|
|
|
|
static const struct gdb_xml_element library_children[] = {
|
|
{ "segment", segment_attributes, NULL,
|
|
GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
|
|
library_list_start_segment, NULL },
|
|
{ "section", section_attributes, NULL,
|
|
GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
|
|
library_list_start_section, NULL },
|
|
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
|
|
};
|
|
|
|
static const struct gdb_xml_attribute library_attributes[] = {
|
|
{ "name", GDB_XML_AF_NONE, NULL, NULL },
|
|
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
|
|
};
|
|
|
|
static const struct gdb_xml_element library_list_children[] = {
|
|
{ "library", library_attributes, library_children,
|
|
GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
|
|
library_list_start_library, library_list_end_library },
|
|
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
|
|
};
|
|
|
|
static const struct gdb_xml_attribute library_list_attributes[] = {
|
|
{ "version", GDB_XML_AF_OPTIONAL, NULL, NULL },
|
|
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
|
|
};
|
|
|
|
static const struct gdb_xml_element library_list_elements[] = {
|
|
{ "library-list", library_list_attributes, library_list_children,
|
|
GDB_XML_EF_NONE, library_list_start_list, NULL },
|
|
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
|
|
};
|
|
|
|
static lm_info_vector
|
|
solib_target_parse_libraries (const char *library)
|
|
{
|
|
lm_info_vector result;
|
|
|
|
if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
|
|
library_list_elements, library, &result) == 0)
|
|
{
|
|
/* Parsed successfully. */
|
|
return result;
|
|
}
|
|
|
|
result.clear ();
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
static struct so_list *
|
|
solib_target_current_sos (void)
|
|
{
|
|
struct so_list *new_solib, *start = NULL, *last = NULL;
|
|
|
|
/* Fetch the list of shared libraries. */
|
|
gdb::optional<gdb::char_vector> library_document
|
|
= target_read_stralloc (current_top_target (), TARGET_OBJECT_LIBRARIES,
|
|
NULL);
|
|
if (!library_document)
|
|
return NULL;
|
|
|
|
/* Parse the list. */
|
|
lm_info_vector library_list
|
|
= solib_target_parse_libraries (library_document->data ());
|
|
|
|
if (library_list.empty ())
|
|
return NULL;
|
|
|
|
/* Build a struct so_list for each entry on the list. */
|
|
for (auto &&info : library_list)
|
|
{
|
|
new_solib = XCNEW (struct so_list);
|
|
strncpy (new_solib->so_name, info->name.c_str (),
|
|
SO_NAME_MAX_PATH_SIZE - 1);
|
|
new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
|
|
strncpy (new_solib->so_original_name, info->name.c_str (),
|
|
SO_NAME_MAX_PATH_SIZE - 1);
|
|
new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
|
|
|
|
/* We no longer need this copy of the name. */
|
|
info->name.clear ();
|
|
|
|
new_solib->lm_info = info.release ();
|
|
|
|
/* Add it to the list. */
|
|
if (!start)
|
|
last = start = new_solib;
|
|
else
|
|
{
|
|
last->next = new_solib;
|
|
last = new_solib;
|
|
}
|
|
}
|
|
|
|
return start;
|
|
}
|
|
|
|
static void
|
|
solib_target_solib_create_inferior_hook (int from_tty)
|
|
{
|
|
/* Nothing needed. */
|
|
}
|
|
|
|
static void
|
|
solib_target_clear_solib (void)
|
|
{
|
|
/* Nothing needed. */
|
|
}
|
|
|
|
static void
|
|
solib_target_free_so (struct so_list *so)
|
|
{
|
|
lm_info_target *li = (lm_info_target *) so->lm_info;
|
|
|
|
gdb_assert (li->name.empty ());
|
|
|
|
delete li;
|
|
}
|
|
|
|
static void
|
|
solib_target_relocate_section_addresses (struct so_list *so,
|
|
struct target_section *sec)
|
|
{
|
|
CORE_ADDR offset;
|
|
lm_info_target *li = (lm_info_target *) so->lm_info;
|
|
|
|
/* Build the offset table only once per object file. We can not do
|
|
it any earlier, since we need to open the file first. */
|
|
if (li->offsets == NULL)
|
|
{
|
|
int num_sections = gdb_bfd_count_sections (so->abfd);
|
|
|
|
li->offsets
|
|
= ((struct section_offsets *)
|
|
xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections)));
|
|
|
|
if (!li->section_bases.empty ())
|
|
{
|
|
int i;
|
|
asection *sect;
|
|
int num_alloc_sections = 0;
|
|
|
|
for (i = 0, sect = so->abfd->sections;
|
|
sect != NULL;
|
|
i++, sect = sect->next)
|
|
if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
|
|
num_alloc_sections++;
|
|
|
|
if (num_alloc_sections != li->section_bases.size ())
|
|
warning (_("\
|
|
Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
|
|
so->so_name);
|
|
else
|
|
{
|
|
int bases_index = 0;
|
|
int found_range = 0;
|
|
|
|
so->addr_low = ~(CORE_ADDR) 0;
|
|
so->addr_high = 0;
|
|
for (i = 0, sect = so->abfd->sections;
|
|
sect != NULL;
|
|
i++, sect = sect->next)
|
|
{
|
|
if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
|
|
continue;
|
|
if (bfd_section_size (so->abfd, sect) > 0)
|
|
{
|
|
CORE_ADDR low, high;
|
|
|
|
low = li->section_bases[i];
|
|
high = low + bfd_section_size (so->abfd, sect) - 1;
|
|
|
|
if (low < so->addr_low)
|
|
so->addr_low = low;
|
|
if (high > so->addr_high)
|
|
so->addr_high = high;
|
|
gdb_assert (so->addr_low <= so->addr_high);
|
|
found_range = 1;
|
|
}
|
|
li->offsets->offsets[i] = li->section_bases[bases_index];
|
|
bases_index++;
|
|
}
|
|
if (!found_range)
|
|
so->addr_low = so->addr_high = 0;
|
|
gdb_assert (so->addr_low <= so->addr_high);
|
|
}
|
|
}
|
|
else if (!li->segment_bases.empty ())
|
|
{
|
|
struct symfile_segment_data *data;
|
|
|
|
data = get_symfile_segment_data (so->abfd);
|
|
if (data == NULL)
|
|
warning (_("\
|
|
Could not relocate shared library \"%s\": no segments"), so->so_name);
|
|
else
|
|
{
|
|
ULONGEST orig_delta;
|
|
int i;
|
|
|
|
if (!symfile_map_offsets_to_segments (so->abfd, data, li->offsets,
|
|
li->segment_bases.size (),
|
|
li->segment_bases.data ()))
|
|
warning (_("\
|
|
Could not relocate shared library \"%s\": bad offsets"), so->so_name);
|
|
|
|
/* Find the range of addresses to report for this library in
|
|
"info sharedlibrary". Report any consecutive segments
|
|
which were relocated as a single unit. */
|
|
gdb_assert (li->segment_bases.size () > 0);
|
|
orig_delta = li->segment_bases[0] - data->segment_bases[0];
|
|
|
|
for (i = 1; i < data->num_segments; i++)
|
|
{
|
|
/* If we have run out of offsets, assume all
|
|
remaining segments have the same offset. */
|
|
if (i >= li->segment_bases.size ())
|
|
continue;
|
|
|
|
/* If this segment does not have the same offset, do
|
|
not include it in the library's range. */
|
|
if (li->segment_bases[i] - data->segment_bases[i]
|
|
!= orig_delta)
|
|
break;
|
|
}
|
|
|
|
so->addr_low = li->segment_bases[0];
|
|
so->addr_high = (data->segment_bases[i - 1]
|
|
+ data->segment_sizes[i - 1]
|
|
+ orig_delta);
|
|
gdb_assert (so->addr_low <= so->addr_high);
|
|
|
|
free_symfile_segment_data (data);
|
|
}
|
|
}
|
|
}
|
|
|
|
offset = li->offsets->offsets[gdb_bfd_section_index
|
|
(sec->the_bfd_section->owner,
|
|
sec->the_bfd_section)];
|
|
sec->addr += offset;
|
|
sec->endaddr += offset;
|
|
}
|
|
|
|
static int
|
|
solib_target_open_symbol_file_object (int from_tty)
|
|
{
|
|
/* We can't locate the main symbol file based on the target's
|
|
knowledge; the user has to specify it. */
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
|
|
{
|
|
/* We don't have a range of addresses for the dynamic linker; there
|
|
may not be one in the program's address space. So only report
|
|
PLT entries (which may be import stubs). */
|
|
return in_plt_section (pc);
|
|
}
|
|
|
|
struct target_so_ops solib_target_so_ops;
|
|
|
|
void
|
|
_initialize_solib_target (void)
|
|
{
|
|
solib_target_so_ops.relocate_section_addresses
|
|
= solib_target_relocate_section_addresses;
|
|
solib_target_so_ops.free_so = solib_target_free_so;
|
|
solib_target_so_ops.clear_solib = solib_target_clear_solib;
|
|
solib_target_so_ops.solib_create_inferior_hook
|
|
= solib_target_solib_create_inferior_hook;
|
|
solib_target_so_ops.current_sos = solib_target_current_sos;
|
|
solib_target_so_ops.open_symbol_file_object
|
|
= solib_target_open_symbol_file_object;
|
|
solib_target_so_ops.in_dynsym_resolve_code
|
|
= solib_target_in_dynsym_resolve_code;
|
|
solib_target_so_ops.bfd_open = solib_bfd_open;
|
|
|
|
/* Set current_target_so_ops to solib_target_so_ops if not already
|
|
set. */
|
|
if (current_target_so_ops == 0)
|
|
current_target_so_ops = &solib_target_so_ops;
|
|
}
|