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