gdb/solib-aix.c - gdb
Global variables defined
Data types defined
Functions defined
Source code
- #include "defs.h"
- #include "solib-aix.h"
- #include "solist.h"
- #include "inferior.h"
- #include "gdb_bfd.h"
- #include "gdbcore.h"
- #include "objfiles.h"
- #include "symtab.h"
- #include "xcoffread.h"
- #include "observer.h"
- #include "gdbcmd.h"
- static int solib_aix_debug;
- struct lm_info
- {
-
- char *filename;
-
- char *member_name;
-
- CORE_ADDR text_addr;
-
- ULONGEST text_size;
-
- CORE_ADDR data_addr;
-
- ULONGEST data_size;
- };
- typedef struct lm_info *lm_info_p;
- DEF_VEC_P(lm_info_p);
- static struct lm_info *
- solib_aix_new_lm_info (struct lm_info *info)
- {
- struct lm_info *result = xmalloc (sizeof (struct lm_info));
- memcpy (result, info, sizeof (struct lm_info));
- result->filename = xstrdup (info->filename);
- if (info->member_name != NULL)
- result->member_name = xstrdup (info->member_name);
- return result;
- }
- static void
- solib_aix_xfree_lm_info (struct lm_info *info)
- {
- xfree (info->filename);
- xfree (info->member_name);
- xfree (info);
- }
- struct solib_aix_inferior_data
- {
-
- VEC (lm_info_p) *library_list;
- };
- static const struct inferior_data *solib_aix_inferior_data_handle;
- static struct solib_aix_inferior_data *
- get_solib_aix_inferior_data (struct inferior *inf)
- {
- struct solib_aix_inferior_data *data;
- data = inferior_data (inf, solib_aix_inferior_data_handle);
- if (data == NULL)
- {
- data = XCNEW (struct solib_aix_inferior_data);
- set_inferior_data (inf, solib_aix_inferior_data_handle, data);
- }
- return data;
- }
- #if !defined(HAVE_LIBEXPAT)
- static VEC (lm_info_p) *
- solib_aix_parse_libraries (const char *library)
- {
- static int have_warned;
- if (!have_warned)
- {
- have_warned = 1;
- warning (_("Can not parse XML library list; XML support was disabled "
- "at compile time"));
- }
- return NULL;
- }
- static void
- solib_aix_free_library_list (void *p)
- {
- }
- #else
- #include "xml-support.h"
- 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)
- {
- VEC (lm_info_p) **list = user_data;
- struct lm_info *item = XCNEW (struct lm_info);
- struct gdb_xml_value *attr;
- attr = xml_find_attribute (attributes, "name");
- item->filename = xstrdup (attr->value);
- attr = xml_find_attribute (attributes, "member");
- if (attr != NULL)
- item->member_name = xstrdup (attr->value);
- attr = xml_find_attribute (attributes, "text_addr");
- item->text_addr = * (ULONGEST *) attr->value;
- attr = xml_find_attribute (attributes, "text_size");
- item->text_size = * (ULONGEST *) attr->value;
- attr = xml_find_attribute (attributes, "data_addr");
- item->data_addr = * (ULONGEST *) attr->value;
- attr = xml_find_attribute (attributes, "data_size");
- item->data_size = * (ULONGEST *) attr->value;
- VEC_safe_push (lm_info_p, *list, item);
- }
- 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)
- {
- char *version = xml_find_attribute (attributes, "version")->value;
- if (strcmp (version, "1.0") != 0)
- gdb_xml_error (parser,
- _("Library list has unsupported version \"%s\""),
- version);
- }
- static void
- solib_aix_free_library_list (void *p)
- {
- VEC (lm_info_p) **result = p;
- struct lm_info *info;
- int ix;
- if (solib_aix_debug)
- fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_library_list\n");
- for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++)
- solib_aix_xfree_lm_info (info);
- VEC_free (lm_info_p, *result);
- *result = NULL;
- }
- static const struct gdb_xml_attribute library_attributes[] =
- {
- { "name", GDB_XML_AF_NONE, NULL, NULL },
- { "member", GDB_XML_AF_OPTIONAL, NULL, NULL },
- { "text_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
- { "text_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
- { "data_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
- { "data_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
- { NULL, GDB_XML_AF_NONE, NULL, NULL }
- };
- static const struct gdb_xml_element library_list_children[] =
- {
- { "library", library_attributes, NULL,
- GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
- library_list_start_library, NULL},
- { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
- };
- static const struct gdb_xml_attribute library_list_attributes[] =
- {
- { "version", GDB_XML_AF_NONE, NULL, NULL },
- { NULL, GDB_XML_AF_NONE, NULL, NULL }
- };
- static const struct gdb_xml_element library_list_elements[] =
- {
- { "library-list-aix", library_list_attributes, library_list_children,
- GDB_XML_EF_NONE, library_list_start_list, NULL },
- { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
- };
- static VEC (lm_info_p) *
- solib_aix_parse_libraries (const char *library)
- {
- VEC (lm_info_p) *result = NULL;
- struct cleanup *back_to = make_cleanup (solib_aix_free_library_list,
- &result);
- if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd",
- library_list_elements, library, &result) == 0)
- {
-
- discard_cleanups (back_to);
- return result;
- }
- do_cleanups (back_to);
- return NULL;
- }
- #endif
- static VEC (lm_info_p) *
- solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
- {
- struct solib_aix_inferior_data *data;
- char *library_document;
- struct cleanup *cleanup;
-
- data = get_solib_aix_inferior_data (inf);
- if (data->library_list != NULL)
- return data->library_list;
- library_document = target_read_stralloc (¤t_target,
- TARGET_OBJECT_LIBRARIES_AIX,
- NULL);
- if (library_document == NULL && warning_msg != NULL)
- {
- warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
- warning_msg);
- return NULL;
- }
- cleanup = make_cleanup (xfree, library_document);
- if (solib_aix_debug)
- fprintf_unfiltered (gdb_stdlog,
- "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n",
- library_document);
- data->library_list = solib_aix_parse_libraries (library_document);
- if (data->library_list == NULL && warning_msg != NULL)
- {
- warning (_("%s (missing XML support?)"), warning_msg);
- do_cleanups (cleanup);
- return NULL;
- }
- do_cleanups (cleanup);
- return data->library_list;
- }
- static CORE_ADDR
- solib_aix_bss_data_overlap (bfd *abfd)
- {
- struct bfd_section *data_sect, *bss_sect;
- data_sect = bfd_get_section_by_name (abfd, ".data");
- if (data_sect == NULL)
- return 0;
- bss_sect = bfd_get_section_by_name (abfd, ".bss");
- if (bss_sect == NULL)
- return 0;
-
- if (bfd_section_vma (abfd, bss_sect)
- < bfd_section_vma (abfd, data_sect))
- return 0;
- if (bfd_section_vma (abfd, bss_sect)
- < bfd_section_vma (abfd, data_sect) + bfd_get_section_size (data_sect))
- return ((bfd_section_vma (abfd, data_sect)
- + bfd_get_section_size (data_sect))
- - bfd_section_vma (abfd, bss_sect));
- return 0;
- }
- static void
- solib_aix_relocate_section_addresses (struct so_list *so,
- struct target_section *sec)
- {
- struct bfd_section *bfd_sect = sec->the_bfd_section;
- bfd *abfd = bfd_sect->owner;
- const char *section_name = bfd_section_name (abfd, bfd_sect);
- struct lm_info *info = so->lm_info;
- if (strcmp (section_name, ".text") == 0)
- {
- sec->addr = info->text_addr;
- sec->endaddr = sec->addr + info->text_size;
-
- sec->addr += bfd_sect->filepos;
- }
- else if (strcmp (section_name, ".data") == 0)
- {
- sec->addr = info->data_addr;
- sec->endaddr = sec->addr + info->data_size;
- }
- else if (strcmp (section_name, ".bss") == 0)
- {
-
- struct bfd_section *data_sect
- = bfd_get_section_by_name (abfd, ".data");
- CORE_ADDR data_offset = 0;
- if (data_sect != NULL)
- data_offset = info->data_addr - bfd_section_vma (abfd, data_sect);
- sec->addr = bfd_section_vma (abfd, bfd_sect) + data_offset;
- sec->addr += solib_aix_bss_data_overlap (abfd);
- sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect);
- }
- else
- {
-
- sec->addr = bfd_section_vma (abfd, bfd_sect);
- sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect);
- }
- }
- static void
- solib_aix_free_so (struct so_list *so)
- {
- if (solib_aix_debug)
- fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n",
- so->so_name);
- solib_aix_xfree_lm_info (so->lm_info);
- }
- static void
- solib_aix_clear_solib (void)
- {
-
- }
- static struct section_offsets *
- solib_aix_get_section_offsets (struct objfile *objfile,
- struct lm_info *info)
- {
- struct section_offsets *offsets;
- bfd *abfd = objfile->obfd;
- int i;
- offsets = XCNEWVEC (struct section_offsets, objfile->num_sections);
-
- if (objfile->sect_index_text != -1)
- {
- struct bfd_section *sect
- = objfile->sections[objfile->sect_index_text].the_bfd_section;
- offsets->offsets[objfile->sect_index_text]
- = info->text_addr + sect->filepos - bfd_section_vma (abfd, sect);
- }
-
- if (objfile->sect_index_data != -1)
- {
- struct bfd_section *sect
- = objfile->sections[objfile->sect_index_data].the_bfd_section;
- offsets->offsets[objfile->sect_index_data]
- = info->data_addr - bfd_section_vma (abfd, sect);
- }
-
- if (objfile->sect_index_bss != -1
- && objfile->sect_index_data != -1)
- {
- offsets->offsets[objfile->sect_index_bss]
- = (offsets->offsets[objfile->sect_index_data]
- + solib_aix_bss_data_overlap (abfd));
- }
-
- return offsets;
- }
- static void
- solib_aix_solib_create_inferior_hook (int from_tty)
- {
- const char *warning_msg = "unable to relocate main executable";
- VEC (lm_info_p) *library_list;
- struct lm_info *exec_info;
-
- library_list = solib_aix_get_library_list (current_inferior (),
- warning_msg);
- if (library_list == NULL)
- return;
- if (VEC_length (lm_info_p, library_list) < 1)
- {
- warning (_("unable to relocate main executable (no info from loader)"));
- return;
- }
- exec_info = VEC_index (lm_info_p, library_list, 0);
- if (symfile_objfile != NULL)
- {
- struct section_offsets *offsets
- = solib_aix_get_section_offsets (symfile_objfile, exec_info);
- struct cleanup *cleanup = make_cleanup (xfree, offsets);
- objfile_relocate (symfile_objfile, offsets);
- do_cleanups (cleanup);
- }
- }
- static void
- solib_aix_special_symbol_handling (void)
- {
-
- }
- static struct so_list *
- solib_aix_current_sos (void)
- {
- struct so_list *start = NULL, *last = NULL;
- VEC (lm_info_p) *library_list;
- struct lm_info *info;
- int ix;
- library_list = solib_aix_get_library_list (current_inferior (), NULL);
- if (library_list == NULL)
- return NULL;
-
- for (ix = 1; VEC_iterate (lm_info_p, library_list, ix, info); ix++)
- {
- struct so_list *new_solib = XCNEW (struct so_list);
- char *so_name;
- if (info->member_name == NULL)
- {
-
- so_name = xstrdup (info->filename);
- }
- else
- {
-
- so_name = xstrprintf ("%s(%s)", info->filename, info->member_name);
- }
- strncpy (new_solib->so_original_name, so_name,
- SO_NAME_MAX_PATH_SIZE - 1);
- new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
- memcpy (new_solib->so_name, new_solib->so_original_name,
- SO_NAME_MAX_PATH_SIZE);
- new_solib->lm_info = solib_aix_new_lm_info (info);
-
- if (!start)
- last = start = new_solib;
- else
- {
- last->next = new_solib;
- last = new_solib;
- }
- }
- return start;
- }
- static int
- solib_aix_open_symbol_file_object (void *from_ttyp)
- {
- return 0;
- }
- static int
- solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
- {
- return 0;
- }
- static bfd *
- solib_aix_bfd_open (char *pathname)
- {
-
- FIXME
- const int path_len = strlen (pathname);
- char *sep;
- char *filename;
- int filename_len;
- char *member_name;
- bfd *archive_bfd, *object_bfd;
- struct cleanup *cleanup;
- if (pathname[path_len - 1] != ')')
- return solib_bfd_open (pathname);
-
- sep = strrchr (pathname, '(');
- if (sep == NULL)
- {
-
- warning (_("missing '(' in shared object pathname: %s"), pathname);
- return solib_bfd_open (pathname);
- }
- filename_len = sep - pathname;
- filename = xstrprintf ("%.*s", filename_len, pathname);
- cleanup = make_cleanup (xfree, filename);
- member_name = xstrprintf ("%.*s", path_len - filename_len - 2, sep + 1);
- make_cleanup (xfree, member_name);
- archive_bfd = gdb_bfd_open (filename, gnutarget, -1);
- if (archive_bfd == NULL)
- {
- warning (_("Could not open `%s' as an executable file: %s"),
- filename, bfd_errmsg (bfd_get_error ()));
- do_cleanups (cleanup);
- return NULL;
- }
- if (bfd_check_format (archive_bfd, bfd_object))
- {
- do_cleanups (cleanup);
- return archive_bfd;
- }
- if (! bfd_check_format (archive_bfd, bfd_archive))
- {
- warning (_("\"%s\": not in executable format: %s."),
- filename, bfd_errmsg (bfd_get_error ()));
- gdb_bfd_unref (archive_bfd);
- do_cleanups (cleanup);
- return NULL;
- }
- object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL);
- while (object_bfd != NULL)
- {
- bfd *next;
- if (strcmp (member_name, object_bfd->filename) == 0)
- break;
- next = gdb_bfd_openr_next_archived_file (archive_bfd, object_bfd);
- gdb_bfd_unref (object_bfd);
- object_bfd = next;
- }
- if (object_bfd == NULL)
- {
- warning (_("\"%s\": member \"%s\" missing."), filename, member_name);
- gdb_bfd_unref (archive_bfd);
- do_cleanups (cleanup);
- return NULL;
- }
- if (! bfd_check_format (object_bfd, bfd_object))
- {
- warning (_("%s(%s): not in object format: %s."),
- filename, member_name, bfd_errmsg (bfd_get_error ()));
- gdb_bfd_unref (archive_bfd);
- gdb_bfd_unref (object_bfd);
- do_cleanups (cleanup);
- return NULL;
- }
-
- xfree (bfd_get_filename (object_bfd));
- object_bfd->filename = xstrdup (pathname);
- gdb_bfd_unref (archive_bfd);
- do_cleanups (cleanup);
- return object_bfd;
- }
- FIXME
- static struct obj_section *
- data_obj_section_from_objfile (struct objfile *objfile)
- {
- struct obj_section *osect;
- ALL_OBJFILE_OSECTIONS (objfile, osect)
- if (strcmp (bfd_section_name (objfile->obfd, osect->the_bfd_section),
- ".data") == 0)
- return osect;
- return NULL;
- }
- CORE_ADDR
- solib_aix_get_toc_value (CORE_ADDR pc)
- {
- struct obj_section *pc_osect = find_pc_section (pc);
- struct obj_section *data_osect;
- CORE_ADDR result;
- if (pc_osect == NULL)
- error (_("unable to find TOC entry for pc %s "
- "(no section contains this PC)"),
- core_addr_to_string (pc));
- data_osect = data_obj_section_from_objfile (pc_osect->objfile);
- if (data_osect == NULL)
- error (_("unable to find TOC entry for pc %s "
- "(%s has no data section)"),
- core_addr_to_string (pc), objfile_name (pc_osect->objfile));
- result = (obj_section_addr (data_osect)
- + xcoff_get_toc_offset (pc_osect->objfile));
- if (solib_aix_debug)
- fprintf_unfiltered (gdb_stdlog,
- "DEBUG: solib_aix_get_toc_value (pc=%s) -> %s\n",
- core_addr_to_string (pc),
- core_addr_to_string (result));
- return result;
- }
- static void
- solib_aix_normal_stop_observer (struct bpstats *unused_1, int unused_2)
- {
- struct solib_aix_inferior_data *data
- = get_solib_aix_inferior_data (current_inferior ());
-
- solib_aix_free_library_list (&data->library_list);
- }
- static void
- show_solib_aix_debug (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
- {
- fprintf_filtered (file, _("solib-aix debugging is %s.\n"), value);
- }
- struct target_so_ops solib_aix_so_ops;
- extern initialize_file_ftype _initialize_solib_aix;
- void
- _initialize_solib_aix (void)
- {
- solib_aix_so_ops.relocate_section_addresses
- = solib_aix_relocate_section_addresses;
- solib_aix_so_ops.free_so = solib_aix_free_so;
- solib_aix_so_ops.clear_solib = solib_aix_clear_solib;
- solib_aix_so_ops.solib_create_inferior_hook
- = solib_aix_solib_create_inferior_hook;
- solib_aix_so_ops.special_symbol_handling
- = solib_aix_special_symbol_handling;
- solib_aix_so_ops.current_sos = solib_aix_current_sos;
- solib_aix_so_ops.open_symbol_file_object
- = solib_aix_open_symbol_file_object;
- solib_aix_so_ops.in_dynsym_resolve_code
- = solib_aix_in_dynsym_resolve_code;
- solib_aix_so_ops.bfd_open = solib_aix_bfd_open;
- solib_aix_inferior_data_handle = register_inferior_data ();
- observer_attach_normal_stop (solib_aix_normal_stop_observer);
-
- add_setshow_boolean_cmd ("aix-solib", class_maintenance,
- &solib_aix_debug, _("\
- Control the debugging traces for the solib-aix module."), _("\
- Show whether solib-aix debugging traces are enabled."), _("\
- When on, solib-aix debugging traces are enabled."),
- NULL,
- show_solib_aix_debug,
- &setdebuglist, &showdebuglist);
- }