+/* Helper function for psym_find_compunit_symtab_by_address that fills
+ in psymbol_map for a given range of psymbols. */
+
+static void
+psym_fill_psymbol_map (struct objfile *objfile,
+ struct partial_symtab *psymtab,
+ std::set<CORE_ADDR> *seen_addrs,
+ const std::vector<partial_symbol *> &symbols,
+ int start,
+ int length)
+{
+ for (int i = 0; i < length; ++i)
+ {
+ struct partial_symbol *psym = symbols[start + i];
+
+ if (psym->aclass == LOC_STATIC)
+ {
+ CORE_ADDR addr = psym->address (objfile);
+ if (seen_addrs->find (addr) == seen_addrs->end ())
+ {
+ seen_addrs->insert (addr);
+ objfile->psymbol_map.emplace_back (addr, psymtab);
+ }
+ }
+ }
+}
+
+/* See find_compunit_symtab_by_address in quick_symbol_functions, in
+ symfile.h. */
+
+static compunit_symtab *
+psym_find_compunit_symtab_by_address (struct objfile *objfile,
+ CORE_ADDR address)
+{
+ if (objfile->psymbol_map.empty ())
+ {
+ struct partial_symtab *pst;
+
+ std::set<CORE_ADDR> seen_addrs;
+
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
+ {
+ psym_fill_psymbol_map (objfile, pst,
+ &seen_addrs,
+ objfile->global_psymbols,
+ pst->globals_offset,
+ pst->n_global_syms);
+ psym_fill_psymbol_map (objfile, pst,
+ &seen_addrs,
+ objfile->static_psymbols,
+ pst->statics_offset,
+ pst->n_static_syms);
+ }
+
+ objfile->psymbol_map.shrink_to_fit ();
+
+ std::sort (objfile->psymbol_map.begin (), objfile->psymbol_map.end (),
+ [] (const std::pair<CORE_ADDR, partial_symtab *> &a,
+ const std::pair<CORE_ADDR, partial_symtab *> &b)
+ {
+ return a.first < b.first;
+ });
+ }
+
+ auto iter = std::lower_bound
+ (objfile->psymbol_map.begin (), objfile->psymbol_map.end (), address,
+ [] (const std::pair<CORE_ADDR, partial_symtab *> &a,
+ CORE_ADDR b)
+ {
+ return a.first < b;
+ });
+
+ if (iter == objfile->psymbol_map.end () || iter->first != address)
+ return NULL;
+
+ return psymtab_to_symtab (objfile, iter->second);
+}
+