/* ** autosegs.h ** Arrays built at link-time ** **--------------------------------------------------------------------------- ** Copyright 1998-2006 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions ** are met: ** ** 1. Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** 2. Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** 3. The name of the author may not be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** */ #ifndef AUTOSEGS_H #define AUTOSEGS_H #include #if defined(__clang__) #if defined(__has_feature) && __has_feature(address_sanitizer) #define NO_SANITIZE __attribute__((no_sanitize("address"))) #else #define NO_SANITIZE #endif #else #define NO_SANITIZE #endif #if defined _MSC_VER #define NO_SANITIZE_M __declspec(no_sanitize_address) #else #define NO_SANITIZE_M #endif class FAutoSeg { const char *name; void **begin; void **end; template struct ArgumentType; template struct ArgumentType { using Type = Arg; }; template using ArgumentTypeT = typename ArgumentType::Type; template struct ReturnType { using Type = std::invoke_result_t>; }; template using ReturnTypeT = typename ReturnType::Type; template struct HasReturnType { static constexpr bool Value = std::is_same_v, Ret>; }; template static constexpr bool HasReturnTypeV = HasReturnType::Value; void Initialize(); public: explicit FAutoSeg(const char *name) : name(name) , begin(nullptr) , end(nullptr) { Initialize(); } FAutoSeg(void** begin, void** end) : name(nullptr) , begin(begin) , end(end) { } template void NO_SANITIZE_M ForEach(Func func, std::enable_if_t> * = nullptr) { using CallableType = decltype(&Func::operator()); using ArgType = typename ArgumentType::Type; for (void **it = begin; it < end; ++it) { if (intptr_t(it) > 0xffff && *it && intptr_t(*it) > 0xffff) { func(reinterpret_cast(*it)); } } } template void NO_SANITIZE_M ForEach(Func func, std::enable_if_t> * = nullptr) { using CallableType = decltype(&Func::operator()); using ArgType = typename ArgumentType::Type; for (void **it = begin; it < end; ++it) { if (intptr_t(it) > 0xffff && *it && intptr_t(*it) > 0xffff) { if (!func(reinterpret_cast(*it))) { return; }; } } } }; namespace AutoSegs { extern FAutoSeg ActionFunctons; extern FAutoSeg TypeInfos; extern FAutoSeg ClassFields; extern FAutoSeg Properties; extern FAutoSeg MapInfoOptions; extern FAutoSeg CVarDecl; } #define AUTOSEG_AREG areg #define AUTOSEG_CREG creg #define AUTOSEG_FREG freg #define AUTOSEG_GREG greg #define AUTOSEG_YREG yreg #define AUTOSEG_VREG vreg #define AUTOSEG_STR(string) AUTOSEG_STR2(string) #define AUTOSEG_STR2(string) #string #ifdef __MACH__ #define AUTOSEG_MACH_SEGMENT "__DATA" #define AUTOSEG_MACH_SECTION(section) AUTOSEG_MACH_SEGMENT "," AUTOSEG_STR(section) #define SECTION_AREG AUTOSEG_MACH_SECTION(AUTOSEG_AREG) #define SECTION_CREG AUTOSEG_MACH_SECTION(AUTOSEG_CREG) #define SECTION_FREG AUTOSEG_MACH_SECTION(AUTOSEG_FREG) #define SECTION_GREG AUTOSEG_MACH_SECTION(AUTOSEG_GREG) #define SECTION_YREG AUTOSEG_MACH_SECTION(AUTOSEG_YREG) #define SECTION_VREG AUTOSEG_MACH_SECTION(AUTOSEG_VREG) #else #define SECTION_AREG AUTOSEG_STR(AUTOSEG_AREG) #define SECTION_CREG AUTOSEG_STR(AUTOSEG_CREG) #define SECTION_FREG AUTOSEG_STR(AUTOSEG_FREG) #define SECTION_GREG AUTOSEG_STR(AUTOSEG_GREG) #define SECTION_YREG AUTOSEG_STR(AUTOSEG_YREG) #define SECTION_VREG AUTOSEG_STR(AUTOSEG_VREG) #endif #endif