Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Unified Diff: util/mac/mach_o_image_reader.h

Issue 539263003: Add MachOImageSymbolTableReader and hook it up to MachOImageReader (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Fix 32-bit x86 Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | util/mac/mach_o_image_reader.cc » ('j') | util/mac/mach_o_image_reader_test.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: util/mac/mach_o_image_reader.h
diff --git a/util/mac/mach_o_image_reader.h b/util/mac/mach_o_image_reader.h
index eb2435486361172dc7def5e4aa240768e724bda3..70f557dbc1ec0d25cfb2e2d219bbbfabb977e282 100644
--- a/util/mac/mach_o_image_reader.h
+++ b/util/mac/mach_o_image_reader.h
@@ -31,6 +31,7 @@
namespace crashpad {
class MachOImageSegmentReader;
+class MachOImageSymbolTableReader;
class ProcessReader;
//! \brief A reader for Mach-O images mapped into another process.
@@ -162,6 +163,8 @@ class MachOImageReader {
//! \param[in] index The index of the section to return, in the order that it
//! appears in the segment load commands. This is a 1-based index,
//! matching the section number values used for `nlist::n_sect`.
+ //! \param[out] containing_segment The segment that contains the section.
+ //! This parameter can be `NULL`.
Robert Sesek 2014/09/05 19:04:16 Ownership/lifetime?
//! \param[out] address The actual address that the section was loaded at in
//! memory, taking any “slide” into account if the section did not load at
//! its preferred address as stored in the Mach-O image file. This
@@ -186,8 +189,50 @@ class MachOImageReader {
//! and handled non-fatally by reporting the error to the caller.
const process_types::section* GetSectionAtIndex(
size_t index,
+ const MachOImageSegmentReader** containing_segment,
mach_vm_address_t* address) const;
+ //! \brief Looks up a symbol in the image’s symbol table.
+ //!
+ //! This method is capable of locating external defined symbols: those without
+ //! `N_STAB` (debugging) or `N_PEXT` (private external) set, and with `N_EXT`
+ //! (external) set. Only `N_ABS` (absolute) and `N_SECT` (defined in section)
+ //! symbols are supported. `N_UNDF` (undefined) and `N_INDR` (indirect)
+ //! symbols cannot be located through this mechanism, nor can `N_PEXT`
Robert Sesek 2014/09/05 19:04:16 This sounds contradictory to what you wrote on lin
+ //! (private external) symbols.
+ //!
+ //! \param[in] name The name of the symbol to look up, “mangled” or
+ //! “decorated” appropriately. For example, use `"_main"` to look up the
+ //! symbol for the C `main()` function, and use `"__Z4Funcv"` to look up
+ //! the symbol for the C++ `Func()` function. Contrary to `dlsym()`, the
+ //! leading underscore must not be stripped when using this interface.
+ //! \param[out] value If the lookup was successful, this will be set to the
+ //! value of the symbol, adjusted for any “slide” as needed. The value can
+ //! be used as an address in the remote process’ address space where the
+ //! pointee of the symbol exists in memory.
+ //!
+ //! \return `true` if the symbol lookup was successful and the symbol was
+ //! found. `false` otherwise, including error conditions (for which a
+ //! warning message will be logged), modules without symbol tables, and
+ //! symbol names not found in the symbol table.
+ //!
+ //! \note Symbol values returned via this interface are adjusted for “slide”
+ //! as appropriate, in contrast to the underlying implementation,
+ //! MachOImageSymbolTableReader::LookUpExternalDefinedSymbol().
+ //!
+ //! \warning Symbols that are resolved by running symbol resolvers
+ //! (`.symbol_resolver`) are not properly handled by this interface. The
+ //! address of the symbol resolver is returned because that’s what shows
+ //! up in the symbol table, rather than the effective address of the
+ //! resolved symbol as used by dyld after running the resolver. The only
+ //! way to detect this situation would be to read the `LC_DYLD_INFO` or
+ //! `LC_DYLD_INFO_ONLY` load command if present and looking for the
+ //! `EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER` flag, but that would just be
+ //! able to detect symbols with a resolver, it would not be able to
+ //! resolve them from out-of-process, so it’s not currently done.
+ bool LookUpExternalDefinedSymbol(const std::string& name,
+ mach_vm_address_t* value) const;
+
//! \brief Returns a Mach-O dylib image’s current version.
//!
//! This information comes from the `dylib_current_version` field of a dylib’s
@@ -255,6 +300,19 @@ class MachOImageReader {
bool ReadUnexpectedCommand(mach_vm_address_t load_command_address,
const std::string& load_command_info);
+ // Performs deferred initialization of the symbol table. Because a module’s
+ // symbol table is often not needed, this is not handled in Initialize(), but
+ // is done lazily, on-demand as needed.
+ //
+ // symbol_table_initialized_ will be transitioned to the appropriate state. If
+ // initialization completes successfully, this will be the valid state.
+ // Otherwise, it will be left in the invalid state and a warning message will
+ // be logged.
+ //
+ // Note that if the object contains no symbol table, symbol_table_initialized_
+ // will be set to the valid state, but symbol_table_ will be NULL.
+ void InitializeSymbolTable() const;
+
PointerVector<MachOImageSegmentReader> segments_;
std::map<std::string, size_t> segment_map_;
std::string module_info_;
@@ -266,11 +324,25 @@ class MachOImageReader {
uint64_t source_version_;
scoped_ptr<process_types::symtab_command> symtab_command_;
scoped_ptr<process_types::dysymtab_command> dysymtab_command_;
+
+ // symbol_table_ (and symbol_table_initialized_) are mutable in order to
+ // maintain LookUpExternalDefinedSymbol() as a const interface while allowing
+ // lazy initialization via InitializeSymbolTable(). This is logical
+ // const-ness, not physical const-ness.
+ mutable scoped_ptr<MachOImageSymbolTableReader> symbol_table_;
+
scoped_ptr<process_types::dylib_command> id_dylib_command_;
ProcessReader* process_reader_; // weak
uint32_t file_type_;
InitializationStateDcheck initialized_;
+ // symbol_table_initialized_ protects symbol_table_: symbol_table_ can only
Robert Sesek 2014/09/05 19:04:16 Why are there members between the state and the ta
Mark Mentovai 2014/09/05 20:22:31 rsesek wrote:
+ // be used when symbol_table_initialized_ is valid, although
+ // symbol_table_initialized_ being valid doesn’t imply that symbol_table_ is
+ // set. symbol_table_initialized_ will be valid without symbol_table_ being
+ // set in modules that have no symbol table.
+ mutable InitializationState symbol_table_initialized_;
+
DISALLOW_COPY_AND_ASSIGN(MachOImageReader);
};
« no previous file with comments | « no previous file | util/mac/mach_o_image_reader.cc » ('j') | util/mac/mach_o_image_reader_test.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698