1fd98b2af3773437487af0df22c428f3db630949awaylonis// Copyright (c) 2006, Google Inc. 2fd98b2af3773437487af0df22c428f3db630949awaylonis// All rights reserved. 3fd98b2af3773437487af0df22c428f3db630949awaylonis// 4fd98b2af3773437487af0df22c428f3db630949awaylonis// Redistribution and use in source and binary forms, with or without 5fd98b2af3773437487af0df22c428f3db630949awaylonis// modification, are permitted provided that the following conditions are 6fd98b2af3773437487af0df22c428f3db630949awaylonis// met: 7fd98b2af3773437487af0df22c428f3db630949awaylonis// 8fd98b2af3773437487af0df22c428f3db630949awaylonis// * Redistributions of source code must retain the above copyright 9fd98b2af3773437487af0df22c428f3db630949awaylonis// notice, this list of conditions and the following disclaimer. 10fd98b2af3773437487af0df22c428f3db630949awaylonis// * Redistributions in binary form must reproduce the above 11fd98b2af3773437487af0df22c428f3db630949awaylonis// copyright notice, this list of conditions and the following disclaimer 12fd98b2af3773437487af0df22c428f3db630949awaylonis// in the documentation and/or other materials provided with the 13fd98b2af3773437487af0df22c428f3db630949awaylonis// distribution. 14fd98b2af3773437487af0df22c428f3db630949awaylonis// * Neither the name of Google Inc. nor the names of its 15fd98b2af3773437487af0df22c428f3db630949awaylonis// contributors may be used to endorse or promote products derived from 16fd98b2af3773437487af0df22c428f3db630949awaylonis// this software without specific prior written permission. 17fd98b2af3773437487af0df22c428f3db630949awaylonis// 18fd98b2af3773437487af0df22c428f3db630949awaylonis// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19fd98b2af3773437487af0df22c428f3db630949awaylonis// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20fd98b2af3773437487af0df22c428f3db630949awaylonis// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21fd98b2af3773437487af0df22c428f3db630949awaylonis// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22fd98b2af3773437487af0df22c428f3db630949awaylonis// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23fd98b2af3773437487af0df22c428f3db630949awaylonis// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24fd98b2af3773437487af0df22c428f3db630949awaylonis// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25fd98b2af3773437487af0df22c428f3db630949awaylonis// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26fd98b2af3773437487af0df22c428f3db630949awaylonis// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27fd98b2af3773437487af0df22c428f3db630949awaylonis// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28fd98b2af3773437487af0df22c428f3db630949awaylonis// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29e5dc60822e5938fea2ae892ccddb906641ba174emmentovai 30fd98b2af3773437487af0df22c428f3db630949awaylonis// macho_walker.h: Iterate over the load commands in a mach-o file 31fd98b2af3773437487af0df22c428f3db630949awaylonis// 32fd98b2af3773437487af0df22c428f3db630949awaylonis// Author: Dan Waylonis 33fd98b2af3773437487af0df22c428f3db630949awaylonis 34fd98b2af3773437487af0df22c428f3db630949awaylonis#ifndef COMMON_MAC_MACHO_WALKER_H__ 35fd98b2af3773437487af0df22c428f3db630949awaylonis#define COMMON_MAC_MACHO_WALKER_H__ 36fd98b2af3773437487af0df22c428f3db630949awaylonis 37b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org#include <mach/machine.h> 38fd98b2af3773437487af0df22c428f3db630949awaylonis#include <mach-o/loader.h> 39fd98b2af3773437487af0df22c428f3db630949awaylonis#include <sys/types.h> 40fd98b2af3773437487af0df22c428f3db630949awaylonis 41fd98b2af3773437487af0df22c428f3db630949awaylonisnamespace MacFileUtilities { 42fd98b2af3773437487af0df22c428f3db630949awaylonis 43fd98b2af3773437487af0df22c428f3db630949awaylonisclass MachoWalker { 44fd98b2af3773437487af0df22c428f3db630949awaylonis public: 45fd98b2af3773437487af0df22c428f3db630949awaylonis // A callback function executed when a new load command is read. If no 46fd98b2af3773437487af0df22c428f3db630949awaylonis // further processing of load commands is desired, return false. Otherwise, 47fd98b2af3773437487af0df22c428f3db630949awaylonis // return true. 48fd98b2af3773437487af0df22c428f3db630949awaylonis // |cmd| is the current command, and |offset| is the location relative to the 49fd98b2af3773437487af0df22c428f3db630949awaylonis // beginning of the file (not header) where the command was read. If |swap| 50fd98b2af3773437487af0df22c428f3db630949awaylonis // is set, then any command data (other than the returned load_command) should 51fd98b2af3773437487af0df22c428f3db630949awaylonis // be swapped when read 52fd98b2af3773437487af0df22c428f3db630949awaylonis typedef bool (*LoadCommandCallback)(MachoWalker *walker, load_command *cmd, 53fd98b2af3773437487af0df22c428f3db630949awaylonis off_t offset, bool swap, void *context); 54fd98b2af3773437487af0df22c428f3db630949awaylonis 55fd98b2af3773437487af0df22c428f3db630949awaylonis MachoWalker(const char *path, LoadCommandCallback callback, void *context); 568fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org MachoWalker(void *memory, size_t size, LoadCommandCallback callback, 578fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org void *context); 58fd98b2af3773437487af0df22c428f3db630949awaylonis ~MachoWalker(); 59fd98b2af3773437487af0df22c428f3db630949awaylonis 60b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org // Begin walking the header for |cpu_type| and |cpu_subtype|. If |cpu_type| 61b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org // is 0, then the native cpu type is used. Otherwise, accepted values are 62b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org // listed in /usr/include/mach/machine.h (e.g., CPU_TYPE_X86 or 63b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org // CPU_TYPE_POWERPC). If |cpu_subtype| is CPU_SUBTYPE_MULTIPLE, the match is 64b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org // only done on |cpu_type|. 65b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org // Returns false if opening the file failed or if the |cpu_type|/|cpu_subtype| 66b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org // is not present in the file. 67b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org bool WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype); 68fd98b2af3773437487af0df22c428f3db630949awaylonis 69fd98b2af3773437487af0df22c428f3db630949awaylonis // Read |size| bytes from the opened file at |offset| into |buffer| 70fd98b2af3773437487af0df22c428f3db630949awaylonis bool ReadBytes(void *buffer, size_t size, off_t offset); 718fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org 72983264848d5372d8e64d62eb67f672c71e4b6470waylonis // Return the current header and header offset 73983264848d5372d8e64d62eb67f672c71e4b6470waylonis bool CurrentHeader(struct mach_header_64 *header, off_t *offset); 74fd98b2af3773437487af0df22c428f3db630949awaylonis 75fd98b2af3773437487af0df22c428f3db630949awaylonis private: 76b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org // Locate (if any) the header offset for |cpu_type| and return in |offset|. 77b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org // Return true if found, false otherwise. 78b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org bool FindHeader(cpu_type_t cpu_type, 79b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org cpu_subtype_t cpu_subtype, 80b2cb7ad7bc83205d23f77b660438bf8e8d16fcb5qsr@chromium.org off_t &offset); 81fd98b2af3773437487af0df22c428f3db630949awaylonis 82fd98b2af3773437487af0df22c428f3db630949awaylonis // Process an individual header starting at |offset| from the start of the 83fd98b2af3773437487af0df22c428f3db630949awaylonis // file. Return true if successful, false otherwise. 84fd98b2af3773437487af0df22c428f3db630949awaylonis bool WalkHeaderAtOffset(off_t offset); 85fd98b2af3773437487af0df22c428f3db630949awaylonis bool WalkHeader64AtOffset(off_t offset); 86fd98b2af3773437487af0df22c428f3db630949awaylonis 87fd98b2af3773437487af0df22c428f3db630949awaylonis // Bottleneck for walking the load commands 88fd98b2af3773437487af0df22c428f3db630949awaylonis bool WalkHeaderCore(off_t offset, uint32_t number_of_commands, bool swap); 89fd98b2af3773437487af0df22c428f3db630949awaylonis 90fd98b2af3773437487af0df22c428f3db630949awaylonis // File descriptor to the opened file 91fd98b2af3773437487af0df22c428f3db630949awaylonis int file_; 92fd98b2af3773437487af0df22c428f3db630949awaylonis 938fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org // Memory location to read from. 948fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org void *memory_; 958fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org 968fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org // Size of the memory segment we can read from. 978fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org size_t memory_size_; 988fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org 99fd98b2af3773437487af0df22c428f3db630949awaylonis // User specified callback & context 100fd98b2af3773437487af0df22c428f3db630949awaylonis LoadCommandCallback callback_; 101fd98b2af3773437487af0df22c428f3db630949awaylonis void *callback_context_; 1028fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org 103983264848d5372d8e64d62eb67f672c71e4b6470waylonis // Current header, size, and offset. The mach_header_64 is used for both 104983264848d5372d8e64d62eb67f672c71e4b6470waylonis // 32-bit and 64-bit headers because they only differ in their last field 1058fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org // (reserved). By adding the |current_header_size_| and the 106983264848d5372d8e64d62eb67f672c71e4b6470waylonis // |current_header_offset_|, you can determine the offset in the file just 107983264848d5372d8e64d62eb67f672c71e4b6470waylonis // after the header. 108983264848d5372d8e64d62eb67f672c71e4b6470waylonis struct mach_header_64 *current_header_; 109983264848d5372d8e64d62eb67f672c71e4b6470waylonis unsigned long current_header_size_; 110983264848d5372d8e64d62eb67f672c71e4b6470waylonis off_t current_header_offset_; 1118fac6df2a0dfbfe7512c3f6616cda4cbac4f0d9dqsr@chromium.org 1124ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach private: 1134ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach MachoWalker(const MachoWalker &); 1144ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach MachoWalker &operator=(const MachoWalker &); 115fd98b2af3773437487af0df22c428f3db630949awaylonis}; 116fd98b2af3773437487af0df22c428f3db630949awaylonis 117fd98b2af3773437487af0df22c428f3db630949awaylonis} // namespace MacFileUtilities 118fd98b2af3773437487af0df22c428f3db630949awaylonis 119fd98b2af3773437487af0df22c428f3db630949awaylonis#endif // COMMON_MAC_MACHO_WALKER_H__ 120