xref: /dflybsd-src/contrib/gdb-7/gdb/solib-target.c (revision a45ae5f869d9cfcb3e41dbab486e10bfa9e336bf)
1cf7f2e2dSJohn Marino /* Definitions for targets which report shared library events.
2cf7f2e2dSJohn Marino 
3*a45ae5f8SJohn Marino    Copyright (C) 2007-2012 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 
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
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);
87*a45ae5f8SJohn 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 
94*a45ae5f8SJohn Marino   VEC_safe_push (CORE_ADDR, last->segment_bases, address);
95cf7f2e2dSJohn Marino }
96cf7f2e2dSJohn Marino 
97cf7f2e2dSJohn Marino static void
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);
104*a45ae5f8SJohn 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 
111*a45ae5f8SJohn 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
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);
123*a45ae5f8SJohn 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
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
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 {
151*a45ae5f8SJohn 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
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 
182*a45ae5f8SJohn 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 
187*a45ae5f8SJohn 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 
192*a45ae5f8SJohn 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 
202*a45ae5f8SJohn 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 
207*a45ae5f8SJohn 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 
214*a45ae5f8SJohn 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 
219*a45ae5f8SJohn 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 
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;
229*a45ae5f8SJohn Marino   struct cleanup *back_to = make_cleanup (solib_target_free_library_list,
230cf7f2e2dSJohn Marino 					  &result);
231cf7f2e2dSJohn Marino 
232*a45ae5f8SJohn Marino   if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
233*a45ae5f8SJohn Marino 			   library_list_elements, library, &result) == 0)
234*a45ae5f8SJohn Marino     {
235*a45ae5f8SJohn Marino       /* Parsed successfully, keep the result.  */
236*a45ae5f8SJohn Marino       discard_cleanups (back_to);
237*a45ae5f8SJohn Marino       return result;
238*a45ae5f8SJohn Marino     }
239cf7f2e2dSJohn Marino 
240cf7f2e2dSJohn Marino   do_cleanups (back_to);
241*a45ae5f8SJohn Marino   return NULL;
242cf7f2e2dSJohn Marino }
243cf7f2e2dSJohn Marino #endif
244cf7f2e2dSJohn Marino 
245cf7f2e2dSJohn Marino static struct so_list *
246cf7f2e2dSJohn Marino solib_target_current_sos (void)
247cf7f2e2dSJohn Marino {
248cf7f2e2dSJohn Marino   struct so_list *new_solib, *start = NULL, *last = NULL;
249cf7f2e2dSJohn Marino   const char *library_document;
250cf7f2e2dSJohn Marino   VEC(lm_info_p) *library_list;
251cf7f2e2dSJohn Marino   struct lm_info *info;
252cf7f2e2dSJohn Marino   int ix;
253cf7f2e2dSJohn Marino 
254cf7f2e2dSJohn Marino   /* Fetch the list of shared libraries.  */
255cf7f2e2dSJohn Marino   library_document = target_read_stralloc (&current_target,
256cf7f2e2dSJohn Marino 					   TARGET_OBJECT_LIBRARIES,
257cf7f2e2dSJohn Marino 					   NULL);
258cf7f2e2dSJohn Marino   if (library_document == NULL)
259cf7f2e2dSJohn Marino     return NULL;
260cf7f2e2dSJohn Marino 
261cf7f2e2dSJohn Marino   /* Parse the list.  */
262cf7f2e2dSJohn Marino   library_list = solib_target_parse_libraries (library_document);
263cf7f2e2dSJohn Marino   if (library_list == NULL)
264cf7f2e2dSJohn Marino     return NULL;
265cf7f2e2dSJohn Marino 
266cf7f2e2dSJohn Marino   /* Build a struct so_list for each entry on the list.  */
267cf7f2e2dSJohn Marino   for (ix = 0; VEC_iterate (lm_info_p, library_list, ix, info); ix++)
268cf7f2e2dSJohn Marino     {
269cf7f2e2dSJohn Marino       new_solib = XZALLOC (struct so_list);
270cf7f2e2dSJohn Marino       strncpy (new_solib->so_name, info->name, SO_NAME_MAX_PATH_SIZE - 1);
271cf7f2e2dSJohn Marino       new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
272cf7f2e2dSJohn Marino       strncpy (new_solib->so_original_name, info->name,
273cf7f2e2dSJohn Marino 	       SO_NAME_MAX_PATH_SIZE - 1);
274cf7f2e2dSJohn Marino       new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
275cf7f2e2dSJohn Marino       new_solib->lm_info = info;
276cf7f2e2dSJohn Marino 
277cf7f2e2dSJohn Marino       /* We no longer need this copy of the name.  */
278cf7f2e2dSJohn Marino       xfree (info->name);
279cf7f2e2dSJohn Marino       info->name = NULL;
280cf7f2e2dSJohn Marino 
281cf7f2e2dSJohn Marino       /* Add it to the list.  */
282cf7f2e2dSJohn Marino       if (!start)
283cf7f2e2dSJohn Marino 	last = start = new_solib;
284cf7f2e2dSJohn Marino       else
285cf7f2e2dSJohn Marino 	{
286cf7f2e2dSJohn Marino 	  last->next = new_solib;
287cf7f2e2dSJohn Marino 	  last = new_solib;
288cf7f2e2dSJohn Marino 	}
289cf7f2e2dSJohn Marino     }
290cf7f2e2dSJohn Marino 
291cf7f2e2dSJohn Marino   /* Free the library list, but not its members.  */
292cf7f2e2dSJohn Marino   VEC_free (lm_info_p, library_list);
293cf7f2e2dSJohn Marino 
294cf7f2e2dSJohn Marino   return start;
295cf7f2e2dSJohn Marino }
296cf7f2e2dSJohn Marino 
297cf7f2e2dSJohn Marino static void
298cf7f2e2dSJohn Marino solib_target_special_symbol_handling (void)
299cf7f2e2dSJohn Marino {
300cf7f2e2dSJohn Marino   /* Nothing needed.  */
301cf7f2e2dSJohn Marino }
302cf7f2e2dSJohn Marino 
303cf7f2e2dSJohn Marino static void
304cf7f2e2dSJohn Marino solib_target_solib_create_inferior_hook (int from_tty)
305cf7f2e2dSJohn Marino {
306cf7f2e2dSJohn Marino   /* Nothing needed.  */
307cf7f2e2dSJohn Marino }
308cf7f2e2dSJohn Marino 
309cf7f2e2dSJohn Marino static void
310cf7f2e2dSJohn Marino solib_target_clear_solib (void)
311cf7f2e2dSJohn Marino {
312cf7f2e2dSJohn Marino   /* Nothing needed.  */
313cf7f2e2dSJohn Marino }
314cf7f2e2dSJohn Marino 
315cf7f2e2dSJohn Marino static void
316cf7f2e2dSJohn Marino solib_target_free_so (struct so_list *so)
317cf7f2e2dSJohn Marino {
318cf7f2e2dSJohn Marino   gdb_assert (so->lm_info->name == NULL);
319cf7f2e2dSJohn Marino   xfree (so->lm_info->offsets);
320cf7f2e2dSJohn Marino   VEC_free (CORE_ADDR, so->lm_info->segment_bases);
321cf7f2e2dSJohn Marino   xfree (so->lm_info);
322cf7f2e2dSJohn Marino }
323cf7f2e2dSJohn Marino 
324cf7f2e2dSJohn Marino static void
325cf7f2e2dSJohn Marino solib_target_relocate_section_addresses (struct so_list *so,
326cf7f2e2dSJohn Marino 					 struct target_section *sec)
327cf7f2e2dSJohn Marino {
328cf7f2e2dSJohn Marino   int flags = bfd_get_section_flags (sec->bfd, sec->the_bfd_section);
329cf7f2e2dSJohn Marino   CORE_ADDR offset;
330cf7f2e2dSJohn Marino 
331cf7f2e2dSJohn Marino   /* Build the offset table only once per object file.  We can not do
332cf7f2e2dSJohn Marino      it any earlier, since we need to open the file first.  */
333cf7f2e2dSJohn Marino   if (so->lm_info->offsets == NULL)
334cf7f2e2dSJohn Marino     {
335cf7f2e2dSJohn Marino       int num_sections = bfd_count_sections (so->abfd);
336cf7f2e2dSJohn Marino 
337cf7f2e2dSJohn Marino       so->lm_info->offsets = xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections));
338cf7f2e2dSJohn Marino 
339cf7f2e2dSJohn Marino       if (so->lm_info->section_bases)
340cf7f2e2dSJohn Marino 	{
341cf7f2e2dSJohn Marino 	  int i;
342cf7f2e2dSJohn Marino 	  asection *sect;
343cf7f2e2dSJohn Marino 	  int num_section_bases
344cf7f2e2dSJohn Marino 	    = VEC_length (CORE_ADDR, so->lm_info->section_bases);
345cf7f2e2dSJohn Marino 	  int num_alloc_sections = 0;
346cf7f2e2dSJohn Marino 
347cf7f2e2dSJohn Marino 	  for (i = 0, sect = so->abfd->sections;
348cf7f2e2dSJohn Marino 	       sect != NULL;
349cf7f2e2dSJohn Marino 	       i++, sect = sect->next)
350cf7f2e2dSJohn Marino 	    if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
351cf7f2e2dSJohn Marino 	      num_alloc_sections++;
352cf7f2e2dSJohn Marino 
353cf7f2e2dSJohn Marino 	  if (num_alloc_sections != num_section_bases)
354cf7f2e2dSJohn Marino 	    warning (_("\
355cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
356cf7f2e2dSJohn Marino 		     so->so_name);
357cf7f2e2dSJohn Marino 	  else
358cf7f2e2dSJohn Marino 	    {
359cf7f2e2dSJohn Marino 	      int bases_index = 0;
360cf7f2e2dSJohn Marino 	      int found_range = 0;
361cf7f2e2dSJohn Marino 	      CORE_ADDR *section_bases;
362cf7f2e2dSJohn Marino 
363cf7f2e2dSJohn Marino 	      section_bases = VEC_address (CORE_ADDR,
364cf7f2e2dSJohn Marino 					   so->lm_info->section_bases);
365cf7f2e2dSJohn Marino 
366cf7f2e2dSJohn Marino 	      so->addr_low = ~(CORE_ADDR) 0;
367cf7f2e2dSJohn Marino 	      so->addr_high = 0;
368cf7f2e2dSJohn Marino 	      for (i = 0, sect = so->abfd->sections;
369cf7f2e2dSJohn Marino 		   sect != NULL;
370cf7f2e2dSJohn Marino 		   i++, sect = sect->next)
371cf7f2e2dSJohn Marino 		{
372cf7f2e2dSJohn Marino 		  if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
373cf7f2e2dSJohn Marino 		    continue;
374cf7f2e2dSJohn Marino 		  if (bfd_section_size (so->abfd, sect) > 0)
375cf7f2e2dSJohn Marino 		    {
376cf7f2e2dSJohn Marino 		      CORE_ADDR low, high;
377cf7f2e2dSJohn Marino 
378cf7f2e2dSJohn Marino 		      low = section_bases[i];
379cf7f2e2dSJohn Marino 		      high = low + bfd_section_size (so->abfd, sect) - 1;
380cf7f2e2dSJohn Marino 
381cf7f2e2dSJohn Marino 		      if (low < so->addr_low)
382cf7f2e2dSJohn Marino 			so->addr_low = low;
383cf7f2e2dSJohn Marino 		      if (high > so->addr_high)
384cf7f2e2dSJohn Marino 			so->addr_high = high;
385cf7f2e2dSJohn Marino 		      gdb_assert (so->addr_low <= so->addr_high);
386cf7f2e2dSJohn Marino 		      found_range = 1;
387cf7f2e2dSJohn Marino 		    }
388*a45ae5f8SJohn Marino 		  so->lm_info->offsets->offsets[i]
389*a45ae5f8SJohn Marino 		    = section_bases[bases_index];
390cf7f2e2dSJohn Marino 		  bases_index++;
391cf7f2e2dSJohn Marino 		}
392cf7f2e2dSJohn Marino 	      if (!found_range)
393cf7f2e2dSJohn Marino 		so->addr_low = so->addr_high = 0;
394cf7f2e2dSJohn Marino 	      gdb_assert (so->addr_low <= so->addr_high);
395cf7f2e2dSJohn Marino 	    }
396cf7f2e2dSJohn Marino 	}
397cf7f2e2dSJohn Marino       else if (so->lm_info->segment_bases)
398cf7f2e2dSJohn Marino 	{
399cf7f2e2dSJohn Marino 	  struct symfile_segment_data *data;
400cf7f2e2dSJohn Marino 
401cf7f2e2dSJohn Marino 	  data = get_symfile_segment_data (so->abfd);
402cf7f2e2dSJohn Marino 	  if (data == NULL)
403cf7f2e2dSJohn Marino 	    warning (_("\
404cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": no segments"), so->so_name);
405cf7f2e2dSJohn Marino 	  else
406cf7f2e2dSJohn Marino 	    {
407cf7f2e2dSJohn Marino 	      ULONGEST orig_delta;
408cf7f2e2dSJohn Marino 	      int i;
409cf7f2e2dSJohn Marino 	      int num_bases;
410cf7f2e2dSJohn Marino 	      CORE_ADDR *segment_bases;
411cf7f2e2dSJohn Marino 
412cf7f2e2dSJohn Marino 	      num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases);
413cf7f2e2dSJohn Marino 	      segment_bases = VEC_address (CORE_ADDR,
414cf7f2e2dSJohn Marino 					   so->lm_info->segment_bases);
415cf7f2e2dSJohn Marino 
416cf7f2e2dSJohn Marino 	      if (!symfile_map_offsets_to_segments (so->abfd, data,
417cf7f2e2dSJohn Marino 						    so->lm_info->offsets,
418cf7f2e2dSJohn Marino 						    num_bases, segment_bases))
419cf7f2e2dSJohn Marino 		warning (_("\
420cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": bad offsets"), so->so_name);
421cf7f2e2dSJohn Marino 
422cf7f2e2dSJohn Marino 	      /* Find the range of addresses to report for this library in
423cf7f2e2dSJohn Marino 		 "info sharedlibrary".  Report any consecutive segments
424cf7f2e2dSJohn Marino 		 which were relocated as a single unit.  */
425cf7f2e2dSJohn Marino 	      gdb_assert (num_bases > 0);
426cf7f2e2dSJohn Marino 	      orig_delta = segment_bases[0] - data->segment_bases[0];
427cf7f2e2dSJohn Marino 
428cf7f2e2dSJohn Marino 	      for (i = 1; i < data->num_segments; i++)
429cf7f2e2dSJohn Marino 		{
430cf7f2e2dSJohn Marino 		  /* If we have run out of offsets, assume all
431cf7f2e2dSJohn Marino 		     remaining segments have the same offset.  */
432cf7f2e2dSJohn Marino 		  if (i >= num_bases)
433cf7f2e2dSJohn Marino 		    continue;
434cf7f2e2dSJohn Marino 
435cf7f2e2dSJohn Marino 		  /* If this segment does not have the same offset, do
436cf7f2e2dSJohn Marino 		     not include it in the library's range.  */
437cf7f2e2dSJohn Marino 		  if (segment_bases[i] - data->segment_bases[i] != orig_delta)
438cf7f2e2dSJohn Marino 		    break;
439cf7f2e2dSJohn Marino 		}
440cf7f2e2dSJohn Marino 
441cf7f2e2dSJohn Marino 	      so->addr_low = segment_bases[0];
442cf7f2e2dSJohn Marino 	      so->addr_high = (data->segment_bases[i - 1]
443cf7f2e2dSJohn Marino 			       + data->segment_sizes[i - 1]
444cf7f2e2dSJohn Marino 			       + orig_delta);
445cf7f2e2dSJohn Marino 	      gdb_assert (so->addr_low <= so->addr_high);
446cf7f2e2dSJohn Marino 
447cf7f2e2dSJohn Marino 	      free_symfile_segment_data (data);
448cf7f2e2dSJohn Marino 	    }
449cf7f2e2dSJohn Marino 	}
450cf7f2e2dSJohn Marino     }
451cf7f2e2dSJohn Marino 
452cf7f2e2dSJohn Marino   offset = so->lm_info->offsets->offsets[sec->the_bfd_section->index];
453cf7f2e2dSJohn Marino   sec->addr += offset;
454cf7f2e2dSJohn Marino   sec->endaddr += offset;
455cf7f2e2dSJohn Marino }
456cf7f2e2dSJohn Marino 
457cf7f2e2dSJohn Marino static int
458cf7f2e2dSJohn Marino solib_target_open_symbol_file_object (void *from_ttyp)
459cf7f2e2dSJohn Marino {
460cf7f2e2dSJohn Marino   /* We can't locate the main symbol file based on the target's
461cf7f2e2dSJohn Marino      knowledge; the user has to specify it.  */
462cf7f2e2dSJohn Marino   return 0;
463cf7f2e2dSJohn Marino }
464cf7f2e2dSJohn Marino 
465cf7f2e2dSJohn Marino static int
466cf7f2e2dSJohn Marino solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
467cf7f2e2dSJohn Marino {
468cf7f2e2dSJohn Marino   /* We don't have a range of addresses for the dynamic linker; there
469cf7f2e2dSJohn Marino      may not be one in the program's address space.  So only report
470cf7f2e2dSJohn Marino      PLT entries (which may be import stubs).  */
471cf7f2e2dSJohn Marino   return in_plt_section (pc, NULL);
472cf7f2e2dSJohn Marino }
473cf7f2e2dSJohn Marino 
474cf7f2e2dSJohn Marino struct target_so_ops solib_target_so_ops;
475cf7f2e2dSJohn Marino 
476*a45ae5f8SJohn Marino /* -Wmissing-prototypes */
477*a45ae5f8SJohn Marino extern initialize_file_ftype _initialize_solib_target;
478cf7f2e2dSJohn Marino 
479cf7f2e2dSJohn Marino void
480cf7f2e2dSJohn Marino _initialize_solib_target (void)
481cf7f2e2dSJohn Marino {
482cf7f2e2dSJohn Marino   solib_target_so_ops.relocate_section_addresses
483cf7f2e2dSJohn Marino     = solib_target_relocate_section_addresses;
484cf7f2e2dSJohn Marino   solib_target_so_ops.free_so = solib_target_free_so;
485cf7f2e2dSJohn Marino   solib_target_so_ops.clear_solib = solib_target_clear_solib;
486cf7f2e2dSJohn Marino   solib_target_so_ops.solib_create_inferior_hook
487cf7f2e2dSJohn Marino     = solib_target_solib_create_inferior_hook;
488cf7f2e2dSJohn Marino   solib_target_so_ops.special_symbol_handling
489cf7f2e2dSJohn Marino     = solib_target_special_symbol_handling;
490cf7f2e2dSJohn Marino   solib_target_so_ops.current_sos = solib_target_current_sos;
491cf7f2e2dSJohn Marino   solib_target_so_ops.open_symbol_file_object
492cf7f2e2dSJohn Marino     = solib_target_open_symbol_file_object;
493cf7f2e2dSJohn Marino   solib_target_so_ops.in_dynsym_resolve_code
494cf7f2e2dSJohn Marino     = solib_target_in_dynsym_resolve_code;
495cf7f2e2dSJohn Marino   solib_target_so_ops.bfd_open = solib_bfd_open;
496cf7f2e2dSJohn Marino 
497cf7f2e2dSJohn Marino   /* Set current_target_so_ops to solib_target_so_ops if not already
498cf7f2e2dSJohn Marino      set.  */
499cf7f2e2dSJohn Marino   if (current_target_so_ops == 0)
500cf7f2e2dSJohn Marino     current_target_so_ops = &solib_target_so_ops;
501cf7f2e2dSJohn Marino }
502