+static int
+oso_el_compare_name (const void *vl, const void *vr)
+{
+ const oso_el *l = (const oso_el *)vl;
+ const oso_el *r = (const oso_el *)vr;
+
+ return strcmp (l->name, r->name);
+}
+
+/* Add an oso file as a symbol file. */
+
+static void
+macho_add_oso_symfile (oso_el *oso, bfd *abfd,
+ struct objfile *main_objfile, int symfile_flags)
+{
+ struct objfile *objfile;
+ int i;
+ char leading_char;
+
+ if (mach_o_debug_level > 0)
+ printf_unfiltered (_("Loading symbols from oso: %s\n"), oso->name);
+
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ warning (_("`%s': can't read symbols: %s."), oso->name,
+ bfd_errmsg (bfd_get_error ()));
+ bfd_close (abfd);
+ return;
+ }
+
+ bfd_set_cacheable (abfd, 1);
+
+ /* Relocate sections. */
+
+ leading_char = bfd_get_symbol_leading_char (main_objfile->obfd);
+
+ for (i = 0; i < oso->num_sections; i++)
+ {
+ asection *sect;
+ const char *sectname;
+ bfd_vma vma;
+
+ /* Empty slot. */
+ if (oso->symbols[i] == NULL)
+ continue;
+
+ if (oso->offsets[i])
+ vma = oso->offsets[i];
+ else
+ {
+ struct minimal_symbol *msym;
+ const char *name = oso->symbols[i]->name;
+
+ if (name[0] == leading_char)
+ ++name;
+
+ if (mach_o_debug_level > 3)
+ printf_unfiltered (_("resolve sect %s with %s\n"),
+ oso->symbols[i]->section->name,
+ oso->symbols[i]->name);
+ msym = lookup_minimal_symbol (name, NULL, main_objfile);
+ if (msym == NULL)
+ {
+ warning (_("can't find symbol '%s' in minsymtab"), name);
+ continue;
+ }
+ else
+ vma = SYMBOL_VALUE_ADDRESS (msym);
+ }
+ sectname = (char *)oso->symbols[i]->section->name;
+
+ sect = bfd_get_section_by_name (abfd, sectname);
+ if (sect == NULL)
+ {
+ warning (_("can't find section '%s' in OSO file %s"),
+ sectname, oso->name);
+ continue;
+ }
+ bfd_set_section_vma (abfd, sect, vma);
+
+ if (mach_o_debug_level > 1)
+ printf_unfiltered (_(" %s: %s\n"),
+ core_addr_to_string (vma), sectname);
+ }
+
+ /* Make sure that the filename was malloc'ed. The current filename comes
+ either from an OSO symbol name or from an archive name. Memory for both
+ is not managed by gdb. */
+ abfd->filename = xstrdup (abfd->filename);
+
+ gdb_assert (current_oso.symbol_table == NULL);
+ current_oso.main_objfile = main_objfile;
+
+ /* We need to clear SYMFILE_MAINLINE to avoid interractive question
+ from symfile.c:symbol_file_add_with_addrs_or_offsets. */
+ objfile = symbol_file_add_from_bfd
+ (abfd, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE), NULL,
+ main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED
+ | OBJF_READNOW | OBJF_USERLOADED));
+ add_separate_debug_objfile (objfile, main_objfile);
+
+ current_oso.main_objfile = NULL;
+ if (current_oso.symbol_table)
+ {
+ xfree (current_oso.symbol_table);
+ current_oso.symbol_table = NULL;
+ }
+}
+