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

Side by Side 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 unified diff | 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')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Crashpad Authors. All rights reserved. 1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 13 matching lines...) Expand all
24 #include "base/basictypes.h" 24 #include "base/basictypes.h"
25 #include "base/memory/scoped_ptr.h" 25 #include "base/memory/scoped_ptr.h"
26 #include "util/misc/initialization_state_dcheck.h" 26 #include "util/misc/initialization_state_dcheck.h"
27 #include "util/misc/uuid.h" 27 #include "util/misc/uuid.h"
28 #include "util/stdlib/pointer_container.h" 28 #include "util/stdlib/pointer_container.h"
29 #include "util/mac/process_types.h" 29 #include "util/mac/process_types.h"
30 30
31 namespace crashpad { 31 namespace crashpad {
32 32
33 class MachOImageSegmentReader; 33 class MachOImageSegmentReader;
34 class MachOImageSymbolTableReader;
34 class ProcessReader; 35 class ProcessReader;
35 36
36 //! \brief A reader for Mach-O images mapped into another process. 37 //! \brief A reader for Mach-O images mapped into another process.
37 //! 38 //!
38 //! This class is capable of reading both 32-bit (`mach_header`/`MH_MAGIC`) and 39 //! This class is capable of reading both 32-bit (`mach_header`/`MH_MAGIC`) and
39 //! 64-bit (`mach_header_64`/`MH_MAGIC_64`) images based on the bitness of the 40 //! 64-bit (`mach_header_64`/`MH_MAGIC_64`) images based on the bitness of the
40 //! remote process. 41 //! remote process.
41 class MachOImageReader { 42 class MachOImageReader {
42 public: 43 public:
43 MachOImageReader(); 44 MachOImageReader();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 const process_types::section* GetSectionByName( 156 const process_types::section* GetSectionByName(
156 const std::string& segment_name, 157 const std::string& segment_name,
157 const std::string& section_name, 158 const std::string& section_name,
158 mach_vm_address_t* address) const; 159 mach_vm_address_t* address) const;
159 160
160 //! \brief Obtain section information by section index. 161 //! \brief Obtain section information by section index.
161 //! 162 //!
162 //! \param[in] index The index of the section to return, in the order that it 163 //! \param[in] index The index of the section to return, in the order that it
163 //! appears in the segment load commands. This is a 1-based index, 164 //! appears in the segment load commands. This is a 1-based index,
164 //! matching the section number values used for `nlist::n_sect`. 165 //! matching the section number values used for `nlist::n_sect`.
166 //! \param[out] containing_segment The segment that contains the section.
167 //! This parameter can be `NULL`.
Robert Sesek 2014/09/05 19:04:16 Ownership/lifetime?
165 //! \param[out] address The actual address that the section was loaded at in 168 //! \param[out] address The actual address that the section was loaded at in
166 //! memory, taking any “slide” into account if the section did not load at 169 //! memory, taking any “slide” into account if the section did not load at
167 //! its preferred address as stored in the Mach-O image file. This 170 //! its preferred address as stored in the Mach-O image file. This
168 //! parameter can be `NULL`. 171 //! parameter can be `NULL`.
169 //! 172 //!
170 //! \return A pointer to the section information. If \a index is out of range, 173 //! \return A pointer to the section information. If \a index is out of range,
171 //! logs a warning and returns `NULL`. 174 //! logs a warning and returns `NULL`.
172 //! 175 //!
173 //! No parameter is provided for the section’s size, because it can be 176 //! No parameter is provided for the section’s size, because it can be
174 //! obtained from the returned process_types::section::size field. 177 //! obtained from the returned process_types::section::size field.
175 //! 178 //!
176 //! \note The process_types::section::addr field gives the section’s preferred 179 //! \note The process_types::section::addr field gives the section’s preferred
177 //! load address as stored in the Mach-O image file, and is not adjusted 180 //! load address as stored in the Mach-O image file, and is not adjusted
178 //! for any “slide” that may have occurred when the image was loaded. Use 181 //! for any “slide” that may have occurred when the image was loaded. Use
179 //! \a address to obtain the section’s actual load address. 182 //! \a address to obtain the section’s actual load address.
180 //! \note Unlike MachOImageSegmentReader::GetSectionAtIndex(), this method 183 //! \note Unlike MachOImageSegmentReader::GetSectionAtIndex(), this method
181 //! accepts out-of-range values for \a index, and returns `NULL` instead 184 //! accepts out-of-range values for \a index, and returns `NULL` instead
182 //! of aborting execution upon encountering an out-of-range value. This is 185 //! of aborting execution upon encountering an out-of-range value. This is
183 //! because a Mach-O image file’s symbol table refers to this per-module 186 //! because a Mach-O image file’s symbol table refers to this per-module
184 //! section index, and an out-of-range index in that case should be 187 //! section index, and an out-of-range index in that case should be
185 //! treated as a data error (where the data is beyond this code’s control) 188 //! treated as a data error (where the data is beyond this code’s control)
186 //! and handled non-fatally by reporting the error to the caller. 189 //! and handled non-fatally by reporting the error to the caller.
187 const process_types::section* GetSectionAtIndex( 190 const process_types::section* GetSectionAtIndex(
188 size_t index, 191 size_t index,
192 const MachOImageSegmentReader** containing_segment,
189 mach_vm_address_t* address) const; 193 mach_vm_address_t* address) const;
190 194
195 //! \brief Looks up a symbol in the image’s symbol table.
196 //!
197 //! This method is capable of locating external defined symbols: those without
198 //! `N_STAB` (debugging) or `N_PEXT` (private external) set, and with `N_EXT`
199 //! (external) set. Only `N_ABS` (absolute) and `N_SECT` (defined in section)
200 //! symbols are supported. `N_UNDF` (undefined) and `N_INDR` (indirect)
201 //! 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
202 //! (private external) symbols.
203 //!
204 //! \param[in] name The name of the symbol to look up, “mangled” or
205 //! “decorated” appropriately. For example, use `"_main"` to look up the
206 //! symbol for the C `main()` function, and use `"__Z4Funcv"` to look up
207 //! the symbol for the C++ `Func()` function. Contrary to `dlsym()`, the
208 //! leading underscore must not be stripped when using this interface.
209 //! \param[out] value If the lookup was successful, this will be set to the
210 //! value of the symbol, adjusted for any “slide” as needed. The value can
211 //! be used as an address in the remote process’ address space where the
212 //! pointee of the symbol exists in memory.
213 //!
214 //! \return `true` if the symbol lookup was successful and the symbol was
215 //! found. `false` otherwise, including error conditions (for which a
216 //! warning message will be logged), modules without symbol tables, and
217 //! symbol names not found in the symbol table.
218 //!
219 //! \note Symbol values returned via this interface are adjusted for “slide”
220 //! as appropriate, in contrast to the underlying implementation,
221 //! MachOImageSymbolTableReader::LookUpExternalDefinedSymbol().
222 //!
223 //! \warning Symbols that are resolved by running symbol resolvers
224 //! (`.symbol_resolver`) are not properly handled by this interface. The
225 //! address of the symbol resolver is returned because that’s what shows
226 //! up in the symbol table, rather than the effective address of the
227 //! resolved symbol as used by dyld after running the resolver. The only
228 //! way to detect this situation would be to read the `LC_DYLD_INFO` or
229 //! `LC_DYLD_INFO_ONLY` load command if present and looking for the
230 //! `EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER` flag, but that would just be
231 //! able to detect symbols with a resolver, it would not be able to
232 //! resolve them from out-of-process, so it’s not currently done.
233 bool LookUpExternalDefinedSymbol(const std::string& name,
234 mach_vm_address_t* value) const;
235
191 //! \brief Returns a Mach-O dylib image’s current version. 236 //! \brief Returns a Mach-O dylib image’s current version.
192 //! 237 //!
193 //! This information comes from the `dylib_current_version` field of a dylib’s 238 //! This information comes from the `dylib_current_version` field of a dylib’s
194 //! `LC_ID_DYLIB` load command. For dylibs without this load command, `0` will 239 //! `LC_ID_DYLIB` load command. For dylibs without this load command, `0` will
195 //! be returned. 240 //! be returned.
196 //! 241 //!
197 //! This method may only be called on Mach-O images for which FileType() 242 //! This method may only be called on Mach-O images for which FileType()
198 //! returns `MH_DYLIB`. 243 //! returns `MH_DYLIB`.
199 uint32_t DylibVersion() const; 244 uint32_t DylibVersion() const;
200 245
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 const std::string& load_command_info); 293 const std::string& load_command_info);
249 bool ReadDylinkerCommand(mach_vm_address_t load_command_address, 294 bool ReadDylinkerCommand(mach_vm_address_t load_command_address,
250 const std::string& load_command_info); 295 const std::string& load_command_info);
251 bool ReadUUIDCommand(mach_vm_address_t load_command_address, 296 bool ReadUUIDCommand(mach_vm_address_t load_command_address,
252 const std::string& load_command_info); 297 const std::string& load_command_info);
253 bool ReadSourceVersionCommand(mach_vm_address_t load_command_address, 298 bool ReadSourceVersionCommand(mach_vm_address_t load_command_address,
254 const std::string& load_command_info); 299 const std::string& load_command_info);
255 bool ReadUnexpectedCommand(mach_vm_address_t load_command_address, 300 bool ReadUnexpectedCommand(mach_vm_address_t load_command_address,
256 const std::string& load_command_info); 301 const std::string& load_command_info);
257 302
303 // Performs deferred initialization of the symbol table. Because a module’s
304 // symbol table is often not needed, this is not handled in Initialize(), but
305 // is done lazily, on-demand as needed.
306 //
307 // symbol_table_initialized_ will be transitioned to the appropriate state. If
308 // initialization completes successfully, this will be the valid state.
309 // Otherwise, it will be left in the invalid state and a warning message will
310 // be logged.
311 //
312 // Note that if the object contains no symbol table, symbol_table_initialized_
313 // will be set to the valid state, but symbol_table_ will be NULL.
314 void InitializeSymbolTable() const;
315
258 PointerVector<MachOImageSegmentReader> segments_; 316 PointerVector<MachOImageSegmentReader> segments_;
259 std::map<std::string, size_t> segment_map_; 317 std::map<std::string, size_t> segment_map_;
260 std::string module_info_; 318 std::string module_info_;
261 std::string dylinker_name_; 319 std::string dylinker_name_;
262 crashpad::UUID uuid_; 320 crashpad::UUID uuid_;
263 mach_vm_address_t address_; 321 mach_vm_address_t address_;
264 mach_vm_size_t size_; 322 mach_vm_size_t size_;
265 mach_vm_size_t slide_; 323 mach_vm_size_t slide_;
266 uint64_t source_version_; 324 uint64_t source_version_;
267 scoped_ptr<process_types::symtab_command> symtab_command_; 325 scoped_ptr<process_types::symtab_command> symtab_command_;
268 scoped_ptr<process_types::dysymtab_command> dysymtab_command_; 326 scoped_ptr<process_types::dysymtab_command> dysymtab_command_;
327
328 // symbol_table_ (and symbol_table_initialized_) are mutable in order to
329 // maintain LookUpExternalDefinedSymbol() as a const interface while allowing
330 // lazy initialization via InitializeSymbolTable(). This is logical
331 // const-ness, not physical const-ness.
332 mutable scoped_ptr<MachOImageSymbolTableReader> symbol_table_;
333
269 scoped_ptr<process_types::dylib_command> id_dylib_command_; 334 scoped_ptr<process_types::dylib_command> id_dylib_command_;
270 ProcessReader* process_reader_; // weak 335 ProcessReader* process_reader_; // weak
271 uint32_t file_type_; 336 uint32_t file_type_;
272 InitializationStateDcheck initialized_; 337 InitializationStateDcheck initialized_;
273 338
339 // 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:
340 // be used when symbol_table_initialized_ is valid, although
341 // symbol_table_initialized_ being valid doesn’t imply that symbol_table_ is
342 // set. symbol_table_initialized_ will be valid without symbol_table_ being
343 // set in modules that have no symbol table.
344 mutable InitializationState symbol_table_initialized_;
345
274 DISALLOW_COPY_AND_ASSIGN(MachOImageReader); 346 DISALLOW_COPY_AND_ASSIGN(MachOImageReader);
275 }; 347 };
276 348
277 } // namespace crashpad 349 } // namespace crashpad
278 350
279 #endif // CRASHPAD_UTIL_MAC_MACH_O_IMAGE_READER_H_ 351 #endif // CRASHPAD_UTIL_MAC_MACH_O_IMAGE_READER_H_
OLDNEW
« 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