blob: a268e1363cbd733fffab15840aea438d3c662364 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <map>
#include <memory>
#include "garnet/bin/zxdb/common/err.h"
#include "garnet/bin/zxdb/symbols/build_id_index.h"
#include "garnet/public/lib/fxl/macros.h"
#include "garnet/public/lib/fxl/memory/ref_counted.h"
namespace zxdb {
class ModuleSymbols;
// Tracks a global view of all ModuleSymbols objects. Since each object is
// independent of load address, we can share these between processes that
// load the same binary.
//
// This is an internal object but since there is no public API, there is no
// "Impl" split.
class SystemSymbols {
public:
// A reference-counted holder for the ModuleSymbols object. This object
// will notify the owning SystemSymbols object when all references have
// been destroyed.
class ModuleRef : public fxl::RefCountedThreadSafe<ModuleRef> {
public:
ModuleRef(SystemSymbols* system_symbols,
std::unique_ptr<ModuleSymbols> module_symbols);
ModuleSymbols* module_symbols() { return module_symbols_.get(); }
const ModuleSymbols* module_symbols() const {
return module_symbols_.get();
}
// Notification from SystemSymbols that it's being deleted and no callbacks
// should be issued on the pointer.
void SystemSymbolsDeleting();
private:
FRIEND_REF_COUNTED_THREAD_SAFE(ModuleRef);
~ModuleRef();
// May be null to indicate the SystemSymbols object is deleted.
SystemSymbols* system_symbols_;
std::unique_ptr<ModuleSymbols> module_symbols_;
};
SystemSymbols();
~SystemSymbols();
// Returns the directory to which paths are relative.
const std::string& build_dir() const { return build_dir_; }
BuildIDIndex& build_id_index() { return build_id_index_; }
// Injects a ModuleSymbols object for the given build ID. Used for testing.
// Normally the test would provide a dummy implementation for ModuleSymbols.
// Ownership of the symbols will be transferred to the returned refcounted
// ModuleRef. As long as this is alive, the build id -> module mapping will
// remain in the SystemSymbols object.
fxl::RefPtr<ModuleRef> InjectModuleForTesting(
const std::string& build_id, std::unique_ptr<ModuleSymbols> module);
// Retrieves the symbols for the module with the given build ID. If the
// module's symbols have already been loaded, just puts an owning reference
// into the given out param. If not, the symbols will be loaded.
//
// This function uses the build_id for loading symbols. The name is only
// used for generating informational messages.
Err GetModule(const std::string& name_for_msg, const std::string& build_id,
fxl::RefPtr<ModuleRef>* module);
private:
friend ModuleRef;
// Notification from the ModuleRef that all references have been deleted and
// the tracking information should be removed from the map.
void WillDeleteModule(ModuleRef* module);
// The directory to which paths are relative.
std::string build_dir_;
BuildIDIndex build_id_index_;
// Index from module build ID to a non-owning ModuleRef pointer. The
// ModuleRef will notify us when it's being deleted so the pointers stay
// up-to-date.
std::map<std::string, ModuleRef*> modules_;
FXL_DISALLOW_COPY_AND_ASSIGN(SystemSymbols);
};
} // namespace zxdb