solib-aix.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  1. /* Copyright (C) 2013-2022 Free Software Foundation, Inc.
  2. This file is part of GDB.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #include "defs.h"
  14. #include "solib-aix.h"
  15. #include "solist.h"
  16. #include "inferior.h"
  17. #include "gdb_bfd.h"
  18. #include "gdbcore.h"
  19. #include "objfiles.h"
  20. #include "symtab.h"
  21. #include "xcoffread.h"
  22. #include "observable.h"
  23. #include "gdbcmd.h"
  24. #include "gdbsupport/scope-exit.h"
  25. /* Variable controlling the output of the debugging traces for
  26. this module. */
  27. static bool solib_aix_debug;
  28. /* Print an "aix-solib" debug statement. */
  29. #define solib_aix_debug_printf(fmt, ...) \
  30. debug_prefixed_printf_cond (solib_aix_debug, "aix-solib",fmt, ##__VA_ARGS__)
  31. /* Our private data in struct so_list. */
  32. struct lm_info_aix : public lm_info_base
  33. {
  34. /* The name of the file mapped by the loader. Apart from the entry
  35. for the main executable, this is usually a shared library (which,
  36. on AIX, is an archive library file, created using the "ar"
  37. command). */
  38. std::string filename;
  39. /* The name of the shared object file with the actual dynamic
  40. loading dependency. This may be empty (Eg. main executable). */
  41. std::string member_name;
  42. /* The address in inferior memory where the text section got mapped. */
  43. CORE_ADDR text_addr = 0;
  44. /* The size of the text section, obtained via the loader data. */
  45. ULONGEST text_size = 0;
  46. /* The address in inferior memory where the data section got mapped. */
  47. CORE_ADDR data_addr = 0;
  48. /* The size of the data section, obtained via the loader data. */
  49. ULONGEST data_size = 0;
  50. };
  51. /* This module's per-inferior data. */
  52. struct solib_aix_inferior_data
  53. {
  54. /* The list of shared libraries.
  55. Note that the first element of this list is always the main
  56. executable, which is not technically a shared library. But
  57. we need that information to perform its relocation, and
  58. the same principles applied to shared libraries also apply
  59. to the main executable. So it's simpler to keep it as part
  60. of this list. */
  61. gdb::optional<std::vector<lm_info_aix>> library_list;
  62. };
  63. /* Key to our per-inferior data. */
  64. static inferior_key<solib_aix_inferior_data> solib_aix_inferior_data_handle;
  65. /* Return this module's data for the given inferior.
  66. If none is found, add a zero'ed one now. */
  67. static struct solib_aix_inferior_data *
  68. get_solib_aix_inferior_data (struct inferior *inf)
  69. {
  70. struct solib_aix_inferior_data *data;
  71. data = solib_aix_inferior_data_handle.get (inf);
  72. if (data == NULL)
  73. data = solib_aix_inferior_data_handle.emplace (inf);
  74. return data;
  75. }
  76. #if !defined(HAVE_LIBEXPAT)
  77. /* Dummy implementation if XML support is not compiled in. */
  78. static gdb::optional<std::vector<lm_info_aix>>
  79. solib_aix_parse_libraries (const char *library)
  80. {
  81. static int have_warned;
  82. if (!have_warned)
  83. {
  84. have_warned = 1;
  85. warning (_("Can not parse XML library list; XML support was disabled "
  86. "at compile time"));
  87. }
  88. return {};
  89. }
  90. #else /* HAVE_LIBEXPAT */
  91. #include "xml-support.h"
  92. /* Handle the start of a <library> element. */
  93. static void
  94. library_list_start_library (struct gdb_xml_parser *parser,
  95. const struct gdb_xml_element *element,
  96. void *user_data,
  97. std::vector<gdb_xml_value> &attributes)
  98. {
  99. std::vector<lm_info_aix> *list = (std::vector<lm_info_aix> *) user_data;
  100. lm_info_aix item;
  101. struct gdb_xml_value *attr;
  102. attr = xml_find_attribute (attributes, "name");
  103. item.filename = (const char *) attr->value.get ();
  104. attr = xml_find_attribute (attributes, "member");
  105. if (attr != NULL)
  106. item.member_name = (const char *) attr->value.get ();
  107. attr = xml_find_attribute (attributes, "text_addr");
  108. item.text_addr = * (ULONGEST *) attr->value.get ();
  109. attr = xml_find_attribute (attributes, "text_size");
  110. item.text_size = * (ULONGEST *) attr->value.get ();
  111. attr = xml_find_attribute (attributes, "data_addr");
  112. item.data_addr = * (ULONGEST *) attr->value.get ();
  113. attr = xml_find_attribute (attributes, "data_size");
  114. item.data_size = * (ULONGEST *) attr->value.get ();
  115. list->push_back (std::move (item));
  116. }
  117. /* Handle the start of a <library-list-aix> element. */
  118. static void
  119. library_list_start_list (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. char *version
  125. = (char *) xml_find_attribute (attributes, "version")->value.get ();
  126. if (strcmp (version, "1.0") != 0)
  127. gdb_xml_error (parser,
  128. _("Library list has unsupported version \"%s\""),
  129. version);
  130. }
  131. /* The allowed elements and attributes for an AIX library list
  132. described in XML format. The root element is a <library-list-aix>. */
  133. static const struct gdb_xml_attribute library_attributes[] =
  134. {
  135. { "name", GDB_XML_AF_NONE, NULL, NULL },
  136. { "member", GDB_XML_AF_OPTIONAL, NULL, NULL },
  137. { "text_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  138. { "text_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  139. { "data_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  140. { "data_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  141. { NULL, GDB_XML_AF_NONE, NULL, NULL }
  142. };
  143. static const struct gdb_xml_element library_list_children[] =
  144. {
  145. { "library", library_attributes, NULL,
  146. GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
  147. library_list_start_library, NULL},
  148. { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
  149. };
  150. static const struct gdb_xml_attribute library_list_attributes[] =
  151. {
  152. { "version", GDB_XML_AF_NONE, NULL, NULL },
  153. { NULL, GDB_XML_AF_NONE, NULL, NULL }
  154. };
  155. static const struct gdb_xml_element library_list_elements[] =
  156. {
  157. { "library-list-aix", library_list_attributes, library_list_children,
  158. GDB_XML_EF_NONE, library_list_start_list, NULL },
  159. { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
  160. };
  161. /* Parse LIBRARY, a string containing the loader info in XML format,
  162. and return a vector of lm_info_aix objects.
  163. Return an empty option if the parsing failed. */
  164. static gdb::optional<std::vector<lm_info_aix>>
  165. solib_aix_parse_libraries (const char *library)
  166. {
  167. std::vector<lm_info_aix> result;
  168. if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd",
  169. library_list_elements, library, &result) == 0)
  170. return result;
  171. return {};
  172. }
  173. #endif /* HAVE_LIBEXPAT */
  174. /* Return the loader info for the given inferior (INF), or an empty
  175. option if the list could not be computed.
  176. Cache the result in per-inferior data, so as to avoid recomputing it
  177. each time this function is called.
  178. If an error occurs while computing this list, and WARNING_MSG
  179. is not NULL, then print a warning including WARNING_MSG and
  180. a description of the error. */
  181. static gdb::optional<std::vector<lm_info_aix>> &
  182. solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
  183. {
  184. struct solib_aix_inferior_data *data;
  185. /* If already computed, return the cached value. */
  186. data = get_solib_aix_inferior_data (inf);
  187. if (data->library_list.has_value ())
  188. return data->library_list;
  189. gdb::optional<gdb::char_vector> library_document
  190. = target_read_stralloc (current_inferior ()->top_target (),
  191. TARGET_OBJECT_LIBRARIES_AIX,
  192. NULL);
  193. if (!library_document && warning_msg != NULL)
  194. {
  195. warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
  196. warning_msg);
  197. return data->library_list;
  198. }
  199. solib_aix_debug_printf ("TARGET_OBJECT_LIBRARIES_AIX = %s",
  200. library_document->data ());
  201. data->library_list = solib_aix_parse_libraries (library_document->data ());
  202. if (!data->library_list.has_value () && warning_msg != NULL)
  203. warning (_("%s (missing XML support?)"), warning_msg);
  204. return data->library_list;
  205. }
  206. /* If the .bss section's VMA is set to an address located before
  207. the end of the .data section, causing the two sections to overlap,
  208. return the overlap in bytes. Otherwise, return zero.
  209. Motivation:
  210. The GNU linker sometimes sets the start address of the .bss session
  211. before the end of the .data section, making the 2 sections overlap.
  212. The loader appears to handle this situation gracefully, by simply
  213. loading the bss section right after the end of the .data section.
  214. This means that the .data and the .bss sections are sometimes
  215. no longer relocated by the same amount. The problem is that
  216. the ldinfo data does not contain any information regarding
  217. the relocation of the .bss section, assuming that it would be
  218. identical to the information provided for the .data section
  219. (this is what would normally happen if the program was linked
  220. correctly).
  221. GDB therefore needs to detect those cases, and make the corresponding
  222. adjustment to the .bss section offset computed from the ldinfo data
  223. when necessary. This function returns the adjustment amount (or
  224. zero when no adjustment is needed). */
  225. static CORE_ADDR
  226. solib_aix_bss_data_overlap (bfd *abfd)
  227. {
  228. struct bfd_section *data_sect, *bss_sect;
  229. data_sect = bfd_get_section_by_name (abfd, ".data");
  230. if (data_sect == NULL)
  231. return 0; /* No overlap possible. */
  232. bss_sect = bfd_get_section_by_name (abfd, ".bss");
  233. if (bss_sect == NULL)
  234. return 0; /* No overlap possible. */
  235. /* Assume the problem only occurs with linkers that place the .bss
  236. section after the .data section (the problem has only been
  237. observed when using the GNU linker, and the default linker
  238. script always places the .data and .bss sections in that order). */
  239. if (bfd_section_vma (bss_sect) < bfd_section_vma (data_sect))
  240. return 0;
  241. if (bfd_section_vma (bss_sect)
  242. < bfd_section_vma (data_sect) + bfd_section_size (data_sect))
  243. return (bfd_section_vma (data_sect) + bfd_section_size (data_sect)
  244. - bfd_section_vma (bss_sect));
  245. return 0;
  246. }
  247. /* Implement the "relocate_section_addresses" target_so_ops method. */
  248. static void
  249. solib_aix_relocate_section_addresses (struct so_list *so,
  250. struct target_section *sec)
  251. {
  252. struct bfd_section *bfd_sect = sec->the_bfd_section;
  253. bfd *abfd = bfd_sect->owner;
  254. const char *section_name = bfd_section_name (bfd_sect);
  255. lm_info_aix *info = (lm_info_aix *) so->lm_info;
  256. if (strcmp (section_name, ".text") == 0)
  257. {
  258. sec->addr = info->text_addr;
  259. sec->endaddr = sec->addr + info->text_size;
  260. /* The text address given to us by the loader contains
  261. XCOFF headers, so we need to adjust by this much. */
  262. sec->addr += bfd_sect->filepos;
  263. }
  264. else if (strcmp (section_name, ".data") == 0)
  265. {
  266. sec->addr = info->data_addr;
  267. sec->endaddr = sec->addr + info->data_size;
  268. }
  269. else if (strcmp (section_name, ".bss") == 0)
  270. {
  271. /* The information provided by the loader does not include
  272. the address of the .bss section, but we know that it gets
  273. relocated by the same offset as the .data section. So,
  274. compute the relocation offset for the .data section, and
  275. apply it to the .bss section as well. If the .data section
  276. is not defined (which seems highly unlikely), do our best
  277. by assuming no relocation. */
  278. struct bfd_section *data_sect
  279. = bfd_get_section_by_name (abfd, ".data");
  280. CORE_ADDR data_offset = 0;
  281. if (data_sect != NULL)
  282. data_offset = info->data_addr - bfd_section_vma (data_sect);
  283. sec->addr = bfd_section_vma (bfd_sect) + data_offset;
  284. sec->addr += solib_aix_bss_data_overlap (abfd);
  285. sec->endaddr = sec->addr + bfd_section_size (bfd_sect);
  286. }
  287. else
  288. {
  289. /* All other sections should not be relocated. */
  290. sec->addr = bfd_section_vma (bfd_sect);
  291. sec->endaddr = sec->addr + bfd_section_size (bfd_sect);
  292. }
  293. }
  294. /* Implement the "free_so" target_so_ops method. */
  295. static void
  296. solib_aix_free_so (struct so_list *so)
  297. {
  298. lm_info_aix *li = (lm_info_aix *) so->lm_info;
  299. solib_aix_debug_printf ("%s", so->so_name);
  300. delete li;
  301. }
  302. /* Implement the "clear_solib" target_so_ops method. */
  303. static void
  304. solib_aix_clear_solib (void)
  305. {
  306. /* Nothing needed. */
  307. }
  308. /* Compute and return the OBJFILE's section_offset array, using
  309. the associated loader info (INFO). */
  310. static section_offsets
  311. solib_aix_get_section_offsets (struct objfile *objfile,
  312. lm_info_aix *info)
  313. {
  314. bfd *abfd = objfile->obfd;
  315. section_offsets offsets (objfile->section_offsets.size ());
  316. /* .text */
  317. if (objfile->sect_index_text != -1)
  318. {
  319. struct bfd_section *sect
  320. = objfile->sections[objfile->sect_index_text].the_bfd_section;
  321. offsets[objfile->sect_index_text]
  322. = info->text_addr + sect->filepos - bfd_section_vma (sect);
  323. }
  324. /* .data */
  325. if (objfile->sect_index_data != -1)
  326. {
  327. struct bfd_section *sect
  328. = objfile->sections[objfile->sect_index_data].the_bfd_section;
  329. offsets[objfile->sect_index_data]
  330. = info->data_addr - bfd_section_vma (sect);
  331. }
  332. /* .bss
  333. The offset of the .bss section should be identical to the offset
  334. of the .data section. If no .data section (which seems hard to
  335. believe it is possible), assume it is zero. */
  336. if (objfile->sect_index_bss != -1
  337. && objfile->sect_index_data != -1)
  338. {
  339. offsets[objfile->sect_index_bss]
  340. = (offsets[objfile->sect_index_data]
  341. + solib_aix_bss_data_overlap (abfd));
  342. }
  343. /* All other sections should not need relocation. */
  344. return offsets;
  345. }
  346. /* Implement the "solib_create_inferior_hook" target_so_ops method. */
  347. static void
  348. solib_aix_solib_create_inferior_hook (int from_tty)
  349. {
  350. const char *warning_msg = "unable to relocate main executable";
  351. /* We need to relocate the main executable... */
  352. gdb::optional<std::vector<lm_info_aix>> &library_list
  353. = solib_aix_get_library_list (current_inferior (), warning_msg);
  354. if (!library_list.has_value ())
  355. return; /* Warning already printed. */
  356. if (library_list->empty ())
  357. {
  358. warning (_("unable to relocate main executable (no info from loader)"));
  359. return;
  360. }
  361. lm_info_aix &exec_info = (*library_list)[0];
  362. if (current_program_space->symfile_object_file != NULL)
  363. {
  364. objfile *objf = current_program_space->symfile_object_file;
  365. section_offsets offsets = solib_aix_get_section_offsets (objf,
  366. &exec_info);
  367. objfile_relocate (objf, offsets);
  368. }
  369. }
  370. /* Implement the "current_sos" target_so_ops method. */
  371. static struct so_list *
  372. solib_aix_current_sos (void)
  373. {
  374. struct so_list *start = NULL, *last = NULL;
  375. int ix;
  376. gdb::optional<std::vector<lm_info_aix>> &library_list
  377. = solib_aix_get_library_list (current_inferior (), NULL);
  378. if (!library_list.has_value ())
  379. return NULL;
  380. /* Build a struct so_list for each entry on the list.
  381. We skip the first entry, since this is the entry corresponding
  382. to the main executable, not a shared library. */
  383. for (ix = 1; ix < library_list->size (); ix++)
  384. {
  385. struct so_list *new_solib = XCNEW (struct so_list);
  386. std::string so_name;
  387. lm_info_aix &info = (*library_list)[ix];
  388. if (info.member_name.empty ())
  389. {
  390. /* INFO.FILENAME is probably not an archive, but rather
  391. a shared object. Unusual, but it should be possible
  392. to link a program against a shared object directory,
  393. without having to put it in an archive first. */
  394. so_name = info.filename;
  395. }
  396. else
  397. {
  398. /* This is the usual case on AIX, where the shared object
  399. is a member of an archive. Create a synthetic so_name
  400. that follows the same convention as AIX's ldd tool
  401. (Eg: "/lib/libc.a(shr.o)"). */
  402. so_name = string_printf ("%s(%s)", info.filename.c_str (),
  403. info.member_name.c_str ());
  404. }
  405. strncpy (new_solib->so_original_name, so_name.c_str (),
  406. SO_NAME_MAX_PATH_SIZE - 1);
  407. new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
  408. memcpy (new_solib->so_name, new_solib->so_original_name,
  409. SO_NAME_MAX_PATH_SIZE);
  410. new_solib->lm_info = new lm_info_aix (info);
  411. /* Add it to the list. */
  412. if (!start)
  413. last = start = new_solib;
  414. else
  415. {
  416. last->next = new_solib;
  417. last = new_solib;
  418. }
  419. }
  420. return start;
  421. }
  422. /* Implement the "open_symbol_file_object" target_so_ops method. */
  423. static int
  424. solib_aix_open_symbol_file_object (int from_tty)
  425. {
  426. return 0;
  427. }
  428. /* Implement the "in_dynsym_resolve_code" target_so_ops method. */
  429. static int
  430. solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
  431. {
  432. return 0;
  433. }
  434. /* Implement the "bfd_open" target_so_ops method. */
  435. static gdb_bfd_ref_ptr
  436. solib_aix_bfd_open (const char *pathname)
  437. {
  438. /* The pathname is actually a synthetic filename with the following
  439. form: "/path/to/sharedlib(member.o)" (double-quotes excluded).
  440. split this into archive name and member name.
  441. FIXME: This is a little hacky. Perhaps we should provide access
  442. to the solib's lm_info here? */
  443. const int path_len = strlen (pathname);
  444. const char *sep;
  445. int filename_len;
  446. int found_file;
  447. if (pathname[path_len - 1] != ')')
  448. return solib_bfd_open (pathname);
  449. /* Search for the associated parens. */
  450. sep = strrchr (pathname, '(');
  451. if (sep == NULL)
  452. {
  453. /* Should never happen, but recover as best as we can (trying
  454. to open pathname without decoding, possibly leading to
  455. a failure), rather than triggering an assert failure). */
  456. warning (_("missing '(' in shared object pathname: %s"), pathname);
  457. return solib_bfd_open (pathname);
  458. }
  459. filename_len = sep - pathname;
  460. std::string filename (string_printf ("%.*s", filename_len, pathname));
  461. std::string member_name (string_printf ("%.*s", path_len - filename_len - 2,
  462. sep + 1));
  463. /* Calling solib_find makes certain that sysroot path is set properly
  464. if program has a dependency on .a archive and sysroot is set via
  465. set sysroot command. */
  466. gdb::unique_xmalloc_ptr<char> found_pathname
  467. = solib_find (filename.c_str (), &found_file);
  468. if (found_pathname == NULL)
  469. perror_with_name (pathname);
  470. gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname.get (),
  471. found_file));
  472. if (archive_bfd == NULL)
  473. {
  474. warning (_("Could not open `%s' as an executable file: %s"),
  475. filename.c_str (), bfd_errmsg (bfd_get_error ()));
  476. return NULL;
  477. }
  478. if (bfd_check_format (archive_bfd.get (), bfd_object))
  479. return archive_bfd;
  480. if (! bfd_check_format (archive_bfd.get (), bfd_archive))
  481. {
  482. warning (_("\"%s\": not in executable format: %s."),
  483. filename.c_str (), bfd_errmsg (bfd_get_error ()));
  484. return NULL;
  485. }
  486. gdb_bfd_ref_ptr object_bfd
  487. (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL));
  488. while (object_bfd != NULL)
  489. {
  490. if (member_name == bfd_get_filename (object_bfd.get ()))
  491. break;
  492. object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (),
  493. object_bfd.get ());
  494. }
  495. if (object_bfd == NULL)
  496. {
  497. warning (_("\"%s\": member \"%s\" missing."), filename.c_str (),
  498. member_name.c_str ());
  499. return NULL;
  500. }
  501. if (! bfd_check_format (object_bfd.get (), bfd_object))
  502. {
  503. warning (_("%s(%s): not in object format: %s."),
  504. filename.c_str (), member_name.c_str (),
  505. bfd_errmsg (bfd_get_error ()));
  506. return NULL;
  507. }
  508. /* Override the returned bfd's name with the name returned from solib_find
  509. along with appended parenthesized member name in order to allow commands
  510. listing all shared libraries to display. Otherwise, we would only be
  511. displaying the name of the archive member object. */
  512. std::string fname = string_printf ("%s%s",
  513. bfd_get_filename (archive_bfd.get ()),
  514. sep);
  515. bfd_set_filename (object_bfd.get (), fname.c_str ());
  516. return object_bfd;
  517. }
  518. /* Return the obj_section corresponding to OBJFILE's data section,
  519. or NULL if not found. */
  520. /* FIXME: Define in a more general location? */
  521. static struct obj_section *
  522. data_obj_section_from_objfile (struct objfile *objfile)
  523. {
  524. struct obj_section *osect;
  525. ALL_OBJFILE_OSECTIONS (objfile, osect)
  526. if (strcmp (bfd_section_name (osect->the_bfd_section), ".data") == 0)
  527. return osect;
  528. return NULL;
  529. }
  530. /* Return the TOC value corresponding to the given PC address,
  531. or raise an error if the value could not be determined. */
  532. CORE_ADDR
  533. solib_aix_get_toc_value (CORE_ADDR pc)
  534. {
  535. struct obj_section *pc_osect = find_pc_section (pc);
  536. struct obj_section *data_osect;
  537. CORE_ADDR result;
  538. if (pc_osect == NULL)
  539. error (_("unable to find TOC entry for pc %s "
  540. "(no section contains this PC)"),
  541. core_addr_to_string (pc));
  542. data_osect = data_obj_section_from_objfile (pc_osect->objfile);
  543. if (data_osect == NULL)
  544. error (_("unable to find TOC entry for pc %s "
  545. "(%s has no data section)"),
  546. core_addr_to_string (pc), objfile_name (pc_osect->objfile));
  547. result = data_osect->addr () + xcoff_get_toc_offset (pc_osect->objfile);
  548. solib_aix_debug_printf ("pc=%s -> %s", core_addr_to_string (pc),
  549. core_addr_to_string (result));
  550. return result;
  551. }
  552. /* This module's normal_stop observer. */
  553. static void
  554. solib_aix_normal_stop_observer (struct bpstat *unused_1, int unused_2)
  555. {
  556. struct solib_aix_inferior_data *data
  557. = get_solib_aix_inferior_data (current_inferior ());
  558. /* The inferior execution has been resumed, and it just stopped
  559. again. This means that the list of shared libraries may have
  560. evolved. Reset our cached value. */
  561. data->library_list.reset ();
  562. }
  563. /* Implements the "show debug aix-solib" command. */
  564. static void
  565. show_solib_aix_debug (struct ui_file *file, int from_tty,
  566. struct cmd_list_element *c, const char *value)
  567. {
  568. gdb_printf (file, _("solib-aix debugging is %s.\n"), value);
  569. }
  570. /* The target_so_ops for AIX targets. */
  571. struct target_so_ops solib_aix_so_ops;
  572. void _initialize_solib_aix ();
  573. void
  574. _initialize_solib_aix ()
  575. {
  576. solib_aix_so_ops.relocate_section_addresses
  577. = solib_aix_relocate_section_addresses;
  578. solib_aix_so_ops.free_so = solib_aix_free_so;
  579. solib_aix_so_ops.clear_solib = solib_aix_clear_solib;
  580. solib_aix_so_ops.solib_create_inferior_hook
  581. = solib_aix_solib_create_inferior_hook;
  582. solib_aix_so_ops.current_sos = solib_aix_current_sos;
  583. solib_aix_so_ops.open_symbol_file_object
  584. = solib_aix_open_symbol_file_object;
  585. solib_aix_so_ops.in_dynsym_resolve_code
  586. = solib_aix_in_dynsym_resolve_code;
  587. solib_aix_so_ops.bfd_open = solib_aix_bfd_open;
  588. gdb::observers::normal_stop.attach (solib_aix_normal_stop_observer,
  589. "solib-aix");
  590. /* Debug this file's internals. */
  591. add_setshow_boolean_cmd ("aix-solib", class_maintenance,
  592. &solib_aix_debug, _("\
  593. Control the debugging traces for the solib-aix module."), _("\
  594. Show whether solib-aix debugging traces are enabled."), _("\
  595. When on, solib-aix debugging traces are enabled."),
  596. NULL,
  597. show_solib_aix_debug,
  598. &setdebuglist, &showdebuglist);
  599. }