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 | /* * 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_Symbol_h #define mach_o_Symbol_h #include <stdint.h> #include "MachODefines.h" #include "CString.h" namespace mach_o { /*! * @class Symbol * * @abstract * Abstraction for symbols in mach-o final linked executables */ class VIS_HIDDEN Symbol { public: Symbol() = default; bool operator==(const Symbol&) const; bool operator!=(const Symbol& other) const { return !operator==(other); } enum class Scope: uint8_t { translationUnit, wasLinkageUnit, linkageUnit, autoHide, global, globalNeverStrip }; CString name() const { return _name; } uint64_t implOffset() const; // fails for re-exports and absolute Scope scope() const { return _scope; } // global vs local symbol bool isWeakDef() const { return _weakDef; } bool dontDeadStrip() const { return _dontDeadStrip; } bool cold() const { return _cold; } bool isThumb() const { return _isThumb; } bool isThreadLocal() const { return (_kind == Kind::threadLocal); } bool isDynamicResolver(uint64_t& resolverStubOffset) const; bool isFunctionVariant(uint32_t& functionVariantTableIndex) const; bool isReExport(int& libOrdinal, const char*& importName) const; bool isAbsolute(uint64_t& absAddress) const; bool isUndefined() const; bool isUndefined(int& libOrdinal, bool& weakImport) const; bool isRegular(uint64_t& implOffset) const; bool isThreadLocal(uint64_t& implOffset) const; bool isTentativeDef() const; bool isTentativeDef(uint64_t& size, uint8_t& p2align) const; uint8_t sectionOrdinal() const { return _sectOrdinal; } bool isAltEntry(uint64_t& implOffset) const; bool isAltEntry() const { return _kind == Kind::altEntry; } void setName(const char* n); void setimplOffset(uint64_t); void setDontDeadStrip() { _dontDeadStrip = true; } void setCold() { _cold = true; } void setWeakDef() { _weakDef = true; } void setNotWeakDef() { _weakDef = false; } void setIsThumb() { _isThumb = true; } void changeRegularToAltEntry(); void changeAltEntryToRegular(); static Symbol makeRegularExport(CString name, uint64_t imageOffset, uint8_t sectNum, bool dontDeadStrip, bool cold, bool neverStrip=false, bool isThumb=false); static Symbol makeRegularHidden(CString name, uint64_t imageOffset, uint8_t sectNum, bool dontDeadStrip, bool cold, bool isThumb=false); static Symbol makeRegularLocal(CString name, uint64_t imageOffset, uint8_t sectNum, bool dontDeadStrip, bool cold, bool isThumb=false); static Symbol makeRegularWasPrivateExtern(CString name, uint64_t imageOffset, uint8_t sectNum, bool dontDeadStrip, bool cold, bool isThumb=false); static Symbol makeWeakDefAutoHide(CString name, uint64_t imageOffset, uint8_t sectNum, bool dontDeadStrip, bool cold, bool isThumb=false); // given the current encoding in mach-o, only weak-defs can be auto-hide static Symbol makeWeakDefExport(CString name, uint64_t imageOffset, uint8_t sectNum, bool dontDeadStrip, bool cold, bool isThumb=false); static Symbol makeAltEntry(CString name, uint64_t imageOffset, uint8_t sectNum, Scope s, bool dontDeadStrip, bool cold, bool weakDef, bool isThumb=false); static Symbol makeWeakDefHidden(CString name, uint64_t imageOffset, uint8_t sectNum, bool dontDeadStrip, bool cold, bool isThumb=false); static Symbol makeWeakDefWasPrivateExtern(CString name, uint64_t imageOffset, uint8_t sectNum, bool dontDeadStrip, bool cold, bool isThumb=false); static Symbol makeDynamicResolver(CString name, uint8_t sectNum, uint64_t stubImageOffset, uint64_t funcImageOffset, Symbol::Scope=Symbol::Scope::global); static Symbol makeFunctionVariantExport(CString name, uint8_t sectNum, uint64_t imageOffsetOfDefault, uint32_t functionVariantTableIndex); static Symbol makeThreadLocalExport(CString name, uint64_t imageOffset, uint8_t sectOrd, bool dontDeadStrip, bool cold, bool weakDef); static Symbol makeAbsolute(CString name, uint64_t address, bool dontDeadStrip, Scope scope, uint8_t sectNum=0); static Symbol makeReExport(CString name, int libOrdinal, const char* importName=nullptr, Symbol::Scope=Symbol::Scope::global); static Symbol makeUndefined(CString name, int libOrdinal, bool weakImport=false); static Symbol makeTentativeDef(CString name, uint64_t size, uint8_t alignP2, bool dontDeadStrip, bool cold); static Symbol makeHiddenTentativeDef(CString name, uint64_t size, uint8_t alignP2, bool dontDeadStrip, bool cold); private: Symbol(CString name) : _name(name) { } enum class Kind: uint8_t { regular, altEntry, resolver, absolute, reExport, threadLocal, tentative, undefine, functionVariant }; CString _name = ""; uint64_t _implOffset = 0; // resolver => offset to stub, re-exports,undefined => libOrdinal, absolute => address, tentative => size union { const char* importName; uint64_t resolverStubOffset = 0; uint32_t functionVariantTableIndex; } _u; Kind _kind = Kind::regular; uint8_t _sectOrdinal = 0; Scope _scope = Scope::translationUnit; // global vs local bool _weakDef = false; // regular only bool _dontDeadStrip = false; // regular only bool _cold = false; // regular only bool _weakImport = false; // undefines only bool _isThumb = false; // regular only }; static_assert(sizeof(Symbol) == 24+2*sizeof(void*)); } // namespace mach_o #endif // mach_o_Symbol_h |