Chromium Code Reviews| 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); |
| }; |