Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | /* * Copyright (c) 2021 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #ifndef mach_o_SymbolTable_h #define mach_o_SymbolTable_h #include <stdint.h> #include <mach-o/nlist.h> #include <span> #include <vector> #include "Error.h" #include "MemoryBuffer.h" #include "Symbol.h" #ifndef N_LIB #define N_LIB 0x68 #endif namespace mach_o { struct DebugNoteFileInfo; /*! * @class NListSymbolTable * * @abstract * Class to encapsulate accessing and building an nlist symbol table in mach-o */ class VIS_HIDDEN NListSymbolTable { public: struct DebugNoteItem { uint64_t addr=0; uint64_t size=0; const char* name=nullptr; uint8_t type=0; uint8_t sectNum=0; }; struct DebugNote { const DebugNoteFileInfo* fileInfo; std::vector<DebugNoteItem> items; }; // encapsulates symbol table in a final linked image NListSymbolTable(uint32_t preferredLoadAddress, const struct nlist*, uint32_t nlistCount, const char* stringPool, uint32_t stringPoolSize, uint32_t localsCount, uint32_t globalsCount, uint32_t undefsCount); NListSymbolTable(uint64_t preferredLoadAddress, const struct nlist_64*, uint32_t nlistCount, const char* stringPool, uint32_t stringPoolSize, uint32_t localsCount, uint32_t globalsCount, uint32_t undefsCount); Error valid(uint64_t maxVmOffset) const; bool hasExportedSymbol(const char* symbolName, Symbol& symbol) const; void forEachSymbol(void (^callback)(const Symbol& symbol, uint32_t symbolIndex, bool& stop)) const; void forEachExportedSymbol(void (^callback)(const Symbol& symbol, uint32_t symbolIndex, bool& stop)) const; void forEachDefinedSymbol(void (^callback)(const Symbol& symbol, uint32_t symbolIndex, bool& stop)) const; bool findClosestDefinedSymbol(uint64_t unslidAddr, Symbol& symbol) const; void forEachUndefinedSymbol(void (^callback)(const Symbol& symbol, uint32_t symbolIndex, bool& stop)) const; void forEachSymbol(void (^callback)(const char* symbolName, uint64_t n_value, uint8_t n_type, uint8_t n_sect, uint16_t n_desc, uint32_t symbolIndex, bool& stop)) const; void forEachDebugNote(bool freeFileInfo, void (^callback)(const DebugNote& note, bool& stop)) const; void forEachDebugNote(void (^callback)(const DebugNote& note, bool& stop)) const { forEachDebugNote(/* freeFileInfo */ true, callback); } uint64_t nValueFromSymbolIndex(uint32_t symbolIndex) const; const char* stringPool() const { return _stringPool; } uint32_t stringPoolSize() const { return _stringPoolSize; } const void* nlistArray() const { return ((_nlist64 != nullptr) ? (void*)_nlist64 : (void*)_nlist32); } uint32_t localsCount() const { return _localsCount; } uint32_t globalsCount() const { return _globalsCount; } uint32_t undefsCount() const { return _undefsCount; } uint32_t totalCount() const { return _nlistCount; } uint32_t nlistSize() const { return _nlist32 ? (totalCount() * sizeof(struct nlist)) : (totalCount() * sizeof(struct nlist_64)); } uint32_t undefsStartIndex() const; bool symbolAtIndex(uint32_t symbolIndex, Symbol& symbol) const; protected: // only for use by NListSymbolTableWriter NListSymbolTable() = default; int libOrdinalFromDesc(uint16_t n_desc) const; Symbol symbolFromNList(const char* symbolName, uint64_t n_value, uint8_t n_type, uint8_t n_sect, uint16_t n_desc) const; bool forEachSymbol(uint32_t startSymbolIndex, uint32_t symbolCount, void (^callback)(const char* symbolName, uint64_t n_value, uint8_t n_type, uint8_t n_sect, uint16_t n_desc, uint32_t symbolIndex, bool& stop)) const; uint64_t _preferredLoadAddress; const char* _stringPool; const struct nlist* _nlist32; const struct nlist_64* _nlist64; uint32_t _stringPoolSize; uint32_t _nlistCount; uint32_t _localsCount; uint32_t _globalsCount; uint32_t _undefsCount; }; /*! * @class DebugNoteFileInfo * * @abstract * A position and read-only blob, encapsulating debug file info. */ struct VIS_HIDDEN DebugNoteFileInfo { public: DebugNoteFileInfo(const DebugNoteFileInfo&) = delete; DebugNoteFileInfo(DebugNoteFileInfo&&) = delete; DebugNoteFileInfo& operator=(const DebugNoteFileInfo&) = delete; DebugNoteFileInfo& operator=(DebugNoteFileInfo&&) = delete; static const DebugNoteFileInfo* make(CString srcDir, CString srcName, CString objPath, uint32_t objModTime=0, uint8_t objSubType=0, CString libPath=CString(), CString originLibPath=CString()); static mach_o::Error valid(std::span<const uint8_t> buffer); const DebugNoteFileInfo* copy() const; CString srcDir() const { return _srcDir; } CString srcName() const { return _srcName; } CString objPath() const { return _objPath; } uint32_t objModTime() const { return _objModTime; } uint8_t objSubType() const { return _objSubType; } CString originLibPath() const { return _originLibPath; } CString libPath() const { return _libPath; } bool hasLibInfo() const { return !_libPath.empty(); } bool hasOriginLibInfo() const { return !_originLibPath.empty(); } bool shouldbeUpdated(CString LibPath) const; void dump() const; private: uint32_t _objModTime; uint32_t _objSubType; CString _srcDir; CString _srcName; CString _objPath; CString _libPath; CString _originLibPath; }; } // namespace mach_o #endif // mach_o_SymbolTable_h |