1cf7f2e2dSJohn Marino /* Definitions for targets which report shared library events.
2cf7f2e2dSJohn Marino
3*ef5ccd6cSJohn Marino Copyright (C) 2007-2013 Free Software Foundation, Inc.
4cf7f2e2dSJohn Marino
5cf7f2e2dSJohn Marino This file is part of GDB.
6cf7f2e2dSJohn Marino
7cf7f2e2dSJohn Marino This program is free software; you can redistribute it and/or modify
8cf7f2e2dSJohn Marino it under the terms of the GNU General Public License as published by
9cf7f2e2dSJohn Marino the Free Software Foundation; either version 3 of the License, or
10cf7f2e2dSJohn Marino (at your option) any later version.
11cf7f2e2dSJohn Marino
12cf7f2e2dSJohn Marino This program is distributed in the hope that it will be useful,
13cf7f2e2dSJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14cf7f2e2dSJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15cf7f2e2dSJohn Marino GNU General Public License for more details.
16cf7f2e2dSJohn Marino
17cf7f2e2dSJohn Marino You should have received a copy of the GNU General Public License
18cf7f2e2dSJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */
19cf7f2e2dSJohn Marino
20cf7f2e2dSJohn Marino #include "defs.h"
21cf7f2e2dSJohn Marino #include "objfiles.h"
22cf7f2e2dSJohn Marino #include "solist.h"
23cf7f2e2dSJohn Marino #include "symtab.h"
24cf7f2e2dSJohn Marino #include "symfile.h"
25cf7f2e2dSJohn Marino #include "target.h"
26cf7f2e2dSJohn Marino #include "vec.h"
27cf7f2e2dSJohn Marino #include "solib-target.h"
28cf7f2e2dSJohn Marino
29cf7f2e2dSJohn Marino #include "gdb_string.h"
30cf7f2e2dSJohn Marino
31cf7f2e2dSJohn Marino /* Private data for each loaded library. */
32cf7f2e2dSJohn Marino struct lm_info
33cf7f2e2dSJohn Marino {
34cf7f2e2dSJohn Marino /* The library's name. The name is normally kept in the struct
35cf7f2e2dSJohn Marino so_list; it is only here during XML parsing. */
36cf7f2e2dSJohn Marino char *name;
37cf7f2e2dSJohn Marino
38cf7f2e2dSJohn Marino /* The target can either specify segment bases or section bases, not
39cf7f2e2dSJohn Marino both. */
40cf7f2e2dSJohn Marino
41cf7f2e2dSJohn Marino /* The base addresses for each independently relocatable segment of
42cf7f2e2dSJohn Marino this shared library. */
43cf7f2e2dSJohn Marino VEC(CORE_ADDR) *segment_bases;
44cf7f2e2dSJohn Marino
45cf7f2e2dSJohn Marino /* The base addresses for each independently allocatable,
46cf7f2e2dSJohn Marino relocatable section of this shared library. */
47cf7f2e2dSJohn Marino VEC(CORE_ADDR) *section_bases;
48cf7f2e2dSJohn Marino
49cf7f2e2dSJohn Marino /* The cached offsets for each section of this shared library,
50cf7f2e2dSJohn Marino determined from SEGMENT_BASES, or SECTION_BASES. */
51cf7f2e2dSJohn Marino struct section_offsets *offsets;
52cf7f2e2dSJohn Marino };
53cf7f2e2dSJohn Marino
54cf7f2e2dSJohn Marino typedef struct lm_info *lm_info_p;
55cf7f2e2dSJohn Marino DEF_VEC_P(lm_info_p);
56cf7f2e2dSJohn Marino
57cf7f2e2dSJohn Marino #if !defined(HAVE_LIBEXPAT)
58cf7f2e2dSJohn Marino
VEC(lm_info_p)59cf7f2e2dSJohn Marino static VEC(lm_info_p) *
60cf7f2e2dSJohn Marino solib_target_parse_libraries (const char *library)
61cf7f2e2dSJohn Marino {
62cf7f2e2dSJohn Marino static int have_warned;
63cf7f2e2dSJohn Marino
64cf7f2e2dSJohn Marino if (!have_warned)
65cf7f2e2dSJohn Marino {
66cf7f2e2dSJohn Marino have_warned = 1;
67cf7f2e2dSJohn Marino warning (_("Can not parse XML library list; XML support was disabled "
68cf7f2e2dSJohn Marino "at compile time"));
69cf7f2e2dSJohn Marino }
70cf7f2e2dSJohn Marino
71cf7f2e2dSJohn Marino return NULL;
72cf7f2e2dSJohn Marino }
73cf7f2e2dSJohn Marino
74cf7f2e2dSJohn Marino #else /* HAVE_LIBEXPAT */
75cf7f2e2dSJohn Marino
76cf7f2e2dSJohn Marino #include "xml-support.h"
77cf7f2e2dSJohn Marino
78cf7f2e2dSJohn Marino /* Handle the start of a <segment> element. */
79cf7f2e2dSJohn Marino
80cf7f2e2dSJohn Marino static void
library_list_start_segment(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,VEC (gdb_xml_value_s)* attributes)81cf7f2e2dSJohn Marino library_list_start_segment (struct gdb_xml_parser *parser,
82cf7f2e2dSJohn Marino const struct gdb_xml_element *element,
83cf7f2e2dSJohn Marino void *user_data, VEC(gdb_xml_value_s) *attributes)
84cf7f2e2dSJohn Marino {
85cf7f2e2dSJohn Marino VEC(lm_info_p) **list = user_data;
86cf7f2e2dSJohn Marino struct lm_info *last = VEC_last (lm_info_p, *list);
87a45ae5f8SJohn Marino ULONGEST *address_p = xml_find_attribute (attributes, "address")->value;
88cf7f2e2dSJohn Marino CORE_ADDR address = (CORE_ADDR) *address_p;
89cf7f2e2dSJohn Marino
90cf7f2e2dSJohn Marino if (last->section_bases != NULL)
91cf7f2e2dSJohn Marino gdb_xml_error (parser,
92cf7f2e2dSJohn Marino _("Library list with both segments and sections"));
93cf7f2e2dSJohn Marino
94a45ae5f8SJohn Marino VEC_safe_push (CORE_ADDR, last->segment_bases, address);
95cf7f2e2dSJohn Marino }
96cf7f2e2dSJohn Marino
97cf7f2e2dSJohn Marino static void
library_list_start_section(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,VEC (gdb_xml_value_s)* attributes)98cf7f2e2dSJohn Marino library_list_start_section (struct gdb_xml_parser *parser,
99cf7f2e2dSJohn Marino const struct gdb_xml_element *element,
100cf7f2e2dSJohn Marino void *user_data, VEC(gdb_xml_value_s) *attributes)
101cf7f2e2dSJohn Marino {
102cf7f2e2dSJohn Marino VEC(lm_info_p) **list = user_data;
103cf7f2e2dSJohn Marino struct lm_info *last = VEC_last (lm_info_p, *list);
104a45ae5f8SJohn Marino ULONGEST *address_p = xml_find_attribute (attributes, "address")->value;
105cf7f2e2dSJohn Marino CORE_ADDR address = (CORE_ADDR) *address_p;
106cf7f2e2dSJohn Marino
107cf7f2e2dSJohn Marino if (last->segment_bases != NULL)
108cf7f2e2dSJohn Marino gdb_xml_error (parser,
109cf7f2e2dSJohn Marino _("Library list with both segments and sections"));
110cf7f2e2dSJohn Marino
111a45ae5f8SJohn Marino VEC_safe_push (CORE_ADDR, last->section_bases, address);
112cf7f2e2dSJohn Marino }
113cf7f2e2dSJohn Marino
114cf7f2e2dSJohn Marino /* Handle the start of a <library> element. */
115cf7f2e2dSJohn Marino
116cf7f2e2dSJohn Marino static void
library_list_start_library(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,VEC (gdb_xml_value_s)* attributes)117cf7f2e2dSJohn Marino library_list_start_library (struct gdb_xml_parser *parser,
118cf7f2e2dSJohn Marino const struct gdb_xml_element *element,
119cf7f2e2dSJohn Marino void *user_data, VEC(gdb_xml_value_s) *attributes)
120cf7f2e2dSJohn Marino {
121cf7f2e2dSJohn Marino VEC(lm_info_p) **list = user_data;
122cf7f2e2dSJohn Marino struct lm_info *item = XZALLOC (struct lm_info);
123a45ae5f8SJohn Marino const char *name = xml_find_attribute (attributes, "name")->value;
124cf7f2e2dSJohn Marino
125cf7f2e2dSJohn Marino item->name = xstrdup (name);
126cf7f2e2dSJohn Marino VEC_safe_push (lm_info_p, *list, item);
127cf7f2e2dSJohn Marino }
128cf7f2e2dSJohn Marino
129cf7f2e2dSJohn Marino static void
library_list_end_library(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,const char * body_text)130cf7f2e2dSJohn Marino library_list_end_library (struct gdb_xml_parser *parser,
131cf7f2e2dSJohn Marino const struct gdb_xml_element *element,
132cf7f2e2dSJohn Marino void *user_data, const char *body_text)
133cf7f2e2dSJohn Marino {
134cf7f2e2dSJohn Marino VEC(lm_info_p) **list = user_data;
135cf7f2e2dSJohn Marino struct lm_info *lm_info = VEC_last (lm_info_p, *list);
136cf7f2e2dSJohn Marino
137cf7f2e2dSJohn Marino if (lm_info->segment_bases == NULL
138cf7f2e2dSJohn Marino && lm_info->section_bases == NULL)
139cf7f2e2dSJohn Marino gdb_xml_error (parser,
140cf7f2e2dSJohn Marino _("No segment or section bases defined"));
141cf7f2e2dSJohn Marino }
142cf7f2e2dSJohn Marino
143cf7f2e2dSJohn Marino
144cf7f2e2dSJohn Marino /* Handle the start of a <library-list> element. */
145cf7f2e2dSJohn Marino
146cf7f2e2dSJohn Marino static void
library_list_start_list(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,VEC (gdb_xml_value_s)* attributes)147cf7f2e2dSJohn Marino library_list_start_list (struct gdb_xml_parser *parser,
148cf7f2e2dSJohn Marino const struct gdb_xml_element *element,
149cf7f2e2dSJohn Marino void *user_data, VEC(gdb_xml_value_s) *attributes)
150cf7f2e2dSJohn Marino {
151a45ae5f8SJohn Marino char *version = xml_find_attribute (attributes, "version")->value;
152cf7f2e2dSJohn Marino
153cf7f2e2dSJohn Marino if (strcmp (version, "1.0") != 0)
154cf7f2e2dSJohn Marino gdb_xml_error (parser,
155cf7f2e2dSJohn Marino _("Library list has unsupported version \"%s\""),
156cf7f2e2dSJohn Marino version);
157cf7f2e2dSJohn Marino }
158cf7f2e2dSJohn Marino
159cf7f2e2dSJohn Marino /* Discard the constructed library list. */
160cf7f2e2dSJohn Marino
161cf7f2e2dSJohn Marino static void
solib_target_free_library_list(void * p)162cf7f2e2dSJohn Marino solib_target_free_library_list (void *p)
163cf7f2e2dSJohn Marino {
164cf7f2e2dSJohn Marino VEC(lm_info_p) **result = p;
165cf7f2e2dSJohn Marino struct lm_info *info;
166cf7f2e2dSJohn Marino int ix;
167cf7f2e2dSJohn Marino
168cf7f2e2dSJohn Marino for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++)
169cf7f2e2dSJohn Marino {
170cf7f2e2dSJohn Marino xfree (info->name);
171cf7f2e2dSJohn Marino VEC_free (CORE_ADDR, info->segment_bases);
172cf7f2e2dSJohn Marino VEC_free (CORE_ADDR, info->section_bases);
173cf7f2e2dSJohn Marino xfree (info);
174cf7f2e2dSJohn Marino }
175cf7f2e2dSJohn Marino VEC_free (lm_info_p, *result);
176cf7f2e2dSJohn Marino *result = NULL;
177cf7f2e2dSJohn Marino }
178cf7f2e2dSJohn Marino
179cf7f2e2dSJohn Marino /* The allowed elements and attributes for an XML library list.
180cf7f2e2dSJohn Marino The root element is a <library-list>. */
181cf7f2e2dSJohn Marino
182a45ae5f8SJohn Marino static const struct gdb_xml_attribute segment_attributes[] = {
183cf7f2e2dSJohn Marino { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
184cf7f2e2dSJohn Marino { NULL, GDB_XML_AF_NONE, NULL, NULL }
185cf7f2e2dSJohn Marino };
186cf7f2e2dSJohn Marino
187a45ae5f8SJohn Marino static const struct gdb_xml_attribute section_attributes[] = {
188cf7f2e2dSJohn Marino { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
189cf7f2e2dSJohn Marino { NULL, GDB_XML_AF_NONE, NULL, NULL }
190cf7f2e2dSJohn Marino };
191cf7f2e2dSJohn Marino
192a45ae5f8SJohn Marino static const struct gdb_xml_element library_children[] = {
193cf7f2e2dSJohn Marino { "segment", segment_attributes, NULL,
194cf7f2e2dSJohn Marino GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
195cf7f2e2dSJohn Marino library_list_start_segment, NULL },
196cf7f2e2dSJohn Marino { "section", section_attributes, NULL,
197cf7f2e2dSJohn Marino GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
198cf7f2e2dSJohn Marino library_list_start_section, NULL },
199cf7f2e2dSJohn Marino { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
200cf7f2e2dSJohn Marino };
201cf7f2e2dSJohn Marino
202a45ae5f8SJohn Marino static const struct gdb_xml_attribute library_attributes[] = {
203cf7f2e2dSJohn Marino { "name", GDB_XML_AF_NONE, NULL, NULL },
204cf7f2e2dSJohn Marino { NULL, GDB_XML_AF_NONE, NULL, NULL }
205cf7f2e2dSJohn Marino };
206cf7f2e2dSJohn Marino
207a45ae5f8SJohn Marino static const struct gdb_xml_element library_list_children[] = {
208cf7f2e2dSJohn Marino { "library", library_attributes, library_children,
209cf7f2e2dSJohn Marino GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
210cf7f2e2dSJohn Marino library_list_start_library, library_list_end_library },
211cf7f2e2dSJohn Marino { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
212cf7f2e2dSJohn Marino };
213cf7f2e2dSJohn Marino
214a45ae5f8SJohn Marino static const struct gdb_xml_attribute library_list_attributes[] = {
215cf7f2e2dSJohn Marino { "version", GDB_XML_AF_NONE, NULL, NULL },
216cf7f2e2dSJohn Marino { NULL, GDB_XML_AF_NONE, NULL, NULL }
217cf7f2e2dSJohn Marino };
218cf7f2e2dSJohn Marino
219a45ae5f8SJohn Marino static const struct gdb_xml_element library_list_elements[] = {
220cf7f2e2dSJohn Marino { "library-list", library_list_attributes, library_list_children,
221cf7f2e2dSJohn Marino GDB_XML_EF_NONE, library_list_start_list, NULL },
222cf7f2e2dSJohn Marino { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
223cf7f2e2dSJohn Marino };
224cf7f2e2dSJohn Marino
VEC(lm_info_p)225cf7f2e2dSJohn Marino static VEC(lm_info_p) *
226cf7f2e2dSJohn Marino solib_target_parse_libraries (const char *library)
227cf7f2e2dSJohn Marino {
228cf7f2e2dSJohn Marino VEC(lm_info_p) *result = NULL;
229a45ae5f8SJohn Marino struct cleanup *back_to = make_cleanup (solib_target_free_library_list,
230cf7f2e2dSJohn Marino &result);
231cf7f2e2dSJohn Marino
232a45ae5f8SJohn Marino if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
233a45ae5f8SJohn Marino library_list_elements, library, &result) == 0)
234a45ae5f8SJohn Marino {
235a45ae5f8SJohn Marino /* Parsed successfully, keep the result. */
236a45ae5f8SJohn Marino discard_cleanups (back_to);
237a45ae5f8SJohn Marino return result;
238a45ae5f8SJohn Marino }
239cf7f2e2dSJohn Marino
240cf7f2e2dSJohn Marino do_cleanups (back_to);
241a45ae5f8SJohn Marino return NULL;
242cf7f2e2dSJohn Marino }
243cf7f2e2dSJohn Marino #endif
244cf7f2e2dSJohn Marino
245cf7f2e2dSJohn Marino static struct so_list *
solib_target_current_sos(void)246cf7f2e2dSJohn Marino solib_target_current_sos (void)
247cf7f2e2dSJohn Marino {
248cf7f2e2dSJohn Marino struct so_list *new_solib, *start = NULL, *last = NULL;
249*ef5ccd6cSJohn Marino char *library_document;
250*ef5ccd6cSJohn Marino struct cleanup *old_chain;
251cf7f2e2dSJohn Marino VEC(lm_info_p) *library_list;
252cf7f2e2dSJohn Marino struct lm_info *info;
253cf7f2e2dSJohn Marino int ix;
254cf7f2e2dSJohn Marino
255cf7f2e2dSJohn Marino /* Fetch the list of shared libraries. */
256cf7f2e2dSJohn Marino library_document = target_read_stralloc (¤t_target,
257cf7f2e2dSJohn Marino TARGET_OBJECT_LIBRARIES,
258cf7f2e2dSJohn Marino NULL);
259cf7f2e2dSJohn Marino if (library_document == NULL)
260cf7f2e2dSJohn Marino return NULL;
261cf7f2e2dSJohn Marino
262*ef5ccd6cSJohn Marino /* solib_target_parse_libraries may throw, so we use a cleanup. */
263*ef5ccd6cSJohn Marino old_chain = make_cleanup (xfree, library_document);
264*ef5ccd6cSJohn Marino
265cf7f2e2dSJohn Marino /* Parse the list. */
266cf7f2e2dSJohn Marino library_list = solib_target_parse_libraries (library_document);
267*ef5ccd6cSJohn Marino
268*ef5ccd6cSJohn Marino /* library_document string is not needed behind this point. */
269*ef5ccd6cSJohn Marino do_cleanups (old_chain);
270*ef5ccd6cSJohn Marino
271cf7f2e2dSJohn Marino if (library_list == NULL)
272cf7f2e2dSJohn Marino return NULL;
273cf7f2e2dSJohn Marino
274cf7f2e2dSJohn Marino /* Build a struct so_list for each entry on the list. */
275cf7f2e2dSJohn Marino for (ix = 0; VEC_iterate (lm_info_p, library_list, ix, info); ix++)
276cf7f2e2dSJohn Marino {
277cf7f2e2dSJohn Marino new_solib = XZALLOC (struct so_list);
278cf7f2e2dSJohn Marino strncpy (new_solib->so_name, info->name, SO_NAME_MAX_PATH_SIZE - 1);
279cf7f2e2dSJohn Marino new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
280cf7f2e2dSJohn Marino strncpy (new_solib->so_original_name, info->name,
281cf7f2e2dSJohn Marino SO_NAME_MAX_PATH_SIZE - 1);
282cf7f2e2dSJohn Marino new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
283cf7f2e2dSJohn Marino new_solib->lm_info = info;
284cf7f2e2dSJohn Marino
285cf7f2e2dSJohn Marino /* We no longer need this copy of the name. */
286cf7f2e2dSJohn Marino xfree (info->name);
287cf7f2e2dSJohn Marino info->name = NULL;
288cf7f2e2dSJohn Marino
289cf7f2e2dSJohn Marino /* Add it to the list. */
290cf7f2e2dSJohn Marino if (!start)
291cf7f2e2dSJohn Marino last = start = new_solib;
292cf7f2e2dSJohn Marino else
293cf7f2e2dSJohn Marino {
294cf7f2e2dSJohn Marino last->next = new_solib;
295cf7f2e2dSJohn Marino last = new_solib;
296cf7f2e2dSJohn Marino }
297cf7f2e2dSJohn Marino }
298cf7f2e2dSJohn Marino
299cf7f2e2dSJohn Marino /* Free the library list, but not its members. */
300cf7f2e2dSJohn Marino VEC_free (lm_info_p, library_list);
301cf7f2e2dSJohn Marino
302cf7f2e2dSJohn Marino return start;
303cf7f2e2dSJohn Marino }
304cf7f2e2dSJohn Marino
305cf7f2e2dSJohn Marino static void
solib_target_special_symbol_handling(void)306cf7f2e2dSJohn Marino solib_target_special_symbol_handling (void)
307cf7f2e2dSJohn Marino {
308cf7f2e2dSJohn Marino /* Nothing needed. */
309cf7f2e2dSJohn Marino }
310cf7f2e2dSJohn Marino
311cf7f2e2dSJohn Marino static void
solib_target_solib_create_inferior_hook(int from_tty)312cf7f2e2dSJohn Marino solib_target_solib_create_inferior_hook (int from_tty)
313cf7f2e2dSJohn Marino {
314cf7f2e2dSJohn Marino /* Nothing needed. */
315cf7f2e2dSJohn Marino }
316cf7f2e2dSJohn Marino
317cf7f2e2dSJohn Marino static void
solib_target_clear_solib(void)318cf7f2e2dSJohn Marino solib_target_clear_solib (void)
319cf7f2e2dSJohn Marino {
320cf7f2e2dSJohn Marino /* Nothing needed. */
321cf7f2e2dSJohn Marino }
322cf7f2e2dSJohn Marino
323cf7f2e2dSJohn Marino static void
solib_target_free_so(struct so_list * so)324cf7f2e2dSJohn Marino solib_target_free_so (struct so_list *so)
325cf7f2e2dSJohn Marino {
326cf7f2e2dSJohn Marino gdb_assert (so->lm_info->name == NULL);
327cf7f2e2dSJohn Marino xfree (so->lm_info->offsets);
328cf7f2e2dSJohn Marino VEC_free (CORE_ADDR, so->lm_info->segment_bases);
329cf7f2e2dSJohn Marino xfree (so->lm_info);
330cf7f2e2dSJohn Marino }
331cf7f2e2dSJohn Marino
332cf7f2e2dSJohn Marino static void
solib_target_relocate_section_addresses(struct so_list * so,struct target_section * sec)333cf7f2e2dSJohn Marino solib_target_relocate_section_addresses (struct so_list *so,
334cf7f2e2dSJohn Marino struct target_section *sec)
335cf7f2e2dSJohn Marino {
336cf7f2e2dSJohn Marino CORE_ADDR offset;
337cf7f2e2dSJohn Marino
338cf7f2e2dSJohn Marino /* Build the offset table only once per object file. We can not do
339cf7f2e2dSJohn Marino it any earlier, since we need to open the file first. */
340cf7f2e2dSJohn Marino if (so->lm_info->offsets == NULL)
341cf7f2e2dSJohn Marino {
342cf7f2e2dSJohn Marino int num_sections = bfd_count_sections (so->abfd);
343cf7f2e2dSJohn Marino
344cf7f2e2dSJohn Marino so->lm_info->offsets = xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections));
345cf7f2e2dSJohn Marino
346cf7f2e2dSJohn Marino if (so->lm_info->section_bases)
347cf7f2e2dSJohn Marino {
348cf7f2e2dSJohn Marino int i;
349cf7f2e2dSJohn Marino asection *sect;
350cf7f2e2dSJohn Marino int num_section_bases
351cf7f2e2dSJohn Marino = VEC_length (CORE_ADDR, so->lm_info->section_bases);
352cf7f2e2dSJohn Marino int num_alloc_sections = 0;
353cf7f2e2dSJohn Marino
354cf7f2e2dSJohn Marino for (i = 0, sect = so->abfd->sections;
355cf7f2e2dSJohn Marino sect != NULL;
356cf7f2e2dSJohn Marino i++, sect = sect->next)
357cf7f2e2dSJohn Marino if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
358cf7f2e2dSJohn Marino num_alloc_sections++;
359cf7f2e2dSJohn Marino
360cf7f2e2dSJohn Marino if (num_alloc_sections != num_section_bases)
361cf7f2e2dSJohn Marino warning (_("\
362cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
363cf7f2e2dSJohn Marino so->so_name);
364cf7f2e2dSJohn Marino else
365cf7f2e2dSJohn Marino {
366cf7f2e2dSJohn Marino int bases_index = 0;
367cf7f2e2dSJohn Marino int found_range = 0;
368cf7f2e2dSJohn Marino CORE_ADDR *section_bases;
369cf7f2e2dSJohn Marino
370cf7f2e2dSJohn Marino section_bases = VEC_address (CORE_ADDR,
371cf7f2e2dSJohn Marino so->lm_info->section_bases);
372cf7f2e2dSJohn Marino
373cf7f2e2dSJohn Marino so->addr_low = ~(CORE_ADDR) 0;
374cf7f2e2dSJohn Marino so->addr_high = 0;
375cf7f2e2dSJohn Marino for (i = 0, sect = so->abfd->sections;
376cf7f2e2dSJohn Marino sect != NULL;
377cf7f2e2dSJohn Marino i++, sect = sect->next)
378cf7f2e2dSJohn Marino {
379cf7f2e2dSJohn Marino if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
380cf7f2e2dSJohn Marino continue;
381cf7f2e2dSJohn Marino if (bfd_section_size (so->abfd, sect) > 0)
382cf7f2e2dSJohn Marino {
383cf7f2e2dSJohn Marino CORE_ADDR low, high;
384cf7f2e2dSJohn Marino
385cf7f2e2dSJohn Marino low = section_bases[i];
386cf7f2e2dSJohn Marino high = low + bfd_section_size (so->abfd, sect) - 1;
387cf7f2e2dSJohn Marino
388cf7f2e2dSJohn Marino if (low < so->addr_low)
389cf7f2e2dSJohn Marino so->addr_low = low;
390cf7f2e2dSJohn Marino if (high > so->addr_high)
391cf7f2e2dSJohn Marino so->addr_high = high;
392cf7f2e2dSJohn Marino gdb_assert (so->addr_low <= so->addr_high);
393cf7f2e2dSJohn Marino found_range = 1;
394cf7f2e2dSJohn Marino }
395a45ae5f8SJohn Marino so->lm_info->offsets->offsets[i]
396a45ae5f8SJohn Marino = section_bases[bases_index];
397cf7f2e2dSJohn Marino bases_index++;
398cf7f2e2dSJohn Marino }
399cf7f2e2dSJohn Marino if (!found_range)
400cf7f2e2dSJohn Marino so->addr_low = so->addr_high = 0;
401cf7f2e2dSJohn Marino gdb_assert (so->addr_low <= so->addr_high);
402cf7f2e2dSJohn Marino }
403cf7f2e2dSJohn Marino }
404cf7f2e2dSJohn Marino else if (so->lm_info->segment_bases)
405cf7f2e2dSJohn Marino {
406cf7f2e2dSJohn Marino struct symfile_segment_data *data;
407cf7f2e2dSJohn Marino
408cf7f2e2dSJohn Marino data = get_symfile_segment_data (so->abfd);
409cf7f2e2dSJohn Marino if (data == NULL)
410cf7f2e2dSJohn Marino warning (_("\
411cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": no segments"), so->so_name);
412cf7f2e2dSJohn Marino else
413cf7f2e2dSJohn Marino {
414cf7f2e2dSJohn Marino ULONGEST orig_delta;
415cf7f2e2dSJohn Marino int i;
416cf7f2e2dSJohn Marino int num_bases;
417cf7f2e2dSJohn Marino CORE_ADDR *segment_bases;
418cf7f2e2dSJohn Marino
419cf7f2e2dSJohn Marino num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases);
420cf7f2e2dSJohn Marino segment_bases = VEC_address (CORE_ADDR,
421cf7f2e2dSJohn Marino so->lm_info->segment_bases);
422cf7f2e2dSJohn Marino
423cf7f2e2dSJohn Marino if (!symfile_map_offsets_to_segments (so->abfd, data,
424cf7f2e2dSJohn Marino so->lm_info->offsets,
425cf7f2e2dSJohn Marino num_bases, segment_bases))
426cf7f2e2dSJohn Marino warning (_("\
427cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": bad offsets"), so->so_name);
428cf7f2e2dSJohn Marino
429cf7f2e2dSJohn Marino /* Find the range of addresses to report for this library in
430cf7f2e2dSJohn Marino "info sharedlibrary". Report any consecutive segments
431cf7f2e2dSJohn Marino which were relocated as a single unit. */
432cf7f2e2dSJohn Marino gdb_assert (num_bases > 0);
433cf7f2e2dSJohn Marino orig_delta = segment_bases[0] - data->segment_bases[0];
434cf7f2e2dSJohn Marino
435cf7f2e2dSJohn Marino for (i = 1; i < data->num_segments; i++)
436cf7f2e2dSJohn Marino {
437cf7f2e2dSJohn Marino /* If we have run out of offsets, assume all
438cf7f2e2dSJohn Marino remaining segments have the same offset. */
439cf7f2e2dSJohn Marino if (i >= num_bases)
440cf7f2e2dSJohn Marino continue;
441cf7f2e2dSJohn Marino
442cf7f2e2dSJohn Marino /* If this segment does not have the same offset, do
443cf7f2e2dSJohn Marino not include it in the library's range. */
444cf7f2e2dSJohn Marino if (segment_bases[i] - data->segment_bases[i] != orig_delta)
445cf7f2e2dSJohn Marino break;
446cf7f2e2dSJohn Marino }
447cf7f2e2dSJohn Marino
448cf7f2e2dSJohn Marino so->addr_low = segment_bases[0];
449cf7f2e2dSJohn Marino so->addr_high = (data->segment_bases[i - 1]
450cf7f2e2dSJohn Marino + data->segment_sizes[i - 1]
451cf7f2e2dSJohn Marino + orig_delta);
452cf7f2e2dSJohn Marino gdb_assert (so->addr_low <= so->addr_high);
453cf7f2e2dSJohn Marino
454cf7f2e2dSJohn Marino free_symfile_segment_data (data);
455cf7f2e2dSJohn Marino }
456cf7f2e2dSJohn Marino }
457cf7f2e2dSJohn Marino }
458cf7f2e2dSJohn Marino
459cf7f2e2dSJohn Marino offset = so->lm_info->offsets->offsets[sec->the_bfd_section->index];
460cf7f2e2dSJohn Marino sec->addr += offset;
461cf7f2e2dSJohn Marino sec->endaddr += offset;
462cf7f2e2dSJohn Marino }
463cf7f2e2dSJohn Marino
464cf7f2e2dSJohn Marino static int
solib_target_open_symbol_file_object(void * from_ttyp)465cf7f2e2dSJohn Marino solib_target_open_symbol_file_object (void *from_ttyp)
466cf7f2e2dSJohn Marino {
467cf7f2e2dSJohn Marino /* We can't locate the main symbol file based on the target's
468cf7f2e2dSJohn Marino knowledge; the user has to specify it. */
469cf7f2e2dSJohn Marino return 0;
470cf7f2e2dSJohn Marino }
471cf7f2e2dSJohn Marino
472cf7f2e2dSJohn Marino static int
solib_target_in_dynsym_resolve_code(CORE_ADDR pc)473cf7f2e2dSJohn Marino solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
474cf7f2e2dSJohn Marino {
475cf7f2e2dSJohn Marino /* We don't have a range of addresses for the dynamic linker; there
476cf7f2e2dSJohn Marino may not be one in the program's address space. So only report
477cf7f2e2dSJohn Marino PLT entries (which may be import stubs). */
478cf7f2e2dSJohn Marino return in_plt_section (pc, NULL);
479cf7f2e2dSJohn Marino }
480cf7f2e2dSJohn Marino
481cf7f2e2dSJohn Marino struct target_so_ops solib_target_so_ops;
482cf7f2e2dSJohn Marino
483a45ae5f8SJohn Marino /* -Wmissing-prototypes */
484a45ae5f8SJohn Marino extern initialize_file_ftype _initialize_solib_target;
485cf7f2e2dSJohn Marino
486cf7f2e2dSJohn Marino void
_initialize_solib_target(void)487cf7f2e2dSJohn Marino _initialize_solib_target (void)
488cf7f2e2dSJohn Marino {
489cf7f2e2dSJohn Marino solib_target_so_ops.relocate_section_addresses
490cf7f2e2dSJohn Marino = solib_target_relocate_section_addresses;
491cf7f2e2dSJohn Marino solib_target_so_ops.free_so = solib_target_free_so;
492cf7f2e2dSJohn Marino solib_target_so_ops.clear_solib = solib_target_clear_solib;
493cf7f2e2dSJohn Marino solib_target_so_ops.solib_create_inferior_hook
494cf7f2e2dSJohn Marino = solib_target_solib_create_inferior_hook;
495cf7f2e2dSJohn Marino solib_target_so_ops.special_symbol_handling
496cf7f2e2dSJohn Marino = solib_target_special_symbol_handling;
497cf7f2e2dSJohn Marino solib_target_so_ops.current_sos = solib_target_current_sos;
498cf7f2e2dSJohn Marino solib_target_so_ops.open_symbol_file_object
499cf7f2e2dSJohn Marino = solib_target_open_symbol_file_object;
500cf7f2e2dSJohn Marino solib_target_so_ops.in_dynsym_resolve_code
501cf7f2e2dSJohn Marino = solib_target_in_dynsym_resolve_code;
502cf7f2e2dSJohn Marino solib_target_so_ops.bfd_open = solib_bfd_open;
503cf7f2e2dSJohn Marino
504cf7f2e2dSJohn Marino /* Set current_target_so_ops to solib_target_so_ops if not already
505cf7f2e2dSJohn Marino set. */
506cf7f2e2dSJohn Marino if (current_target_so_ops == 0)
507cf7f2e2dSJohn Marino current_target_so_ops = &solib_target_so_ops;
508cf7f2e2dSJohn Marino }
509