mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #69163 from apple/rebranch
Merge `rebranch` into `main` to support `stable/20230725` llvm-project branch
This commit is contained in:
@@ -353,6 +353,12 @@ How swift-C++ bridging code is compiled:
|
|||||||
DEFAULT: based on the build configuration
|
DEFAULT: based on the build configuration
|
||||||
]=] DEFAULT)
|
]=] DEFAULT)
|
||||||
|
|
||||||
|
option(SWIFT_USE_SYMLINKS "Use symlinks instead of copying binaries" ${CMAKE_HOST_UNIX})
|
||||||
|
set(SWIFT_COPY_OR_SYMLINK "copy")
|
||||||
|
if(SWIFT_USE_SYMLINKS)
|
||||||
|
set(SWIFT_COPY_OR_SYMLINK "create_symlink")
|
||||||
|
endif()
|
||||||
|
|
||||||
# The following only works with the Ninja generator in CMake >= 3.0.
|
# The following only works with the Ninja generator in CMake >= 3.0.
|
||||||
set(SWIFT_PARALLEL_LINK_JOBS "" CACHE STRING
|
set(SWIFT_PARALLEL_LINK_JOBS "" CACHE STRING
|
||||||
"Define the maximum number of linker jobs for swift.")
|
"Define the maximum number of linker jobs for swift.")
|
||||||
@@ -1333,6 +1339,15 @@ endif()
|
|||||||
add_subdirectory(include)
|
add_subdirectory(include)
|
||||||
|
|
||||||
if(SWIFT_INCLUDE_TOOLS)
|
if(SWIFT_INCLUDE_TOOLS)
|
||||||
|
|
||||||
|
# TODO Remove this once release/5.9 is done and we can finish migrating Swift
|
||||||
|
# off of `llvm::None`/`llvm::Optional`, and `llvm::makeArrayRef`.
|
||||||
|
# This is to silence the avalanche of deprecation warnings from LLVM headers
|
||||||
|
# until we can actually do something about them. This is nasty, but it's
|
||||||
|
# better than losing context due to the sheer number in-actionable deprecation
|
||||||
|
# warnings or the massive number of merge-conflicts we would get otherwise.
|
||||||
|
add_definitions(-DSWIFT_TARGET)
|
||||||
|
|
||||||
# Include 'swift-syntax'.
|
# Include 'swift-syntax'.
|
||||||
# This is a function because we want to set some 'CMAKE_*' variables temporarily.'
|
# This is a function because we want to set some 'CMAKE_*' variables temporarily.'
|
||||||
# TODO: Replace this with 'block()' after CMake 3.25
|
# TODO: Replace this with 'block()' after CMake 3.25
|
||||||
|
|||||||
@@ -8,15 +8,14 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
|||||||
set(SWIFT_LIBDISPATCH_CXX_COMPILER ${CMAKE_CXX_COMPILER})
|
set(SWIFT_LIBDISPATCH_CXX_COMPILER ${CMAKE_CXX_COMPILER})
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME)
|
elseif(CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME)
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL CMAKE_HOST_SYSTEM_PROCESSOR AND
|
if(DEFINED SWIFT_CLANG_LOCATION)
|
||||||
TARGET clang)
|
set(SWIFT_LIBDISPATCH_C_COMPILER ${SWIFT_CLANG_LOCATION}/clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
|
set(SWIFT_LIBDISPATCH_CXX_COMPILER ${SWIFT_CLANG_LOCATION}/clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL CMAKE_HOST_SYSTEM_PROCESSOR AND TARGET clang)
|
||||||
set(SWIFT_LIBDISPATCH_C_COMPILER
|
set(SWIFT_LIBDISPATCH_C_COMPILER
|
||||||
$<TARGET_FILE_DIR:clang>/clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
$<TARGET_FILE_DIR:clang>/clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
set(SWIFT_LIBDISPATCH_CXX_COMPILER
|
set(SWIFT_LIBDISPATCH_CXX_COMPILER
|
||||||
$<TARGET_FILE_DIR:clang>/clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
$<TARGET_FILE_DIR:clang>/clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
elseif(DEFINED SWIFT_CLANG_LOCATION)
|
|
||||||
set(SWIFT_LIBDISPATCH_C_COMPILER ${SWIFT_CLANG_LOCATION}/clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
|
||||||
set(SWIFT_LIBDISPATCH_CXX_COMPILER ${SWIFT_CLANG_LOCATION}/clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
|
||||||
else()
|
else()
|
||||||
set(SWIFT_LIBDISPATCH_C_COMPILER clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
set(SWIFT_LIBDISPATCH_C_COMPILER clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
set(SWIFT_LIBDISPATCH_CXX_COMPILER clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
set(SWIFT_LIBDISPATCH_CXX_COMPILER clang-cl${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
|
|||||||
@@ -203,6 +203,9 @@ function(swift_install_symlink_component component)
|
|||||||
# otherwise.
|
# otherwise.
|
||||||
install(DIRECTORY DESTINATION "${ARG_DESTINATION}" COMPONENT ${component})
|
install(DIRECTORY DESTINATION "${ARG_DESTINATION}" COMPONENT ${component})
|
||||||
install(SCRIPT ${INSTALL_SYMLINK}
|
install(SCRIPT ${INSTALL_SYMLINK}
|
||||||
CODE "install_symlink(${ARG_LINK_NAME} ${ARG_TARGET} ${ARG_DESTINATION})"
|
CODE "install_symlink(${ARG_LINK_NAME}
|
||||||
|
${ARG_TARGET}
|
||||||
|
${ARG_DESTINATION}
|
||||||
|
${SWIFT_COPY_OR_SYMLINK})"
|
||||||
COMPONENT ${component})
|
COMPONENT ${component})
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|||||||
@@ -7,8 +7,9 @@
|
|||||||
#ifndef SWIFT_ABI_OBJECTFILE_H
|
#ifndef SWIFT_ABI_OBJECTFILE_H
|
||||||
#define SWIFT_ABI_OBJECTFILE_H
|
#define SWIFT_ABI_OBJECTFILE_H
|
||||||
|
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
|
|
||||||
|
|||||||
@@ -506,9 +506,9 @@ public:
|
|||||||
return StringRef(Result.data(), Result.size());
|
return StringRef(Result.data(), Result.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Vector, typename Set>
|
template<typename T, typename Vector, typename Set, unsigned N>
|
||||||
MutableArrayRef<T>
|
MutableArrayRef<T>
|
||||||
AllocateCopy(llvm::SetVector<T, Vector, Set> setVector,
|
AllocateCopy(llvm::SetVector<T, Vector, Set, N> setVector,
|
||||||
AllocationArena arena = AllocationArena::Permanent) const {
|
AllocationArena arena = AllocationArena::Permanent) const {
|
||||||
return MutableArrayRef<T>(AllocateCopy<T>(setVector.begin(),
|
return MutableArrayRef<T>(AllocateCopy<T>(setVector.begin(),
|
||||||
setVector.end(),
|
setVector.end(),
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "swift/Basic/LLVM.h"
|
#include "swift/Basic/LLVM.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
|
#include "llvm/ADT/None.h"
|
||||||
#include "llvm/ADT/PointerUnion.h"
|
#include "llvm/ADT/PointerUnion.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|||||||
@@ -5020,7 +5020,7 @@ class ProtocolDecl final : public NominalTypeDecl {
|
|||||||
/// \c None if it hasn't yet been computed.
|
/// \c None if it hasn't yet been computed.
|
||||||
llvm::Optional<bool> getCachedHasSelfOrAssociatedTypeRequirements() {
|
llvm::Optional<bool> getCachedHasSelfOrAssociatedTypeRequirements() {
|
||||||
if (Bits.ProtocolDecl.HasSelfOrAssociatedTypeRequirementsValid)
|
if (Bits.ProtocolDecl.HasSelfOrAssociatedTypeRequirementsValid)
|
||||||
return Bits.ProtocolDecl.HasSelfOrAssociatedTypeRequirements;
|
return static_cast<bool>(Bits.ProtocolDecl.HasSelfOrAssociatedTypeRequirements);
|
||||||
|
|
||||||
return llvm::None;
|
return llvm::None;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public:
|
|||||||
/// collecting the identifiers in \p spiGroups.
|
/// collecting the identifiers in \p spiGroups.
|
||||||
virtual void lookupImportedSPIGroups(
|
virtual void lookupImportedSPIGroups(
|
||||||
const ModuleDecl *importedModule,
|
const ModuleDecl *importedModule,
|
||||||
SmallSetVector<Identifier, 4> &spiGroups) const {};
|
llvm::SmallSetVector<Identifier, 4> &spiGroups) const {};
|
||||||
|
|
||||||
/// Checks whether this file imports \c module as \c @_weakLinked.
|
/// Checks whether this file imports \c module as \c @_weakLinked.
|
||||||
virtual bool importsModuleAsWeakLinked(const ModuleDecl *module) const {
|
virtual bool importsModuleAsWeakLinked(const ModuleDecl *module) const {
|
||||||
|
|||||||
@@ -502,6 +502,15 @@ public:
|
|||||||
/// The calling convention used to perform non-swift calls.
|
/// The calling convention used to perform non-swift calls.
|
||||||
llvm::CallingConv::ID PlatformCCallingConvention;
|
llvm::CallingConv::ID PlatformCCallingConvention;
|
||||||
|
|
||||||
|
/// Use CAS based object format as the output.
|
||||||
|
bool UseCASBackend;
|
||||||
|
|
||||||
|
/// The output mode for the CAS Backend.
|
||||||
|
llvm::CASBackendMode CASObjMode;
|
||||||
|
|
||||||
|
/// Emit a .casid file next to the object file if CAS Backend is used.
|
||||||
|
bool EmitCASIDFile;
|
||||||
|
|
||||||
IRGenOptions()
|
IRGenOptions()
|
||||||
: DWARFVersion(2),
|
: DWARFVersion(2),
|
||||||
OutputKind(IRGenOutputKind::LLVMAssemblyAfterOptimization),
|
OutputKind(IRGenOutputKind::LLVMAssemblyAfterOptimization),
|
||||||
@@ -513,9 +522,9 @@ public:
|
|||||||
DebugInfoFormat(IRGenDebugInfoFormat::None),
|
DebugInfoFormat(IRGenDebugInfoFormat::None),
|
||||||
DisableClangModuleSkeletonCUs(false), UseJIT(false),
|
DisableClangModuleSkeletonCUs(false), UseJIT(false),
|
||||||
DisableLLVMOptzns(false), DisableSwiftSpecificLLVMOptzns(false),
|
DisableLLVMOptzns(false), DisableSwiftSpecificLLVMOptzns(false),
|
||||||
Playground(false),
|
Playground(false), EmitStackPromotionChecks(false),
|
||||||
EmitStackPromotionChecks(false), UseSingleModuleLLVMEmission(false),
|
UseSingleModuleLLVMEmission(false), FunctionSections(false),
|
||||||
FunctionSections(false), PrintInlineTree(false), AlwaysCompile(false),
|
PrintInlineTree(false), AlwaysCompile(false),
|
||||||
EmbedMode(IRGenEmbedMode::None), LLVMLTOKind(IRGenLLVMLTOKind::None),
|
EmbedMode(IRGenEmbedMode::None), LLVMLTOKind(IRGenLLVMLTOKind::None),
|
||||||
SwiftAsyncFramePointer(SwiftAsyncFramePointerKind::Auto),
|
SwiftAsyncFramePointer(SwiftAsyncFramePointerKind::Auto),
|
||||||
HasValueNamesSetting(false), ValueNames(false),
|
HasValueNamesSetting(false), ValueNames(false),
|
||||||
@@ -538,13 +547,12 @@ public:
|
|||||||
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
|
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
|
||||||
InternalizeAtLink(false), InternalizeSymbols(false),
|
InternalizeAtLink(false), InternalizeSymbols(false),
|
||||||
EmitGenericRODatas(false), NoPreallocatedInstantiationCaches(false),
|
EmitGenericRODatas(false), NoPreallocatedInstantiationCaches(false),
|
||||||
DisableReadonlyStaticObjects(false),
|
DisableReadonlyStaticObjects(false), CollocatedMetadataFunctions(false),
|
||||||
CollocatedMetadataFunctions(false),
|
ColocateTypeDescriptors(true), UseRelativeProtocolWitnessTables(false),
|
||||||
ColocateTypeDescriptors(true),
|
CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()),
|
||||||
UseRelativeProtocolWitnessTables(false), CmdArgs(),
|
|
||||||
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
|
|
||||||
TypeInfoFilter(TypeInfoDumpFilter::All),
|
TypeInfoFilter(TypeInfoDumpFilter::All),
|
||||||
PlatformCCallingConvention(llvm::CallingConv::C) {
|
PlatformCCallingConvention(llvm::CallingConv::C), UseCASBackend(false),
|
||||||
|
CASObjMode(llvm::CASBackendMode::Native) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DisableRoundTripDebugTypes = false;
|
DisableRoundTripDebugTypes = false;
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -776,7 +776,7 @@ struct DenseMapInfo<swift::AttributedImport<ModuleInfo>> {
|
|||||||
SourceLocDMI::getEmptyKey(),
|
SourceLocDMI::getEmptyKey(),
|
||||||
ImportOptionsDMI::getEmptyKey(),
|
ImportOptionsDMI::getEmptyKey(),
|
||||||
StringRefDMI::getEmptyKey(),
|
StringRefDMI::getEmptyKey(),
|
||||||
{}, {}, None,
|
{}, {}, llvm::None,
|
||||||
swift::AccessLevel::Public, {});
|
swift::AccessLevel::Public, {});
|
||||||
}
|
}
|
||||||
static inline AttributedImport getTombstoneKey() {
|
static inline AttributedImport getTombstoneKey() {
|
||||||
@@ -784,7 +784,7 @@ struct DenseMapInfo<swift::AttributedImport<ModuleInfo>> {
|
|||||||
SourceLocDMI::getEmptyKey(),
|
SourceLocDMI::getEmptyKey(),
|
||||||
ImportOptionsDMI::getTombstoneKey(),
|
ImportOptionsDMI::getTombstoneKey(),
|
||||||
StringRefDMI::getTombstoneKey(),
|
StringRefDMI::getTombstoneKey(),
|
||||||
{}, {}, None,
|
{}, {}, llvm::None,
|
||||||
swift::AccessLevel::Public, {});
|
swift::AccessLevel::Public, {});
|
||||||
}
|
}
|
||||||
static inline unsigned getHashValue(const AttributedImport &import) {
|
static inline unsigned getHashValue(const AttributedImport &import) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/ADT/SetVector.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "swift/Basic/LLVM.h"
|
#include "swift/Basic/LLVM.h"
|
||||||
#include "swift/Basic/Located.h"
|
#include "swift/Basic/Located.h"
|
||||||
#include "swift/Basic/SourceLoc.h"
|
#include "swift/Basic/SourceLoc.h"
|
||||||
|
#include "clang/Basic/FileManager.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/SetVector.h"
|
#include "llvm/ADT/SetVector.h"
|
||||||
#include "llvm/ADT/StringSet.h"
|
#include "llvm/ADT/StringSet.h"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#define SWIFT_AST_RESILIENCE_EXPANSION_H
|
#define SWIFT_AST_RESILIENCE_EXPANSION_H
|
||||||
|
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
#include "llvm/ADT/Hashing.h"
|
#include "llvm/ADT/Hashing.h"
|
||||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
|
#include "llvm/ADT/None.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
#include "llvm/Support/VirtualFileSystem.h"
|
#include "llvm/Support/VirtualFileSystem.h"
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "swift/Basic/LLVM.h"
|
#include "swift/Basic/LLVM.h"
|
||||||
#include "swift/Basic/Range.h"
|
#include "swift/Basic/Range.h"
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
|
|||||||
@@ -15,8 +15,9 @@
|
|||||||
|
|
||||||
#include "llvm/ADT/DenseMapInfo.h"
|
#include "llvm/ADT/DenseMapInfo.h"
|
||||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/None.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
namespace sys {
|
namespace sys {
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ public:
|
|||||||
|
|
||||||
/// Count the number of set bits in this vector.
|
/// Count the number of set bits in this vector.
|
||||||
size_t count() const {
|
size_t count() const {
|
||||||
return Bits ? Bits.value().countPopulation() : 0;
|
return Bits ? Bits.value().popcount() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine if there are any bits set in this vector.
|
/// Determine if there are any bits set in this vector.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#include "swift/Basic/LLVM.h"
|
#include "swift/Basic/LLVM.h"
|
||||||
#include "swift/Basic/PrefixMap.h"
|
#include "swift/Basic/PrefixMap.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/Support/Host.h"
|
#include "llvm/TargetParser/Host.h"
|
||||||
#include "llvm/Support/TrailingObjects.h"
|
#include "llvm/Support/TrailingObjects.h"
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|||||||
@@ -218,9 +218,8 @@ public:
|
|||||||
|
|
||||||
ValueType operator*() const {
|
ValueType operator*() const {
|
||||||
assert(remainingChunk && "dereferencing a completed iterator");
|
assert(remainingChunk && "dereferencing a completed iterator");
|
||||||
return ValueType(chunkIndex * chunkSize
|
return ValueType(chunkIndex * chunkSize +
|
||||||
+ llvm::findFirstSet(remainingChunk,
|
llvm::countr_zero(remainingChunk));
|
||||||
llvm::ZB_Undefined));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const iterator &other) const {
|
bool operator==(const iterator &other) const {
|
||||||
|
|||||||
@@ -48,10 +48,11 @@
|
|||||||
#ifndef SWIFT_BASIC_IMMUTABLEPOINTERSET_H
|
#ifndef SWIFT_BASIC_IMMUTABLEPOINTERSET_H
|
||||||
#define SWIFT_BASIC_IMMUTABLEPOINTERSET_H
|
#define SWIFT_BASIC_IMMUTABLEPOINTERSET_H
|
||||||
|
|
||||||
#include "swift/Basic/STLExtras.h"
|
|
||||||
#include "swift/Basic/NullablePtr.h"
|
#include "swift/Basic/NullablePtr.h"
|
||||||
#include "llvm/Support/Allocator.h"
|
#include "swift/Basic/STLExtras.h"
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
|
#include "llvm/Support/Allocator.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ namespace llvm {
|
|||||||
template <typename T, unsigned N> class SmallVector;
|
template <typename T, unsigned N> class SmallVector;
|
||||||
#endif
|
#endif
|
||||||
template <unsigned N> class SmallString;
|
template <unsigned N> class SmallString;
|
||||||
template <typename T, unsigned N> class SmallSetVector;
|
|
||||||
#if SWIFT_LLVM_ODR_SAFE
|
#if SWIFT_LLVM_ODR_SAFE
|
||||||
template<typename T> class ArrayRef;
|
template<typename T> class ArrayRef;
|
||||||
template<typename T> class MutableArrayRef;
|
template<typename T> class MutableArrayRef;
|
||||||
@@ -93,7 +92,6 @@ namespace swift {
|
|||||||
using llvm::SmallBitVector;
|
using llvm::SmallBitVector;
|
||||||
using llvm::SmallPtrSet;
|
using llvm::SmallPtrSet;
|
||||||
using llvm::SmallPtrSetImpl;
|
using llvm::SmallPtrSetImpl;
|
||||||
using llvm::SmallSetVector;
|
|
||||||
using llvm::SmallString;
|
using llvm::SmallString;
|
||||||
#if SWIFT_LLVM_ODR_SAFE
|
#if SWIFT_LLVM_ODR_SAFE
|
||||||
using llvm::SmallVector;
|
using llvm::SmallVector;
|
||||||
|
|||||||
36
include/swift/Basic/LLVMExtras.h
Normal file
36
include/swift/Basic/LLVMExtras.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
//===--- LLVMExtras.h -----------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This source file is part of the Swift.org open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
|
||||||
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||||
|
//
|
||||||
|
// See https://swift.org/LICENSE.txt for license information
|
||||||
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file provides additional functionality on top of LLVM types
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef SWIFT_BASIC_LLVMEXTRAS_H
|
||||||
|
#define SWIFT_BASIC_LLVMEXTRAS_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/DenseSet.h"
|
||||||
|
#include "llvm/ADT/SetVector.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
|
||||||
|
namespace swift {
|
||||||
|
|
||||||
|
/// A SetVector that does no allocations under the specified size
|
||||||
|
///
|
||||||
|
/// swift::SmallSetVector provides the old SmallSetVector semantics that allow
|
||||||
|
/// storing types that don't have `operator==`.
|
||||||
|
template <typename T, unsigned N>
|
||||||
|
using SmallSetVector = llvm::SetVector<T, llvm::SmallVector<T, N>,
|
||||||
|
llvm::SmallDenseSet<T, N, llvm::DenseMapInfo<T>>>;
|
||||||
|
|
||||||
|
} // namespace swift
|
||||||
|
|
||||||
|
#endif // SWIFT_BASIC_LLVMEXTRAS_H
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/TargetParser/Triple.h"
|
||||||
#include "llvm/Support/Regex.h"
|
#include "llvm/Support/Regex.h"
|
||||||
#include "llvm/Support/VersionTuple.h"
|
#include "llvm/Support/VersionTuple.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
#include "swift/Basic/LLVM.h"
|
#include "swift/Basic/LLVM.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
|
#include "llvm/ADT/None.h"
|
||||||
|
#include "swift/Basic/STLExtras.h"
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
|
|
||||||
@@ -61,7 +64,8 @@ public:
|
|||||||
|
|
||||||
// If we already have a cached value, just return the cached value.
|
// If we already have a cached value, just return the cached value.
|
||||||
if (!iter.second) {
|
if (!iter.second) {
|
||||||
return iter.first->second.transform(
|
|
||||||
|
return swift::transform(iter.first->second,
|
||||||
[&](std::tuple<unsigned, unsigned> startLengthRange) {
|
[&](std::tuple<unsigned, unsigned> startLengthRange) {
|
||||||
return llvm::makeArrayRef(data).slice(
|
return llvm::makeArrayRef(data).slice(
|
||||||
std::get<ArrayStartOffset>(startLengthRange),
|
std::get<ArrayStartOffset>(startLengthRange),
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#define SWIFT_BASIC_PROGRAM_H
|
#define SWIFT_BASIC_PROGRAM_H
|
||||||
|
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/None.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/Support/ErrorOr.h"
|
#include "llvm/Support/ErrorOr.h"
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
|
|
||||||
@@ -783,6 +784,17 @@ void emplace_back_all(VectorType &vector, ValueType &&value,
|
|||||||
template <class VectorType>
|
template <class VectorType>
|
||||||
void emplace_back_all(VectorType &vector) {}
|
void emplace_back_all(VectorType &vector) {}
|
||||||
|
|
||||||
|
/// Apply a function to the value if present; otherwise return None.
|
||||||
|
template <typename OptionalElement, typename Function>
|
||||||
|
auto transform(const llvm::Optional<OptionalElement> &value,
|
||||||
|
const Function &operation)
|
||||||
|
-> llvm::Optional<decltype(operation(*value))> {
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
return operation(*value);
|
||||||
|
}
|
||||||
|
return llvm::None;
|
||||||
|
}
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|
||||||
#endif // SWIFT_BASIC_STLEXTRAS_H
|
#endif // SWIFT_BASIC_STLEXTRAS_H
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ SANITIZER(0, Address, address, asan)
|
|||||||
SANITIZER(1, Thread, thread, tsan)
|
SANITIZER(1, Thread, thread, tsan)
|
||||||
SANITIZER(2, Undefined, undefined, ubsan)
|
SANITIZER(2, Undefined, undefined, ubsan)
|
||||||
SANITIZER(3, Fuzzer, fuzzer, fuzzer)
|
SANITIZER(3, Fuzzer, fuzzer, fuzzer)
|
||||||
SANITIZER(4, Scudo, scudo, scudo)
|
SANITIZER(4, Scudo, scudo, scudo_standalone)
|
||||||
|
|
||||||
#undef SANITIZER
|
#undef SANITIZER
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#include "swift/Basic/LLVM.h"
|
#include "swift/Basic/LLVM.h"
|
||||||
|
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class Triple;
|
class Triple;
|
||||||
class VersionTuple;
|
class VersionTuple;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ struct CXXMethodBridging {
|
|||||||
nameKind != NameKind::lower && nameKind != NameKind::snake)
|
nameKind != NameKind::lower && nameKind != NameKind::snake)
|
||||||
return Kind::unknown;
|
return Kind::unknown;
|
||||||
|
|
||||||
if (getClangName().startswith_insensitive("set")) {
|
if (getClangName().starts_with_insensitive("set")) {
|
||||||
// Setters only have one parameter.
|
// Setters only have one parameter.
|
||||||
if (method->getNumParams() != 1)
|
if (method->getNumParams() != 1)
|
||||||
return Kind::unknown;
|
return Kind::unknown;
|
||||||
@@ -43,7 +43,7 @@ struct CXXMethodBridging {
|
|||||||
if (method->getReturnType()->isVoidType())
|
if (method->getReturnType()->isVoidType())
|
||||||
return Kind::unknown;
|
return Kind::unknown;
|
||||||
|
|
||||||
if (getClangName().startswith_insensitive("get")) {
|
if (getClangName().starts_with_insensitive("get")) {
|
||||||
// Getters cannot take arguments.
|
// Getters cannot take arguments.
|
||||||
if (method->getNumParams() != 0)
|
if (method->getNumParams() != 0)
|
||||||
return Kind::unknown;
|
return Kind::unknown;
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ public:
|
|||||||
|
|
||||||
using RemapPathCallback = llvm::function_ref<std::string(StringRef)>;
|
using RemapPathCallback = llvm::function_ref<std::string(StringRef)>;
|
||||||
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1> bridgeClangModuleDependencies(
|
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1> bridgeClangModuleDependencies(
|
||||||
const clang::tooling::dependencies::ModuleDepsGraph &clangDependencies,
|
clang::tooling::dependencies::ModuleDepsGraph &clangDependencies,
|
||||||
StringRef moduleOutputPath, RemapPathCallback remapPath = nullptr);
|
StringRef moduleOutputPath, RemapPathCallback remapPath = nullptr);
|
||||||
|
|
||||||
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
|
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "swift/Basic/LLVM.h"
|
#include "swift/Basic/LLVM.h"
|
||||||
#include "swift/Driver/Util.h"
|
#include "swift/Driver/Util.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/None.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
#include "llvm/ADT/TinyPtrVector.h"
|
#include "llvm/ADT/TinyPtrVector.h"
|
||||||
#include "llvm/Support/Chrono.h"
|
#include "llvm/Support/Chrono.h"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "swift/Driver/Action.h"
|
#include "swift/Driver/Action.h"
|
||||||
#include "swift/Driver/Job.h"
|
#include "swift/Driver/Job.h"
|
||||||
#include "swift/Option/Options.h"
|
#include "swift/Option/Options.h"
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/TargetParser/Triple.h"
|
||||||
#include "llvm/Option/Option.h"
|
#include "llvm/Option/Option.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
Output getOutput(size_t I) const;
|
Output getOutput(size_t I) const;
|
||||||
|
|
||||||
/// Retrieves a specific output specified by \p Kind, if it exists.
|
/// Retrieves a specific output specified by \p Kind, if it exists.
|
||||||
llvm::Optional<Output> getOutput(file_types::ID Kind) const;
|
std::optional<Output> getOutput(file_types::ID Kind) const;
|
||||||
|
|
||||||
/// Print this result to \p OS.
|
/// Print this result to \p OS.
|
||||||
llvm::Error print(llvm::raw_ostream &OS);
|
llvm::Error print(llvm::raw_ostream &OS);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
#include "llvm/Option/ArgList.h"
|
#include "llvm/Option/ArgList.h"
|
||||||
#include "llvm/Support/BLAKE3.h"
|
#include "llvm/Support/BLAKE3.h"
|
||||||
#include "llvm/Support/HashingOutputBackend.h"
|
#include "llvm/Support/HashingOutputBackend.h"
|
||||||
#include "llvm/Support/Host.h"
|
#include "llvm/TargetParser/Host.h"
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/VirtualOutputBackend.h"
|
#include "llvm/Support/VirtualOutputBackend.h"
|
||||||
|
|
||||||
@@ -165,6 +165,10 @@ public:
|
|||||||
return LangOpts.Target.str();
|
return LangOpts.Target.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool requiresCAS() const {
|
||||||
|
return FrontendOpts.EnableCaching || FrontendOpts.UseCASBackend;
|
||||||
|
}
|
||||||
|
|
||||||
void setClangModuleCachePath(StringRef Path) {
|
void setClangModuleCachePath(StringRef Path) {
|
||||||
ClangImporterOpts.ModuleCachePath = Path.str();
|
ClangImporterOpts.ModuleCachePath = Path.str();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,15 +14,17 @@
|
|||||||
#define SWIFT_FRONTEND_FRONTENDOPTIONS_H
|
#define SWIFT_FRONTEND_FRONTENDOPTIONS_H
|
||||||
|
|
||||||
#include "swift/Basic/FileTypes.h"
|
#include "swift/Basic/FileTypes.h"
|
||||||
#include "swift/Basic/Version.h"
|
|
||||||
#include "swift/Basic/PathRemapper.h"
|
#include "swift/Basic/PathRemapper.h"
|
||||||
|
#include "swift/Basic/Version.h"
|
||||||
#include "swift/Frontend/FrontendInputsAndOutputs.h"
|
#include "swift/Frontend/FrontendInputsAndOutputs.h"
|
||||||
#include "swift/Frontend/InputFile.h"
|
#include "swift/Frontend/InputFile.h"
|
||||||
|
#include "clang/CAS/CASOptions.h"
|
||||||
#include "llvm/ADT/Hashing.h"
|
#include "llvm/ADT/Hashing.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
#include "clang/CAS/CASOptions.h"
|
#include "llvm/MC/MCTargetOptions.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -148,6 +150,15 @@ public:
|
|||||||
/// CacheKey for input file.
|
/// CacheKey for input file.
|
||||||
std::string InputFileKey;
|
std::string InputFileKey;
|
||||||
|
|
||||||
|
/// Enable using the LLVM MCCAS backend for object file output.
|
||||||
|
bool UseCASBackend = false;
|
||||||
|
|
||||||
|
/// The output mode for the CAS Backend.
|
||||||
|
llvm::CASBackendMode CASObjMode;
|
||||||
|
|
||||||
|
/// Emit a .casid file next to the object file if CAS Backend is used.
|
||||||
|
bool EmitCASIDFile = false;
|
||||||
|
|
||||||
/// CacheReplay PrefixMap.
|
/// CacheReplay PrefixMap.
|
||||||
std::vector<std::string> CacheReplayPrefixMap;
|
std::vector<std::string> CacheReplayPrefixMap;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
#include "swift/Basic/Debug.h"
|
#include "swift/Basic/Debug.h"
|
||||||
#include "swift/Basic/LLVM.h"
|
#include "swift/Basic/LLVM.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/None.h"
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/Support/Allocator.h"
|
#include "llvm/Support/Allocator.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
#include "swift/Basic/LLVM.h"
|
#include "swift/Basic/LLVM.h"
|
||||||
#include "swift/Basic/OptionSet.h"
|
#include "swift/Basic/OptionSet.h"
|
||||||
|
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|||||||
@@ -98,9 +98,11 @@ private:
|
|||||||
llvm::Error
|
llvm::Error
|
||||||
notifyFailed(llvm::orc::MaterializationResponsibility &MR) override;
|
notifyFailed(llvm::orc::MaterializationResponsibility &MR) override;
|
||||||
|
|
||||||
llvm::Error notifyRemovingResources(llvm::orc::ResourceKey K) override;
|
llvm::Error notifyRemovingResources(llvm::orc::JITDylib &JD,
|
||||||
|
llvm::orc::ResourceKey K) override;
|
||||||
|
|
||||||
void notifyTransferringResources(llvm::orc::ResourceKey DstKey,
|
void notifyTransferringResources(llvm::orc::JITDylib &JD,
|
||||||
|
llvm::orc::ResourceKey DstKey,
|
||||||
llvm::orc::ResourceKey SrcKey) override;
|
llvm::orc::ResourceKey SrcKey) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -144,12 +144,6 @@ namespace swift {
|
|||||||
llvm::ModuleAnalysisManager &AM);
|
llvm::ModuleAnalysisManager &AM);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SwiftDbgAddrBlockSplitterPass
|
|
||||||
: public llvm::PassInfoMixin<SwiftDbgAddrBlockSplitterPass> {
|
|
||||||
llvm::PreservedAnalyses run(llvm::Function &F,
|
|
||||||
llvm::FunctionAnalysisManager &AM);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InlineTreePrinterPass
|
struct InlineTreePrinterPass
|
||||||
: public llvm::PassInfoMixin<InlineTreePrinterPass> {
|
: public llvm::PassInfoMixin<InlineTreePrinterPass> {
|
||||||
llvm::PreservedAnalyses run(llvm::Module &M,
|
llvm::PreservedAnalyses run(llvm::Module &M,
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ namespace llvm {
|
|||||||
void initializeSwiftARCContractPass(PassRegistry &);
|
void initializeSwiftARCContractPass(PassRegistry &);
|
||||||
void initializeInlineTreePrinterPass(PassRegistry &);
|
void initializeInlineTreePrinterPass(PassRegistry &);
|
||||||
void initializeLegacySwiftMergeFunctionsPass(PassRegistry &);
|
void initializeLegacySwiftMergeFunctionsPass(PassRegistry &);
|
||||||
void initializeSwiftDbgAddrBlockSplitterPass(PassRegistry &);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
@@ -33,7 +32,6 @@ namespace swift {
|
|||||||
llvm::ModulePass *createInlineTreePrinterPass();
|
llvm::ModulePass *createInlineTreePrinterPass();
|
||||||
llvm::ModulePass *createLegacySwiftMergeFunctionsPass(bool ptrAuthEnabled,
|
llvm::ModulePass *createLegacySwiftMergeFunctionsPass(bool ptrAuthEnabled,
|
||||||
unsigned ptrAuthKey);
|
unsigned ptrAuthKey);
|
||||||
llvm::FunctionPass *createSwiftDbgAddrBlockSplitter();
|
|
||||||
llvm::ImmutablePass *createSwiftAAWrapperPass();
|
llvm::ImmutablePass *createSwiftAAWrapperPass();
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|
||||||
|
|||||||
@@ -1900,6 +1900,19 @@ def external_plugin_path : Separate<["-"], "external-plugin-path">, Group<plugin
|
|||||||
Flags<[FrontendOption, ArgumentIsPath, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>,
|
Flags<[FrontendOption, ArgumentIsPath, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>,
|
||||||
HelpText<"Add directory to the plugin search path with a plugin server executable">,
|
HelpText<"Add directory to the plugin search path with a plugin server executable">,
|
||||||
MetaVarName<"<path>#<plugin-server-path>">;
|
MetaVarName<"<path>#<plugin-server-path>">;
|
||||||
|
|
||||||
|
def cas_backend: Flag<["-"], "cas-backend">,
|
||||||
|
Flags<[FrontendOption, NoDriverOption]>,
|
||||||
|
HelpText<"Enable using CASBackend for object file output">;
|
||||||
|
|
||||||
|
def cas_backend_mode: Joined<["-"], "cas-backend-mode=">,
|
||||||
|
Flags<[FrontendOption, NoDriverOption]>,
|
||||||
|
HelpText<"CASBackendMode for output kind">,
|
||||||
|
MetaVarName<"native|casid|verify">;
|
||||||
|
|
||||||
|
def cas_emit_casid_file: Flag<["-"], "cas-emit-casid-file">,
|
||||||
|
Flags<[FrontendOption, NoDriverOption]>,
|
||||||
|
HelpText<"Emit .casid file next to object file when CAS Backend is enabled">;
|
||||||
|
|
||||||
def load_plugin_library:
|
def load_plugin_library:
|
||||||
Separate<["-"], "load-plugin-library">, Group<plugin_search_Group>,
|
Separate<["-"], "load-plugin-library">, Group<plugin_search_Group>,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
#include "swift/Basic/Sanitizers.h"
|
#include "swift/Basic/Sanitizers.h"
|
||||||
#include "swift/Basic/OptionSet.h"
|
#include "swift/Basic/OptionSet.h"
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/TargetParser/Triple.h"
|
||||||
#include "llvm/Option/Arg.h"
|
#include "llvm/Option/Arg.h"
|
||||||
#include "llvm/Option/ArgList.h"
|
#include "llvm/Option/ArgList.h"
|
||||||
// FIXME: This include is just for llvm::SanitizerCoverageOptions. We should
|
// FIXME: This include is just for llvm::SanitizerCoverageOptions. We should
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*===-- include/llvm-c/DataTypes.h - Define fixed size types ------*- C -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* This file contains definitions to figure out the size of _HOST_ data types.*|
|
||||||
|
|* This file is important because different host OS's define different macros,*|
|
||||||
|
|* which makes portability tough. This file exports the following *|
|
||||||
|
|* definitions: *|
|
||||||
|
|* *|
|
||||||
|
|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
|
||||||
|
|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
|
||||||
|
|* *|
|
||||||
|
|* No library is required when using these functions. *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
/* Please leave this file C-compatible. */
|
||||||
|
|
||||||
|
#ifndef LLVM_C_DATATYPES_H
|
||||||
|
#define LLVM_C_DATATYPES_H
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
|
||||||
|
#if !defined(UINT32_MAX)
|
||||||
|
# error "The standard header <cstdint> is not C++11 compliant. Must #define "\
|
||||||
|
"__STDC_LIMIT_MACROS before #including llvm-c/DataTypes.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(UINT32_C)
|
||||||
|
# error "The standard header <cstdint> is not C++11 compliant. Must #define "\
|
||||||
|
"__STDC_CONSTANT_MACROS before #including llvm-c/DataTypes.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef _AIX
|
||||||
|
// GCC is strict about defining large constants: they must have LL modifier.
|
||||||
|
#undef INT64_MAX
|
||||||
|
#undef INT64_MIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* _MSC_VER */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdlib>
|
||||||
|
#else
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
typedef signed __int64 ssize_t;
|
||||||
|
#else
|
||||||
|
typedef signed int ssize_t;
|
||||||
|
#endif /* _WIN64 */
|
||||||
|
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
/* Set defaults for constants which we cannot find. */
|
||||||
|
#if !defined(INT64_MAX)
|
||||||
|
# define INT64_MAX 9223372036854775807LL
|
||||||
|
#endif
|
||||||
|
#if !defined(INT64_MIN)
|
||||||
|
# define INT64_MIN ((-INT64_MAX)-1)
|
||||||
|
#endif
|
||||||
|
#if !defined(UINT64_MAX)
|
||||||
|
# define UINT64_MAX 0xffffffffffffffffULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LLVM_C_DATATYPES_H */
|
||||||
83
include/swift/RemoteInspection/RuntimeHeaders/llvm-c/Error.h
Normal file
83
include/swift/RemoteInspection/RuntimeHeaders/llvm-c/Error.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*===------- llvm-c/Error.h - llvm::Error class C Interface -------*- C -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* This file defines the C interface to LLVM's Error class. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#ifndef LLVM_C_ERROR_H
|
||||||
|
#define LLVM_C_ERROR_H
|
||||||
|
|
||||||
|
#include "llvm-c/ExternC.h"
|
||||||
|
|
||||||
|
LLVM_C_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup LLVMCError Error Handling
|
||||||
|
* @ingroup LLVMC
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LLVMErrorSuccess 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opaque reference to an error instance. Null serves as the 'success' value.
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueError *LLVMErrorRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error type identifier.
|
||||||
|
*/
|
||||||
|
typedef const void *LLVMErrorTypeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type id for the given error instance, which must be a failure
|
||||||
|
* value (i.e. non-null).
|
||||||
|
*/
|
||||||
|
LLVMErrorTypeId LLVMGetErrorTypeId(LLVMErrorRef Err);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispose of the given error without handling it. This operation consumes the
|
||||||
|
* error, and the given LLVMErrorRef value is not usable once this call returns.
|
||||||
|
* Note: This method *only* needs to be called if the error is not being passed
|
||||||
|
* to some other consuming operation, e.g. LLVMGetErrorMessage.
|
||||||
|
*/
|
||||||
|
void LLVMConsumeError(LLVMErrorRef Err);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the given string's error message. This operation consumes the error,
|
||||||
|
* and the given LLVMErrorRef value is not usable once this call returns.
|
||||||
|
* The caller is responsible for disposing of the string by calling
|
||||||
|
* LLVMDisposeErrorMessage.
|
||||||
|
*/
|
||||||
|
char *LLVMGetErrorMessage(LLVMErrorRef Err);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispose of the given error message.
|
||||||
|
*/
|
||||||
|
void LLVMDisposeErrorMessage(char *ErrMsg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type id for llvm StringError.
|
||||||
|
*/
|
||||||
|
LLVMErrorTypeId LLVMGetStringErrorTypeId(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a StringError.
|
||||||
|
*/
|
||||||
|
LLVMErrorRef LLVMCreateStringError(const char *ErrMsg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
LLVM_C_EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*===- llvm-c/ExternC.h - Wrapper for 'extern "C"' ----------------*- C -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* This file defines an 'extern "C"' wrapper *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#ifndef LLVM_C_EXTERNC_H
|
||||||
|
#define LLVM_C_EXTERNC_H
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#define LLVM_C_STRICT_PROTOTYPES_BEGIN \
|
||||||
|
_Pragma("clang diagnostic push") \
|
||||||
|
_Pragma("clang diagnostic error \"-Wstrict-prototypes\"")
|
||||||
|
#define LLVM_C_STRICT_PROTOTYPES_END _Pragma("clang diagnostic pop")
|
||||||
|
#else
|
||||||
|
#define LLVM_C_STRICT_PROTOTYPES_BEGIN
|
||||||
|
#define LLVM_C_STRICT_PROTOTYPES_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define LLVM_C_EXTERN_C_BEGIN \
|
||||||
|
extern "C" { \
|
||||||
|
LLVM_C_STRICT_PROTOTYPES_BEGIN
|
||||||
|
#define LLVM_C_EXTERN_C_END \
|
||||||
|
LLVM_C_STRICT_PROTOTYPES_END \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define LLVM_C_EXTERN_C_BEGIN LLVM_C_STRICT_PROTOTYPES_BEGIN
|
||||||
|
#define LLVM_C_EXTERN_C_END LLVM_C_STRICT_PROTOTYPES_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
173
include/swift/RemoteInspection/RuntimeHeaders/llvm-c/Types.h
Normal file
173
include/swift/RemoteInspection/RuntimeHeaders/llvm-c/Types.h
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
/*===-- llvm-c/Support.h - C Interface Types declarations ---------*- C -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* This file defines types used by the C interface to LLVM. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#ifndef LLVM_C_TYPES_H
|
||||||
|
#define LLVM_C_TYPES_H
|
||||||
|
|
||||||
|
#include "llvm-c/DataTypes.h"
|
||||||
|
#include "llvm-c/ExternC.h"
|
||||||
|
|
||||||
|
LLVM_C_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup LLVMCSupportTypes Types and Enumerations
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int LLVMBool;
|
||||||
|
|
||||||
|
/* Opaque types. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LLVM uses a polymorphic type hierarchy which C cannot represent, therefore
|
||||||
|
* parameters must be passed as base types. Despite the declared types, most
|
||||||
|
* of the functions provided operate only on branches of the type hierarchy.
|
||||||
|
* The declared parameter names are descriptive and specify which type is
|
||||||
|
* required. Additionally, each type hierarchy is documented along with the
|
||||||
|
* functions that operate upon it. For more detail, refer to LLVM's C++ code.
|
||||||
|
* If in doubt, refer to Core.cpp, which performs parameter downcasts in the
|
||||||
|
* form unwrap<RequiredType>(Param).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to pass regions of memory through LLVM interfaces.
|
||||||
|
*
|
||||||
|
* @see llvm::MemoryBuffer
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The top-level container for all LLVM global data. See the LLVMContext class.
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueContext *LLVMContextRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The top-level container for all other LLVM Intermediate Representation (IR)
|
||||||
|
* objects.
|
||||||
|
*
|
||||||
|
* @see llvm::Module
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueModule *LLVMModuleRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each value in the LLVM IR has a type, an LLVMTypeRef.
|
||||||
|
*
|
||||||
|
* @see llvm::Type
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueType *LLVMTypeRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an individual value in LLVM IR.
|
||||||
|
*
|
||||||
|
* This models llvm::Value.
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueValue *LLVMValueRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a basic block of instructions in LLVM IR.
|
||||||
|
*
|
||||||
|
* This models llvm::BasicBlock.
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an LLVM Metadata.
|
||||||
|
*
|
||||||
|
* This models llvm::Metadata.
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an LLVM Named Metadata Node.
|
||||||
|
*
|
||||||
|
* This models llvm::NamedMDNode.
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueNamedMDNode *LLVMNamedMDNodeRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an entry in a Global Object's metadata attachments.
|
||||||
|
*
|
||||||
|
* This models std::pair<unsigned, MDNode *>
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueValueMetadataEntry LLVMValueMetadataEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an LLVM basic block builder.
|
||||||
|
*
|
||||||
|
* This models llvm::IRBuilder.
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an LLVM debug info builder.
|
||||||
|
*
|
||||||
|
* This models llvm::DIBuilder.
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueDIBuilder *LLVMDIBuilderRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface used to provide a module to JIT or interpreter.
|
||||||
|
* This is now just a synonym for llvm::Module, but we have to keep using the
|
||||||
|
* different type to keep binary compatibility.
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
|
||||||
|
|
||||||
|
/** @see llvm::PassManagerBase */
|
||||||
|
typedef struct LLVMOpaquePassManager *LLVMPassManagerRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to get the users and usees of a Value.
|
||||||
|
*
|
||||||
|
* @see llvm::Use */
|
||||||
|
typedef struct LLVMOpaqueUse *LLVMUseRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to represent an attributes.
|
||||||
|
*
|
||||||
|
* @see llvm::Attribute
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueAttributeRef *LLVMAttributeRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see llvm::DiagnosticInfo
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueDiagnosticInfo *LLVMDiagnosticInfoRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see llvm::Comdat
|
||||||
|
*/
|
||||||
|
typedef struct LLVMComdat *LLVMComdatRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see llvm::Module::ModuleFlagEntry
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueModuleFlagEntry LLVMModuleFlagEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see llvm::JITEventListener
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueJITEventListener *LLVMJITEventListenerRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see llvm::object::Binary
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueBinary *LLVMBinaryRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
LLVM_C_EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
//===-- llvm/ADT/BitmaskEnum.h ----------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_ADT_BITMASKENUM_H
|
||||||
|
#define LLVM_ADT_BITMASKENUM_H
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "llvm/Support/MathExtras.h"
|
||||||
|
|
||||||
|
/// LLVM_MARK_AS_BITMASK_ENUM lets you opt in an individual enum type so you can
|
||||||
|
/// perform bitwise operations on it without putting static_cast everywhere.
|
||||||
|
///
|
||||||
|
/// \code
|
||||||
|
/// enum MyEnum {
|
||||||
|
/// E1 = 1, E2 = 2, E3 = 4, E4 = 8,
|
||||||
|
/// LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ E4)
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// void Foo() {
|
||||||
|
/// MyEnum A = (E1 | E2) & E3 ^ ~E4; // Look, ma: No static_cast!
|
||||||
|
/// }
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
/// Normally when you do a bitwise operation on an enum value, you get back an
|
||||||
|
/// instance of the underlying type (e.g. int). But using this macro, bitwise
|
||||||
|
/// ops on your enum will return you back instances of the enum. This is
|
||||||
|
/// particularly useful for enums which represent a combination of flags.
|
||||||
|
///
|
||||||
|
/// The parameter to LLVM_MARK_AS_BITMASK_ENUM should be the largest individual
|
||||||
|
/// value in your enum.
|
||||||
|
///
|
||||||
|
/// All of the enum's values must be non-negative.
|
||||||
|
#define LLVM_MARK_AS_BITMASK_ENUM(LargestValue) \
|
||||||
|
LLVM_BITMASK_LARGEST_ENUMERATOR = LargestValue
|
||||||
|
|
||||||
|
/// LLVM_DECLARE_ENUM_AS_BITMASK can be used to declare an enum type as a bit
|
||||||
|
/// set, so that bitwise operation on such enum does not require static_cast.
|
||||||
|
///
|
||||||
|
/// \code
|
||||||
|
/// enum MyEnum { E1 = 1, E2 = 2, E3 = 4, E4 = 8 };
|
||||||
|
/// LLVM_DECLARE_ENUM_AS_BITMASK(MyEnum, E4);
|
||||||
|
///
|
||||||
|
/// void Foo() {
|
||||||
|
/// MyEnum A = (E1 | E2) & E3 ^ ~E4; // No static_cast
|
||||||
|
/// }
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
/// The second parameter to LLVM_DECLARE_ENUM_AS_BITMASK specifies the largest
|
||||||
|
/// bit value of the enum type.
|
||||||
|
///
|
||||||
|
/// LLVM_DECLARE_ENUM_AS_BITMASK should be used in llvm namespace.
|
||||||
|
///
|
||||||
|
/// This a non-intrusive alternative for LLVM_MARK_AS_BITMASK_ENUM. It allows
|
||||||
|
/// declaring more than one non-scoped enumerations as bitmask types in the same
|
||||||
|
/// scope. Otherwise it provides the same functionality as
|
||||||
|
/// LLVM_MARK_AS_BITMASK_ENUM.
|
||||||
|
#define LLVM_DECLARE_ENUM_AS_BITMASK(Enum, LargestValue) \
|
||||||
|
template <> struct is_bitmask_enum<Enum> : std::true_type {}; \
|
||||||
|
template <> struct largest_bitmask_enum_bit<Enum> { \
|
||||||
|
static constexpr std::underlying_type_t<Enum> value = LargestValue; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE() pulls the operator overloads used
|
||||||
|
/// by LLVM_MARK_AS_BITMASK_ENUM into the current namespace.
|
||||||
|
///
|
||||||
|
/// Suppose you have an enum foo::bar::MyEnum. Before using
|
||||||
|
/// LLVM_MARK_AS_BITMASK_ENUM on MyEnum, you must put
|
||||||
|
/// LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE() somewhere inside namespace foo or
|
||||||
|
/// namespace foo::bar. This allows the relevant operator overloads to be found
|
||||||
|
/// by ADL.
|
||||||
|
///
|
||||||
|
/// You don't need to use this macro in namespace llvm; it's done at the bottom
|
||||||
|
/// of this file.
|
||||||
|
#define LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE() \
|
||||||
|
using ::llvm::BitmaskEnumDetail::operator~; \
|
||||||
|
using ::llvm::BitmaskEnumDetail::operator|; \
|
||||||
|
using ::llvm::BitmaskEnumDetail::operator&; \
|
||||||
|
using ::llvm::BitmaskEnumDetail::operator^; \
|
||||||
|
using ::llvm::BitmaskEnumDetail::operator|=; \
|
||||||
|
using ::llvm::BitmaskEnumDetail::operator&=; \
|
||||||
|
/* Force a semicolon at the end of this macro. */ \
|
||||||
|
using ::llvm::BitmaskEnumDetail::operator^=
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
/// Traits class to determine whether an enum has a
|
||||||
|
/// LLVM_BITMASK_LARGEST_ENUMERATOR enumerator.
|
||||||
|
template <typename E, typename Enable = void>
|
||||||
|
struct is_bitmask_enum : std::false_type {};
|
||||||
|
|
||||||
|
template <typename E>
|
||||||
|
struct is_bitmask_enum<
|
||||||
|
E, std::enable_if_t<sizeof(E::LLVM_BITMASK_LARGEST_ENUMERATOR) >= 0>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
|
/// Trait class to determine bitmask enumeration largest bit.
|
||||||
|
template <typename E, typename Enable = void> struct largest_bitmask_enum_bit;
|
||||||
|
|
||||||
|
template <typename E>
|
||||||
|
struct largest_bitmask_enum_bit<
|
||||||
|
E, std::enable_if_t<sizeof(E::LLVM_BITMASK_LARGEST_ENUMERATOR) >= 0>> {
|
||||||
|
using UnderlyingTy = std::underlying_type_t<E>;
|
||||||
|
static constexpr UnderlyingTy value =
|
||||||
|
static_cast<UnderlyingTy>(E::LLVM_BITMASK_LARGEST_ENUMERATOR);
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace BitmaskEnumDetail {
|
||||||
|
|
||||||
|
/// Get a bitmask with 1s in all places up to the high-order bit of E's largest
|
||||||
|
/// value.
|
||||||
|
template <typename E> constexpr std::underlying_type_t<E> Mask() {
|
||||||
|
// On overflow, NextPowerOf2 returns zero with the type uint64_t, so
|
||||||
|
// subtracting 1 gives us the mask with all bits set, like we want.
|
||||||
|
return NextPowerOf2(largest_bitmask_enum_bit<E>::value) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check that Val is in range for E, and return Val cast to E's underlying
|
||||||
|
/// type.
|
||||||
|
template <typename E> constexpr std::underlying_type_t<E> Underlying(E Val) {
|
||||||
|
auto U = static_cast<std::underlying_type_t<E>>(Val);
|
||||||
|
assert(U >= 0 && "Negative enum values are not allowed.");
|
||||||
|
assert(U <= Mask<E>() && "Enum value too large (or largest val too small?)");
|
||||||
|
return U;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr unsigned bitWidth(uint64_t Value) {
|
||||||
|
return Value ? 1 + bitWidth(Value >> 1) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
|
||||||
|
constexpr E operator~(E Val) {
|
||||||
|
return static_cast<E>(~Underlying(Val) & Mask<E>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
|
||||||
|
constexpr E operator|(E LHS, E RHS) {
|
||||||
|
return static_cast<E>(Underlying(LHS) | Underlying(RHS));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
|
||||||
|
constexpr E operator&(E LHS, E RHS) {
|
||||||
|
return static_cast<E>(Underlying(LHS) & Underlying(RHS));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
|
||||||
|
constexpr E operator^(E LHS, E RHS) {
|
||||||
|
return static_cast<E>(Underlying(LHS) ^ Underlying(RHS));
|
||||||
|
}
|
||||||
|
|
||||||
|
// |=, &=, and ^= return a reference to LHS, to match the behavior of the
|
||||||
|
// operators on builtin types.
|
||||||
|
|
||||||
|
template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
|
||||||
|
E &operator|=(E &LHS, E RHS) {
|
||||||
|
LHS = LHS | RHS;
|
||||||
|
return LHS;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
|
||||||
|
E &operator&=(E &LHS, E RHS) {
|
||||||
|
LHS = LHS & RHS;
|
||||||
|
return LHS;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
|
||||||
|
E &operator^=(E &LHS, E RHS) {
|
||||||
|
LHS = LHS ^ RHS;
|
||||||
|
return LHS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BitmaskEnumDetail
|
||||||
|
|
||||||
|
// Enable bitmask enums in namespace ::llvm and all nested namespaces.
|
||||||
|
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
|
||||||
|
template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
|
||||||
|
constexpr unsigned BitWidth = BitmaskEnumDetail::bitWidth(uint64_t{
|
||||||
|
static_cast<std::underlying_type_t<E>>(
|
||||||
|
E::LLVM_BITMASK_LARGEST_ENUMERATOR)});
|
||||||
|
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,817 @@
|
|||||||
|
//===-- llvm/BinaryFormat/COFF.h --------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file contains an definitions used in Windows COFF Files.
|
||||||
|
//
|
||||||
|
// Structures and enums defined within this file where created using
|
||||||
|
// information from Microsoft's publicly available PE/COFF format document:
|
||||||
|
//
|
||||||
|
// Microsoft Portable Executable and Common Object File Format Specification
|
||||||
|
// Revision 8.1 - February 15, 2008
|
||||||
|
//
|
||||||
|
// As of 5/2/2010, hosted by Microsoft at:
|
||||||
|
// http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_BINARYFORMAT_COFF_H
|
||||||
|
#define LLVM_BINARYFORMAT_COFF_H
|
||||||
|
|
||||||
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace COFF {
|
||||||
|
|
||||||
|
// The maximum number of sections that a COFF object can have (inclusive).
|
||||||
|
const int32_t MaxNumberOfSections16 = 65279;
|
||||||
|
|
||||||
|
// The PE signature bytes that follows the DOS stub header.
|
||||||
|
static const char PEMagic[] = {'P', 'E', '\0', '\0'};
|
||||||
|
|
||||||
|
static const char BigObjMagic[] = {
|
||||||
|
'\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b',
|
||||||
|
'\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8',
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char ClGlObjMagic[] = {
|
||||||
|
'\x38', '\xfe', '\xb3', '\x0c', '\xa5', '\xd9', '\xab', '\x4d',
|
||||||
|
'\xac', '\x9b', '\xd6', '\xb6', '\x22', '\x26', '\x53', '\xc2',
|
||||||
|
};
|
||||||
|
|
||||||
|
// The signature bytes that start a .res file.
|
||||||
|
static const char WinResMagic[] = {
|
||||||
|
'\x00', '\x00', '\x00', '\x00', '\x20', '\x00', '\x00', '\x00',
|
||||||
|
'\xff', '\xff', '\x00', '\x00', '\xff', '\xff', '\x00', '\x00',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sizes in bytes of various things in the COFF format.
|
||||||
|
enum {
|
||||||
|
Header16Size = 20,
|
||||||
|
Header32Size = 56,
|
||||||
|
NameSize = 8,
|
||||||
|
Symbol16Size = 18,
|
||||||
|
Symbol32Size = 20,
|
||||||
|
SectionSize = 40,
|
||||||
|
RelocationSize = 10
|
||||||
|
};
|
||||||
|
|
||||||
|
struct header {
|
||||||
|
uint16_t Machine;
|
||||||
|
int32_t NumberOfSections;
|
||||||
|
uint32_t TimeDateStamp;
|
||||||
|
uint32_t PointerToSymbolTable;
|
||||||
|
uint32_t NumberOfSymbols;
|
||||||
|
uint16_t SizeOfOptionalHeader;
|
||||||
|
uint16_t Characteristics;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BigObjHeader {
|
||||||
|
enum : uint16_t { MinBigObjectVersion = 2 };
|
||||||
|
|
||||||
|
uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
|
||||||
|
uint16_t Sig2; ///< Must be 0xFFFF.
|
||||||
|
uint16_t Version;
|
||||||
|
uint16_t Machine;
|
||||||
|
uint32_t TimeDateStamp;
|
||||||
|
uint8_t UUID[16];
|
||||||
|
uint32_t unused1;
|
||||||
|
uint32_t unused2;
|
||||||
|
uint32_t unused3;
|
||||||
|
uint32_t unused4;
|
||||||
|
uint32_t NumberOfSections;
|
||||||
|
uint32_t PointerToSymbolTable;
|
||||||
|
uint32_t NumberOfSymbols;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MachineTypes : unsigned {
|
||||||
|
MT_Invalid = 0xffff,
|
||||||
|
|
||||||
|
IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
|
||||||
|
IMAGE_FILE_MACHINE_AM33 = 0x1D3,
|
||||||
|
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
|
||||||
|
IMAGE_FILE_MACHINE_ARM = 0x1C0,
|
||||||
|
IMAGE_FILE_MACHINE_ARMNT = 0x1C4,
|
||||||
|
IMAGE_FILE_MACHINE_ARM64 = 0xAA64,
|
||||||
|
IMAGE_FILE_MACHINE_ARM64EC = 0xA641,
|
||||||
|
IMAGE_FILE_MACHINE_ARM64X = 0xA64E,
|
||||||
|
IMAGE_FILE_MACHINE_EBC = 0xEBC,
|
||||||
|
IMAGE_FILE_MACHINE_I386 = 0x14C,
|
||||||
|
IMAGE_FILE_MACHINE_IA64 = 0x200,
|
||||||
|
IMAGE_FILE_MACHINE_M32R = 0x9041,
|
||||||
|
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
|
||||||
|
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
|
||||||
|
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
|
||||||
|
IMAGE_FILE_MACHINE_POWERPC = 0x1F0,
|
||||||
|
IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1,
|
||||||
|
IMAGE_FILE_MACHINE_R4000 = 0x166,
|
||||||
|
IMAGE_FILE_MACHINE_RISCV32 = 0x5032,
|
||||||
|
IMAGE_FILE_MACHINE_RISCV64 = 0x5064,
|
||||||
|
IMAGE_FILE_MACHINE_RISCV128 = 0x5128,
|
||||||
|
IMAGE_FILE_MACHINE_SH3 = 0x1A2,
|
||||||
|
IMAGE_FILE_MACHINE_SH3DSP = 0x1A3,
|
||||||
|
IMAGE_FILE_MACHINE_SH4 = 0x1A6,
|
||||||
|
IMAGE_FILE_MACHINE_SH5 = 0x1A8,
|
||||||
|
IMAGE_FILE_MACHINE_THUMB = 0x1C2,
|
||||||
|
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> bool isArm64EC(T Machine) {
|
||||||
|
return Machine == IMAGE_FILE_MACHINE_ARM64EC ||
|
||||||
|
Machine == IMAGE_FILE_MACHINE_ARM64X;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> bool isAnyArm64(T Machine) {
|
||||||
|
return Machine == IMAGE_FILE_MACHINE_ARM64 || isArm64EC(Machine);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> bool is64Bit(T Machine) {
|
||||||
|
return Machine == IMAGE_FILE_MACHINE_AMD64 || isAnyArm64(Machine);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Characteristics : unsigned {
|
||||||
|
C_Invalid = 0,
|
||||||
|
|
||||||
|
/// The file does not contain base relocations and must be loaded at its
|
||||||
|
/// preferred base. If this cannot be done, the loader will error.
|
||||||
|
IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
|
||||||
|
/// The file is valid and can be run.
|
||||||
|
IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,
|
||||||
|
/// COFF line numbers have been stripped. This is deprecated and should be
|
||||||
|
/// 0.
|
||||||
|
IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004,
|
||||||
|
/// COFF symbol table entries for local symbols have been removed. This is
|
||||||
|
/// deprecated and should be 0.
|
||||||
|
IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008,
|
||||||
|
/// Aggressively trim working set. This is deprecated and must be 0.
|
||||||
|
IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010,
|
||||||
|
/// Image can handle > 2GiB addresses.
|
||||||
|
IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,
|
||||||
|
/// Little endian: the LSB precedes the MSB in memory. This is deprecated
|
||||||
|
/// and should be 0.
|
||||||
|
IMAGE_FILE_BYTES_REVERSED_LO = 0x0080,
|
||||||
|
/// Machine is based on a 32bit word architecture.
|
||||||
|
IMAGE_FILE_32BIT_MACHINE = 0x0100,
|
||||||
|
/// Debugging info has been removed.
|
||||||
|
IMAGE_FILE_DEBUG_STRIPPED = 0x0200,
|
||||||
|
/// If the image is on removable media, fully load it and copy it to swap.
|
||||||
|
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,
|
||||||
|
/// If the image is on network media, fully load it and copy it to swap.
|
||||||
|
IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800,
|
||||||
|
/// The image file is a system file, not a user program.
|
||||||
|
IMAGE_FILE_SYSTEM = 0x1000,
|
||||||
|
/// The image file is a DLL.
|
||||||
|
IMAGE_FILE_DLL = 0x2000,
|
||||||
|
/// This file should only be run on a uniprocessor machine.
|
||||||
|
IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,
|
||||||
|
/// Big endian: the MSB precedes the LSB in memory. This is deprecated
|
||||||
|
/// and should be 0.
|
||||||
|
IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ResourceTypeID : unsigned {
|
||||||
|
RID_Cursor = 1,
|
||||||
|
RID_Bitmap = 2,
|
||||||
|
RID_Icon = 3,
|
||||||
|
RID_Menu = 4,
|
||||||
|
RID_Dialog = 5,
|
||||||
|
RID_String = 6,
|
||||||
|
RID_FontDir = 7,
|
||||||
|
RID_Font = 8,
|
||||||
|
RID_Accelerator = 9,
|
||||||
|
RID_RCData = 10,
|
||||||
|
RID_MessageTable = 11,
|
||||||
|
RID_Group_Cursor = 12,
|
||||||
|
RID_Group_Icon = 14,
|
||||||
|
RID_Version = 16,
|
||||||
|
RID_DLGInclude = 17,
|
||||||
|
RID_PlugPlay = 19,
|
||||||
|
RID_VXD = 20,
|
||||||
|
RID_AniCursor = 21,
|
||||||
|
RID_AniIcon = 22,
|
||||||
|
RID_HTML = 23,
|
||||||
|
RID_Manifest = 24,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct symbol {
|
||||||
|
char Name[NameSize];
|
||||||
|
uint32_t Value;
|
||||||
|
int32_t SectionNumber;
|
||||||
|
uint16_t Type;
|
||||||
|
uint8_t StorageClass;
|
||||||
|
uint8_t NumberOfAuxSymbols;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SymbolSectionNumber : int32_t {
|
||||||
|
IMAGE_SYM_DEBUG = -2,
|
||||||
|
IMAGE_SYM_ABSOLUTE = -1,
|
||||||
|
IMAGE_SYM_UNDEFINED = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Storage class tells where and what the symbol represents
|
||||||
|
enum SymbolStorageClass {
|
||||||
|
SSC_Invalid = 0xff,
|
||||||
|
|
||||||
|
IMAGE_SYM_CLASS_END_OF_FUNCTION = -1, ///< Physical end of function
|
||||||
|
IMAGE_SYM_CLASS_NULL = 0, ///< No symbol
|
||||||
|
IMAGE_SYM_CLASS_AUTOMATIC = 1, ///< Stack variable
|
||||||
|
IMAGE_SYM_CLASS_EXTERNAL = 2, ///< External symbol
|
||||||
|
IMAGE_SYM_CLASS_STATIC = 3, ///< Static
|
||||||
|
IMAGE_SYM_CLASS_REGISTER = 4, ///< Register variable
|
||||||
|
IMAGE_SYM_CLASS_EXTERNAL_DEF = 5, ///< External definition
|
||||||
|
IMAGE_SYM_CLASS_LABEL = 6, ///< Label
|
||||||
|
IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7, ///< Undefined label
|
||||||
|
IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8, ///< Member of structure
|
||||||
|
IMAGE_SYM_CLASS_ARGUMENT = 9, ///< Function argument
|
||||||
|
IMAGE_SYM_CLASS_STRUCT_TAG = 10, ///< Structure tag
|
||||||
|
IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11, ///< Member of union
|
||||||
|
IMAGE_SYM_CLASS_UNION_TAG = 12, ///< Union tag
|
||||||
|
IMAGE_SYM_CLASS_TYPE_DEFINITION = 13, ///< Type definition
|
||||||
|
IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14, ///< Undefined static
|
||||||
|
IMAGE_SYM_CLASS_ENUM_TAG = 15, ///< Enumeration tag
|
||||||
|
IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16, ///< Member of enumeration
|
||||||
|
IMAGE_SYM_CLASS_REGISTER_PARAM = 17, ///< Register parameter
|
||||||
|
IMAGE_SYM_CLASS_BIT_FIELD = 18, ///< Bit field
|
||||||
|
/// ".bb" or ".eb" - beginning or end of block
|
||||||
|
IMAGE_SYM_CLASS_BLOCK = 100,
|
||||||
|
/// ".bf" or ".ef" - beginning or end of function
|
||||||
|
IMAGE_SYM_CLASS_FUNCTION = 101,
|
||||||
|
IMAGE_SYM_CLASS_END_OF_STRUCT = 102, ///< End of structure
|
||||||
|
IMAGE_SYM_CLASS_FILE = 103, ///< File name
|
||||||
|
/// Line number, reformatted as symbol
|
||||||
|
IMAGE_SYM_CLASS_SECTION = 104,
|
||||||
|
IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105, ///< Duplicate tag
|
||||||
|
/// External symbol in dmert public lib
|
||||||
|
IMAGE_SYM_CLASS_CLR_TOKEN = 107
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SymbolBaseType : unsigned {
|
||||||
|
IMAGE_SYM_TYPE_NULL = 0, ///< No type information or unknown base type.
|
||||||
|
IMAGE_SYM_TYPE_VOID = 1, ///< Used with void pointers and functions.
|
||||||
|
IMAGE_SYM_TYPE_CHAR = 2, ///< A character (signed byte).
|
||||||
|
IMAGE_SYM_TYPE_SHORT = 3, ///< A 2-byte signed integer.
|
||||||
|
IMAGE_SYM_TYPE_INT = 4, ///< A natural integer type on the target.
|
||||||
|
IMAGE_SYM_TYPE_LONG = 5, ///< A 4-byte signed integer.
|
||||||
|
IMAGE_SYM_TYPE_FLOAT = 6, ///< A 4-byte floating-point number.
|
||||||
|
IMAGE_SYM_TYPE_DOUBLE = 7, ///< An 8-byte floating-point number.
|
||||||
|
IMAGE_SYM_TYPE_STRUCT = 8, ///< A structure.
|
||||||
|
IMAGE_SYM_TYPE_UNION = 9, ///< An union.
|
||||||
|
IMAGE_SYM_TYPE_ENUM = 10, ///< An enumerated type.
|
||||||
|
IMAGE_SYM_TYPE_MOE = 11, ///< A member of enumeration (a specific value).
|
||||||
|
IMAGE_SYM_TYPE_BYTE = 12, ///< A byte; unsigned 1-byte integer.
|
||||||
|
IMAGE_SYM_TYPE_WORD = 13, ///< A word; unsigned 2-byte integer.
|
||||||
|
IMAGE_SYM_TYPE_UINT = 14, ///< An unsigned integer of natural size.
|
||||||
|
IMAGE_SYM_TYPE_DWORD = 15 ///< An unsigned 4-byte integer.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SymbolComplexType : unsigned {
|
||||||
|
IMAGE_SYM_DTYPE_NULL = 0, ///< No complex type; simple scalar variable.
|
||||||
|
IMAGE_SYM_DTYPE_POINTER = 1, ///< A pointer to base type.
|
||||||
|
IMAGE_SYM_DTYPE_FUNCTION = 2, ///< A function that returns a base type.
|
||||||
|
IMAGE_SYM_DTYPE_ARRAY = 3, ///< An array of base type.
|
||||||
|
|
||||||
|
/// Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
|
||||||
|
SCT_COMPLEX_TYPE_SHIFT = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AuxSymbolType { IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1 };
|
||||||
|
|
||||||
|
struct section {
|
||||||
|
char Name[NameSize];
|
||||||
|
uint32_t VirtualSize;
|
||||||
|
uint32_t VirtualAddress;
|
||||||
|
uint32_t SizeOfRawData;
|
||||||
|
uint32_t PointerToRawData;
|
||||||
|
uint32_t PointerToRelocations;
|
||||||
|
uint32_t PointerToLineNumbers;
|
||||||
|
uint16_t NumberOfRelocations;
|
||||||
|
uint16_t NumberOfLineNumbers;
|
||||||
|
uint32_t Characteristics;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SectionCharacteristics : uint32_t {
|
||||||
|
SC_Invalid = 0xffffffff,
|
||||||
|
|
||||||
|
IMAGE_SCN_TYPE_NOLOAD = 0x00000002,
|
||||||
|
IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
|
||||||
|
IMAGE_SCN_CNT_CODE = 0x00000020,
|
||||||
|
IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
|
||||||
|
IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
|
||||||
|
IMAGE_SCN_LNK_OTHER = 0x00000100,
|
||||||
|
IMAGE_SCN_LNK_INFO = 0x00000200,
|
||||||
|
IMAGE_SCN_LNK_REMOVE = 0x00000800,
|
||||||
|
IMAGE_SCN_LNK_COMDAT = 0x00001000,
|
||||||
|
IMAGE_SCN_GPREL = 0x00008000,
|
||||||
|
IMAGE_SCN_MEM_PURGEABLE = 0x00020000,
|
||||||
|
IMAGE_SCN_MEM_16BIT = 0x00020000,
|
||||||
|
IMAGE_SCN_MEM_LOCKED = 0x00040000,
|
||||||
|
IMAGE_SCN_MEM_PRELOAD = 0x00080000,
|
||||||
|
IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
|
||||||
|
IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
|
||||||
|
IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
|
||||||
|
IMAGE_SCN_ALIGN_8BYTES = 0x00400000,
|
||||||
|
IMAGE_SCN_ALIGN_16BYTES = 0x00500000,
|
||||||
|
IMAGE_SCN_ALIGN_32BYTES = 0x00600000,
|
||||||
|
IMAGE_SCN_ALIGN_64BYTES = 0x00700000,
|
||||||
|
IMAGE_SCN_ALIGN_128BYTES = 0x00800000,
|
||||||
|
IMAGE_SCN_ALIGN_256BYTES = 0x00900000,
|
||||||
|
IMAGE_SCN_ALIGN_512BYTES = 0x00A00000,
|
||||||
|
IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000,
|
||||||
|
IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000,
|
||||||
|
IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000,
|
||||||
|
IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000,
|
||||||
|
IMAGE_SCN_ALIGN_MASK = 0x00F00000,
|
||||||
|
IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
|
||||||
|
IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
|
||||||
|
IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
|
||||||
|
IMAGE_SCN_MEM_NOT_PAGED = 0x08000000,
|
||||||
|
IMAGE_SCN_MEM_SHARED = 0x10000000,
|
||||||
|
IMAGE_SCN_MEM_EXECUTE = 0x20000000,
|
||||||
|
IMAGE_SCN_MEM_READ = 0x40000000,
|
||||||
|
IMAGE_SCN_MEM_WRITE = 0x80000000
|
||||||
|
};
|
||||||
|
|
||||||
|
struct relocation {
|
||||||
|
uint32_t VirtualAddress;
|
||||||
|
uint32_t SymbolTableIndex;
|
||||||
|
uint16_t Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RelocationTypeI386 : unsigned {
|
||||||
|
IMAGE_REL_I386_ABSOLUTE = 0x0000,
|
||||||
|
IMAGE_REL_I386_DIR16 = 0x0001,
|
||||||
|
IMAGE_REL_I386_REL16 = 0x0002,
|
||||||
|
IMAGE_REL_I386_DIR32 = 0x0006,
|
||||||
|
IMAGE_REL_I386_DIR32NB = 0x0007,
|
||||||
|
IMAGE_REL_I386_SEG12 = 0x0009,
|
||||||
|
IMAGE_REL_I386_SECTION = 0x000A,
|
||||||
|
IMAGE_REL_I386_SECREL = 0x000B,
|
||||||
|
IMAGE_REL_I386_TOKEN = 0x000C,
|
||||||
|
IMAGE_REL_I386_SECREL7 = 0x000D,
|
||||||
|
IMAGE_REL_I386_REL32 = 0x0014
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RelocationTypeAMD64 : unsigned {
|
||||||
|
IMAGE_REL_AMD64_ABSOLUTE = 0x0000,
|
||||||
|
IMAGE_REL_AMD64_ADDR64 = 0x0001,
|
||||||
|
IMAGE_REL_AMD64_ADDR32 = 0x0002,
|
||||||
|
IMAGE_REL_AMD64_ADDR32NB = 0x0003,
|
||||||
|
IMAGE_REL_AMD64_REL32 = 0x0004,
|
||||||
|
IMAGE_REL_AMD64_REL32_1 = 0x0005,
|
||||||
|
IMAGE_REL_AMD64_REL32_2 = 0x0006,
|
||||||
|
IMAGE_REL_AMD64_REL32_3 = 0x0007,
|
||||||
|
IMAGE_REL_AMD64_REL32_4 = 0x0008,
|
||||||
|
IMAGE_REL_AMD64_REL32_5 = 0x0009,
|
||||||
|
IMAGE_REL_AMD64_SECTION = 0x000A,
|
||||||
|
IMAGE_REL_AMD64_SECREL = 0x000B,
|
||||||
|
IMAGE_REL_AMD64_SECREL7 = 0x000C,
|
||||||
|
IMAGE_REL_AMD64_TOKEN = 0x000D,
|
||||||
|
IMAGE_REL_AMD64_SREL32 = 0x000E,
|
||||||
|
IMAGE_REL_AMD64_PAIR = 0x000F,
|
||||||
|
IMAGE_REL_AMD64_SSPAN32 = 0x0010
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RelocationTypesARM : unsigned {
|
||||||
|
IMAGE_REL_ARM_ABSOLUTE = 0x0000,
|
||||||
|
IMAGE_REL_ARM_ADDR32 = 0x0001,
|
||||||
|
IMAGE_REL_ARM_ADDR32NB = 0x0002,
|
||||||
|
IMAGE_REL_ARM_BRANCH24 = 0x0003,
|
||||||
|
IMAGE_REL_ARM_BRANCH11 = 0x0004,
|
||||||
|
IMAGE_REL_ARM_TOKEN = 0x0005,
|
||||||
|
IMAGE_REL_ARM_BLX24 = 0x0008,
|
||||||
|
IMAGE_REL_ARM_BLX11 = 0x0009,
|
||||||
|
IMAGE_REL_ARM_REL32 = 0x000A,
|
||||||
|
IMAGE_REL_ARM_SECTION = 0x000E,
|
||||||
|
IMAGE_REL_ARM_SECREL = 0x000F,
|
||||||
|
IMAGE_REL_ARM_MOV32A = 0x0010,
|
||||||
|
IMAGE_REL_ARM_MOV32T = 0x0011,
|
||||||
|
IMAGE_REL_ARM_BRANCH20T = 0x0012,
|
||||||
|
IMAGE_REL_ARM_BRANCH24T = 0x0014,
|
||||||
|
IMAGE_REL_ARM_BLX23T = 0x0015,
|
||||||
|
IMAGE_REL_ARM_PAIR = 0x0016,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RelocationTypesARM64 : unsigned {
|
||||||
|
IMAGE_REL_ARM64_ABSOLUTE = 0x0000,
|
||||||
|
IMAGE_REL_ARM64_ADDR32 = 0x0001,
|
||||||
|
IMAGE_REL_ARM64_ADDR32NB = 0x0002,
|
||||||
|
IMAGE_REL_ARM64_BRANCH26 = 0x0003,
|
||||||
|
IMAGE_REL_ARM64_PAGEBASE_REL21 = 0x0004,
|
||||||
|
IMAGE_REL_ARM64_REL21 = 0x0005,
|
||||||
|
IMAGE_REL_ARM64_PAGEOFFSET_12A = 0x0006,
|
||||||
|
IMAGE_REL_ARM64_PAGEOFFSET_12L = 0x0007,
|
||||||
|
IMAGE_REL_ARM64_SECREL = 0x0008,
|
||||||
|
IMAGE_REL_ARM64_SECREL_LOW12A = 0x0009,
|
||||||
|
IMAGE_REL_ARM64_SECREL_HIGH12A = 0x000A,
|
||||||
|
IMAGE_REL_ARM64_SECREL_LOW12L = 0x000B,
|
||||||
|
IMAGE_REL_ARM64_TOKEN = 0x000C,
|
||||||
|
IMAGE_REL_ARM64_SECTION = 0x000D,
|
||||||
|
IMAGE_REL_ARM64_ADDR64 = 0x000E,
|
||||||
|
IMAGE_REL_ARM64_BRANCH19 = 0x000F,
|
||||||
|
IMAGE_REL_ARM64_BRANCH14 = 0x0010,
|
||||||
|
IMAGE_REL_ARM64_REL32 = 0x0011,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum COMDATType : uint8_t {
|
||||||
|
IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
|
||||||
|
IMAGE_COMDAT_SELECT_ANY,
|
||||||
|
IMAGE_COMDAT_SELECT_SAME_SIZE,
|
||||||
|
IMAGE_COMDAT_SELECT_EXACT_MATCH,
|
||||||
|
IMAGE_COMDAT_SELECT_ASSOCIATIVE,
|
||||||
|
IMAGE_COMDAT_SELECT_LARGEST,
|
||||||
|
IMAGE_COMDAT_SELECT_NEWEST
|
||||||
|
};
|
||||||
|
|
||||||
|
// Auxiliary Symbol Formats
|
||||||
|
struct AuxiliaryFunctionDefinition {
|
||||||
|
uint32_t TagIndex;
|
||||||
|
uint32_t TotalSize;
|
||||||
|
uint32_t PointerToLinenumber;
|
||||||
|
uint32_t PointerToNextFunction;
|
||||||
|
char unused[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AuxiliarybfAndefSymbol {
|
||||||
|
uint8_t unused1[4];
|
||||||
|
uint16_t Linenumber;
|
||||||
|
uint8_t unused2[6];
|
||||||
|
uint32_t PointerToNextFunction;
|
||||||
|
uint8_t unused3[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AuxiliaryWeakExternal {
|
||||||
|
uint32_t TagIndex;
|
||||||
|
uint32_t Characteristics;
|
||||||
|
uint8_t unused[10];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WeakExternalCharacteristics : unsigned {
|
||||||
|
IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1,
|
||||||
|
IMAGE_WEAK_EXTERN_SEARCH_LIBRARY = 2,
|
||||||
|
IMAGE_WEAK_EXTERN_SEARCH_ALIAS = 3,
|
||||||
|
IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AuxiliarySectionDefinition {
|
||||||
|
uint32_t Length;
|
||||||
|
uint16_t NumberOfRelocations;
|
||||||
|
uint16_t NumberOfLinenumbers;
|
||||||
|
uint32_t CheckSum;
|
||||||
|
uint32_t Number;
|
||||||
|
uint8_t Selection;
|
||||||
|
char unused;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AuxiliaryCLRToken {
|
||||||
|
uint8_t AuxType;
|
||||||
|
uint8_t unused1;
|
||||||
|
uint32_t SymbolTableIndex;
|
||||||
|
char unused2[12];
|
||||||
|
};
|
||||||
|
|
||||||
|
union Auxiliary {
|
||||||
|
AuxiliaryFunctionDefinition FunctionDefinition;
|
||||||
|
AuxiliarybfAndefSymbol bfAndefSymbol;
|
||||||
|
AuxiliaryWeakExternal WeakExternal;
|
||||||
|
AuxiliarySectionDefinition SectionDefinition;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The Import Directory Table.
|
||||||
|
///
|
||||||
|
/// There is a single array of these and one entry per imported DLL.
|
||||||
|
struct ImportDirectoryTableEntry {
|
||||||
|
uint32_t ImportLookupTableRVA;
|
||||||
|
uint32_t TimeDateStamp;
|
||||||
|
uint32_t ForwarderChain;
|
||||||
|
uint32_t NameRVA;
|
||||||
|
uint32_t ImportAddressTableRVA;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The PE32 Import Lookup Table.
|
||||||
|
///
|
||||||
|
/// There is an array of these for each imported DLL. It represents either
|
||||||
|
/// the ordinal to import from the target DLL, or a name to lookup and import
|
||||||
|
/// from the target DLL.
|
||||||
|
///
|
||||||
|
/// This also happens to be the same format used by the Import Address Table
|
||||||
|
/// when it is initially written out to the image.
|
||||||
|
struct ImportLookupTableEntry32 {
|
||||||
|
uint32_t data;
|
||||||
|
|
||||||
|
/// Is this entry specified by ordinal, or name?
|
||||||
|
bool isOrdinal() const { return data & 0x80000000; }
|
||||||
|
|
||||||
|
/// Get the ordinal value of this entry. isOrdinal must be true.
|
||||||
|
uint16_t getOrdinal() const {
|
||||||
|
assert(isOrdinal() && "ILT entry is not an ordinal!");
|
||||||
|
return data & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the ordinal value and set isOrdinal to true.
|
||||||
|
void setOrdinal(uint16_t o) {
|
||||||
|
data = o;
|
||||||
|
data |= 0x80000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the Hint/Name entry RVA. isOrdinal must be false.
|
||||||
|
uint32_t getHintNameRVA() const {
|
||||||
|
assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the Hint/Name entry RVA and set isOrdinal to false.
|
||||||
|
void setHintNameRVA(uint32_t rva) { data = rva; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The DOS compatible header at the front of all PEs.
|
||||||
|
struct DOSHeader {
|
||||||
|
uint16_t Magic;
|
||||||
|
uint16_t UsedBytesInTheLastPage;
|
||||||
|
uint16_t FileSizeInPages;
|
||||||
|
uint16_t NumberOfRelocationItems;
|
||||||
|
uint16_t HeaderSizeInParagraphs;
|
||||||
|
uint16_t MinimumExtraParagraphs;
|
||||||
|
uint16_t MaximumExtraParagraphs;
|
||||||
|
uint16_t InitialRelativeSS;
|
||||||
|
uint16_t InitialSP;
|
||||||
|
uint16_t Checksum;
|
||||||
|
uint16_t InitialIP;
|
||||||
|
uint16_t InitialRelativeCS;
|
||||||
|
uint16_t AddressOfRelocationTable;
|
||||||
|
uint16_t OverlayNumber;
|
||||||
|
uint16_t Reserved[4];
|
||||||
|
uint16_t OEMid;
|
||||||
|
uint16_t OEMinfo;
|
||||||
|
uint16_t Reserved2[10];
|
||||||
|
uint32_t AddressOfNewExeHeader;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PE32Header {
|
||||||
|
enum { PE32 = 0x10b, PE32_PLUS = 0x20b };
|
||||||
|
|
||||||
|
uint16_t Magic;
|
||||||
|
uint8_t MajorLinkerVersion;
|
||||||
|
uint8_t MinorLinkerVersion;
|
||||||
|
uint32_t SizeOfCode;
|
||||||
|
uint32_t SizeOfInitializedData;
|
||||||
|
uint32_t SizeOfUninitializedData;
|
||||||
|
uint32_t AddressOfEntryPoint; // RVA
|
||||||
|
uint32_t BaseOfCode; // RVA
|
||||||
|
uint32_t BaseOfData; // RVA
|
||||||
|
uint64_t ImageBase;
|
||||||
|
uint32_t SectionAlignment;
|
||||||
|
uint32_t FileAlignment;
|
||||||
|
uint16_t MajorOperatingSystemVersion;
|
||||||
|
uint16_t MinorOperatingSystemVersion;
|
||||||
|
uint16_t MajorImageVersion;
|
||||||
|
uint16_t MinorImageVersion;
|
||||||
|
uint16_t MajorSubsystemVersion;
|
||||||
|
uint16_t MinorSubsystemVersion;
|
||||||
|
uint32_t Win32VersionValue;
|
||||||
|
uint32_t SizeOfImage;
|
||||||
|
uint32_t SizeOfHeaders;
|
||||||
|
uint32_t CheckSum;
|
||||||
|
uint16_t Subsystem;
|
||||||
|
// FIXME: This should be DllCharacteristics to match the COFF spec.
|
||||||
|
uint16_t DLLCharacteristics;
|
||||||
|
uint64_t SizeOfStackReserve;
|
||||||
|
uint64_t SizeOfStackCommit;
|
||||||
|
uint64_t SizeOfHeapReserve;
|
||||||
|
uint64_t SizeOfHeapCommit;
|
||||||
|
uint32_t LoaderFlags;
|
||||||
|
// FIXME: This should be NumberOfRvaAndSizes to match the COFF spec.
|
||||||
|
uint32_t NumberOfRvaAndSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DataDirectory {
|
||||||
|
uint32_t RelativeVirtualAddress;
|
||||||
|
uint32_t Size;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DataDirectoryIndex : unsigned {
|
||||||
|
EXPORT_TABLE = 0,
|
||||||
|
IMPORT_TABLE,
|
||||||
|
RESOURCE_TABLE,
|
||||||
|
EXCEPTION_TABLE,
|
||||||
|
CERTIFICATE_TABLE,
|
||||||
|
BASE_RELOCATION_TABLE,
|
||||||
|
DEBUG_DIRECTORY,
|
||||||
|
ARCHITECTURE,
|
||||||
|
GLOBAL_PTR,
|
||||||
|
TLS_TABLE,
|
||||||
|
LOAD_CONFIG_TABLE,
|
||||||
|
BOUND_IMPORT,
|
||||||
|
IAT,
|
||||||
|
DELAY_IMPORT_DESCRIPTOR,
|
||||||
|
CLR_RUNTIME_HEADER,
|
||||||
|
|
||||||
|
NUM_DATA_DIRECTORIES
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WindowsSubsystem : unsigned {
|
||||||
|
IMAGE_SUBSYSTEM_UNKNOWN = 0, ///< An unknown subsystem.
|
||||||
|
IMAGE_SUBSYSTEM_NATIVE = 1, ///< Device drivers and native Windows processes
|
||||||
|
IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, ///< The Windows GUI subsystem.
|
||||||
|
IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, ///< The Windows character subsystem.
|
||||||
|
IMAGE_SUBSYSTEM_OS2_CUI = 5, ///< The OS/2 character subsystem.
|
||||||
|
IMAGE_SUBSYSTEM_POSIX_CUI = 7, ///< The POSIX character subsystem.
|
||||||
|
IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8, ///< Native Windows 9x driver.
|
||||||
|
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, ///< Windows CE.
|
||||||
|
IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, ///< An EFI application.
|
||||||
|
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, ///< An EFI driver with boot
|
||||||
|
/// services.
|
||||||
|
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, ///< An EFI driver with run-time
|
||||||
|
/// services.
|
||||||
|
IMAGE_SUBSYSTEM_EFI_ROM = 13, ///< An EFI ROM image.
|
||||||
|
IMAGE_SUBSYSTEM_XBOX = 14, ///< XBOX.
|
||||||
|
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16 ///< A BCD application.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DLLCharacteristics : unsigned {
|
||||||
|
/// ASLR with 64 bit address space.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
|
||||||
|
/// DLL can be relocated at load time.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
|
||||||
|
/// Code integrity checks are enforced.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
|
||||||
|
///< Image is NX compatible.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
|
||||||
|
/// Isolation aware, but do not isolate the image.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200,
|
||||||
|
/// Does not use structured exception handling (SEH). No SEH handler may be
|
||||||
|
/// called in this image.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400,
|
||||||
|
/// Do not bind the image.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800,
|
||||||
|
///< Image should execute in an AppContainer.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_APPCONTAINER = 0x1000,
|
||||||
|
///< A WDM driver.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000,
|
||||||
|
///< Image supports Control Flow Guard.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_GUARD_CF = 0x4000,
|
||||||
|
/// Terminal Server aware.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ExtendedDLLCharacteristics : unsigned {
|
||||||
|
/// Image is CET compatible
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT = 0x0001
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DebugType : unsigned {
|
||||||
|
IMAGE_DEBUG_TYPE_UNKNOWN = 0,
|
||||||
|
IMAGE_DEBUG_TYPE_COFF = 1,
|
||||||
|
IMAGE_DEBUG_TYPE_CODEVIEW = 2,
|
||||||
|
IMAGE_DEBUG_TYPE_FPO = 3,
|
||||||
|
IMAGE_DEBUG_TYPE_MISC = 4,
|
||||||
|
IMAGE_DEBUG_TYPE_EXCEPTION = 5,
|
||||||
|
IMAGE_DEBUG_TYPE_FIXUP = 6,
|
||||||
|
IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7,
|
||||||
|
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
|
||||||
|
IMAGE_DEBUG_TYPE_BORLAND = 9,
|
||||||
|
IMAGE_DEBUG_TYPE_RESERVED10 = 10,
|
||||||
|
IMAGE_DEBUG_TYPE_CLSID = 11,
|
||||||
|
IMAGE_DEBUG_TYPE_VC_FEATURE = 12,
|
||||||
|
IMAGE_DEBUG_TYPE_POGO = 13,
|
||||||
|
IMAGE_DEBUG_TYPE_ILTCG = 14,
|
||||||
|
IMAGE_DEBUG_TYPE_MPX = 15,
|
||||||
|
IMAGE_DEBUG_TYPE_REPRO = 16,
|
||||||
|
IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS = 20,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BaseRelocationType : unsigned {
|
||||||
|
IMAGE_REL_BASED_ABSOLUTE = 0,
|
||||||
|
IMAGE_REL_BASED_HIGH = 1,
|
||||||
|
IMAGE_REL_BASED_LOW = 2,
|
||||||
|
IMAGE_REL_BASED_HIGHLOW = 3,
|
||||||
|
IMAGE_REL_BASED_HIGHADJ = 4,
|
||||||
|
IMAGE_REL_BASED_MIPS_JMPADDR = 5,
|
||||||
|
IMAGE_REL_BASED_ARM_MOV32A = 5,
|
||||||
|
IMAGE_REL_BASED_ARM_MOV32T = 7,
|
||||||
|
IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
|
||||||
|
IMAGE_REL_BASED_DIR64 = 10
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImportType : unsigned {
|
||||||
|
IMPORT_CODE = 0,
|
||||||
|
IMPORT_DATA = 1,
|
||||||
|
IMPORT_CONST = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImportNameType : unsigned {
|
||||||
|
/// Import is by ordinal. This indicates that the value in the Ordinal/Hint
|
||||||
|
/// field of the import header is the import's ordinal. If this constant is
|
||||||
|
/// not specified, then the Ordinal/Hint field should always be interpreted
|
||||||
|
/// as the import's hint.
|
||||||
|
IMPORT_ORDINAL = 0,
|
||||||
|
/// The import name is identical to the public symbol name
|
||||||
|
IMPORT_NAME = 1,
|
||||||
|
/// The import name is the public symbol name, but skipping the leading ?,
|
||||||
|
/// @, or optionally _.
|
||||||
|
IMPORT_NAME_NOPREFIX = 2,
|
||||||
|
/// The import name is the public symbol name, but skipping the leading ?,
|
||||||
|
/// @, or optionally _, and truncating at the first @.
|
||||||
|
IMPORT_NAME_UNDECORATE = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class GuardFlags : uint32_t {
|
||||||
|
/// Module performs control flow integrity checks using system-supplied
|
||||||
|
/// support.
|
||||||
|
CF_INSTRUMENTED = 0x100,
|
||||||
|
/// Module performs control flow and write integrity checks.
|
||||||
|
CFW_INSTRUMENTED = 0x200,
|
||||||
|
/// Module contains valid control flow target metadata.
|
||||||
|
CF_FUNCTION_TABLE_PRESENT = 0x400,
|
||||||
|
/// Module does not make use of the /GS security cookie.
|
||||||
|
SECURITY_COOKIE_UNUSED = 0x800,
|
||||||
|
/// Module supports read only delay load IAT.
|
||||||
|
PROTECT_DELAYLOAD_IAT = 0x1000,
|
||||||
|
/// Delayload import table in its own .didat section (with nothing else in it)
|
||||||
|
/// that can be freely reprotected.
|
||||||
|
DELAYLOAD_IAT_IN_ITS_OWN_SECTION = 0x2000,
|
||||||
|
/// Module contains suppressed export information. This also infers that the
|
||||||
|
/// address taken IAT table is also present in the load config.
|
||||||
|
CF_EXPORT_SUPPRESSION_INFO_PRESENT = 0x4000,
|
||||||
|
/// Module enables suppression of exports.
|
||||||
|
CF_ENABLE_EXPORT_SUPPRESSION = 0x8000,
|
||||||
|
/// Module contains longjmp target information.
|
||||||
|
CF_LONGJUMP_TABLE_PRESENT = 0x10000,
|
||||||
|
/// Module contains EH continuation target information.
|
||||||
|
EH_CONTINUATION_TABLE_PRESENT = 0x400000,
|
||||||
|
/// Mask for the subfield that contains the stride of Control Flow Guard
|
||||||
|
/// function table entries (that is, the additional count of bytes per table
|
||||||
|
/// entry).
|
||||||
|
CF_FUNCTION_TABLE_SIZE_MASK = 0xF0000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_5BYTES = 0x10000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_6BYTES = 0x20000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_7BYTES = 0x30000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_8BYTES = 0x40000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_9BYTES = 0x50000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_10BYTES = 0x60000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_11BYTES = 0x70000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_12BYTES = 0x80000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_13BYTES = 0x90000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_14BYTES = 0xA0000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_15BYTES = 0xB0000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_16BYTES = 0xC0000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_17BYTES = 0xD0000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_18BYTES = 0xE0000000,
|
||||||
|
CF_FUNCTION_TABLE_SIZE_19BYTES = 0xF0000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImportHeader {
|
||||||
|
uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
|
||||||
|
uint16_t Sig2; ///< Must be 0xFFFF.
|
||||||
|
uint16_t Version;
|
||||||
|
uint16_t Machine;
|
||||||
|
uint32_t TimeDateStamp;
|
||||||
|
uint32_t SizeOfData;
|
||||||
|
uint16_t OrdinalHint;
|
||||||
|
uint16_t TypeInfo;
|
||||||
|
|
||||||
|
ImportType getType() const { return static_cast<ImportType>(TypeInfo & 0x3); }
|
||||||
|
|
||||||
|
ImportNameType getNameType() const {
|
||||||
|
return static_cast<ImportNameType>((TypeInfo & 0x1C) >> 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CodeViewIdentifiers {
|
||||||
|
DEBUG_SECTION_MAGIC = 0x4,
|
||||||
|
DEBUG_HASHES_SECTION_MAGIC = 0x133C9C5
|
||||||
|
};
|
||||||
|
|
||||||
|
// These flags show up in the @feat.00 symbol. They appear to be some kind of
|
||||||
|
// compiler features bitfield read by link.exe.
|
||||||
|
enum Feat00Flags : uint32_t {
|
||||||
|
// Object is compatible with /safeseh.
|
||||||
|
SafeSEH = 0x1,
|
||||||
|
// Object was compiled with /GS.
|
||||||
|
GuardStack = 0x100,
|
||||||
|
// Object was compiled with /sdl.
|
||||||
|
SDL = 0x200,
|
||||||
|
// Object was compiled with /guard:cf.
|
||||||
|
GuardCF = 0x800,
|
||||||
|
// Object was compiled with /guard:ehcont.
|
||||||
|
GuardEHCont = 0x4000,
|
||||||
|
// Object was compiled with /kernel.
|
||||||
|
Kernel = 0x40000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool isReservedSectionNumber(int32_t SectionNumber) {
|
||||||
|
return SectionNumber <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encode section name based on string table offset.
|
||||||
|
/// The size of Out must be at least COFF::NameSize.
|
||||||
|
bool encodeSectionName(char *Out, uint64_t Offset);
|
||||||
|
|
||||||
|
} // End namespace COFF.
|
||||||
|
} // End namespace llvm.
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,265 @@
|
|||||||
|
#ifndef DYNAMIC_TAG
|
||||||
|
#error "DYNAMIC_TAG must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Add separate macros for the architecture specific tags and the markers
|
||||||
|
// such as DT_HIOS, etc. to allow using this file to in other contexts.
|
||||||
|
// For example we can use it to generate a stringification switch statement.
|
||||||
|
|
||||||
|
#ifndef AARCH64_DYNAMIC_TAG
|
||||||
|
#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
|
||||||
|
#define AARCH64_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HEXAGON_DYNAMIC_TAG
|
||||||
|
#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
|
||||||
|
#define HEXAGON_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MIPS_DYNAMIC_TAG
|
||||||
|
#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
|
||||||
|
#define MIPS_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PPC_DYNAMIC_TAG
|
||||||
|
#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
|
||||||
|
#define PPC_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PPC64_DYNAMIC_TAG
|
||||||
|
#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
|
||||||
|
#define PPC64_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RISCV_DYNAMIC_TAG
|
||||||
|
#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
|
||||||
|
#define RISCV_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DYNAMIC_TAG_MARKER
|
||||||
|
#define DYNAMIC_TAG_MARKER(name, value) DYNAMIC_TAG(name, value)
|
||||||
|
#define DYNAMIC_TAG_MARKER_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DYNAMIC_TAG(NULL, 0) // Marks end of dynamic array.
|
||||||
|
DYNAMIC_TAG(NEEDED, 1) // String table offset of needed library.
|
||||||
|
DYNAMIC_TAG(PLTRELSZ, 2) // Size of relocation entries in PLT.
|
||||||
|
DYNAMIC_TAG(PLTGOT, 3) // Address associated with linkage table.
|
||||||
|
DYNAMIC_TAG(HASH, 4) // Address of symbolic hash table.
|
||||||
|
DYNAMIC_TAG(STRTAB, 5) // Address of dynamic string table.
|
||||||
|
DYNAMIC_TAG(SYMTAB, 6) // Address of dynamic symbol table.
|
||||||
|
DYNAMIC_TAG(RELA, 7) // Address of relocation table (Rela entries).
|
||||||
|
DYNAMIC_TAG(RELASZ, 8) // Size of Rela relocation table.
|
||||||
|
DYNAMIC_TAG(RELAENT, 9) // Size of a Rela relocation entry.
|
||||||
|
DYNAMIC_TAG(STRSZ, 10) // Total size of the string table.
|
||||||
|
DYNAMIC_TAG(SYMENT, 11) // Size of a symbol table entry.
|
||||||
|
DYNAMIC_TAG(INIT, 12) // Address of initialization function.
|
||||||
|
DYNAMIC_TAG(FINI, 13) // Address of termination function.
|
||||||
|
DYNAMIC_TAG(SONAME, 14) // String table offset of a shared objects name.
|
||||||
|
DYNAMIC_TAG(RPATH, 15) // String table offset of library search path.
|
||||||
|
DYNAMIC_TAG(SYMBOLIC, 16) // Changes symbol resolution algorithm.
|
||||||
|
DYNAMIC_TAG(REL, 17) // Address of relocation table (Rel entries).
|
||||||
|
DYNAMIC_TAG(RELSZ, 18) // Size of Rel relocation table.
|
||||||
|
DYNAMIC_TAG(RELENT, 19) // Size of a Rel relocation entry.
|
||||||
|
DYNAMIC_TAG(PLTREL, 20) // Type of relocation entry used for linking.
|
||||||
|
DYNAMIC_TAG(DEBUG, 21) // Reserved for debugger.
|
||||||
|
DYNAMIC_TAG(TEXTREL, 22) // Relocations exist for non-writable segments.
|
||||||
|
DYNAMIC_TAG(JMPREL, 23) // Address of relocations associated with PLT.
|
||||||
|
DYNAMIC_TAG(BIND_NOW, 24) // Process all relocations before execution.
|
||||||
|
DYNAMIC_TAG(INIT_ARRAY, 25) // Pointer to array of initialization functions.
|
||||||
|
DYNAMIC_TAG(FINI_ARRAY, 26) // Pointer to array of termination functions.
|
||||||
|
DYNAMIC_TAG(INIT_ARRAYSZ, 27) // Size of DT_INIT_ARRAY.
|
||||||
|
DYNAMIC_TAG(FINI_ARRAYSZ, 28) // Size of DT_FINI_ARRAY.
|
||||||
|
DYNAMIC_TAG(RUNPATH, 29) // String table offset of lib search path.
|
||||||
|
DYNAMIC_TAG(FLAGS, 30) // Flags.
|
||||||
|
DYNAMIC_TAG_MARKER(ENCODING, 32) // Values from here to DT_LOOS follow the rules
|
||||||
|
// for the interpretation of the d_un union.
|
||||||
|
|
||||||
|
DYNAMIC_TAG(PREINIT_ARRAY, 32) // Pointer to array of preinit functions.
|
||||||
|
DYNAMIC_TAG(PREINIT_ARRAYSZ, 33) // Size of the DT_PREINIT_ARRAY array.
|
||||||
|
|
||||||
|
DYNAMIC_TAG(SYMTAB_SHNDX, 34) // Address of the SHT_SYMTAB_SHNDX section.
|
||||||
|
|
||||||
|
// Experimental support for SHT_RELR sections. For details, see proposal
|
||||||
|
// at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
|
||||||
|
DYNAMIC_TAG(RELRSZ, 35) // Size of Relr relocation table.
|
||||||
|
DYNAMIC_TAG(RELR, 36) // Address of relocation table (Relr entries).
|
||||||
|
DYNAMIC_TAG(RELRENT, 37) // Size of a Relr relocation entry.
|
||||||
|
|
||||||
|
DYNAMIC_TAG_MARKER(LOOS, 0x60000000) // Start of environment specific tags.
|
||||||
|
DYNAMIC_TAG_MARKER(HIOS, 0x6FFFFFFF) // End of environment specific tags.
|
||||||
|
DYNAMIC_TAG_MARKER(LOPROC, 0x70000000) // Start of processor specific tags.
|
||||||
|
DYNAMIC_TAG_MARKER(HIPROC, 0x7FFFFFFF) // End of processor specific tags.
|
||||||
|
|
||||||
|
// Android packed relocation section tags.
|
||||||
|
// https://android.googlesource.com/platform/bionic/+/6f12bfece5dcc01325e0abba56a46b1bcf991c69/tools/relocation_packer/src/elf_file.cc#31
|
||||||
|
DYNAMIC_TAG(ANDROID_REL, 0x6000000F)
|
||||||
|
DYNAMIC_TAG(ANDROID_RELSZ, 0x60000010)
|
||||||
|
DYNAMIC_TAG(ANDROID_RELA, 0x60000011)
|
||||||
|
DYNAMIC_TAG(ANDROID_RELASZ, 0x60000012)
|
||||||
|
|
||||||
|
// Android's experimental support for SHT_RELR sections.
|
||||||
|
// https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#253
|
||||||
|
DYNAMIC_TAG(ANDROID_RELR, 0x6FFFE000) // Address of relocation table (Relr entries).
|
||||||
|
DYNAMIC_TAG(ANDROID_RELRSZ, 0x6FFFE001) // Size of Relr relocation table.
|
||||||
|
DYNAMIC_TAG(ANDROID_RELRENT, 0x6FFFE003) // Size of a Relr relocation entry.
|
||||||
|
|
||||||
|
DYNAMIC_TAG(GNU_HASH, 0x6FFFFEF5) // Reference to the GNU hash table.
|
||||||
|
DYNAMIC_TAG(TLSDESC_PLT, 0x6FFFFEF6) // Location of PLT entry for TLS
|
||||||
|
// descriptor resolver calls.
|
||||||
|
DYNAMIC_TAG(TLSDESC_GOT, 0x6FFFFEF7) // Location of GOT entry used by TLS
|
||||||
|
// descriptor resolver PLT entry.
|
||||||
|
DYNAMIC_TAG(RELACOUNT, 0x6FFFFFF9) // ELF32_Rela count.
|
||||||
|
DYNAMIC_TAG(RELCOUNT, 0x6FFFFFFA) // ELF32_Rel count.
|
||||||
|
|
||||||
|
DYNAMIC_TAG(FLAGS_1, 0X6FFFFFFB) // Flags_1.
|
||||||
|
|
||||||
|
DYNAMIC_TAG(VERSYM, 0x6FFFFFF0) // The address of .gnu.version section.
|
||||||
|
DYNAMIC_TAG(VERDEF, 0X6FFFFFFC) // The address of the version definition
|
||||||
|
// table.
|
||||||
|
DYNAMIC_TAG(VERDEFNUM, 0X6FFFFFFD) // The number of entries in DT_VERDEF.
|
||||||
|
DYNAMIC_TAG(VERNEED, 0X6FFFFFFE) // The address of the version dependency
|
||||||
|
// table.
|
||||||
|
DYNAMIC_TAG(VERNEEDNUM, 0X6FFFFFFF) // The number of entries in DT_VERNEED.
|
||||||
|
|
||||||
|
// AArch64 specific dynamic table entries
|
||||||
|
AARCH64_DYNAMIC_TAG(AARCH64_BTI_PLT, 0x70000001)
|
||||||
|
AARCH64_DYNAMIC_TAG(AARCH64_PAC_PLT, 0x70000003)
|
||||||
|
AARCH64_DYNAMIC_TAG(AARCH64_VARIANT_PCS, 0x70000005)
|
||||||
|
AARCH64_DYNAMIC_TAG(AARCH64_MEMTAG_MODE, 0x70000009)
|
||||||
|
AARCH64_DYNAMIC_TAG(AARCH64_MEMTAG_HEAP, 0x7000000b)
|
||||||
|
AARCH64_DYNAMIC_TAG(AARCH64_MEMTAG_STACK, 0x7000000c)
|
||||||
|
AARCH64_DYNAMIC_TAG(AARCH64_MEMTAG_GLOBALS, 0x7000000d)
|
||||||
|
AARCH64_DYNAMIC_TAG(AARCH64_MEMTAG_GLOBALSSZ, 0x7000000f)
|
||||||
|
|
||||||
|
// Hexagon specific dynamic table entries
|
||||||
|
HEXAGON_DYNAMIC_TAG(HEXAGON_SYMSZ, 0x70000000)
|
||||||
|
HEXAGON_DYNAMIC_TAG(HEXAGON_VER, 0x70000001)
|
||||||
|
HEXAGON_DYNAMIC_TAG(HEXAGON_PLT, 0x70000002)
|
||||||
|
|
||||||
|
// Mips specific dynamic table entry tags.
|
||||||
|
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_RLD_VERSION, 0x70000001) // 32 bit version number for
|
||||||
|
// runtime linker interface.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_TIME_STAMP, 0x70000002) // Time stamp.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_ICHECKSUM, 0x70000003) // Checksum of external strings
|
||||||
|
// and common sizes.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_IVERSION, 0x70000004) // Index of version string
|
||||||
|
// in string table.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_FLAGS, 0x70000005) // 32 bits of flags.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_BASE_ADDRESS, 0x70000006) // Base address of the segment.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_MSYM, 0x70000007) // Address of .msym section.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_CONFLICT, 0x70000008) // Address of .conflict section.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_LIBLIST, 0x70000009) // Address of .liblist section.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_LOCAL_GOTNO, 0x7000000a) // Number of local global offset
|
||||||
|
// table entries.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_CONFLICTNO, 0x7000000b) // Number of entries
|
||||||
|
// in the .conflict section.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_LIBLISTNO, 0x70000010) // Number of entries
|
||||||
|
// in the .liblist section.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_SYMTABNO, 0x70000011) // Number of entries
|
||||||
|
// in the .dynsym section.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_UNREFEXTNO, 0x70000012) // Index of first external dynamic
|
||||||
|
// symbol not referenced locally.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_GOTSYM, 0x70000013) // Index of first dynamic symbol
|
||||||
|
// in global offset table.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_HIPAGENO, 0x70000014) // Number of page table entries
|
||||||
|
// in global offset table.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_RLD_MAP, 0x70000016) // Address of run time loader map
|
||||||
|
// used for debugging.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DELTA_CLASS, 0x70000017) // Delta C++ class definition.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DELTA_CLASS_NO, 0x70000018) // Number of entries
|
||||||
|
// in DT_MIPS_DELTA_CLASS.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DELTA_INSTANCE, 0x70000019) // Delta C++ class instances.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DELTA_INSTANCE_NO, 0x7000001A) // Number of entries
|
||||||
|
// in DT_MIPS_DELTA_INSTANCE.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DELTA_RELOC, 0x7000001B) // Delta relocations.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DELTA_RELOC_NO, 0x7000001C) // Number of entries
|
||||||
|
// in DT_MIPS_DELTA_RELOC.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DELTA_SYM, 0x7000001D) // Delta symbols that Delta
|
||||||
|
// relocations refer to.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DELTA_SYM_NO, 0x7000001E) // Number of entries
|
||||||
|
// in DT_MIPS_DELTA_SYM.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DELTA_CLASSSYM, 0x70000020) // Delta symbols that hold
|
||||||
|
// class declarations.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DELTA_CLASSSYM_NO, 0x70000021) // Number of entries
|
||||||
|
// in DT_MIPS_DELTA_CLASSSYM.
|
||||||
|
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_CXX_FLAGS, 0x70000022) // Flags indicating information
|
||||||
|
// about C++ flavor.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_PIXIE_INIT, 0x70000023) // Pixie information.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_SYMBOL_LIB, 0x70000024) // Address of .MIPS.symlib
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_LOCALPAGE_GOTIDX, 0x70000025) // The GOT index of the first PTE
|
||||||
|
// for a segment
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_LOCAL_GOTIDX, 0x70000026) // The GOT index of the first PTE
|
||||||
|
// for a local symbol
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_HIDDEN_GOTIDX, 0x70000027) // The GOT index of the first PTE
|
||||||
|
// for a hidden symbol
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_PROTECTED_GOTIDX, 0x70000028) // The GOT index of the first PTE
|
||||||
|
// for a protected symbol
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_OPTIONS, 0x70000029) // Address of `.MIPS.options'.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_INTERFACE, 0x7000002A) // Address of `.interface'.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_DYNSTR_ALIGN, 0x7000002B) // Unknown.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_INTERFACE_SIZE, 0x7000002C) // Size of the .interface section.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_RLD_TEXT_RESOLVE_ADDR, 0x7000002D) // Size of rld_text_resolve
|
||||||
|
// function stored in the GOT.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_PERF_SUFFIX, 0x7000002E) // Default suffix of DSO to be added
|
||||||
|
// by rld on dlopen() calls.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_COMPACT_SIZE, 0x7000002F) // Size of compact relocation
|
||||||
|
// section (O32).
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_GP_VALUE, 0x70000030) // GP value for auxiliary GOTs.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_AUX_DYNAMIC, 0x70000031) // Address of auxiliary .dynamic.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_PLTGOT, 0x70000032) // Address of the base of the PLTGOT.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_RWPLT, 0x70000034) // Points to the base
|
||||||
|
// of a writable PLT.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_RLD_MAP_REL, 0x70000035) // Relative offset of run time loader
|
||||||
|
// map, used for debugging.
|
||||||
|
MIPS_DYNAMIC_TAG(MIPS_XHASH, 0x70000036) // GNU-style hash table with xlat.
|
||||||
|
|
||||||
|
// PPC specific dynamic table entries.
|
||||||
|
PPC_DYNAMIC_TAG(PPC_GOT, 0x70000000) // Uses Secure PLT ABI.
|
||||||
|
PPC_DYNAMIC_TAG(PPC_OPT, 0x70000001) // Has TLS optimization.
|
||||||
|
|
||||||
|
// PPC64 specific dynamic table entries.
|
||||||
|
PPC64_DYNAMIC_TAG(PPC64_GLINK, 0x70000000) // Address of 32 bytes before the
|
||||||
|
// first glink lazy resolver stub.
|
||||||
|
PPC64_DYNAMIC_TAG(PPC64_OPT, 0x70000003) // Flags to control optimizations
|
||||||
|
// for TLS and multiple TOCs.
|
||||||
|
|
||||||
|
// RISC-V specific dynamic array tags.
|
||||||
|
RISCV_DYNAMIC_TAG(RISCV_VARIANT_CC, 0x70000001)
|
||||||
|
|
||||||
|
// Sun machine-independent extensions.
|
||||||
|
DYNAMIC_TAG(AUXILIARY, 0x7FFFFFFD) // Shared object to load before self
|
||||||
|
DYNAMIC_TAG(USED, 0x7FFFFFFE) // Same as DT_NEEDED
|
||||||
|
DYNAMIC_TAG(FILTER, 0x7FFFFFFF) // Shared object to get values from
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DYNAMIC_TAG_MARKER_DEFINED
|
||||||
|
#undef DYNAMIC_TAG_MARKER
|
||||||
|
#undef DYNAMIC_TAG_MARKER_DEFINED
|
||||||
|
#endif
|
||||||
|
#ifdef AARCH64_DYNAMIC_TAG_DEFINED
|
||||||
|
#undef AARCH64_DYNAMIC_TAG
|
||||||
|
#undef AARCH64_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
#ifdef MIPS_DYNAMIC_TAG_DEFINED
|
||||||
|
#undef MIPS_DYNAMIC_TAG
|
||||||
|
#undef MIPS_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
#ifdef HEXAGON_DYNAMIC_TAG_DEFINED
|
||||||
|
#undef HEXAGON_DYNAMIC_TAG
|
||||||
|
#undef HEXAGON_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
#ifdef PPC_DYNAMIC_TAG_DEFINED
|
||||||
|
#undef PPC_DYNAMIC_TAG
|
||||||
|
#undef PPC_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
#ifdef PPC64_DYNAMIC_TAG_DEFINED
|
||||||
|
#undef PPC64_DYNAMIC_TAG
|
||||||
|
#undef PPC64_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
|
#ifdef RISCV_DYNAMIC_TAG_DEFINED
|
||||||
|
#undef RISCV_DYNAMIC_TAG
|
||||||
|
#undef RISCV_DYNAMIC_TAG_DEFINED
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,225 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Based on ABI release 1.1-beta, dated 6 November 2013. NB: The cover page of
|
||||||
|
// this document, IHI0056C_beta_aaelf64.pdf, on infocenter.arm.com, still
|
||||||
|
// labels this as release 1.0.
|
||||||
|
ELF_RELOC(R_AARCH64_NONE, 0)
|
||||||
|
ELF_RELOC(R_AARCH64_ABS64, 0x101)
|
||||||
|
ELF_RELOC(R_AARCH64_ABS32, 0x102)
|
||||||
|
ELF_RELOC(R_AARCH64_ABS16, 0x103)
|
||||||
|
ELF_RELOC(R_AARCH64_PREL64, 0x104)
|
||||||
|
ELF_RELOC(R_AARCH64_PREL32, 0x105)
|
||||||
|
ELF_RELOC(R_AARCH64_PREL16, 0x106)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_UABS_G0, 0x107)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_UABS_G0_NC, 0x108)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_UABS_G1, 0x109)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_UABS_G1_NC, 0x10a)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_UABS_G2, 0x10b)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_UABS_G2_NC, 0x10c)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_UABS_G3, 0x10d)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_SABS_G0, 0x10e)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_SABS_G1, 0x10f)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_SABS_G2, 0x110)
|
||||||
|
ELF_RELOC(R_AARCH64_LD_PREL_LO19, 0x111)
|
||||||
|
ELF_RELOC(R_AARCH64_ADR_PREL_LO21, 0x112)
|
||||||
|
ELF_RELOC(R_AARCH64_ADR_PREL_PG_HI21, 0x113)
|
||||||
|
ELF_RELOC(R_AARCH64_ADR_PREL_PG_HI21_NC, 0x114)
|
||||||
|
ELF_RELOC(R_AARCH64_ADD_ABS_LO12_NC, 0x115)
|
||||||
|
ELF_RELOC(R_AARCH64_LDST8_ABS_LO12_NC, 0x116)
|
||||||
|
ELF_RELOC(R_AARCH64_TSTBR14, 0x117)
|
||||||
|
ELF_RELOC(R_AARCH64_CONDBR19, 0x118)
|
||||||
|
ELF_RELOC(R_AARCH64_JUMP26, 0x11a)
|
||||||
|
ELF_RELOC(R_AARCH64_CALL26, 0x11b)
|
||||||
|
ELF_RELOC(R_AARCH64_LDST16_ABS_LO12_NC, 0x11c)
|
||||||
|
ELF_RELOC(R_AARCH64_LDST32_ABS_LO12_NC, 0x11d)
|
||||||
|
ELF_RELOC(R_AARCH64_LDST64_ABS_LO12_NC, 0x11e)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_PREL_G0, 0x11f)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_PREL_G0_NC, 0x120)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_PREL_G1, 0x121)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_PREL_G1_NC, 0x122)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_PREL_G2, 0x123)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_PREL_G2_NC, 0x124)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_PREL_G3, 0x125)
|
||||||
|
ELF_RELOC(R_AARCH64_LDST128_ABS_LO12_NC, 0x12b)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G0, 0x12c)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G0_NC, 0x12d)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G1, 0x12e)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G1_NC, 0x12f)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G2, 0x130)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G2_NC, 0x131)
|
||||||
|
ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G3, 0x132)
|
||||||
|
ELF_RELOC(R_AARCH64_GOTREL64, 0x133)
|
||||||
|
ELF_RELOC(R_AARCH64_GOTREL32, 0x134)
|
||||||
|
ELF_RELOC(R_AARCH64_GOT_LD_PREL19, 0x135)
|
||||||
|
ELF_RELOC(R_AARCH64_LD64_GOTOFF_LO15, 0x136)
|
||||||
|
ELF_RELOC(R_AARCH64_ADR_GOT_PAGE, 0x137)
|
||||||
|
ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC, 0x138)
|
||||||
|
ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15, 0x139)
|
||||||
|
ELF_RELOC(R_AARCH64_PLT32, 0x13a)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21, 0x200)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21, 0x201)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC, 0x202)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSGD_MOVW_G1, 0x203)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSGD_MOVW_G0_NC, 0x204)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_ADR_PREL21, 0x205)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_ADR_PAGE21, 0x206)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_ADD_LO12_NC, 0x207)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_MOVW_G1, 0x208)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_MOVW_G0_NC, 0x209)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LD_PREL19, 0x20a)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G2, 0x20b)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G1, 0x20c)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC, 0x20d)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G0, 0x20e)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC, 0x20f)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_HI12, 0x210)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_LO12, 0x211)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC, 0x212)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LDST8_DTPREL_LO12, 0x213)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC, 0x214)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LDST16_DTPREL_LO12, 0x215)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC, 0x216)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LDST32_DTPREL_LO12, 0x217)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC, 0x218)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LDST64_DTPREL_LO12, 0x219)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC, 0x21a)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1, 0x21b)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC, 0x21c)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, 0x21d)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, 0x21e)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19, 0x21f)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G2, 0x220)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G1, 0x221)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC, 0x222)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G0, 0x223)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC, 0x224)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_ADD_TPREL_HI12, 0x225)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_ADD_TPREL_LO12, 0x226)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC, 0x227)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_LDST8_TPREL_LO12, 0x228)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC, 0x229)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_LDST16_TPREL_LO12, 0x22a)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC, 0x22b)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_LDST32_TPREL_LO12, 0x22c)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC, 0x22d)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12, 0x22e)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC, 0x22f)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC_LD_PREL19, 0x230)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC_ADR_PREL21, 0x231)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC_ADR_PAGE21, 0x232)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC_LD64_LO12, 0x233)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC_ADD_LO12, 0x234)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC_OFF_G1, 0x235)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC_OFF_G0_NC, 0x236)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC_LDR, 0x237)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC_ADD, 0x238)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC_CALL, 0x239)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12, 0x23a)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC, 0x23b)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12, 0x23c)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC, 0x23d)
|
||||||
|
// Dynamic relocations start
|
||||||
|
ELF_RELOC(R_AARCH64_COPY, 0x400)
|
||||||
|
ELF_RELOC(R_AARCH64_GLOB_DAT, 0x401)
|
||||||
|
ELF_RELOC(R_AARCH64_JUMP_SLOT, 0x402)
|
||||||
|
ELF_RELOC(R_AARCH64_RELATIVE, 0x403)
|
||||||
|
// 0x404 and 0x405 are now R_AARCH64_TLS_IMPDEF1 and R_AARCH64_TLS_IMPDEF2
|
||||||
|
// We follow GNU and define TLS_IMPDEF1 as TLS_DTPMOD64 and TLS_IMPDEF2 as
|
||||||
|
// TLS_DTPREL64
|
||||||
|
ELF_RELOC(R_AARCH64_TLS_DTPMOD64, 0x404)
|
||||||
|
ELF_RELOC(R_AARCH64_TLS_DTPREL64, 0x405)
|
||||||
|
ELF_RELOC(R_AARCH64_TLS_TPREL64, 0x406)
|
||||||
|
ELF_RELOC(R_AARCH64_TLSDESC, 0x407)
|
||||||
|
ELF_RELOC(R_AARCH64_IRELATIVE, 0x408)
|
||||||
|
|
||||||
|
// ELF_RELOC(R_AARCH64_P32_NONE, 0)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_ABS32, 0x001)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_ABS16, 0x002)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_PREL32, 0x003)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_PREL16, 0x004)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_MOVW_UABS_G0, 0x005)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_MOVW_UABS_G0_NC, 0x006)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_MOVW_UABS_G1, 0x007)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_MOVW_SABS_G0, 0x008)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_LD_PREL_LO19, 0x009)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_ADR_PREL_LO21, 0x00a)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_ADR_PREL_PG_HI21, 0x00b)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_ADD_ABS_LO12_NC, 0x00c)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_LDST8_ABS_LO12_NC, 0x00d)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_LDST16_ABS_LO12_NC, 0x00e)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_LDST32_ABS_LO12_NC, 0x00f)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_LDST64_ABS_LO12_NC, 0x010)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_LDST128_ABS_LO12_NC, 0x011)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TSTBR14, 0x012)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_CONDBR19, 0x013)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_JUMP26, 0x014)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_CALL26, 0x015)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G0, 0x016)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G0_NC, 0x017)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G1, 0x018)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_GOT_LD_PREL19, 0x019)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE, 0x01a)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_LD32_GOT_LO12_NC, 0x01b)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14, 0x01c)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_PLT32, 0x01d)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PREL21, 0x050)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PAGE21, 0x051)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSGD_ADD_LO12_NC, 0x052)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_ADR_PREL21, 0x053)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_ADR_PAGE21, 0x054)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_ADD_LO12_NC, 0x055)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LD_PREL19, 0x056)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G1, 0x057)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0, 0x058)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0_NC, 0x059)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_ADD_DTPREL_HI12, 0x05a)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_ADD_DTPREL_LO12, 0x05b)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_ADD_DTPREL_LO12_NC, 0x05c)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST8_DTPREL_LO12, 0x05d)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST8_DTPREL_LO12_NC, 0x05e)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST16_DTPREL_LO12, 0x05f)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST16_DTPREL_LO12_NC, 0x060)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST32_DTPREL_LO12, 0x061)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST32_DTPREL_LO12_NC, 0x062)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST64_DTPREL_LO12, 0x063)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST64_DTPREL_LO12_NC, 0x064)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST128_DTPREL_LO12, 0x065)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST128_DTPREL_LO12_NC,0x066)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21, 0x067)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC, 0x068)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19, 0x069)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_MOVW_TPREL_G1, 0x06a)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_MOVW_TPREL_G0, 0x06b)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC, 0x06c)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_ADD_TPREL_HI12, 0x06d)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_ADD_TPREL_LO12, 0x06e)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC, 0x06f)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST8_TPREL_LO12, 0x070)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST8_TPREL_LO12_NC, 0x071)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST16_TPREL_LO12, 0x072)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST16_TPREL_LO12_NC, 0x073)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12, 0x074)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12_NC, 0x075)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12, 0x076)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12_NC, 0x077)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST128_TPREL_LO12, 0x078)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST128_TPREL_LO12_NC, 0x079)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSDESC_LD_PREL19, 0x07a)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSDESC_ADR_PREL21, 0x07b)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSDESC_ADR_PAGE21, 0x07c)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSDESC_LD32_LO12, 0x07d)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSDESC_ADD_LO12, 0x07e)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSDESC_CALL, 0x07f)
|
||||||
|
// Dynamic relocations start
|
||||||
|
ELF_RELOC(R_AARCH64_P32_COPY, 0x0b4)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_GLOB_DAT, 0x0b5)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_JUMP_SLOT, 0x0b6)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_RELATIVE, 0x0b7)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLS_DTPREL, 0x0b8)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLS_DTPMOD, 0x0b9)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLS_TPREL, 0x0ba)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_TLSDESC, 0x0bb)
|
||||||
|
ELF_RELOC(R_AARCH64_P32_IRELATIVE, 0x0bc)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_AMDGPU_NONE, 0)
|
||||||
|
ELF_RELOC(R_AMDGPU_ABS32_LO, 1)
|
||||||
|
ELF_RELOC(R_AMDGPU_ABS32_HI, 2)
|
||||||
|
ELF_RELOC(R_AMDGPU_ABS64, 3)
|
||||||
|
ELF_RELOC(R_AMDGPU_REL32, 4)
|
||||||
|
ELF_RELOC(R_AMDGPU_REL64, 5)
|
||||||
|
ELF_RELOC(R_AMDGPU_ABS32, 6)
|
||||||
|
ELF_RELOC(R_AMDGPU_GOTPCREL, 7)
|
||||||
|
ELF_RELOC(R_AMDGPU_GOTPCREL32_LO, 8)
|
||||||
|
ELF_RELOC(R_AMDGPU_GOTPCREL32_HI, 9)
|
||||||
|
ELF_RELOC(R_AMDGPU_REL32_LO, 10)
|
||||||
|
ELF_RELOC(R_AMDGPU_REL32_HI, 11)
|
||||||
|
ELF_RELOC(R_AMDGPU_RELATIVE64, 13)
|
||||||
|
ELF_RELOC(R_AMDGPU_REL16, 14)
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_ARC_NONE, 0)
|
||||||
|
ELF_RELOC(R_ARC_8, 1)
|
||||||
|
ELF_RELOC(R_ARC_16, 2)
|
||||||
|
ELF_RELOC(R_ARC_24, 3)
|
||||||
|
ELF_RELOC(R_ARC_32, 4)
|
||||||
|
ELF_RELOC(R_ARC_N8, 8)
|
||||||
|
ELF_RELOC(R_ARC_N16, 9)
|
||||||
|
ELF_RELOC(R_ARC_N24, 10)
|
||||||
|
ELF_RELOC(R_ARC_N32, 11)
|
||||||
|
ELF_RELOC(R_ARC_SDA, 12)
|
||||||
|
ELF_RELOC(R_ARC_SECTOFF, 13)
|
||||||
|
ELF_RELOC(R_ARC_S21H_PCREL, 14)
|
||||||
|
ELF_RELOC(R_ARC_S21W_PCREL, 15)
|
||||||
|
ELF_RELOC(R_ARC_S25H_PCREL, 16)
|
||||||
|
ELF_RELOC(R_ARC_S25W_PCREL, 17)
|
||||||
|
ELF_RELOC(R_ARC_SDA32, 18)
|
||||||
|
ELF_RELOC(R_ARC_SDA_LDST, 19)
|
||||||
|
ELF_RELOC(R_ARC_SDA_LDST1, 20)
|
||||||
|
ELF_RELOC(R_ARC_SDA_LDST2, 21)
|
||||||
|
ELF_RELOC(R_ARC_SDA16_LD, 22)
|
||||||
|
ELF_RELOC(R_ARC_SDA16_LD1, 23)
|
||||||
|
ELF_RELOC(R_ARC_SDA16_LD2, 24)
|
||||||
|
ELF_RELOC(R_ARC_S13_PCREL, 25)
|
||||||
|
ELF_RELOC(R_ARC_W, 26)
|
||||||
|
ELF_RELOC(R_ARC_32_ME, 27)
|
||||||
|
ELF_RELOC(R_ARC_32_ME_S, 105)
|
||||||
|
ELF_RELOC(R_ARC_N32_ME, 28)
|
||||||
|
ELF_RELOC(R_ARC_SECTOFF_ME, 29)
|
||||||
|
ELF_RELOC(R_ARC_SDA32_ME, 30)
|
||||||
|
ELF_RELOC(R_ARC_W_ME, 31)
|
||||||
|
ELF_RELOC(R_AC_SECTOFF_U8, 35)
|
||||||
|
ELF_RELOC(R_AC_SECTOFF_U8_1, 36)
|
||||||
|
ELF_RELOC(R_AC_SECTOFF_U8_2, 37)
|
||||||
|
ELF_RELOC(R_AC_SECTOFF_S9, 38)
|
||||||
|
ELF_RELOC(R_AC_SECTOFF_S9_1, 39)
|
||||||
|
ELF_RELOC(R_AC_SECTOFF_S9_2, 40)
|
||||||
|
ELF_RELOC(R_ARC_SECTOFF_ME_1, 41)
|
||||||
|
ELF_RELOC(R_ARC_SECTOFF_ME_2, 42)
|
||||||
|
ELF_RELOC(R_ARC_SECTOFF_1, 43)
|
||||||
|
ELF_RELOC(R_ARC_SECTOFF_2, 44)
|
||||||
|
ELF_RELOC(R_ARC_SDA_12, 45)
|
||||||
|
ELF_RELOC(R_ARC_SDA16_ST2, 48)
|
||||||
|
ELF_RELOC(R_ARC_32_PCREL, 49)
|
||||||
|
ELF_RELOC(R_ARC_PC32, 50)
|
||||||
|
ELF_RELOC(R_ARC_GOT32, 59)
|
||||||
|
ELF_RELOC(R_ARC_GOTPC32, 51)
|
||||||
|
ELF_RELOC(R_ARC_PLT32, 52)
|
||||||
|
ELF_RELOC(R_ARC_COPY, 53)
|
||||||
|
ELF_RELOC(R_ARC_GLOB_DAT, 54)
|
||||||
|
ELF_RELOC(R_ARC_JMP_SLOT, 55)
|
||||||
|
ELF_RELOC(R_ARC_RELATIVE, 56)
|
||||||
|
ELF_RELOC(R_ARC_GOTOFF, 57)
|
||||||
|
ELF_RELOC(R_ARC_GOTPC, 58)
|
||||||
|
ELF_RELOC(R_ARC_S21W_PCREL_PLT, 60)
|
||||||
|
ELF_RELOC(R_ARC_S25H_PCREL_PLT, 61)
|
||||||
|
ELF_RELOC(R_ARC_JLI_SECTOFF, 63)
|
||||||
|
ELF_RELOC(R_ARC_TLS_DTPMOD, 66)
|
||||||
|
ELF_RELOC(R_ARC_TLS_TPOFF, 68)
|
||||||
|
ELF_RELOC(R_ARC_TLS_GD_GOT, 69)
|
||||||
|
ELF_RELOC(R_ARC_TLS_GD_LD, 70)
|
||||||
|
ELF_RELOC(R_ARC_TLS_GD_CALL, 71)
|
||||||
|
ELF_RELOC(R_ARC_TLS_IE_GOT, 72)
|
||||||
|
ELF_RELOC(R_ARC_TLS_DTPOFF, 67)
|
||||||
|
ELF_RELOC(R_ARC_TLS_DTPOFF_S9, 73)
|
||||||
|
ELF_RELOC(R_ARC_TLS_LE_S9, 74)
|
||||||
|
ELF_RELOC(R_ARC_TLS_LE_32, 75)
|
||||||
|
ELF_RELOC(R_ARC_S25W_PCREL_PLT, 76)
|
||||||
|
ELF_RELOC(R_ARC_S21H_PCREL_PLT, 77)
|
||||||
|
ELF_RELOC(R_ARC_NPS_CMEM16, 78)
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Meets 2.09 ABI Specs.
|
||||||
|
ELF_RELOC(R_ARM_NONE, 0x00)
|
||||||
|
ELF_RELOC(R_ARM_PC24, 0x01)
|
||||||
|
ELF_RELOC(R_ARM_ABS32, 0x02)
|
||||||
|
ELF_RELOC(R_ARM_REL32, 0x03)
|
||||||
|
ELF_RELOC(R_ARM_LDR_PC_G0, 0x04)
|
||||||
|
ELF_RELOC(R_ARM_ABS16, 0x05)
|
||||||
|
ELF_RELOC(R_ARM_ABS12, 0x06)
|
||||||
|
ELF_RELOC(R_ARM_THM_ABS5, 0x07)
|
||||||
|
ELF_RELOC(R_ARM_ABS8, 0x08)
|
||||||
|
ELF_RELOC(R_ARM_SBREL32, 0x09)
|
||||||
|
ELF_RELOC(R_ARM_THM_CALL, 0x0a)
|
||||||
|
ELF_RELOC(R_ARM_THM_PC8, 0x0b)
|
||||||
|
ELF_RELOC(R_ARM_BREL_ADJ, 0x0c)
|
||||||
|
ELF_RELOC(R_ARM_TLS_DESC, 0x0d)
|
||||||
|
ELF_RELOC(R_ARM_THM_SWI8, 0x0e)
|
||||||
|
ELF_RELOC(R_ARM_XPC25, 0x0f)
|
||||||
|
ELF_RELOC(R_ARM_THM_XPC22, 0x10)
|
||||||
|
ELF_RELOC(R_ARM_TLS_DTPMOD32, 0x11)
|
||||||
|
ELF_RELOC(R_ARM_TLS_DTPOFF32, 0x12)
|
||||||
|
ELF_RELOC(R_ARM_TLS_TPOFF32, 0x13)
|
||||||
|
ELF_RELOC(R_ARM_COPY, 0x14)
|
||||||
|
ELF_RELOC(R_ARM_GLOB_DAT, 0x15)
|
||||||
|
ELF_RELOC(R_ARM_JUMP_SLOT, 0x16)
|
||||||
|
ELF_RELOC(R_ARM_RELATIVE, 0x17)
|
||||||
|
ELF_RELOC(R_ARM_GOTOFF32, 0x18)
|
||||||
|
ELF_RELOC(R_ARM_BASE_PREL, 0x19)
|
||||||
|
ELF_RELOC(R_ARM_GOT_BREL, 0x1a)
|
||||||
|
ELF_RELOC(R_ARM_PLT32, 0x1b)
|
||||||
|
ELF_RELOC(R_ARM_CALL, 0x1c)
|
||||||
|
ELF_RELOC(R_ARM_JUMP24, 0x1d)
|
||||||
|
ELF_RELOC(R_ARM_THM_JUMP24, 0x1e)
|
||||||
|
ELF_RELOC(R_ARM_BASE_ABS, 0x1f)
|
||||||
|
ELF_RELOC(R_ARM_ALU_PCREL_7_0, 0x20)
|
||||||
|
ELF_RELOC(R_ARM_ALU_PCREL_15_8, 0x21)
|
||||||
|
ELF_RELOC(R_ARM_ALU_PCREL_23_15, 0x22)
|
||||||
|
ELF_RELOC(R_ARM_LDR_SBREL_11_0_NC, 0x23)
|
||||||
|
ELF_RELOC(R_ARM_ALU_SBREL_19_12_NC, 0x24)
|
||||||
|
ELF_RELOC(R_ARM_ALU_SBREL_27_20_CK, 0x25)
|
||||||
|
ELF_RELOC(R_ARM_TARGET1, 0x26)
|
||||||
|
ELF_RELOC(R_ARM_SBREL31, 0x27)
|
||||||
|
ELF_RELOC(R_ARM_V4BX, 0x28)
|
||||||
|
ELF_RELOC(R_ARM_TARGET2, 0x29)
|
||||||
|
ELF_RELOC(R_ARM_PREL31, 0x2a)
|
||||||
|
ELF_RELOC(R_ARM_MOVW_ABS_NC, 0x2b)
|
||||||
|
ELF_RELOC(R_ARM_MOVT_ABS, 0x2c)
|
||||||
|
ELF_RELOC(R_ARM_MOVW_PREL_NC, 0x2d)
|
||||||
|
ELF_RELOC(R_ARM_MOVT_PREL, 0x2e)
|
||||||
|
ELF_RELOC(R_ARM_THM_MOVW_ABS_NC, 0x2f)
|
||||||
|
ELF_RELOC(R_ARM_THM_MOVT_ABS, 0x30)
|
||||||
|
ELF_RELOC(R_ARM_THM_MOVW_PREL_NC, 0x31)
|
||||||
|
ELF_RELOC(R_ARM_THM_MOVT_PREL, 0x32)
|
||||||
|
ELF_RELOC(R_ARM_THM_JUMP19, 0x33)
|
||||||
|
ELF_RELOC(R_ARM_THM_JUMP6, 0x34)
|
||||||
|
ELF_RELOC(R_ARM_THM_ALU_PREL_11_0, 0x35)
|
||||||
|
ELF_RELOC(R_ARM_THM_PC12, 0x36)
|
||||||
|
ELF_RELOC(R_ARM_ABS32_NOI, 0x37)
|
||||||
|
ELF_RELOC(R_ARM_REL32_NOI, 0x38)
|
||||||
|
ELF_RELOC(R_ARM_ALU_PC_G0_NC, 0x39)
|
||||||
|
ELF_RELOC(R_ARM_ALU_PC_G0, 0x3a)
|
||||||
|
ELF_RELOC(R_ARM_ALU_PC_G1_NC, 0x3b)
|
||||||
|
ELF_RELOC(R_ARM_ALU_PC_G1, 0x3c)
|
||||||
|
ELF_RELOC(R_ARM_ALU_PC_G2, 0x3d)
|
||||||
|
ELF_RELOC(R_ARM_LDR_PC_G1, 0x3e)
|
||||||
|
ELF_RELOC(R_ARM_LDR_PC_G2, 0x3f)
|
||||||
|
ELF_RELOC(R_ARM_LDRS_PC_G0, 0x40)
|
||||||
|
ELF_RELOC(R_ARM_LDRS_PC_G1, 0x41)
|
||||||
|
ELF_RELOC(R_ARM_LDRS_PC_G2, 0x42)
|
||||||
|
ELF_RELOC(R_ARM_LDC_PC_G0, 0x43)
|
||||||
|
ELF_RELOC(R_ARM_LDC_PC_G1, 0x44)
|
||||||
|
ELF_RELOC(R_ARM_LDC_PC_G2, 0x45)
|
||||||
|
ELF_RELOC(R_ARM_ALU_SB_G0_NC, 0x46)
|
||||||
|
ELF_RELOC(R_ARM_ALU_SB_G0, 0x47)
|
||||||
|
ELF_RELOC(R_ARM_ALU_SB_G1_NC, 0x48)
|
||||||
|
ELF_RELOC(R_ARM_ALU_SB_G1, 0x49)
|
||||||
|
ELF_RELOC(R_ARM_ALU_SB_G2, 0x4a)
|
||||||
|
ELF_RELOC(R_ARM_LDR_SB_G0, 0x4b)
|
||||||
|
ELF_RELOC(R_ARM_LDR_SB_G1, 0x4c)
|
||||||
|
ELF_RELOC(R_ARM_LDR_SB_G2, 0x4d)
|
||||||
|
ELF_RELOC(R_ARM_LDRS_SB_G0, 0x4e)
|
||||||
|
ELF_RELOC(R_ARM_LDRS_SB_G1, 0x4f)
|
||||||
|
ELF_RELOC(R_ARM_LDRS_SB_G2, 0x50)
|
||||||
|
ELF_RELOC(R_ARM_LDC_SB_G0, 0x51)
|
||||||
|
ELF_RELOC(R_ARM_LDC_SB_G1, 0x52)
|
||||||
|
ELF_RELOC(R_ARM_LDC_SB_G2, 0x53)
|
||||||
|
ELF_RELOC(R_ARM_MOVW_BREL_NC, 0x54)
|
||||||
|
ELF_RELOC(R_ARM_MOVT_BREL, 0x55)
|
||||||
|
ELF_RELOC(R_ARM_MOVW_BREL, 0x56)
|
||||||
|
ELF_RELOC(R_ARM_THM_MOVW_BREL_NC, 0x57)
|
||||||
|
ELF_RELOC(R_ARM_THM_MOVT_BREL, 0x58)
|
||||||
|
ELF_RELOC(R_ARM_THM_MOVW_BREL, 0x59)
|
||||||
|
ELF_RELOC(R_ARM_TLS_GOTDESC, 0x5a)
|
||||||
|
ELF_RELOC(R_ARM_TLS_CALL, 0x5b)
|
||||||
|
ELF_RELOC(R_ARM_TLS_DESCSEQ, 0x5c)
|
||||||
|
ELF_RELOC(R_ARM_THM_TLS_CALL, 0x5d)
|
||||||
|
ELF_RELOC(R_ARM_PLT32_ABS, 0x5e)
|
||||||
|
ELF_RELOC(R_ARM_GOT_ABS, 0x5f)
|
||||||
|
ELF_RELOC(R_ARM_GOT_PREL, 0x60)
|
||||||
|
ELF_RELOC(R_ARM_GOT_BREL12, 0x61)
|
||||||
|
ELF_RELOC(R_ARM_GOTOFF12, 0x62)
|
||||||
|
ELF_RELOC(R_ARM_GOTRELAX, 0x63)
|
||||||
|
ELF_RELOC(R_ARM_GNU_VTENTRY, 0x64)
|
||||||
|
ELF_RELOC(R_ARM_GNU_VTINHERIT, 0x65)
|
||||||
|
ELF_RELOC(R_ARM_THM_JUMP11, 0x66)
|
||||||
|
ELF_RELOC(R_ARM_THM_JUMP8, 0x67)
|
||||||
|
ELF_RELOC(R_ARM_TLS_GD32, 0x68)
|
||||||
|
ELF_RELOC(R_ARM_TLS_LDM32, 0x69)
|
||||||
|
ELF_RELOC(R_ARM_TLS_LDO32, 0x6a)
|
||||||
|
ELF_RELOC(R_ARM_TLS_IE32, 0x6b)
|
||||||
|
ELF_RELOC(R_ARM_TLS_LE32, 0x6c)
|
||||||
|
ELF_RELOC(R_ARM_TLS_LDO12, 0x6d)
|
||||||
|
ELF_RELOC(R_ARM_TLS_LE12, 0x6e)
|
||||||
|
ELF_RELOC(R_ARM_TLS_IE12GP, 0x6f)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_0, 0x70)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_1, 0x71)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_2, 0x72)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_3, 0x73)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_4, 0x74)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_5, 0x75)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_6, 0x76)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_7, 0x77)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_8, 0x78)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_9, 0x79)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_10, 0x7a)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_11, 0x7b)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_12, 0x7c)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_13, 0x7d)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_14, 0x7e)
|
||||||
|
ELF_RELOC(R_ARM_PRIVATE_15, 0x7f)
|
||||||
|
ELF_RELOC(R_ARM_ME_TOO, 0x80)
|
||||||
|
ELF_RELOC(R_ARM_THM_TLS_DESCSEQ16, 0x81)
|
||||||
|
ELF_RELOC(R_ARM_THM_TLS_DESCSEQ32, 0x82)
|
||||||
|
ELF_RELOC(R_ARM_THM_ALU_ABS_G0_NC, 0x84)
|
||||||
|
ELF_RELOC(R_ARM_THM_ALU_ABS_G1_NC, 0x85)
|
||||||
|
ELF_RELOC(R_ARM_THM_ALU_ABS_G2_NC, 0x86)
|
||||||
|
ELF_RELOC(R_ARM_THM_ALU_ABS_G3, 0x87)
|
||||||
|
ELF_RELOC(R_ARM_THM_BF16, 0x88)
|
||||||
|
ELF_RELOC(R_ARM_THM_BF12, 0x89)
|
||||||
|
ELF_RELOC(R_ARM_THM_BF18, 0x8a)
|
||||||
|
ELF_RELOC(R_ARM_IRELATIVE, 0xa0)
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_AVR_NONE, 0)
|
||||||
|
ELF_RELOC(R_AVR_32, 1)
|
||||||
|
ELF_RELOC(R_AVR_7_PCREL, 2)
|
||||||
|
ELF_RELOC(R_AVR_13_PCREL, 3)
|
||||||
|
ELF_RELOC(R_AVR_16, 4)
|
||||||
|
ELF_RELOC(R_AVR_16_PM, 5)
|
||||||
|
ELF_RELOC(R_AVR_LO8_LDI, 6)
|
||||||
|
ELF_RELOC(R_AVR_HI8_LDI, 7)
|
||||||
|
ELF_RELOC(R_AVR_HH8_LDI, 8)
|
||||||
|
ELF_RELOC(R_AVR_LO8_LDI_NEG, 9)
|
||||||
|
ELF_RELOC(R_AVR_HI8_LDI_NEG, 10)
|
||||||
|
ELF_RELOC(R_AVR_HH8_LDI_NEG, 11)
|
||||||
|
ELF_RELOC(R_AVR_LO8_LDI_PM, 12)
|
||||||
|
ELF_RELOC(R_AVR_HI8_LDI_PM, 13)
|
||||||
|
ELF_RELOC(R_AVR_HH8_LDI_PM, 14)
|
||||||
|
ELF_RELOC(R_AVR_LO8_LDI_PM_NEG, 15)
|
||||||
|
ELF_RELOC(R_AVR_HI8_LDI_PM_NEG, 16)
|
||||||
|
ELF_RELOC(R_AVR_HH8_LDI_PM_NEG, 17)
|
||||||
|
ELF_RELOC(R_AVR_CALL, 18)
|
||||||
|
ELF_RELOC(R_AVR_LDI, 19)
|
||||||
|
ELF_RELOC(R_AVR_6, 20)
|
||||||
|
ELF_RELOC(R_AVR_6_ADIW, 21)
|
||||||
|
ELF_RELOC(R_AVR_MS8_LDI, 22)
|
||||||
|
ELF_RELOC(R_AVR_MS8_LDI_NEG, 23)
|
||||||
|
ELF_RELOC(R_AVR_LO8_LDI_GS, 24)
|
||||||
|
ELF_RELOC(R_AVR_HI8_LDI_GS, 25)
|
||||||
|
ELF_RELOC(R_AVR_8, 26)
|
||||||
|
ELF_RELOC(R_AVR_8_LO8, 27)
|
||||||
|
ELF_RELOC(R_AVR_8_HI8, 28)
|
||||||
|
ELF_RELOC(R_AVR_8_HLO8, 29)
|
||||||
|
ELF_RELOC(R_AVR_DIFF8, 30)
|
||||||
|
ELF_RELOC(R_AVR_DIFF16, 31)
|
||||||
|
ELF_RELOC(R_AVR_DIFF32, 32)
|
||||||
|
ELF_RELOC(R_AVR_LDS_STS_16, 33)
|
||||||
|
ELF_RELOC(R_AVR_PORT6, 34)
|
||||||
|
ELF_RELOC(R_AVR_PORT5, 35)
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// No relocation
|
||||||
|
ELF_RELOC(R_BPF_NONE, 0)
|
||||||
|
ELF_RELOC(R_BPF_64_64, 1)
|
||||||
|
ELF_RELOC(R_BPF_64_ABS64, 2)
|
||||||
|
ELF_RELOC(R_BPF_64_ABS32, 3)
|
||||||
|
ELF_RELOC(R_BPF_64_NODYLD32, 4)
|
||||||
|
ELF_RELOC(R_BPF_64_32, 10)
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_CKCORE_NONE, 0)
|
||||||
|
ELF_RELOC(R_CKCORE_ADDR32, 1)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_IMM8_4, 2)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_IMM11_2, 3)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_IMM4_2, 4)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL32, 5)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_JSR_IMM11_2, 6)
|
||||||
|
ELF_RELOC(R_CKCORE_GNU_VTINHERIT, 7)
|
||||||
|
ELF_RELOC(R_CKCORE_GNU_VTENTRY, 8)
|
||||||
|
ELF_RELOC(R_CKCORE_RELATIVE, 9)
|
||||||
|
ELF_RELOC(R_CKCORE_COPY, 10)
|
||||||
|
ELF_RELOC(R_CKCORE_GLOB_DAT, 11)
|
||||||
|
ELF_RELOC(R_CKCORE_JUMP_SLOT, 12)
|
||||||
|
ELF_RELOC(R_CKCORE_GOTOFF, 13)
|
||||||
|
ELF_RELOC(R_CKCORE_GOTPC, 14)
|
||||||
|
ELF_RELOC(R_CKCORE_GOT32, 15)
|
||||||
|
ELF_RELOC(R_CKCORE_PLT32, 16)
|
||||||
|
ELF_RELOC(R_CKCORE_ADDRGOT, 17)
|
||||||
|
ELF_RELOC(R_CKCORE_ADDRPLT, 18)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_IMM26_2, 19)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_IMM16_2, 20)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_IMM16_4, 21)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_IMM10_2, 22)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_IMM10_4, 23)
|
||||||
|
ELF_RELOC(R_CKCORE_ADDR_HI16, 24)
|
||||||
|
ELF_RELOC(R_CKCORE_ADDR_LO16, 25)
|
||||||
|
ELF_RELOC(R_CKCORE_GOTPC_HI16, 26)
|
||||||
|
ELF_RELOC(R_CKCORE_GOTPC_LO16, 27)
|
||||||
|
ELF_RELOC(R_CKCORE_GOTOFF_HI16, 28)
|
||||||
|
ELF_RELOC(R_CKCORE_GOTOFF_LO16, 29)
|
||||||
|
ELF_RELOC(R_CKCORE_GOT12, 30)
|
||||||
|
ELF_RELOC(R_CKCORE_GOT_HI16, 31)
|
||||||
|
ELF_RELOC(R_CKCORE_GOT_LO16, 32)
|
||||||
|
ELF_RELOC(R_CKCORE_PLT12, 33)
|
||||||
|
ELF_RELOC(R_CKCORE_PLT_HI16, 34)
|
||||||
|
ELF_RELOC(R_CKCORE_PLT_LO16, 35)
|
||||||
|
ELF_RELOC(R_CKCORE_ADDRGOT_HI16, 36)
|
||||||
|
ELF_RELOC(R_CKCORE_ADDRGOT_LO16, 37)
|
||||||
|
ELF_RELOC(R_CKCORE_ADDRPLT_HI16, 38)
|
||||||
|
ELF_RELOC(R_CKCORE_ADDRPLT_LO16, 39)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_JSR_IMM26_2, 40)
|
||||||
|
ELF_RELOC(R_CKCORE_TOFFSET_LO16, 41)
|
||||||
|
ELF_RELOC(R_CKCORE_DOFFSET_LO16, 42)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_IMM18_2, 43)
|
||||||
|
ELF_RELOC(R_CKCORE_DOFFSET_IMM18, 44)
|
||||||
|
ELF_RELOC(R_CKCORE_DOFFSET_IMM18_2, 45)
|
||||||
|
ELF_RELOC(R_CKCORE_DOFFSET_IMM18_4, 46)
|
||||||
|
ELF_RELOC(R_CKCORE_GOTOFF_IMM18, 47)
|
||||||
|
ELF_RELOC(R_CKCORE_GOT_IMM18_4, 48)
|
||||||
|
ELF_RELOC(R_CKCORE_PLT_IMM18_4, 49)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_IMM7_4, 50)
|
||||||
|
ELF_RELOC(R_CKCORE_TLS_LE32, 51)
|
||||||
|
ELF_RELOC(R_CKCORE_TLS_IE32, 52)
|
||||||
|
ELF_RELOC(R_CKCORE_TLS_GD32, 53)
|
||||||
|
ELF_RELOC(R_CKCORE_TLS_LDM32, 54)
|
||||||
|
ELF_RELOC(R_CKCORE_TLS_LDO32, 55)
|
||||||
|
ELF_RELOC(R_CKCORE_TLS_DTPMOD32, 56)
|
||||||
|
ELF_RELOC(R_CKCORE_TLS_DTPOFF32, 57)
|
||||||
|
ELF_RELOC(R_CKCORE_TLS_TPOFF32, 58)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_FLRW_IMM8_4, 59)
|
||||||
|
ELF_RELOC(R_CKCORE_NOJSRI, 60)
|
||||||
|
ELF_RELOC(R_CKCORE_CALLGRAPH, 61)
|
||||||
|
ELF_RELOC(R_CKCORE_IRELATIVE, 62)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_BLOOP_IMM4_4, 63)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_BLOOP_IMM12_4, 64)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_1, 65)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_2, 66)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_4, 67)
|
||||||
|
ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_8, 68)
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Release 5 ABI
|
||||||
|
ELF_RELOC(R_HEX_NONE, 0)
|
||||||
|
ELF_RELOC(R_HEX_B22_PCREL, 1)
|
||||||
|
ELF_RELOC(R_HEX_B15_PCREL, 2)
|
||||||
|
ELF_RELOC(R_HEX_B7_PCREL, 3)
|
||||||
|
ELF_RELOC(R_HEX_LO16, 4)
|
||||||
|
ELF_RELOC(R_HEX_HI16, 5)
|
||||||
|
ELF_RELOC(R_HEX_32, 6)
|
||||||
|
ELF_RELOC(R_HEX_16, 7)
|
||||||
|
ELF_RELOC(R_HEX_8, 8)
|
||||||
|
ELF_RELOC(R_HEX_GPREL16_0, 9)
|
||||||
|
ELF_RELOC(R_HEX_GPREL16_1, 10)
|
||||||
|
ELF_RELOC(R_HEX_GPREL16_2, 11)
|
||||||
|
ELF_RELOC(R_HEX_GPREL16_3, 12)
|
||||||
|
ELF_RELOC(R_HEX_HL16, 13)
|
||||||
|
ELF_RELOC(R_HEX_B13_PCREL, 14)
|
||||||
|
ELF_RELOC(R_HEX_B9_PCREL, 15)
|
||||||
|
ELF_RELOC(R_HEX_B32_PCREL_X, 16)
|
||||||
|
ELF_RELOC(R_HEX_32_6_X, 17)
|
||||||
|
ELF_RELOC(R_HEX_B22_PCREL_X, 18)
|
||||||
|
ELF_RELOC(R_HEX_B15_PCREL_X, 19)
|
||||||
|
ELF_RELOC(R_HEX_B13_PCREL_X, 20)
|
||||||
|
ELF_RELOC(R_HEX_B9_PCREL_X, 21)
|
||||||
|
ELF_RELOC(R_HEX_B7_PCREL_X, 22)
|
||||||
|
ELF_RELOC(R_HEX_16_X, 23)
|
||||||
|
ELF_RELOC(R_HEX_12_X, 24)
|
||||||
|
ELF_RELOC(R_HEX_11_X, 25)
|
||||||
|
ELF_RELOC(R_HEX_10_X, 26)
|
||||||
|
ELF_RELOC(R_HEX_9_X, 27)
|
||||||
|
ELF_RELOC(R_HEX_8_X, 28)
|
||||||
|
ELF_RELOC(R_HEX_7_X, 29)
|
||||||
|
ELF_RELOC(R_HEX_6_X, 30)
|
||||||
|
ELF_RELOC(R_HEX_32_PCREL, 31)
|
||||||
|
ELF_RELOC(R_HEX_COPY, 32)
|
||||||
|
ELF_RELOC(R_HEX_GLOB_DAT, 33)
|
||||||
|
ELF_RELOC(R_HEX_JMP_SLOT, 34)
|
||||||
|
ELF_RELOC(R_HEX_RELATIVE, 35)
|
||||||
|
ELF_RELOC(R_HEX_PLT_B22_PCREL, 36)
|
||||||
|
ELF_RELOC(R_HEX_GOTREL_LO16, 37)
|
||||||
|
ELF_RELOC(R_HEX_GOTREL_HI16, 38)
|
||||||
|
ELF_RELOC(R_HEX_GOTREL_32, 39)
|
||||||
|
ELF_RELOC(R_HEX_GOT_LO16, 40)
|
||||||
|
ELF_RELOC(R_HEX_GOT_HI16, 41)
|
||||||
|
ELF_RELOC(R_HEX_GOT_32, 42)
|
||||||
|
ELF_RELOC(R_HEX_GOT_16, 43)
|
||||||
|
ELF_RELOC(R_HEX_DTPMOD_32, 44)
|
||||||
|
ELF_RELOC(R_HEX_DTPREL_LO16, 45)
|
||||||
|
ELF_RELOC(R_HEX_DTPREL_HI16, 46)
|
||||||
|
ELF_RELOC(R_HEX_DTPREL_32, 47)
|
||||||
|
ELF_RELOC(R_HEX_DTPREL_16, 48)
|
||||||
|
ELF_RELOC(R_HEX_GD_PLT_B22_PCREL, 49)
|
||||||
|
ELF_RELOC(R_HEX_GD_GOT_LO16, 50)
|
||||||
|
ELF_RELOC(R_HEX_GD_GOT_HI16, 51)
|
||||||
|
ELF_RELOC(R_HEX_GD_GOT_32, 52)
|
||||||
|
ELF_RELOC(R_HEX_GD_GOT_16, 53)
|
||||||
|
ELF_RELOC(R_HEX_IE_LO16, 54)
|
||||||
|
ELF_RELOC(R_HEX_IE_HI16, 55)
|
||||||
|
ELF_RELOC(R_HEX_IE_32, 56)
|
||||||
|
ELF_RELOC(R_HEX_IE_GOT_LO16, 57)
|
||||||
|
ELF_RELOC(R_HEX_IE_GOT_HI16, 58)
|
||||||
|
ELF_RELOC(R_HEX_IE_GOT_32, 59)
|
||||||
|
ELF_RELOC(R_HEX_IE_GOT_16, 60)
|
||||||
|
ELF_RELOC(R_HEX_TPREL_LO16, 61)
|
||||||
|
ELF_RELOC(R_HEX_TPREL_HI16, 62)
|
||||||
|
ELF_RELOC(R_HEX_TPREL_32, 63)
|
||||||
|
ELF_RELOC(R_HEX_TPREL_16, 64)
|
||||||
|
ELF_RELOC(R_HEX_6_PCREL_X, 65)
|
||||||
|
ELF_RELOC(R_HEX_GOTREL_32_6_X, 66)
|
||||||
|
ELF_RELOC(R_HEX_GOTREL_16_X, 67)
|
||||||
|
ELF_RELOC(R_HEX_GOTREL_11_X, 68)
|
||||||
|
ELF_RELOC(R_HEX_GOT_32_6_X, 69)
|
||||||
|
ELF_RELOC(R_HEX_GOT_16_X, 70)
|
||||||
|
ELF_RELOC(R_HEX_GOT_11_X, 71)
|
||||||
|
ELF_RELOC(R_HEX_DTPREL_32_6_X, 72)
|
||||||
|
ELF_RELOC(R_HEX_DTPREL_16_X, 73)
|
||||||
|
ELF_RELOC(R_HEX_DTPREL_11_X, 74)
|
||||||
|
ELF_RELOC(R_HEX_GD_GOT_32_6_X, 75)
|
||||||
|
ELF_RELOC(R_HEX_GD_GOT_16_X, 76)
|
||||||
|
ELF_RELOC(R_HEX_GD_GOT_11_X, 77)
|
||||||
|
ELF_RELOC(R_HEX_IE_32_6_X, 78)
|
||||||
|
ELF_RELOC(R_HEX_IE_16_X, 79)
|
||||||
|
ELF_RELOC(R_HEX_IE_GOT_32_6_X, 80)
|
||||||
|
ELF_RELOC(R_HEX_IE_GOT_16_X, 81)
|
||||||
|
ELF_RELOC(R_HEX_IE_GOT_11_X, 82)
|
||||||
|
ELF_RELOC(R_HEX_TPREL_32_6_X, 83)
|
||||||
|
ELF_RELOC(R_HEX_TPREL_16_X, 84)
|
||||||
|
ELF_RELOC(R_HEX_TPREL_11_X, 85)
|
||||||
|
ELF_RELOC(R_HEX_LD_PLT_B22_PCREL, 86)
|
||||||
|
ELF_RELOC(R_HEX_LD_GOT_LO16, 87)
|
||||||
|
ELF_RELOC(R_HEX_LD_GOT_HI16, 88)
|
||||||
|
ELF_RELOC(R_HEX_LD_GOT_32, 89)
|
||||||
|
ELF_RELOC(R_HEX_LD_GOT_16, 90)
|
||||||
|
ELF_RELOC(R_HEX_LD_GOT_32_6_X, 91)
|
||||||
|
ELF_RELOC(R_HEX_LD_GOT_16_X, 92)
|
||||||
|
ELF_RELOC(R_HEX_LD_GOT_11_X, 93)
|
||||||
|
ELF_RELOC(R_HEX_23_REG, 94)
|
||||||
|
ELF_RELOC(R_HEX_GD_PLT_B22_PCREL_X, 95)
|
||||||
|
ELF_RELOC(R_HEX_GD_PLT_B32_PCREL_X, 96)
|
||||||
|
ELF_RELOC(R_HEX_LD_PLT_B22_PCREL_X, 97)
|
||||||
|
ELF_RELOC(R_HEX_LD_PLT_B32_PCREL_X, 98)
|
||||||
|
ELF_RELOC(R_HEX_27_REG, 99)
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// No relocation
|
||||||
|
ELF_RELOC(R_LANAI_NONE, 0)
|
||||||
|
// 21-bit symbol relocation
|
||||||
|
ELF_RELOC(R_LANAI_21, 1)
|
||||||
|
// 21-bit symbol relocation with last two bits masked to 0
|
||||||
|
ELF_RELOC(R_LANAI_21_F, 2)
|
||||||
|
// 25-bit branch targets
|
||||||
|
ELF_RELOC(R_LANAI_25, 3)
|
||||||
|
// General 32-bit relocation
|
||||||
|
ELF_RELOC(R_LANAI_32, 4)
|
||||||
|
// Upper 16-bits of a symbolic relocation
|
||||||
|
ELF_RELOC(R_LANAI_HI16, 5)
|
||||||
|
// Lower 16-bits of a symbolic relocation
|
||||||
|
ELF_RELOC(R_LANAI_LO16, 6)
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// These types and values are from the LoongArch ELF psABI which can be found at
|
||||||
|
// https://github.com/loongson/LoongArch-Documentation
|
||||||
|
// and these definitions has been adopted by binutils (include/elf/loongarch.h).
|
||||||
|
// The commit hash (main branch) we reference is:
|
||||||
|
// 9b3bd9f4a497115913c22f1a2a47863798fbc02a
|
||||||
|
|
||||||
|
ELF_RELOC(R_LARCH_NONE, 0)
|
||||||
|
ELF_RELOC(R_LARCH_32, 1)
|
||||||
|
ELF_RELOC(R_LARCH_64, 2)
|
||||||
|
ELF_RELOC(R_LARCH_RELATIVE, 3)
|
||||||
|
ELF_RELOC(R_LARCH_COPY, 4)
|
||||||
|
ELF_RELOC(R_LARCH_JUMP_SLOT, 5)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_DTPMOD32, 6)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_DTPMOD64, 7)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_DTPREL32, 8)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_DTPREL64, 9)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_TPREL32, 10)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_TPREL64, 11)
|
||||||
|
ELF_RELOC(R_LARCH_IRELATIVE, 12)
|
||||||
|
ELF_RELOC(R_LARCH_MARK_LA, 20)
|
||||||
|
ELF_RELOC(R_LARCH_MARK_PCREL, 21)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_PUSH_PCREL, 22)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_PUSH_ABSOLUTE, 23)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_PUSH_DUP, 24)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_PUSH_GPREL, 25)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_PUSH_TLS_TPREL, 26)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_PUSH_TLS_GOT, 27)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_PUSH_TLS_GD, 28)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_PUSH_PLT_PCREL, 29)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_ASSERT, 30)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_NOT, 31)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_SUB, 32)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_SL, 33)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_SR, 34)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_ADD, 35)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_AND, 36)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_IF_ELSE, 37)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_POP_32_S_10_5, 38)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_POP_32_U_10_12, 39)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_POP_32_S_10_12, 40)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_POP_32_S_10_16, 41)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_POP_32_S_10_16_S2, 42)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_POP_32_S_5_20, 43)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_POP_32_S_0_5_10_16_S2, 44)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_POP_32_S_0_10_10_16_S2, 45)
|
||||||
|
ELF_RELOC(R_LARCH_SOP_POP_32_U, 46)
|
||||||
|
ELF_RELOC(R_LARCH_ADD8, 47)
|
||||||
|
ELF_RELOC(R_LARCH_ADD16, 48)
|
||||||
|
ELF_RELOC(R_LARCH_ADD24, 49)
|
||||||
|
ELF_RELOC(R_LARCH_ADD32, 50)
|
||||||
|
ELF_RELOC(R_LARCH_ADD64, 51)
|
||||||
|
ELF_RELOC(R_LARCH_SUB8, 52)
|
||||||
|
ELF_RELOC(R_LARCH_SUB16, 53)
|
||||||
|
ELF_RELOC(R_LARCH_SUB24, 54)
|
||||||
|
ELF_RELOC(R_LARCH_SUB32, 55)
|
||||||
|
ELF_RELOC(R_LARCH_SUB64, 56)
|
||||||
|
ELF_RELOC(R_LARCH_GNU_VTINHERIT, 57)
|
||||||
|
ELF_RELOC(R_LARCH_GNU_VTENTRY, 58)
|
||||||
|
|
||||||
|
// Relocs whose processing do not require a stack machine.
|
||||||
|
//
|
||||||
|
// Spec addition: https://github.com/loongson/LoongArch-Documentation/pull/57
|
||||||
|
// Binutils commit 6d13722a97cee3fd397e116bde3bcedbb1e220be
|
||||||
|
// and commit 9801120721c3a702ce3bd50433ef920f92a83502
|
||||||
|
ELF_RELOC(R_LARCH_B16, 64)
|
||||||
|
ELF_RELOC(R_LARCH_B21, 65)
|
||||||
|
ELF_RELOC(R_LARCH_B26, 66)
|
||||||
|
ELF_RELOC(R_LARCH_ABS_HI20, 67)
|
||||||
|
ELF_RELOC(R_LARCH_ABS_LO12, 68)
|
||||||
|
ELF_RELOC(R_LARCH_ABS64_LO20, 69)
|
||||||
|
ELF_RELOC(R_LARCH_ABS64_HI12, 70)
|
||||||
|
ELF_RELOC(R_LARCH_PCALA_HI20, 71)
|
||||||
|
ELF_RELOC(R_LARCH_PCALA_LO12, 72)
|
||||||
|
ELF_RELOC(R_LARCH_PCALA64_LO20, 73)
|
||||||
|
ELF_RELOC(R_LARCH_PCALA64_HI12, 74)
|
||||||
|
ELF_RELOC(R_LARCH_GOT_PC_HI20, 75)
|
||||||
|
ELF_RELOC(R_LARCH_GOT_PC_LO12, 76)
|
||||||
|
ELF_RELOC(R_LARCH_GOT64_PC_LO20, 77)
|
||||||
|
ELF_RELOC(R_LARCH_GOT64_PC_HI12, 78)
|
||||||
|
ELF_RELOC(R_LARCH_GOT_HI20, 79)
|
||||||
|
ELF_RELOC(R_LARCH_GOT_LO12, 80)
|
||||||
|
ELF_RELOC(R_LARCH_GOT64_LO20, 81)
|
||||||
|
ELF_RELOC(R_LARCH_GOT64_HI12, 82)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_LE_HI20, 83)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_LE_LO12, 84)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_LE64_LO20, 85)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_LE64_HI12, 86)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_IE_PC_HI20, 87)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_IE_PC_LO12, 88)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_IE64_PC_LO20, 89)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_IE64_PC_HI12, 90)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_IE_HI20, 91)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_IE_LO12, 92)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_IE64_LO20, 93)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_IE64_HI12, 94)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_LD_PC_HI20, 95)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_LD_HI20, 96)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_GD_PC_HI20, 97)
|
||||||
|
ELF_RELOC(R_LARCH_TLS_GD_HI20, 98)
|
||||||
|
ELF_RELOC(R_LARCH_32_PCREL, 99)
|
||||||
|
ELF_RELOC(R_LARCH_RELAX, 100)
|
||||||
|
|
||||||
|
// Relocs added in ELF for the LoongArch™ Architecture v20230519, part of the
|
||||||
|
// v2.10 LoongArch ABI specs.
|
||||||
|
//
|
||||||
|
// Spec addition: https://github.com/loongson/la-abi-specs/pull/1
|
||||||
|
// Binutils commit 57a930e3bfe4b2c7fd6463ed39311e1938513138
|
||||||
|
ELF_RELOC(R_LARCH_DELETE, 101)
|
||||||
|
ELF_RELOC(R_LARCH_ALIGN, 102)
|
||||||
|
ELF_RELOC(R_LARCH_PCREL20_S2, 103)
|
||||||
|
ELF_RELOC(R_LARCH_CFA, 104)
|
||||||
|
ELF_RELOC(R_LARCH_ADD6, 105)
|
||||||
|
ELF_RELOC(R_LARCH_SUB6, 106)
|
||||||
|
ELF_RELOC(R_LARCH_ADD_ULEB128, 107)
|
||||||
|
ELF_RELOC(R_LARCH_SUB_ULEB128, 108)
|
||||||
|
ELF_RELOC(R_LARCH_64_PCREL, 109)
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_68K_NONE, 0) /* No reloc */
|
||||||
|
ELF_RELOC(R_68K_32, 1) /* Direct 32 bit */
|
||||||
|
ELF_RELOC(R_68K_16, 2) /* Direct 16 bit */
|
||||||
|
ELF_RELOC(R_68K_8, 3) /* Direct 8 bit */
|
||||||
|
ELF_RELOC(R_68K_PC32, 4) /* PC relative 32 bit */
|
||||||
|
ELF_RELOC(R_68K_PC16, 5) /* PC relative 16 bit */
|
||||||
|
ELF_RELOC(R_68K_PC8, 6) /* PC relative 8 bit */
|
||||||
|
ELF_RELOC(R_68K_GOTPCREL32, 7) /* 32 bit PC relative GOT entry */
|
||||||
|
ELF_RELOC(R_68K_GOTPCREL16, 8) /* 16 bit PC relative GOT entry */
|
||||||
|
ELF_RELOC(R_68K_GOTPCREL8, 9) /* 8 bit PC relative GOT entry */
|
||||||
|
ELF_RELOC(R_68K_GOTOFF32, 10) /* 32 bit GOT offset */
|
||||||
|
ELF_RELOC(R_68K_GOTOFF16, 11) /* 16 bit GOT offset */
|
||||||
|
ELF_RELOC(R_68K_GOTOFF8, 12) /* 8 bit GOT offset */
|
||||||
|
ELF_RELOC(R_68K_PLT32, 13) /* 32 bit PC relative PLT address */
|
||||||
|
ELF_RELOC(R_68K_PLT16, 14) /* 16 bit PC relative PLT address */
|
||||||
|
ELF_RELOC(R_68K_PLT8, 15) /* 8 bit PC relative PLT address */
|
||||||
|
ELF_RELOC(R_68K_PLTOFF32, 16) /* 32 bit PLT offset */
|
||||||
|
ELF_RELOC(R_68K_PLTOFF16, 17) /* 16 bit PLT offset */
|
||||||
|
ELF_RELOC(R_68K_PLTOFF8, 18) /* 8 bit PLT offset */
|
||||||
|
ELF_RELOC(R_68K_COPY, 19) /* Copy symbol at runtime */
|
||||||
|
ELF_RELOC(R_68K_GLOB_DAT, 20) /* Create GOT entry */
|
||||||
|
ELF_RELOC(R_68K_JMP_SLOT, 21) /* Create PLT entry */
|
||||||
|
ELF_RELOC(R_68K_RELATIVE, 22) /* Adjust by program base */
|
||||||
|
/* These are GNU extensions to enable C++ vtable garbage collection. */
|
||||||
|
ELF_RELOC(R_68K_GNU_VTINHERIT, 23)
|
||||||
|
ELF_RELOC(R_68K_GNU_VTENTRY, 24)
|
||||||
|
/* TLS static relocations. */
|
||||||
|
ELF_RELOC(R_68K_TLS_GD32, 25)
|
||||||
|
ELF_RELOC(R_68K_TLS_GD16, 26)
|
||||||
|
ELF_RELOC(R_68K_TLS_GD8, 27)
|
||||||
|
ELF_RELOC(R_68K_TLS_LDM32, 28)
|
||||||
|
ELF_RELOC(R_68K_TLS_LDM16, 29)
|
||||||
|
ELF_RELOC(R_68K_TLS_LDM8, 30)
|
||||||
|
ELF_RELOC(R_68K_TLS_LDO32, 31)
|
||||||
|
ELF_RELOC(R_68K_TLS_LDO16, 32)
|
||||||
|
ELF_RELOC(R_68K_TLS_LDO8, 33)
|
||||||
|
ELF_RELOC(R_68K_TLS_IE32, 34)
|
||||||
|
ELF_RELOC(R_68K_TLS_IE16, 35)
|
||||||
|
ELF_RELOC(R_68K_TLS_IE8, 36)
|
||||||
|
ELF_RELOC(R_68K_TLS_LE32, 37)
|
||||||
|
ELF_RELOC(R_68K_TLS_LE16, 38)
|
||||||
|
ELF_RELOC(R_68K_TLS_LE8, 39)
|
||||||
|
ELF_RELOC(R_68K_TLS_DTPMOD32, 40)
|
||||||
|
ELF_RELOC(R_68K_TLS_DTPREL32, 41)
|
||||||
|
ELF_RELOC(R_68K_TLS_TPREL32, 42)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_MSP430_NONE, 0)
|
||||||
|
ELF_RELOC(R_MSP430_32, 1)
|
||||||
|
ELF_RELOC(R_MSP430_10_PCREL, 2)
|
||||||
|
ELF_RELOC(R_MSP430_16, 3)
|
||||||
|
ELF_RELOC(R_MSP430_16_PCREL, 4)
|
||||||
|
ELF_RELOC(R_MSP430_16_BYTE, 5)
|
||||||
|
ELF_RELOC(R_MSP430_16_PCREL_BYTE, 6)
|
||||||
|
ELF_RELOC(R_MSP430_2X_PCREL, 7)
|
||||||
|
ELF_RELOC(R_MSP430_RL_PCREL, 8)
|
||||||
|
ELF_RELOC(R_MSP430_8, 9)
|
||||||
|
ELF_RELOC(R_MSP430_SYM_DIFF, 10)
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_MIPS_NONE, 0)
|
||||||
|
ELF_RELOC(R_MIPS_16, 1)
|
||||||
|
ELF_RELOC(R_MIPS_32, 2)
|
||||||
|
ELF_RELOC(R_MIPS_REL32, 3)
|
||||||
|
ELF_RELOC(R_MIPS_26, 4)
|
||||||
|
ELF_RELOC(R_MIPS_HI16, 5)
|
||||||
|
ELF_RELOC(R_MIPS_LO16, 6)
|
||||||
|
ELF_RELOC(R_MIPS_GPREL16, 7)
|
||||||
|
ELF_RELOC(R_MIPS_LITERAL, 8)
|
||||||
|
ELF_RELOC(R_MIPS_GOT16, 9)
|
||||||
|
ELF_RELOC(R_MIPS_PC16, 10)
|
||||||
|
ELF_RELOC(R_MIPS_CALL16, 11)
|
||||||
|
ELF_RELOC(R_MIPS_GPREL32, 12)
|
||||||
|
ELF_RELOC(R_MIPS_UNUSED1, 13)
|
||||||
|
ELF_RELOC(R_MIPS_UNUSED2, 14)
|
||||||
|
ELF_RELOC(R_MIPS_UNUSED3, 15)
|
||||||
|
ELF_RELOC(R_MIPS_SHIFT5, 16)
|
||||||
|
ELF_RELOC(R_MIPS_SHIFT6, 17)
|
||||||
|
ELF_RELOC(R_MIPS_64, 18)
|
||||||
|
ELF_RELOC(R_MIPS_GOT_DISP, 19)
|
||||||
|
ELF_RELOC(R_MIPS_GOT_PAGE, 20)
|
||||||
|
ELF_RELOC(R_MIPS_GOT_OFST, 21)
|
||||||
|
ELF_RELOC(R_MIPS_GOT_HI16, 22)
|
||||||
|
ELF_RELOC(R_MIPS_GOT_LO16, 23)
|
||||||
|
ELF_RELOC(R_MIPS_SUB, 24)
|
||||||
|
ELF_RELOC(R_MIPS_INSERT_A, 25)
|
||||||
|
ELF_RELOC(R_MIPS_INSERT_B, 26)
|
||||||
|
ELF_RELOC(R_MIPS_DELETE, 27)
|
||||||
|
ELF_RELOC(R_MIPS_HIGHER, 28)
|
||||||
|
ELF_RELOC(R_MIPS_HIGHEST, 29)
|
||||||
|
ELF_RELOC(R_MIPS_CALL_HI16, 30)
|
||||||
|
ELF_RELOC(R_MIPS_CALL_LO16, 31)
|
||||||
|
ELF_RELOC(R_MIPS_SCN_DISP, 32)
|
||||||
|
ELF_RELOC(R_MIPS_REL16, 33)
|
||||||
|
ELF_RELOC(R_MIPS_ADD_IMMEDIATE, 34)
|
||||||
|
ELF_RELOC(R_MIPS_PJUMP, 35)
|
||||||
|
ELF_RELOC(R_MIPS_RELGOT, 36)
|
||||||
|
ELF_RELOC(R_MIPS_JALR, 37)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_DTPMOD32, 38)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_DTPREL32, 39)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_DTPMOD64, 40)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_DTPREL64, 41)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_GD, 42)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_LDM, 43)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_DTPREL_HI16, 44)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_DTPREL_LO16, 45)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_GOTTPREL, 46)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_TPREL32, 47)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_TPREL64, 48)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_TPREL_HI16, 49)
|
||||||
|
ELF_RELOC(R_MIPS_TLS_TPREL_LO16, 50)
|
||||||
|
ELF_RELOC(R_MIPS_GLOB_DAT, 51)
|
||||||
|
ELF_RELOC(R_MIPS_PC21_S2, 60)
|
||||||
|
ELF_RELOC(R_MIPS_PC26_S2, 61)
|
||||||
|
ELF_RELOC(R_MIPS_PC18_S3, 62)
|
||||||
|
ELF_RELOC(R_MIPS_PC19_S2, 63)
|
||||||
|
ELF_RELOC(R_MIPS_PCHI16, 64)
|
||||||
|
ELF_RELOC(R_MIPS_PCLO16, 65)
|
||||||
|
ELF_RELOC(R_MIPS16_26, 100)
|
||||||
|
ELF_RELOC(R_MIPS16_GPREL, 101)
|
||||||
|
ELF_RELOC(R_MIPS16_GOT16, 102)
|
||||||
|
ELF_RELOC(R_MIPS16_CALL16, 103)
|
||||||
|
ELF_RELOC(R_MIPS16_HI16, 104)
|
||||||
|
ELF_RELOC(R_MIPS16_LO16, 105)
|
||||||
|
ELF_RELOC(R_MIPS16_TLS_GD, 106)
|
||||||
|
ELF_RELOC(R_MIPS16_TLS_LDM, 107)
|
||||||
|
ELF_RELOC(R_MIPS16_TLS_DTPREL_HI16, 108)
|
||||||
|
ELF_RELOC(R_MIPS16_TLS_DTPREL_LO16, 109)
|
||||||
|
ELF_RELOC(R_MIPS16_TLS_GOTTPREL, 110)
|
||||||
|
ELF_RELOC(R_MIPS16_TLS_TPREL_HI16, 111)
|
||||||
|
ELF_RELOC(R_MIPS16_TLS_TPREL_LO16, 112)
|
||||||
|
ELF_RELOC(R_MIPS_COPY, 126)
|
||||||
|
ELF_RELOC(R_MIPS_JUMP_SLOT, 127)
|
||||||
|
ELF_RELOC(R_MICROMIPS_26_S1, 133)
|
||||||
|
ELF_RELOC(R_MICROMIPS_HI16, 134)
|
||||||
|
ELF_RELOC(R_MICROMIPS_LO16, 135)
|
||||||
|
ELF_RELOC(R_MICROMIPS_GPREL16, 136)
|
||||||
|
ELF_RELOC(R_MICROMIPS_LITERAL, 137)
|
||||||
|
ELF_RELOC(R_MICROMIPS_GOT16, 138)
|
||||||
|
ELF_RELOC(R_MICROMIPS_PC7_S1, 139)
|
||||||
|
ELF_RELOC(R_MICROMIPS_PC10_S1, 140)
|
||||||
|
ELF_RELOC(R_MICROMIPS_PC16_S1, 141)
|
||||||
|
ELF_RELOC(R_MICROMIPS_CALL16, 142)
|
||||||
|
ELF_RELOC(R_MICROMIPS_GOT_DISP, 145)
|
||||||
|
ELF_RELOC(R_MICROMIPS_GOT_PAGE, 146)
|
||||||
|
ELF_RELOC(R_MICROMIPS_GOT_OFST, 147)
|
||||||
|
ELF_RELOC(R_MICROMIPS_GOT_HI16, 148)
|
||||||
|
ELF_RELOC(R_MICROMIPS_GOT_LO16, 149)
|
||||||
|
ELF_RELOC(R_MICROMIPS_SUB, 150)
|
||||||
|
ELF_RELOC(R_MICROMIPS_HIGHER, 151)
|
||||||
|
ELF_RELOC(R_MICROMIPS_HIGHEST, 152)
|
||||||
|
ELF_RELOC(R_MICROMIPS_CALL_HI16, 153)
|
||||||
|
ELF_RELOC(R_MICROMIPS_CALL_LO16, 154)
|
||||||
|
ELF_RELOC(R_MICROMIPS_SCN_DISP, 155)
|
||||||
|
ELF_RELOC(R_MICROMIPS_JALR, 156)
|
||||||
|
ELF_RELOC(R_MICROMIPS_HI0_LO16, 157)
|
||||||
|
ELF_RELOC(R_MICROMIPS_TLS_GD, 162)
|
||||||
|
ELF_RELOC(R_MICROMIPS_TLS_LDM, 163)
|
||||||
|
ELF_RELOC(R_MICROMIPS_TLS_DTPREL_HI16, 164)
|
||||||
|
ELF_RELOC(R_MICROMIPS_TLS_DTPREL_LO16, 165)
|
||||||
|
ELF_RELOC(R_MICROMIPS_TLS_GOTTPREL, 166)
|
||||||
|
ELF_RELOC(R_MICROMIPS_TLS_TPREL_HI16, 169)
|
||||||
|
ELF_RELOC(R_MICROMIPS_TLS_TPREL_LO16, 170)
|
||||||
|
ELF_RELOC(R_MICROMIPS_GPREL7_S2, 172)
|
||||||
|
ELF_RELOC(R_MICROMIPS_PC23_S2, 173)
|
||||||
|
ELF_RELOC(R_MICROMIPS_PC21_S1, 174)
|
||||||
|
ELF_RELOC(R_MICROMIPS_PC26_S1, 175)
|
||||||
|
ELF_RELOC(R_MICROMIPS_PC18_S3, 176)
|
||||||
|
ELF_RELOC(R_MICROMIPS_PC19_S2, 177)
|
||||||
|
ELF_RELOC(R_MIPS_NUM, 218)
|
||||||
|
ELF_RELOC(R_MIPS_PC32, 248)
|
||||||
|
ELF_RELOC(R_MIPS_EH, 249)
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// glibc's PowerPC asm/sigcontext.h, when compiling for PPC64, has the
|
||||||
|
// unfortunate behavior of including asm/elf.h, which defines R_PPC_NONE, etc.
|
||||||
|
// to their corresponding integer values. As a result, we need to undef them
|
||||||
|
// here before continuing.
|
||||||
|
|
||||||
|
#undef R_PPC_NONE
|
||||||
|
#undef R_PPC_ADDR32
|
||||||
|
#undef R_PPC_ADDR24
|
||||||
|
#undef R_PPC_ADDR16
|
||||||
|
#undef R_PPC_ADDR16_LO
|
||||||
|
#undef R_PPC_ADDR16_HI
|
||||||
|
#undef R_PPC_ADDR16_HA
|
||||||
|
#undef R_PPC_ADDR14
|
||||||
|
#undef R_PPC_ADDR14_BRTAKEN
|
||||||
|
#undef R_PPC_ADDR14_BRNTAKEN
|
||||||
|
#undef R_PPC_REL24
|
||||||
|
#undef R_PPC_REL14
|
||||||
|
#undef R_PPC_REL14_BRTAKEN
|
||||||
|
#undef R_PPC_REL14_BRNTAKEN
|
||||||
|
#undef R_PPC_GOT16
|
||||||
|
#undef R_PPC_GOT16_LO
|
||||||
|
#undef R_PPC_GOT16_HI
|
||||||
|
#undef R_PPC_GOT16_HA
|
||||||
|
#undef R_PPC_PLTREL24
|
||||||
|
#undef R_PPC_COPY
|
||||||
|
#undef R_PPC_GLOB_DAT
|
||||||
|
#undef R_PPC_JMP_SLOT
|
||||||
|
#undef R_PPC_RELATIVE
|
||||||
|
#undef R_PPC_LOCAL24PC
|
||||||
|
#undef R_PPC_UADDR32
|
||||||
|
#undef R_PPC_UADDR16
|
||||||
|
#undef R_PPC_REL32
|
||||||
|
#undef R_PPC_PLT32
|
||||||
|
#undef R_PPC_PLTREL32
|
||||||
|
#undef R_PPC_PLT16_LO
|
||||||
|
#undef R_PPC_PLT16_HI
|
||||||
|
#undef R_PPC_PLT16_HA
|
||||||
|
#undef R_PPC_SDAREL16
|
||||||
|
#undef R_PPC_SECTOFF
|
||||||
|
#undef R_PPC_SECTOFF_LO
|
||||||
|
#undef R_PPC_SECTOFF_HI
|
||||||
|
#undef R_PPC_SECTOFF_HA
|
||||||
|
#undef R_PPC_ADDR30
|
||||||
|
#undef R_PPC_TLS
|
||||||
|
#undef R_PPC_DTPMOD32
|
||||||
|
#undef R_PPC_TPREL16
|
||||||
|
#undef R_PPC_TPREL16_LO
|
||||||
|
#undef R_PPC_TPREL16_HI
|
||||||
|
#undef R_PPC_TPREL16_HA
|
||||||
|
#undef R_PPC_TPREL32
|
||||||
|
#undef R_PPC_DTPREL16
|
||||||
|
#undef R_PPC_DTPREL16_LO
|
||||||
|
#undef R_PPC_DTPREL16_HI
|
||||||
|
#undef R_PPC_DTPREL16_HA
|
||||||
|
#undef R_PPC_DTPREL32
|
||||||
|
#undef R_PPC_GOT_TLSGD16
|
||||||
|
#undef R_PPC_GOT_TLSGD16_LO
|
||||||
|
#undef R_PPC_GOT_TLSGD16_HI
|
||||||
|
#undef R_PPC_GOT_TLSGD16_HA
|
||||||
|
#undef R_PPC_GOT_TLSLD16
|
||||||
|
#undef R_PPC_GOT_TLSLD16_LO
|
||||||
|
#undef R_PPC_GOT_TLSLD16_HI
|
||||||
|
#undef R_PPC_GOT_TLSLD16_HA
|
||||||
|
#undef R_PPC_GOT_TPREL16
|
||||||
|
#undef R_PPC_GOT_TPREL16_LO
|
||||||
|
#undef R_PPC_GOT_TPREL16_HI
|
||||||
|
#undef R_PPC_GOT_TPREL16_HA
|
||||||
|
#undef R_PPC_GOT_DTPREL16
|
||||||
|
#undef R_PPC_GOT_DTPREL16_LO
|
||||||
|
#undef R_PPC_GOT_DTPREL16_HI
|
||||||
|
#undef R_PPC_GOT_DTPREL16_HA
|
||||||
|
#undef R_PPC_TLSGD
|
||||||
|
#undef R_PPC_TLSLD
|
||||||
|
#undef R_PPC_REL16
|
||||||
|
#undef R_PPC_REL16_LO
|
||||||
|
#undef R_PPC_REL16_HI
|
||||||
|
#undef R_PPC_REL16_HA
|
||||||
|
|
||||||
|
ELF_RELOC(R_PPC_NONE, 0) /* No relocation. */
|
||||||
|
ELF_RELOC(R_PPC_ADDR32, 1)
|
||||||
|
ELF_RELOC(R_PPC_ADDR24, 2)
|
||||||
|
ELF_RELOC(R_PPC_ADDR16, 3)
|
||||||
|
ELF_RELOC(R_PPC_ADDR16_LO, 4)
|
||||||
|
ELF_RELOC(R_PPC_ADDR16_HI, 5)
|
||||||
|
ELF_RELOC(R_PPC_ADDR16_HA, 6)
|
||||||
|
ELF_RELOC(R_PPC_ADDR14, 7)
|
||||||
|
ELF_RELOC(R_PPC_ADDR14_BRTAKEN, 8)
|
||||||
|
ELF_RELOC(R_PPC_ADDR14_BRNTAKEN, 9)
|
||||||
|
ELF_RELOC(R_PPC_REL24, 10)
|
||||||
|
ELF_RELOC(R_PPC_REL14, 11)
|
||||||
|
ELF_RELOC(R_PPC_REL14_BRTAKEN, 12)
|
||||||
|
ELF_RELOC(R_PPC_REL14_BRNTAKEN, 13)
|
||||||
|
ELF_RELOC(R_PPC_GOT16, 14)
|
||||||
|
ELF_RELOC(R_PPC_GOT16_LO, 15)
|
||||||
|
ELF_RELOC(R_PPC_GOT16_HI, 16)
|
||||||
|
ELF_RELOC(R_PPC_GOT16_HA, 17)
|
||||||
|
ELF_RELOC(R_PPC_PLTREL24, 18)
|
||||||
|
ELF_RELOC(R_PPC_COPY, 19)
|
||||||
|
ELF_RELOC(R_PPC_GLOB_DAT, 20)
|
||||||
|
ELF_RELOC(R_PPC_JMP_SLOT, 21)
|
||||||
|
ELF_RELOC(R_PPC_RELATIVE, 22)
|
||||||
|
ELF_RELOC(R_PPC_LOCAL24PC, 23)
|
||||||
|
ELF_RELOC(R_PPC_UADDR32, 24)
|
||||||
|
ELF_RELOC(R_PPC_UADDR16, 25)
|
||||||
|
ELF_RELOC(R_PPC_REL32, 26)
|
||||||
|
ELF_RELOC(R_PPC_PLT32, 27)
|
||||||
|
ELF_RELOC(R_PPC_PLTREL32, 28)
|
||||||
|
ELF_RELOC(R_PPC_PLT16_LO, 29)
|
||||||
|
ELF_RELOC(R_PPC_PLT16_HI, 30)
|
||||||
|
ELF_RELOC(R_PPC_PLT16_HA, 31)
|
||||||
|
ELF_RELOC(R_PPC_SDAREL16, 32)
|
||||||
|
ELF_RELOC(R_PPC_SECTOFF, 33)
|
||||||
|
ELF_RELOC(R_PPC_SECTOFF_LO, 34)
|
||||||
|
ELF_RELOC(R_PPC_SECTOFF_HI, 35)
|
||||||
|
ELF_RELOC(R_PPC_SECTOFF_HA, 36)
|
||||||
|
ELF_RELOC(R_PPC_ADDR30, 37)
|
||||||
|
ELF_RELOC(R_PPC_TLS, 67)
|
||||||
|
ELF_RELOC(R_PPC_DTPMOD32, 68)
|
||||||
|
ELF_RELOC(R_PPC_TPREL16, 69)
|
||||||
|
ELF_RELOC(R_PPC_TPREL16_LO, 70)
|
||||||
|
ELF_RELOC(R_PPC_TPREL16_HI, 71)
|
||||||
|
ELF_RELOC(R_PPC_TPREL16_HA, 72)
|
||||||
|
ELF_RELOC(R_PPC_TPREL32, 73)
|
||||||
|
ELF_RELOC(R_PPC_DTPREL16, 74)
|
||||||
|
ELF_RELOC(R_PPC_DTPREL16_LO, 75)
|
||||||
|
ELF_RELOC(R_PPC_DTPREL16_HI, 76)
|
||||||
|
ELF_RELOC(R_PPC_DTPREL16_HA, 77)
|
||||||
|
ELF_RELOC(R_PPC_DTPREL32, 78)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TLSGD16, 79)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TLSGD16_LO, 80)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TLSGD16_HI, 81)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TLSGD16_HA, 82)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TLSLD16, 83)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TLSLD16_LO, 84)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TLSLD16_HI, 85)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TLSLD16_HA, 86)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TPREL16, 87)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TPREL16_LO, 88)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TPREL16_HI, 89)
|
||||||
|
ELF_RELOC(R_PPC_GOT_TPREL16_HA, 90)
|
||||||
|
ELF_RELOC(R_PPC_GOT_DTPREL16, 91)
|
||||||
|
ELF_RELOC(R_PPC_GOT_DTPREL16_LO, 92)
|
||||||
|
ELF_RELOC(R_PPC_GOT_DTPREL16_HI, 93)
|
||||||
|
ELF_RELOC(R_PPC_GOT_DTPREL16_HA, 94)
|
||||||
|
ELF_RELOC(R_PPC_TLSGD, 95)
|
||||||
|
ELF_RELOC(R_PPC_TLSLD, 96)
|
||||||
|
ELF_RELOC(R_PPC_IRELATIVE, 248)
|
||||||
|
ELF_RELOC(R_PPC_REL16, 249)
|
||||||
|
ELF_RELOC(R_PPC_REL16_LO, 250)
|
||||||
|
ELF_RELOC(R_PPC_REL16_HI, 251)
|
||||||
|
ELF_RELOC(R_PPC_REL16_HA, 252)
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// glibc's PowerPC asm/sigcontext.h, when compiling for PPC64, has the
|
||||||
|
// unfortunate behavior of including asm/elf.h, which defines R_PPC_NONE, etc.
|
||||||
|
// to their corresponding integer values. As a result, we need to undef them
|
||||||
|
// here before continuing.
|
||||||
|
|
||||||
|
#undef R_PPC64_NONE
|
||||||
|
#undef R_PPC64_ADDR32
|
||||||
|
#undef R_PPC64_ADDR24
|
||||||
|
#undef R_PPC64_ADDR16
|
||||||
|
#undef R_PPC64_ADDR16_LO
|
||||||
|
#undef R_PPC64_ADDR16_HI
|
||||||
|
#undef R_PPC64_ADDR16_HA
|
||||||
|
#undef R_PPC64_ADDR14
|
||||||
|
#undef R_PPC64_ADDR14_BRTAKEN
|
||||||
|
#undef R_PPC64_ADDR14_BRNTAKEN
|
||||||
|
#undef R_PPC64_REL24
|
||||||
|
#undef R_PPC64_REL14
|
||||||
|
#undef R_PPC64_REL14_BRTAKEN
|
||||||
|
#undef R_PPC64_REL14_BRNTAKEN
|
||||||
|
#undef R_PPC64_GOT16
|
||||||
|
#undef R_PPC64_GOT16_LO
|
||||||
|
#undef R_PPC64_GOT16_HI
|
||||||
|
#undef R_PPC64_GOT16_HA
|
||||||
|
#undef R_PPC64_COPY
|
||||||
|
#undef R_PPC64_GLOB_DAT
|
||||||
|
#undef R_PPC64_JMP_SLOT
|
||||||
|
#undef R_PPC64_RELATIVE
|
||||||
|
#undef R_PPC64_REL32
|
||||||
|
#undef R_PPC64_ADDR64
|
||||||
|
#undef R_PPC64_ADDR16_HIGHER
|
||||||
|
#undef R_PPC64_ADDR16_HIGHERA
|
||||||
|
#undef R_PPC64_ADDR16_HIGHEST
|
||||||
|
#undef R_PPC64_ADDR16_HIGHESTA
|
||||||
|
#undef R_PPC64_REL64
|
||||||
|
#undef R_PPC64_TOC16
|
||||||
|
#undef R_PPC64_TOC16_LO
|
||||||
|
#undef R_PPC64_TOC16_HI
|
||||||
|
#undef R_PPC64_TOC16_HA
|
||||||
|
#undef R_PPC64_TOC
|
||||||
|
#undef R_PPC64_ADDR16_DS
|
||||||
|
#undef R_PPC64_ADDR16_LO_DS
|
||||||
|
#undef R_PPC64_GOT16_DS
|
||||||
|
#undef R_PPC64_GOT16_LO_DS
|
||||||
|
#undef R_PPC64_TOC16_DS
|
||||||
|
#undef R_PPC64_TOC16_LO_DS
|
||||||
|
#undef R_PPC64_TLS
|
||||||
|
#undef R_PPC64_DTPMOD64
|
||||||
|
#undef R_PPC64_TPREL16
|
||||||
|
#undef R_PPC64_TPREL16_LO
|
||||||
|
#undef R_PPC64_TPREL16_HI
|
||||||
|
#undef R_PPC64_TPREL16_HA
|
||||||
|
#undef R_PPC64_TPREL64
|
||||||
|
#undef R_PPC64_DTPREL16
|
||||||
|
#undef R_PPC64_DTPREL16_LO
|
||||||
|
#undef R_PPC64_DTPREL16_HI
|
||||||
|
#undef R_PPC64_DTPREL16_HA
|
||||||
|
#undef R_PPC64_DTPREL64
|
||||||
|
#undef R_PPC64_GOT_TLSGD16
|
||||||
|
#undef R_PPC64_GOT_TLSGD16_LO
|
||||||
|
#undef R_PPC64_GOT_TLSGD16_HI
|
||||||
|
#undef R_PPC64_GOT_TLSGD16_HA
|
||||||
|
#undef R_PPC64_GOT_TLSLD16
|
||||||
|
#undef R_PPC64_GOT_TLSLD16_LO
|
||||||
|
#undef R_PPC64_GOT_TLSLD16_HI
|
||||||
|
#undef R_PPC64_GOT_TLSLD16_HA
|
||||||
|
#undef R_PPC64_GOT_TPREL16_DS
|
||||||
|
#undef R_PPC64_GOT_TPREL16_LO_DS
|
||||||
|
#undef R_PPC64_GOT_TPREL16_HI
|
||||||
|
#undef R_PPC64_GOT_TPREL16_HA
|
||||||
|
#undef R_PPC64_GOT_DTPREL16_DS
|
||||||
|
#undef R_PPC64_GOT_DTPREL16_LO_DS
|
||||||
|
#undef R_PPC64_GOT_DTPREL16_HI
|
||||||
|
#undef R_PPC64_GOT_DTPREL16_HA
|
||||||
|
#undef R_PPC64_TPREL16_DS
|
||||||
|
#undef R_PPC64_TPREL16_LO_DS
|
||||||
|
#undef R_PPC64_TPREL16_HIGHER
|
||||||
|
#undef R_PPC64_TPREL16_HIGHERA
|
||||||
|
#undef R_PPC64_TPREL16_HIGHEST
|
||||||
|
#undef R_PPC64_TPREL16_HIGHESTA
|
||||||
|
#undef R_PPC64_DTPREL16_DS
|
||||||
|
#undef R_PPC64_DTPREL16_LO_DS
|
||||||
|
#undef R_PPC64_DTPREL16_HIGHER
|
||||||
|
#undef R_PPC64_DTPREL16_HIGHERA
|
||||||
|
#undef R_PPC64_DTPREL16_HIGHEST
|
||||||
|
#undef R_PPC64_DTPREL16_HIGHESTA
|
||||||
|
#undef R_PPC64_TLSGD
|
||||||
|
#undef R_PPC64_TLSLD
|
||||||
|
#undef R_PPC64_ADDR16_HIGH
|
||||||
|
#undef R_PPC64_ADDR16_HIGHA
|
||||||
|
#undef R_PPC64_TPREL16_HIGH
|
||||||
|
#undef R_PPC64_TPREL16_HIGHA
|
||||||
|
#undef R_PPC64_DTPREL16_HIGH
|
||||||
|
#undef R_PPC64_DTPREL16_HIGHA
|
||||||
|
#undef R_PPC64_REL24_NOTOC
|
||||||
|
#undef R_PPC64_PCREL_OPT
|
||||||
|
#undef R_PPC64_PCREL34
|
||||||
|
#undef R_PPC64_GOT_PCREL34
|
||||||
|
#undef R_PPC64_TPREL34
|
||||||
|
#undef R_PPC64_DTPREL34
|
||||||
|
#undef R_PPC64_GOT_TLSGD_PCREL34
|
||||||
|
#undef R_PPC64_GOT_TLSLD_PCREL34
|
||||||
|
#undef R_PPC64_GOT_TPREL_PCREL34
|
||||||
|
#undef R_PPC64_IRELATIVE
|
||||||
|
#undef R_PPC64_REL16
|
||||||
|
#undef R_PPC64_REL16_LO
|
||||||
|
#undef R_PPC64_REL16_HI
|
||||||
|
#undef R_PPC64_REL16_HA
|
||||||
|
|
||||||
|
ELF_RELOC(R_PPC64_NONE, 0)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR32, 1)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR24, 2)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16, 3)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_LO, 4)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_HI, 5)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_HA, 6)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR14, 7)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR14_BRTAKEN, 8)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR14_BRNTAKEN, 9)
|
||||||
|
ELF_RELOC(R_PPC64_REL24, 10)
|
||||||
|
ELF_RELOC(R_PPC64_REL14, 11)
|
||||||
|
ELF_RELOC(R_PPC64_REL14_BRTAKEN, 12)
|
||||||
|
ELF_RELOC(R_PPC64_REL14_BRNTAKEN, 13)
|
||||||
|
ELF_RELOC(R_PPC64_GOT16, 14)
|
||||||
|
ELF_RELOC(R_PPC64_GOT16_LO, 15)
|
||||||
|
ELF_RELOC(R_PPC64_GOT16_HI, 16)
|
||||||
|
ELF_RELOC(R_PPC64_GOT16_HA, 17)
|
||||||
|
ELF_RELOC(R_PPC64_COPY, 19)
|
||||||
|
ELF_RELOC(R_PPC64_GLOB_DAT, 20)
|
||||||
|
ELF_RELOC(R_PPC64_JMP_SLOT, 21)
|
||||||
|
ELF_RELOC(R_PPC64_RELATIVE, 22)
|
||||||
|
ELF_RELOC(R_PPC64_REL32, 26)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR64, 38)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_HIGHER, 39)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_HIGHERA, 40)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_HIGHEST, 41)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_HIGHESTA, 42)
|
||||||
|
ELF_RELOC(R_PPC64_REL64, 44)
|
||||||
|
ELF_RELOC(R_PPC64_TOC16, 47)
|
||||||
|
ELF_RELOC(R_PPC64_TOC16_LO, 48)
|
||||||
|
ELF_RELOC(R_PPC64_TOC16_HI, 49)
|
||||||
|
ELF_RELOC(R_PPC64_TOC16_HA, 50)
|
||||||
|
ELF_RELOC(R_PPC64_TOC, 51)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_DS, 56)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_LO_DS, 57)
|
||||||
|
ELF_RELOC(R_PPC64_GOT16_DS, 58)
|
||||||
|
ELF_RELOC(R_PPC64_GOT16_LO_DS, 59)
|
||||||
|
ELF_RELOC(R_PPC64_TOC16_DS, 63)
|
||||||
|
ELF_RELOC(R_PPC64_TOC16_LO_DS, 64)
|
||||||
|
ELF_RELOC(R_PPC64_TLS, 67)
|
||||||
|
ELF_RELOC(R_PPC64_DTPMOD64, 68)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16, 69)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_LO, 70)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_HI, 71)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_HA, 72)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL64, 73)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16, 74)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_LO, 75)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_HI, 76)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_HA, 77)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL64, 78)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TLSGD16, 79)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TLSGD16_LO, 80)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TLSGD16_HI, 81)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TLSGD16_HA, 82)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TLSLD16, 83)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TLSLD16_LO, 84)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TLSLD16_HI, 85)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TLSLD16_HA, 86)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TPREL16_DS, 87)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TPREL16_LO_DS, 88)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TPREL16_HI, 89)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TPREL16_HA, 90)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_DTPREL16_DS, 91)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_DTPREL16_LO_DS, 92)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_DTPREL16_HI, 93)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_DTPREL16_HA, 94)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_DS, 95)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_LO_DS, 96)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_HIGHER, 97)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_HIGHERA, 98)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_HIGHEST, 99)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_HIGHESTA, 100)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_DS, 101)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_LO_DS, 102)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_HIGHER, 103)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_HIGHERA, 104)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_HIGHEST, 105)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_HIGHESTA, 106)
|
||||||
|
ELF_RELOC(R_PPC64_TLSGD, 107)
|
||||||
|
ELF_RELOC(R_PPC64_TLSLD, 108)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_HIGH, 110)
|
||||||
|
ELF_RELOC(R_PPC64_ADDR16_HIGHA, 111)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_HIGH, 112)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL16_HIGHA, 113)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_HIGH, 114)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL16_HIGHA, 115)
|
||||||
|
ELF_RELOC(R_PPC64_REL24_NOTOC, 116)
|
||||||
|
ELF_RELOC(R_PPC64_PCREL_OPT, 123)
|
||||||
|
ELF_RELOC(R_PPC64_PCREL34, 132)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_PCREL34, 133)
|
||||||
|
ELF_RELOC(R_PPC64_TPREL34, 146)
|
||||||
|
ELF_RELOC(R_PPC64_DTPREL34, 147)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TLSGD_PCREL34, 148)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TLSLD_PCREL34, 149)
|
||||||
|
ELF_RELOC(R_PPC64_GOT_TPREL_PCREL34, 150)
|
||||||
|
ELF_RELOC(R_PPC64_IRELATIVE, 248)
|
||||||
|
ELF_RELOC(R_PPC64_REL16, 249)
|
||||||
|
ELF_RELOC(R_PPC64_REL16_LO, 250)
|
||||||
|
ELF_RELOC(R_PPC64_REL16_HI, 251)
|
||||||
|
ELF_RELOC(R_PPC64_REL16_HA, 252)
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_RISCV_NONE, 0)
|
||||||
|
ELF_RELOC(R_RISCV_32, 1)
|
||||||
|
ELF_RELOC(R_RISCV_64, 2)
|
||||||
|
ELF_RELOC(R_RISCV_RELATIVE, 3)
|
||||||
|
ELF_RELOC(R_RISCV_COPY, 4)
|
||||||
|
ELF_RELOC(R_RISCV_JUMP_SLOT, 5)
|
||||||
|
ELF_RELOC(R_RISCV_TLS_DTPMOD32, 6)
|
||||||
|
ELF_RELOC(R_RISCV_TLS_DTPMOD64, 7)
|
||||||
|
ELF_RELOC(R_RISCV_TLS_DTPREL32, 8)
|
||||||
|
ELF_RELOC(R_RISCV_TLS_DTPREL64, 9)
|
||||||
|
ELF_RELOC(R_RISCV_TLS_TPREL32, 10)
|
||||||
|
ELF_RELOC(R_RISCV_TLS_TPREL64, 11)
|
||||||
|
ELF_RELOC(R_RISCV_BRANCH, 16)
|
||||||
|
ELF_RELOC(R_RISCV_JAL, 17)
|
||||||
|
ELF_RELOC(R_RISCV_CALL, 18)
|
||||||
|
ELF_RELOC(R_RISCV_CALL_PLT, 19)
|
||||||
|
ELF_RELOC(R_RISCV_GOT_HI20, 20)
|
||||||
|
ELF_RELOC(R_RISCV_TLS_GOT_HI20, 21)
|
||||||
|
ELF_RELOC(R_RISCV_TLS_GD_HI20, 22)
|
||||||
|
ELF_RELOC(R_RISCV_PCREL_HI20, 23)
|
||||||
|
ELF_RELOC(R_RISCV_PCREL_LO12_I, 24)
|
||||||
|
ELF_RELOC(R_RISCV_PCREL_LO12_S, 25)
|
||||||
|
ELF_RELOC(R_RISCV_HI20, 26)
|
||||||
|
ELF_RELOC(R_RISCV_LO12_I, 27)
|
||||||
|
ELF_RELOC(R_RISCV_LO12_S, 28)
|
||||||
|
ELF_RELOC(R_RISCV_TPREL_HI20, 29)
|
||||||
|
ELF_RELOC(R_RISCV_TPREL_LO12_I, 30)
|
||||||
|
ELF_RELOC(R_RISCV_TPREL_LO12_S, 31)
|
||||||
|
ELF_RELOC(R_RISCV_TPREL_ADD, 32)
|
||||||
|
ELF_RELOC(R_RISCV_ADD8, 33)
|
||||||
|
ELF_RELOC(R_RISCV_ADD16, 34)
|
||||||
|
ELF_RELOC(R_RISCV_ADD32, 35)
|
||||||
|
ELF_RELOC(R_RISCV_ADD64, 36)
|
||||||
|
ELF_RELOC(R_RISCV_SUB8, 37)
|
||||||
|
ELF_RELOC(R_RISCV_SUB16, 38)
|
||||||
|
ELF_RELOC(R_RISCV_SUB32, 39)
|
||||||
|
ELF_RELOC(R_RISCV_SUB64, 40)
|
||||||
|
ELF_RELOC(R_RISCV_GNU_VTINHERIT, 41)
|
||||||
|
ELF_RELOC(R_RISCV_GNU_VTENTRY, 42)
|
||||||
|
ELF_RELOC(R_RISCV_ALIGN, 43)
|
||||||
|
ELF_RELOC(R_RISCV_RVC_BRANCH, 44)
|
||||||
|
ELF_RELOC(R_RISCV_RVC_JUMP, 45)
|
||||||
|
ELF_RELOC(R_RISCV_RVC_LUI, 46)
|
||||||
|
ELF_RELOC(R_RISCV_RELAX, 51)
|
||||||
|
ELF_RELOC(R_RISCV_SUB6, 52)
|
||||||
|
ELF_RELOC(R_RISCV_SET6, 53)
|
||||||
|
ELF_RELOC(R_RISCV_SET8, 54)
|
||||||
|
ELF_RELOC(R_RISCV_SET16, 55)
|
||||||
|
ELF_RELOC(R_RISCV_SET32, 56)
|
||||||
|
ELF_RELOC(R_RISCV_32_PCREL, 57)
|
||||||
|
ELF_RELOC(R_RISCV_IRELATIVE, 58)
|
||||||
|
ELF_RELOC(R_RISCV_PLT32, 59)
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_SPARC_NONE, 0)
|
||||||
|
ELF_RELOC(R_SPARC_8, 1)
|
||||||
|
ELF_RELOC(R_SPARC_16, 2)
|
||||||
|
ELF_RELOC(R_SPARC_32, 3)
|
||||||
|
ELF_RELOC(R_SPARC_DISP8, 4)
|
||||||
|
ELF_RELOC(R_SPARC_DISP16, 5)
|
||||||
|
ELF_RELOC(R_SPARC_DISP32, 6)
|
||||||
|
ELF_RELOC(R_SPARC_WDISP30, 7)
|
||||||
|
ELF_RELOC(R_SPARC_WDISP22, 8)
|
||||||
|
ELF_RELOC(R_SPARC_HI22, 9)
|
||||||
|
ELF_RELOC(R_SPARC_22, 10)
|
||||||
|
ELF_RELOC(R_SPARC_13, 11)
|
||||||
|
ELF_RELOC(R_SPARC_LO10, 12)
|
||||||
|
ELF_RELOC(R_SPARC_GOT10, 13)
|
||||||
|
ELF_RELOC(R_SPARC_GOT13, 14)
|
||||||
|
ELF_RELOC(R_SPARC_GOT22, 15)
|
||||||
|
ELF_RELOC(R_SPARC_PC10, 16)
|
||||||
|
ELF_RELOC(R_SPARC_PC22, 17)
|
||||||
|
ELF_RELOC(R_SPARC_WPLT30, 18)
|
||||||
|
ELF_RELOC(R_SPARC_COPY, 19)
|
||||||
|
ELF_RELOC(R_SPARC_GLOB_DAT, 20)
|
||||||
|
ELF_RELOC(R_SPARC_JMP_SLOT, 21)
|
||||||
|
ELF_RELOC(R_SPARC_RELATIVE, 22)
|
||||||
|
ELF_RELOC(R_SPARC_UA32, 23)
|
||||||
|
ELF_RELOC(R_SPARC_PLT32, 24)
|
||||||
|
ELF_RELOC(R_SPARC_HIPLT22, 25)
|
||||||
|
ELF_RELOC(R_SPARC_LOPLT10, 26)
|
||||||
|
ELF_RELOC(R_SPARC_PCPLT32, 27)
|
||||||
|
ELF_RELOC(R_SPARC_PCPLT22, 28)
|
||||||
|
ELF_RELOC(R_SPARC_PCPLT10, 29)
|
||||||
|
ELF_RELOC(R_SPARC_10, 30)
|
||||||
|
ELF_RELOC(R_SPARC_11, 31)
|
||||||
|
ELF_RELOC(R_SPARC_64, 32)
|
||||||
|
ELF_RELOC(R_SPARC_OLO10, 33)
|
||||||
|
ELF_RELOC(R_SPARC_HH22, 34)
|
||||||
|
ELF_RELOC(R_SPARC_HM10, 35)
|
||||||
|
ELF_RELOC(R_SPARC_LM22, 36)
|
||||||
|
ELF_RELOC(R_SPARC_PC_HH22, 37)
|
||||||
|
ELF_RELOC(R_SPARC_PC_HM10, 38)
|
||||||
|
ELF_RELOC(R_SPARC_PC_LM22, 39)
|
||||||
|
ELF_RELOC(R_SPARC_WDISP16, 40)
|
||||||
|
ELF_RELOC(R_SPARC_WDISP19, 41)
|
||||||
|
ELF_RELOC(R_SPARC_7, 43)
|
||||||
|
ELF_RELOC(R_SPARC_5, 44)
|
||||||
|
ELF_RELOC(R_SPARC_6, 45)
|
||||||
|
ELF_RELOC(R_SPARC_DISP64, 46)
|
||||||
|
ELF_RELOC(R_SPARC_PLT64, 47)
|
||||||
|
ELF_RELOC(R_SPARC_HIX22, 48)
|
||||||
|
ELF_RELOC(R_SPARC_LOX10, 49)
|
||||||
|
ELF_RELOC(R_SPARC_H44, 50)
|
||||||
|
ELF_RELOC(R_SPARC_M44, 51)
|
||||||
|
ELF_RELOC(R_SPARC_L44, 52)
|
||||||
|
ELF_RELOC(R_SPARC_REGISTER, 53)
|
||||||
|
ELF_RELOC(R_SPARC_UA64, 54)
|
||||||
|
ELF_RELOC(R_SPARC_UA16, 55)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_GD_HI22, 56)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_GD_LO10, 57)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_GD_ADD, 58)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_GD_CALL, 59)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_LDM_HI22, 60)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_LDM_LO10, 61)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_LDM_ADD, 62)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_LDM_CALL, 63)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_LDO_HIX22, 64)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_LDO_LOX10, 65)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_LDO_ADD, 66)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_IE_HI22, 67)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_IE_LO10, 68)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_IE_LD, 69)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_IE_LDX, 70)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_IE_ADD, 71)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_LE_HIX22, 72)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_LE_LOX10, 73)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_DTPMOD32, 74)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_DTPMOD64, 75)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_DTPOFF32, 76)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_DTPOFF64, 77)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_TPOFF32, 78)
|
||||||
|
ELF_RELOC(R_SPARC_TLS_TPOFF64, 79)
|
||||||
|
ELF_RELOC(R_SPARC_GOTDATA_HIX22, 80)
|
||||||
|
ELF_RELOC(R_SPARC_GOTDATA_LOX10, 81)
|
||||||
|
ELF_RELOC(R_SPARC_GOTDATA_OP_HIX22, 82)
|
||||||
|
ELF_RELOC(R_SPARC_GOTDATA_OP_LOX10, 83)
|
||||||
|
ELF_RELOC(R_SPARC_GOTDATA_OP, 84)
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_390_NONE, 0)
|
||||||
|
ELF_RELOC(R_390_8, 1)
|
||||||
|
ELF_RELOC(R_390_12, 2)
|
||||||
|
ELF_RELOC(R_390_16, 3)
|
||||||
|
ELF_RELOC(R_390_32, 4)
|
||||||
|
ELF_RELOC(R_390_PC32, 5)
|
||||||
|
ELF_RELOC(R_390_GOT12, 6)
|
||||||
|
ELF_RELOC(R_390_GOT32, 7)
|
||||||
|
ELF_RELOC(R_390_PLT32, 8)
|
||||||
|
ELF_RELOC(R_390_COPY, 9)
|
||||||
|
ELF_RELOC(R_390_GLOB_DAT, 10)
|
||||||
|
ELF_RELOC(R_390_JMP_SLOT, 11)
|
||||||
|
ELF_RELOC(R_390_RELATIVE, 12)
|
||||||
|
ELF_RELOC(R_390_GOTOFF, 13)
|
||||||
|
ELF_RELOC(R_390_GOTPC, 14)
|
||||||
|
ELF_RELOC(R_390_GOT16, 15)
|
||||||
|
ELF_RELOC(R_390_PC16, 16)
|
||||||
|
ELF_RELOC(R_390_PC16DBL, 17)
|
||||||
|
ELF_RELOC(R_390_PLT16DBL, 18)
|
||||||
|
ELF_RELOC(R_390_PC32DBL, 19)
|
||||||
|
ELF_RELOC(R_390_PLT32DBL, 20)
|
||||||
|
ELF_RELOC(R_390_GOTPCDBL, 21)
|
||||||
|
ELF_RELOC(R_390_64, 22)
|
||||||
|
ELF_RELOC(R_390_PC64, 23)
|
||||||
|
ELF_RELOC(R_390_GOT64, 24)
|
||||||
|
ELF_RELOC(R_390_PLT64, 25)
|
||||||
|
ELF_RELOC(R_390_GOTENT, 26)
|
||||||
|
ELF_RELOC(R_390_GOTOFF16, 27)
|
||||||
|
ELF_RELOC(R_390_GOTOFF64, 28)
|
||||||
|
ELF_RELOC(R_390_GOTPLT12, 29)
|
||||||
|
ELF_RELOC(R_390_GOTPLT16, 30)
|
||||||
|
ELF_RELOC(R_390_GOTPLT32, 31)
|
||||||
|
ELF_RELOC(R_390_GOTPLT64, 32)
|
||||||
|
ELF_RELOC(R_390_GOTPLTENT, 33)
|
||||||
|
ELF_RELOC(R_390_PLTOFF16, 34)
|
||||||
|
ELF_RELOC(R_390_PLTOFF32, 35)
|
||||||
|
ELF_RELOC(R_390_PLTOFF64, 36)
|
||||||
|
ELF_RELOC(R_390_TLS_LOAD, 37)
|
||||||
|
ELF_RELOC(R_390_TLS_GDCALL, 38)
|
||||||
|
ELF_RELOC(R_390_TLS_LDCALL, 39)
|
||||||
|
ELF_RELOC(R_390_TLS_GD32, 40)
|
||||||
|
ELF_RELOC(R_390_TLS_GD64, 41)
|
||||||
|
ELF_RELOC(R_390_TLS_GOTIE12, 42)
|
||||||
|
ELF_RELOC(R_390_TLS_GOTIE32, 43)
|
||||||
|
ELF_RELOC(R_390_TLS_GOTIE64, 44)
|
||||||
|
ELF_RELOC(R_390_TLS_LDM32, 45)
|
||||||
|
ELF_RELOC(R_390_TLS_LDM64, 46)
|
||||||
|
ELF_RELOC(R_390_TLS_IE32, 47)
|
||||||
|
ELF_RELOC(R_390_TLS_IE64, 48)
|
||||||
|
ELF_RELOC(R_390_TLS_IEENT, 49)
|
||||||
|
ELF_RELOC(R_390_TLS_LE32, 50)
|
||||||
|
ELF_RELOC(R_390_TLS_LE64, 51)
|
||||||
|
ELF_RELOC(R_390_TLS_LDO32, 52)
|
||||||
|
ELF_RELOC(R_390_TLS_LDO64, 53)
|
||||||
|
ELF_RELOC(R_390_TLS_DTPMOD, 54)
|
||||||
|
ELF_RELOC(R_390_TLS_DTPOFF, 55)
|
||||||
|
ELF_RELOC(R_390_TLS_TPOFF, 56)
|
||||||
|
ELF_RELOC(R_390_20, 57)
|
||||||
|
ELF_RELOC(R_390_GOT20, 58)
|
||||||
|
ELF_RELOC(R_390_GOTPLT20, 59)
|
||||||
|
ELF_RELOC(R_390_TLS_GOTIE20, 60)
|
||||||
|
ELF_RELOC(R_390_IRELATIVE, 61)
|
||||||
|
ELF_RELOC(R_390_PC12DBL, 62)
|
||||||
|
ELF_RELOC(R_390_PLT12DBL, 63)
|
||||||
|
ELF_RELOC(R_390_PC24DBL, 64)
|
||||||
|
ELF_RELOC(R_390_PLT24DBL, 65)
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Relocation types defined in following documents.
|
||||||
|
//
|
||||||
|
// - System V Application Binary Interface - VE Architecture
|
||||||
|
// Processor Supplement
|
||||||
|
// - ELF Handling For Thread-Local Storage - VE Architecture
|
||||||
|
// Processor Supplement
|
||||||
|
|
||||||
|
ELF_RELOC(R_VE_NONE, 0)
|
||||||
|
ELF_RELOC(R_VE_REFLONG, 1)
|
||||||
|
ELF_RELOC(R_VE_REFQUAD, 2)
|
||||||
|
ELF_RELOC(R_VE_SREL32, 3)
|
||||||
|
ELF_RELOC(R_VE_HI32, 4)
|
||||||
|
ELF_RELOC(R_VE_LO32, 5)
|
||||||
|
ELF_RELOC(R_VE_PC_HI32, 6)
|
||||||
|
ELF_RELOC(R_VE_PC_LO32, 7)
|
||||||
|
ELF_RELOC(R_VE_GOT32, 8)
|
||||||
|
ELF_RELOC(R_VE_GOT_HI32, 9)
|
||||||
|
ELF_RELOC(R_VE_GOT_LO32, 10)
|
||||||
|
ELF_RELOC(R_VE_GOTOFF32, 11)
|
||||||
|
ELF_RELOC(R_VE_GOTOFF_HI32, 12)
|
||||||
|
ELF_RELOC(R_VE_GOTOFF_LO32, 13)
|
||||||
|
ELF_RELOC(R_VE_PLT32, 14)
|
||||||
|
ELF_RELOC(R_VE_PLT_HI32, 15)
|
||||||
|
ELF_RELOC(R_VE_PLT_LO32, 16)
|
||||||
|
ELF_RELOC(R_VE_RELATIVE, 17)
|
||||||
|
ELF_RELOC(R_VE_GLOB_DAT, 18)
|
||||||
|
ELF_RELOC(R_VE_JUMP_SLOT, 19)
|
||||||
|
ELF_RELOC(R_VE_COPY, 20)
|
||||||
|
ELF_RELOC(R_VE_DTPMOD64, 22)
|
||||||
|
ELF_RELOC(R_VE_DTPOFF64, 23)
|
||||||
|
// ELF_RELOC(R_VE_TPOFF64, 24)
|
||||||
|
ELF_RELOC(R_VE_TLS_GD_HI32, 25)
|
||||||
|
ELF_RELOC(R_VE_TLS_GD_LO32, 26)
|
||||||
|
// ELF_RELOC(R_VE_TLS_LD_HI32, 27)
|
||||||
|
// ELF_RELOC(R_VE_TLS_LD_LO32, 28)
|
||||||
|
// ELF_RELOC(R_VE_DTPOFF32, 29)
|
||||||
|
// ELF_RELOC(R_VE_TLS_IE_HI32, 30)
|
||||||
|
// ELF_RELOC(R_VE_TLS_IE_LO32, 31)
|
||||||
|
ELF_RELOC(R_VE_TPOFF_HI32, 32)
|
||||||
|
ELF_RELOC(R_VE_TPOFF_LO32, 33)
|
||||||
|
// ELF_RELOC(R_VE_TPOFF32, 34)
|
||||||
|
ELF_RELOC(R_VE_CALL_HI32, 35)
|
||||||
|
ELF_RELOC(R_VE_CALL_LO32, 36)
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_XTENSA_NONE, 0)
|
||||||
|
ELF_RELOC(R_XTENSA_32, 1)
|
||||||
|
ELF_RELOC(R_XTENSA_RTLD, 2)
|
||||||
|
ELF_RELOC(R_XTENSA_GLOB_DAT, 3)
|
||||||
|
ELF_RELOC(R_XTENSA_JMP_SLOT, 4)
|
||||||
|
ELF_RELOC(R_XTENSA_RELATIVE, 5)
|
||||||
|
ELF_RELOC(R_XTENSA_PLT, 6)
|
||||||
|
// RELOC '7' currently is not used.
|
||||||
|
ELF_RELOC(R_XTENSA_OP0, 8)
|
||||||
|
ELF_RELOC(R_XTENSA_OP1, 9)
|
||||||
|
ELF_RELOC(R_XTENSA_OP2, 10)
|
||||||
|
ELF_RELOC(R_XTENSA_ASM_EXPAND, 11)
|
||||||
|
ELF_RELOC(R_XTENSA_ASM_SIMPLIFY, 12)
|
||||||
|
ELF_RELOC(R_XTENSA_32_PCREL, 14)
|
||||||
|
ELF_RELOC(R_XTENSA_GNU_VTINHERIT, 15)
|
||||||
|
ELF_RELOC(R_XTENSA_GNU_VTENTRY, 16)
|
||||||
|
ELF_RELOC(R_XTENSA_DIFF8, 17)
|
||||||
|
ELF_RELOC(R_XTENSA_DIFF16, 18)
|
||||||
|
ELF_RELOC(R_XTENSA_DIFF32, 19)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT0_OP, 20)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT1_OP, 21)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT2_OP, 22)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT3_OP, 23)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT4_OP, 24)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT5_OP, 25)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT6_OP, 26)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT7_OP, 27)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT8_OP, 28)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT9_OP, 29)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT10_OP, 30)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT11_OP, 31)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT12_OP, 32)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT13_OP, 33)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT14_OP, 34)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT0_ALT, 35)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT1_ALT, 36)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT2_ALT, 37)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT3_ALT, 38)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT4_ALT, 39)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT5_ALT, 40)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT6_ALT, 41)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT7_ALT, 42)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT8_ALT, 43)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT9_ALT, 44)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT10_ALT, 45)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT11_ALT, 46)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT12_ALT, 47)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT13_ALT, 48)
|
||||||
|
ELF_RELOC(R_XTENSA_SLOT14_ALT, 49)
|
||||||
|
ELF_RELOC(R_XTENSA_TLSDESC_FN, 50)
|
||||||
|
ELF_RELOC(R_XTENSA_TLSDESC_ARG, 51)
|
||||||
|
ELF_RELOC(R_XTENSA_TLS_DTPOFF, 52)
|
||||||
|
ELF_RELOC(R_XTENSA_TLS_TPOFF, 53)
|
||||||
|
ELF_RELOC(R_XTENSA_TLS_FUNC, 54)
|
||||||
|
ELF_RELOC(R_XTENSA_TLS_ARG, 55)
|
||||||
|
ELF_RELOC(R_XTENSA_TLS_CALL, 56)
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: this is just a subset
|
||||||
|
ELF_RELOC(R_386_NONE, 0)
|
||||||
|
ELF_RELOC(R_386_32, 1)
|
||||||
|
ELF_RELOC(R_386_PC32, 2)
|
||||||
|
ELF_RELOC(R_386_GOT32, 3)
|
||||||
|
ELF_RELOC(R_386_PLT32, 4)
|
||||||
|
ELF_RELOC(R_386_COPY, 5)
|
||||||
|
ELF_RELOC(R_386_GLOB_DAT, 6)
|
||||||
|
ELF_RELOC(R_386_JUMP_SLOT, 7)
|
||||||
|
ELF_RELOC(R_386_RELATIVE, 8)
|
||||||
|
ELF_RELOC(R_386_GOTOFF, 9)
|
||||||
|
ELF_RELOC(R_386_GOTPC, 10)
|
||||||
|
ELF_RELOC(R_386_32PLT, 11)
|
||||||
|
ELF_RELOC(R_386_TLS_TPOFF, 14)
|
||||||
|
ELF_RELOC(R_386_TLS_IE, 15)
|
||||||
|
ELF_RELOC(R_386_TLS_GOTIE, 16)
|
||||||
|
ELF_RELOC(R_386_TLS_LE, 17)
|
||||||
|
ELF_RELOC(R_386_TLS_GD, 18)
|
||||||
|
ELF_RELOC(R_386_TLS_LDM, 19)
|
||||||
|
ELF_RELOC(R_386_16, 20)
|
||||||
|
ELF_RELOC(R_386_PC16, 21)
|
||||||
|
ELF_RELOC(R_386_8, 22)
|
||||||
|
ELF_RELOC(R_386_PC8, 23)
|
||||||
|
ELF_RELOC(R_386_TLS_GD_32, 24)
|
||||||
|
ELF_RELOC(R_386_TLS_GD_PUSH, 25)
|
||||||
|
ELF_RELOC(R_386_TLS_GD_CALL, 26)
|
||||||
|
ELF_RELOC(R_386_TLS_GD_POP, 27)
|
||||||
|
ELF_RELOC(R_386_TLS_LDM_32, 28)
|
||||||
|
ELF_RELOC(R_386_TLS_LDM_PUSH, 29)
|
||||||
|
ELF_RELOC(R_386_TLS_LDM_CALL, 30)
|
||||||
|
ELF_RELOC(R_386_TLS_LDM_POP, 31)
|
||||||
|
ELF_RELOC(R_386_TLS_LDO_32, 32)
|
||||||
|
ELF_RELOC(R_386_TLS_IE_32, 33)
|
||||||
|
ELF_RELOC(R_386_TLS_LE_32, 34)
|
||||||
|
ELF_RELOC(R_386_TLS_DTPMOD32, 35)
|
||||||
|
ELF_RELOC(R_386_TLS_DTPOFF32, 36)
|
||||||
|
ELF_RELOC(R_386_TLS_TPOFF32, 37)
|
||||||
|
ELF_RELOC(R_386_TLS_GOTDESC, 39)
|
||||||
|
ELF_RELOC(R_386_TLS_DESC_CALL, 40)
|
||||||
|
ELF_RELOC(R_386_TLS_DESC, 41)
|
||||||
|
ELF_RELOC(R_386_IRELATIVE, 42)
|
||||||
|
ELF_RELOC(R_386_GOT32X, 43)
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
#ifndef ELF_RELOC
|
||||||
|
#error "ELF_RELOC must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ELF_RELOC(R_X86_64_NONE, 0)
|
||||||
|
ELF_RELOC(R_X86_64_64, 1)
|
||||||
|
ELF_RELOC(R_X86_64_PC32, 2)
|
||||||
|
ELF_RELOC(R_X86_64_GOT32, 3)
|
||||||
|
ELF_RELOC(R_X86_64_PLT32, 4)
|
||||||
|
ELF_RELOC(R_X86_64_COPY, 5)
|
||||||
|
ELF_RELOC(R_X86_64_GLOB_DAT, 6)
|
||||||
|
ELF_RELOC(R_X86_64_JUMP_SLOT, 7)
|
||||||
|
ELF_RELOC(R_X86_64_RELATIVE, 8)
|
||||||
|
ELF_RELOC(R_X86_64_GOTPCREL, 9)
|
||||||
|
ELF_RELOC(R_X86_64_32, 10)
|
||||||
|
ELF_RELOC(R_X86_64_32S, 11)
|
||||||
|
ELF_RELOC(R_X86_64_16, 12)
|
||||||
|
ELF_RELOC(R_X86_64_PC16, 13)
|
||||||
|
ELF_RELOC(R_X86_64_8, 14)
|
||||||
|
ELF_RELOC(R_X86_64_PC8, 15)
|
||||||
|
ELF_RELOC(R_X86_64_DTPMOD64, 16)
|
||||||
|
ELF_RELOC(R_X86_64_DTPOFF64, 17)
|
||||||
|
ELF_RELOC(R_X86_64_TPOFF64, 18)
|
||||||
|
ELF_RELOC(R_X86_64_TLSGD, 19)
|
||||||
|
ELF_RELOC(R_X86_64_TLSLD, 20)
|
||||||
|
ELF_RELOC(R_X86_64_DTPOFF32, 21)
|
||||||
|
ELF_RELOC(R_X86_64_GOTTPOFF, 22)
|
||||||
|
ELF_RELOC(R_X86_64_TPOFF32, 23)
|
||||||
|
ELF_RELOC(R_X86_64_PC64, 24)
|
||||||
|
ELF_RELOC(R_X86_64_GOTOFF64, 25)
|
||||||
|
ELF_RELOC(R_X86_64_GOTPC32, 26)
|
||||||
|
ELF_RELOC(R_X86_64_GOT64, 27)
|
||||||
|
ELF_RELOC(R_X86_64_GOTPCREL64, 28)
|
||||||
|
ELF_RELOC(R_X86_64_GOTPC64, 29)
|
||||||
|
ELF_RELOC(R_X86_64_GOTPLT64, 30)
|
||||||
|
ELF_RELOC(R_X86_64_PLTOFF64, 31)
|
||||||
|
ELF_RELOC(R_X86_64_SIZE32, 32)
|
||||||
|
ELF_RELOC(R_X86_64_SIZE64, 33)
|
||||||
|
ELF_RELOC(R_X86_64_GOTPC32_TLSDESC, 34)
|
||||||
|
ELF_RELOC(R_X86_64_TLSDESC_CALL, 35)
|
||||||
|
ELF_RELOC(R_X86_64_TLSDESC, 36)
|
||||||
|
ELF_RELOC(R_X86_64_IRELATIVE, 37)
|
||||||
|
ELF_RELOC(R_X86_64_GOTPCRELX, 41)
|
||||||
|
ELF_RELOC(R_X86_64_REX_GOTPCRELX, 42)
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
//,,,-- llvm/Support/MachO.def - The MachO file definitions -----*- C++ -*-,,,//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//,,,----------------------------------------------------------------------,,,//
|
||||||
|
//
|
||||||
|
// Definitions for MachO files
|
||||||
|
//
|
||||||
|
//,,,----------------------------------------------------------------------,,,//
|
||||||
|
|
||||||
|
#ifdef HANDLE_LOAD_COMMAND
|
||||||
|
|
||||||
|
HANDLE_LOAD_COMMAND(LC_SEGMENT, 0x00000001u, segment_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_SYMTAB, 0x00000002u, symtab_command)
|
||||||
|
// LC_SYMSEG is obsolete and no longer supported.
|
||||||
|
HANDLE_LOAD_COMMAND(LC_SYMSEG, 0x00000003u, symseg_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_THREAD, 0x00000004u, thread_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_UNIXTHREAD, 0x00000005u, thread_command)
|
||||||
|
// LC_LOADFVMLIB is obsolete and no longer supported.
|
||||||
|
HANDLE_LOAD_COMMAND(LC_LOADFVMLIB, 0x00000006u, fvmlib_command)
|
||||||
|
// LC_IDFVMLIB is obsolete and no longer supported.
|
||||||
|
HANDLE_LOAD_COMMAND(LC_IDFVMLIB, 0x00000007u, fvmlib_command)
|
||||||
|
// LC_IDENT is obsolete and no longer supported.
|
||||||
|
HANDLE_LOAD_COMMAND(LC_IDENT, 0x00000008u, ident_command)
|
||||||
|
// LC_FVMFILE is obsolete and no longer supported.
|
||||||
|
HANDLE_LOAD_COMMAND(LC_FVMFILE, 0x00000009u, fvmfile_command)
|
||||||
|
// LC_PREPAGE is obsolete and no longer supported.
|
||||||
|
HANDLE_LOAD_COMMAND(LC_PREPAGE, 0x0000000Au, load_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_DYSYMTAB, 0x0000000Bu, dysymtab_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_LOAD_DYLIB, 0x0000000Cu, dylib_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_ID_DYLIB, 0x0000000Du, dylib_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_LOAD_DYLINKER, 0x0000000Eu, dylinker_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_ID_DYLINKER, 0x0000000Fu, dylinker_command)
|
||||||
|
// LC_PREBOUND_DYLIB is obsolete and no longer supported.
|
||||||
|
HANDLE_LOAD_COMMAND(LC_PREBOUND_DYLIB, 0x00000010u, prebound_dylib_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_ROUTINES, 0x00000011u, routines_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_SUB_FRAMEWORK, 0x00000012u, sub_framework_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_SUB_UMBRELLA, 0x00000013u, sub_umbrella_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_SUB_CLIENT, 0x00000014u, sub_client_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_SUB_LIBRARY, 0x00000015u, sub_library_command)
|
||||||
|
// LC_TWOLEVEL_HINTS is obsolete and no longer supported.
|
||||||
|
HANDLE_LOAD_COMMAND(LC_TWOLEVEL_HINTS, 0x00000016u, twolevel_hints_command)
|
||||||
|
// LC_PREBIND_CKSUM is obsolete and no longer supported.
|
||||||
|
HANDLE_LOAD_COMMAND(LC_PREBIND_CKSUM, 0x00000017u, prebind_cksum_command)
|
||||||
|
// LC_LOAD_WEAK_DYLIB is obsolete and no longer supported.
|
||||||
|
HANDLE_LOAD_COMMAND(LC_LOAD_WEAK_DYLIB, 0x80000018u, dylib_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_SEGMENT_64, 0x00000019u, segment_command_64)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_ROUTINES_64, 0x0000001Au, routines_command_64)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_UUID, 0x0000001Bu, uuid_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_RPATH, 0x8000001Cu, rpath_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_CODE_SIGNATURE, 0x0000001Du, linkedit_data_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_SEGMENT_SPLIT_INFO, 0x0000001Eu, linkedit_data_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_REEXPORT_DYLIB, 0x8000001Fu, dylib_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_LAZY_LOAD_DYLIB, 0x00000020u, dylib_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_ENCRYPTION_INFO, 0x00000021u, encryption_info_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_DYLD_INFO, 0x00000022u, dyld_info_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_DYLD_INFO_ONLY, 0x80000022u, dyld_info_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_LOAD_UPWARD_DYLIB, 0x80000023u, dylib_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_VERSION_MIN_MACOSX, 0x00000024u, version_min_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_VERSION_MIN_IPHONEOS, 0x00000025u, version_min_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_FUNCTION_STARTS, 0x00000026u, linkedit_data_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_DYLD_ENVIRONMENT, 0x00000027u, dylinker_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_MAIN, 0x80000028u, entry_point_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_DATA_IN_CODE, 0x00000029u, linkedit_data_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_SOURCE_VERSION, 0x0000002Au, source_version_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_DYLIB_CODE_SIGN_DRS, 0x0000002Bu, linkedit_data_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_ENCRYPTION_INFO_64, 0x0000002Cu,
|
||||||
|
encryption_info_command_64)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_LINKER_OPTION, 0x0000002Du, linker_option_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_LINKER_OPTIMIZATION_HINT, 0x0000002Eu, linkedit_data_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_VERSION_MIN_TVOS, 0x0000002Fu, version_min_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_VERSION_MIN_WATCHOS, 0x00000030u, version_min_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_NOTE, 0x00000031u, note_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_BUILD_VERSION, 0x00000032u, build_version_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_DYLD_EXPORTS_TRIE, 0x80000033u, linkedit_data_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_DYLD_CHAINED_FIXUPS, 0x80000034u, linkedit_data_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_FILESET_ENTRY, 0x80000035u, fileset_entry_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_ATOM_INFO, 0x00000036u, linkedit_data_command)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOAD_COMMAND_STRUCT
|
||||||
|
|
||||||
|
LOAD_COMMAND_STRUCT(dyld_info_command)
|
||||||
|
LOAD_COMMAND_STRUCT(dylib_command)
|
||||||
|
LOAD_COMMAND_STRUCT(dylinker_command)
|
||||||
|
LOAD_COMMAND_STRUCT(dysymtab_command)
|
||||||
|
LOAD_COMMAND_STRUCT(encryption_info_command)
|
||||||
|
LOAD_COMMAND_STRUCT(encryption_info_command_64)
|
||||||
|
LOAD_COMMAND_STRUCT(entry_point_command)
|
||||||
|
LOAD_COMMAND_STRUCT(fvmfile_command)
|
||||||
|
LOAD_COMMAND_STRUCT(fvmlib_command)
|
||||||
|
LOAD_COMMAND_STRUCT(ident_command)
|
||||||
|
LOAD_COMMAND_STRUCT(linkedit_data_command)
|
||||||
|
LOAD_COMMAND_STRUCT(linker_option_command)
|
||||||
|
LOAD_COMMAND_STRUCT(load_command)
|
||||||
|
LOAD_COMMAND_STRUCT(prebind_cksum_command)
|
||||||
|
LOAD_COMMAND_STRUCT(prebound_dylib_command)
|
||||||
|
LOAD_COMMAND_STRUCT(routines_command)
|
||||||
|
LOAD_COMMAND_STRUCT(routines_command_64)
|
||||||
|
LOAD_COMMAND_STRUCT(rpath_command)
|
||||||
|
LOAD_COMMAND_STRUCT(segment_command)
|
||||||
|
LOAD_COMMAND_STRUCT(segment_command_64)
|
||||||
|
LOAD_COMMAND_STRUCT(source_version_command)
|
||||||
|
LOAD_COMMAND_STRUCT(sub_client_command)
|
||||||
|
LOAD_COMMAND_STRUCT(sub_framework_command)
|
||||||
|
LOAD_COMMAND_STRUCT(sub_library_command)
|
||||||
|
LOAD_COMMAND_STRUCT(sub_umbrella_command)
|
||||||
|
LOAD_COMMAND_STRUCT(symseg_command)
|
||||||
|
LOAD_COMMAND_STRUCT(symtab_command)
|
||||||
|
LOAD_COMMAND_STRUCT(thread_command)
|
||||||
|
LOAD_COMMAND_STRUCT(twolevel_hints_command)
|
||||||
|
LOAD_COMMAND_STRUCT(uuid_command)
|
||||||
|
LOAD_COMMAND_STRUCT(version_min_command)
|
||||||
|
LOAD_COMMAND_STRUCT(note_command)
|
||||||
|
LOAD_COMMAND_STRUCT(build_version_command)
|
||||||
|
LOAD_COMMAND_STRUCT(fileset_entry_command)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef HANDLE_LOAD_COMMAND
|
||||||
|
#undef LOAD_COMMAND_STRUCT
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,82 @@
|
|||||||
|
//===- llvm/BinaryFormat/Magic.h - File magic identification ----*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_BINARYFORMAT_MAGIC_H
|
||||||
|
#define LLVM_BINARYFORMAT_MAGIC_H
|
||||||
|
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
class StringRef;
|
||||||
|
class Twine;
|
||||||
|
|
||||||
|
/// file_magic - An "enum class" enumeration of file types based on magic (the
|
||||||
|
/// first N bytes of the file).
|
||||||
|
struct file_magic {
|
||||||
|
enum Impl {
|
||||||
|
unknown = 0, ///< Unrecognized file
|
||||||
|
bitcode, ///< Bitcode file
|
||||||
|
archive, ///< ar style archive file
|
||||||
|
elf, ///< ELF Unknown type
|
||||||
|
elf_relocatable, ///< ELF Relocatable object file
|
||||||
|
elf_executable, ///< ELF Executable image
|
||||||
|
elf_shared_object, ///< ELF dynamically linked shared lib
|
||||||
|
elf_core, ///< ELF core image
|
||||||
|
goff_object, ///< GOFF object file
|
||||||
|
macho_object, ///< Mach-O Object file
|
||||||
|
macho_executable, ///< Mach-O Executable
|
||||||
|
macho_fixed_virtual_memory_shared_lib, ///< Mach-O Shared Lib, FVM
|
||||||
|
macho_core, ///< Mach-O Core File
|
||||||
|
macho_preload_executable, ///< Mach-O Preloaded Executable
|
||||||
|
macho_dynamically_linked_shared_lib, ///< Mach-O dynlinked shared lib
|
||||||
|
macho_dynamic_linker, ///< The Mach-O dynamic linker
|
||||||
|
macho_bundle, ///< Mach-O Bundle file
|
||||||
|
macho_dynamically_linked_shared_lib_stub, ///< Mach-O Shared lib stub
|
||||||
|
macho_dsym_companion, ///< Mach-O dSYM companion file
|
||||||
|
macho_kext_bundle, ///< Mach-O kext bundle file
|
||||||
|
macho_universal_binary, ///< Mach-O universal binary
|
||||||
|
macho_file_set, ///< Mach-O file set binary
|
||||||
|
minidump, ///< Windows minidump file
|
||||||
|
coff_cl_gl_object, ///< Microsoft cl.exe's intermediate code file
|
||||||
|
coff_object, ///< COFF object file
|
||||||
|
coff_import_library, ///< COFF import library
|
||||||
|
pecoff_executable, ///< PECOFF executable file
|
||||||
|
windows_resource, ///< Windows compiled resource file (.res)
|
||||||
|
xcoff_object_32, ///< 32-bit XCOFF object file
|
||||||
|
xcoff_object_64, ///< 64-bit XCOFF object file
|
||||||
|
wasm_object, ///< WebAssembly Object file
|
||||||
|
pdb, ///< Windows PDB debug info file
|
||||||
|
tapi_file, ///< Text-based Dynamic Library Stub file
|
||||||
|
cuda_fatbinary, ///< CUDA Fatbinary object file
|
||||||
|
offload_binary, ///< LLVM offload object file
|
||||||
|
dxcontainer_object, ///< DirectX container file
|
||||||
|
};
|
||||||
|
|
||||||
|
bool is_object() const { return V != unknown; }
|
||||||
|
|
||||||
|
file_magic() = default;
|
||||||
|
file_magic(Impl V) : V(V) {}
|
||||||
|
operator Impl() const { return V; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Impl V = unknown;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Identify the type of a binary file based on how magical it is.
|
||||||
|
file_magic identify_magic(StringRef magic);
|
||||||
|
|
||||||
|
/// Get and identify \a path's type based on its content.
|
||||||
|
///
|
||||||
|
/// @param path Input path.
|
||||||
|
/// @param result Set to the type of file, or file_magic::unknown.
|
||||||
|
/// @returns errc::success if result has been successfully set, otherwise a
|
||||||
|
/// platform-specific error_code.
|
||||||
|
std::error_code identify_magic(const Twine &path, file_magic &result);
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
//===- llvm/BinaryFormat/Swift.def - Swift definitions ---------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Macros for running through Swift enumerators.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#if !(defined HANDLE_SWIFT_SECTION)
|
||||||
|
#error "Missing macro definition of HANDLE_SWIFT_SECTION"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HANDLE_SWIFT_SECTION
|
||||||
|
#define HANDLE_SWIFT_SECTION(KIND, MACHO, ELF, COFF)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HANDLE_SWIFT_SECTION(fieldmd, "__swift5_fieldmd", "swift5_fieldmd", ".sw5flmd")
|
||||||
|
HANDLE_SWIFT_SECTION(assocty, "__swift5_assocty", "swift5_assocty", ".sw5asty")
|
||||||
|
HANDLE_SWIFT_SECTION(builtin, "__swift5_builtin", "swift5_builtin", ".sw5bltn")
|
||||||
|
HANDLE_SWIFT_SECTION(capture, "__swift5_capture", "swift5_capture", ".sw5cptr")
|
||||||
|
HANDLE_SWIFT_SECTION(typeref, "__swift5_typeref", "swift5_typeref", ".sw5tyrf")
|
||||||
|
HANDLE_SWIFT_SECTION(reflstr, "__swift5_reflstr", "swift5_reflstr", ".sw5rfst")
|
||||||
|
HANDLE_SWIFT_SECTION(conform, "__swift5_proto", "swift5_protocol_conformances",
|
||||||
|
".sw5prtc$B")
|
||||||
|
HANDLE_SWIFT_SECTION(protocs, "__swift5_protos", "swift5_protocols",
|
||||||
|
".sw5prt$B")
|
||||||
|
HANDLE_SWIFT_SECTION(acfuncs, "__swift5_acfuncs", "swift5_accessible_functions",
|
||||||
|
".sw5acfn$B")
|
||||||
|
HANDLE_SWIFT_SECTION(mpenum, "__swift5_mpenum", "swift5_mpenum", ".sw5mpen$B")
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
//===-- llvm/BinaryFormat/Swift.h ---Swift Constants-------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef LLVM_BINARYFORMAT_SWIFT_H
|
||||||
|
#define LLVM_BINARYFORMAT_SWIFT_H
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace binaryformat {
|
||||||
|
|
||||||
|
enum Swift5ReflectionSectionKind {
|
||||||
|
#define HANDLE_SWIFT_SECTION(KIND, MACHO, ELF, COFF) KIND,
|
||||||
|
#include "llvm/BinaryFormat/Swift.def"
|
||||||
|
#undef HANDLE_SWIFT_SECTION
|
||||||
|
unknown,
|
||||||
|
last = unknown
|
||||||
|
};
|
||||||
|
} // end of namespace binaryformat
|
||||||
|
} // end of namespace llvm
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
//===- Binary.h - A generic binary file -------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file declares the Binary class.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_OBJECT_BINARY_H
|
||||||
|
#define LLVM_OBJECT_BINARY_H
|
||||||
|
|
||||||
|
#include "llvm-c/Types.h"
|
||||||
|
#include "llvm/Object/Error.h"
|
||||||
|
#include "llvm/Support/CBindingWrapping.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
|
#include "llvm/TargetParser/Triple.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class LLVMContext;
|
||||||
|
class StringRef;
|
||||||
|
|
||||||
|
namespace object {
|
||||||
|
|
||||||
|
class Binary {
|
||||||
|
private:
|
||||||
|
unsigned int TypeID;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MemoryBufferRef Data;
|
||||||
|
|
||||||
|
Binary(unsigned int Type, MemoryBufferRef Source);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ID_Archive,
|
||||||
|
ID_MachOUniversalBinary,
|
||||||
|
ID_COFFImportFile,
|
||||||
|
ID_IR, // LLVM IR
|
||||||
|
ID_TapiUniversal, // Text-based Dynamic Library Stub file.
|
||||||
|
ID_TapiFile, // Text-based Dynamic Library Stub file.
|
||||||
|
|
||||||
|
ID_Minidump,
|
||||||
|
|
||||||
|
ID_WinRes, // Windows resource (.res) file.
|
||||||
|
|
||||||
|
ID_Offload, // Offloading binary file.
|
||||||
|
|
||||||
|
// Object and children.
|
||||||
|
ID_StartObjects,
|
||||||
|
ID_COFF,
|
||||||
|
|
||||||
|
ID_XCOFF32, // AIX XCOFF 32-bit
|
||||||
|
ID_XCOFF64, // AIX XCOFF 64-bit
|
||||||
|
|
||||||
|
ID_ELF32L, // ELF 32-bit, little endian
|
||||||
|
ID_ELF32B, // ELF 32-bit, big endian
|
||||||
|
ID_ELF64L, // ELF 64-bit, little endian
|
||||||
|
ID_ELF64B, // ELF 64-bit, big endian
|
||||||
|
|
||||||
|
ID_MachO32L, // MachO 32-bit, little endian
|
||||||
|
ID_MachO32B, // MachO 32-bit, big endian
|
||||||
|
ID_MachO64L, // MachO 64-bit, little endian
|
||||||
|
ID_MachO64B, // MachO 64-bit, big endian
|
||||||
|
|
||||||
|
ID_GOFF,
|
||||||
|
ID_Wasm,
|
||||||
|
|
||||||
|
ID_EndObjects
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline unsigned int getELFType(bool isLE, bool is64Bits) {
|
||||||
|
if (isLE)
|
||||||
|
return is64Bits ? ID_ELF64L : ID_ELF32L;
|
||||||
|
else
|
||||||
|
return is64Bits ? ID_ELF64B : ID_ELF32B;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int getMachOType(bool isLE, bool is64Bits) {
|
||||||
|
if (isLE)
|
||||||
|
return is64Bits ? ID_MachO64L : ID_MachO32L;
|
||||||
|
else
|
||||||
|
return is64Bits ? ID_MachO64B : ID_MachO32B;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Binary() = delete;
|
||||||
|
Binary(const Binary &other) = delete;
|
||||||
|
virtual ~Binary();
|
||||||
|
|
||||||
|
virtual Error initContent() { return Error::success(); };
|
||||||
|
|
||||||
|
StringRef getData() const;
|
||||||
|
StringRef getFileName() const;
|
||||||
|
MemoryBufferRef getMemoryBufferRef() const;
|
||||||
|
|
||||||
|
// Cast methods.
|
||||||
|
unsigned int getType() const { return TypeID; }
|
||||||
|
|
||||||
|
// Convenience methods
|
||||||
|
bool isObject() const {
|
||||||
|
return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSymbolic() const {
|
||||||
|
return isIR() || isObject() || isCOFFImportFile() || isTapiFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isArchive() const { return TypeID == ID_Archive; }
|
||||||
|
|
||||||
|
bool isMachOUniversalBinary() const {
|
||||||
|
return TypeID == ID_MachOUniversalBinary;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTapiUniversal() const { return TypeID == ID_TapiUniversal; }
|
||||||
|
|
||||||
|
bool isELF() const {
|
||||||
|
return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMachO() const {
|
||||||
|
return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isCOFF() const {
|
||||||
|
return TypeID == ID_COFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isXCOFF() const { return TypeID == ID_XCOFF32 || TypeID == ID_XCOFF64; }
|
||||||
|
|
||||||
|
bool isWasm() const { return TypeID == ID_Wasm; }
|
||||||
|
|
||||||
|
bool isOffloadFile() const { return TypeID == ID_Offload; }
|
||||||
|
|
||||||
|
bool isCOFFImportFile() const {
|
||||||
|
return TypeID == ID_COFFImportFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isIR() const {
|
||||||
|
return TypeID == ID_IR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isGOFF() const { return TypeID == ID_GOFF; }
|
||||||
|
|
||||||
|
bool isMinidump() const { return TypeID == ID_Minidump; }
|
||||||
|
|
||||||
|
bool isTapiFile() const { return TypeID == ID_TapiFile; }
|
||||||
|
|
||||||
|
bool isLittleEndian() const {
|
||||||
|
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
|
||||||
|
TypeID == ID_MachO32B || TypeID == ID_MachO64B ||
|
||||||
|
TypeID == ID_XCOFF32 || TypeID == ID_XCOFF64);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWinRes() const { return TypeID == ID_WinRes; }
|
||||||
|
|
||||||
|
Triple::ObjectFormatType getTripleObjectFormat() const {
|
||||||
|
if (isCOFF())
|
||||||
|
return Triple::COFF;
|
||||||
|
if (isMachO())
|
||||||
|
return Triple::MachO;
|
||||||
|
if (isELF())
|
||||||
|
return Triple::ELF;
|
||||||
|
if (isGOFF())
|
||||||
|
return Triple::GOFF;
|
||||||
|
return Triple::UnknownObjectFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,
|
||||||
|
const uint64_t Size) {
|
||||||
|
if (Addr + Size < Addr || Addr + Size < Size ||
|
||||||
|
Addr + Size > reinterpret_cast<uintptr_t>(M.getBufferEnd()) ||
|
||||||
|
Addr < reinterpret_cast<uintptr_t>(M.getBufferStart())) {
|
||||||
|
return errorCodeToError(object_error::unexpected_eof);
|
||||||
|
}
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||||
|
DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
|
||||||
|
|
||||||
|
/// Create a Binary from Source, autodetecting the file type.
|
||||||
|
///
|
||||||
|
/// @param Source The data to create the Binary from.
|
||||||
|
Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
|
||||||
|
LLVMContext *Context = nullptr,
|
||||||
|
bool InitContent = true);
|
||||||
|
|
||||||
|
template <typename T> class OwningBinary {
|
||||||
|
std::unique_ptr<T> Bin;
|
||||||
|
std::unique_ptr<MemoryBuffer> Buf;
|
||||||
|
|
||||||
|
public:
|
||||||
|
OwningBinary();
|
||||||
|
OwningBinary(std::unique_ptr<T> Bin, std::unique_ptr<MemoryBuffer> Buf);
|
||||||
|
OwningBinary(OwningBinary<T>&& Other);
|
||||||
|
OwningBinary<T> &operator=(OwningBinary<T> &&Other);
|
||||||
|
|
||||||
|
std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>> takeBinary();
|
||||||
|
|
||||||
|
T* getBinary();
|
||||||
|
const T* getBinary() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin,
|
||||||
|
std::unique_ptr<MemoryBuffer> Buf)
|
||||||
|
: Bin(std::move(Bin)), Buf(std::move(Buf)) {}
|
||||||
|
|
||||||
|
template <typename T> OwningBinary<T>::OwningBinary() = default;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
OwningBinary<T>::OwningBinary(OwningBinary &&Other)
|
||||||
|
: Bin(std::move(Other.Bin)), Buf(std::move(Other.Buf)) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
OwningBinary<T> &OwningBinary<T>::operator=(OwningBinary &&Other) {
|
||||||
|
Bin = std::move(Other.Bin);
|
||||||
|
Buf = std::move(Other.Buf);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>>
|
||||||
|
OwningBinary<T>::takeBinary() {
|
||||||
|
return std::make_pair(std::move(Bin), std::move(Buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> T* OwningBinary<T>::getBinary() {
|
||||||
|
return Bin.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> const T* OwningBinary<T>::getBinary() const {
|
||||||
|
return Bin.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Expected<OwningBinary<Binary>> createBinary(StringRef Path,
|
||||||
|
LLVMContext *Context = nullptr,
|
||||||
|
bool InitContent = true);
|
||||||
|
|
||||||
|
} // end namespace object
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_OBJECT_BINARY_H
|
||||||
1362
include/swift/RemoteInspection/RuntimeHeaders/llvm/Object/COFF.h
Normal file
1362
include/swift/RemoteInspection/RuntimeHeaders/llvm/Object/COFF.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
|||||||
|
//===- CVDebugRecord.h ------------------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_OBJECT_CVDEBUGRECORD_H
|
||||||
|
#define LLVM_OBJECT_CVDEBUGRECORD_H
|
||||||
|
|
||||||
|
#include "llvm/Support/Endian.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace OMF {
|
||||||
|
struct Signature {
|
||||||
|
enum ID : uint32_t {
|
||||||
|
PDB70 = 0x53445352, // RSDS
|
||||||
|
PDB20 = 0x3031424e, // NB10
|
||||||
|
CV50 = 0x3131424e, // NB11
|
||||||
|
CV41 = 0x3930424e, // NB09
|
||||||
|
};
|
||||||
|
|
||||||
|
support::ulittle32_t CVSignature;
|
||||||
|
support::ulittle32_t Offset;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace codeview {
|
||||||
|
struct PDB70DebugInfo {
|
||||||
|
support::ulittle32_t CVSignature;
|
||||||
|
uint8_t Signature[16];
|
||||||
|
support::ulittle32_t Age;
|
||||||
|
// char PDBFileName[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PDB20DebugInfo {
|
||||||
|
support::ulittle32_t CVSignature;
|
||||||
|
support::ulittle32_t Offset;
|
||||||
|
support::ulittle32_t Signature;
|
||||||
|
support::ulittle32_t Age;
|
||||||
|
// char PDBFileName[];
|
||||||
|
};
|
||||||
|
|
||||||
|
union DebugInfo {
|
||||||
|
struct OMF::Signature Signature;
|
||||||
|
struct PDB20DebugInfo PDB20;
|
||||||
|
struct PDB70DebugInfo PDB70;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
//===- Error.h - system_error extensions for Object -------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This declares a new error_category for the Object library.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_OBJECT_ERROR_H
|
||||||
|
#define LLVM_OBJECT_ERROR_H
|
||||||
|
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class Twine;
|
||||||
|
|
||||||
|
namespace object {
|
||||||
|
|
||||||
|
const std::error_category &object_category();
|
||||||
|
|
||||||
|
enum class object_error {
|
||||||
|
// Error code 0 is absent. Use std::error_code() instead.
|
||||||
|
arch_not_found = 1,
|
||||||
|
invalid_file_type,
|
||||||
|
parse_failed,
|
||||||
|
unexpected_eof,
|
||||||
|
string_table_non_null_end,
|
||||||
|
invalid_section_index,
|
||||||
|
bitcode_section_not_found,
|
||||||
|
invalid_symbol_index,
|
||||||
|
section_stripped,
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::error_code make_error_code(object_error e) {
|
||||||
|
return std::error_code(static_cast<int>(e), object_category());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Base class for all errors indicating malformed binary files.
|
||||||
|
///
|
||||||
|
/// Having a subclass for all malformed binary files allows archive-walking
|
||||||
|
/// code to skip malformed files without having to understand every possible
|
||||||
|
/// way that a binary file might be malformed.
|
||||||
|
///
|
||||||
|
/// Currently inherits from ECError for easy interoperability with
|
||||||
|
/// std::error_code, but this will be removed in the future.
|
||||||
|
class BinaryError : public ErrorInfo<BinaryError, ECError> {
|
||||||
|
void anchor() override;
|
||||||
|
public:
|
||||||
|
static char ID;
|
||||||
|
BinaryError() {
|
||||||
|
// Default to parse_failed, can be overridden with setErrorCode.
|
||||||
|
setErrorCode(make_error_code(object_error::parse_failed));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Generic binary error.
|
||||||
|
///
|
||||||
|
/// For errors that don't require their own specific sub-error (most errors)
|
||||||
|
/// this class can be used to describe the error via a string message.
|
||||||
|
class GenericBinaryError : public ErrorInfo<GenericBinaryError, BinaryError> {
|
||||||
|
public:
|
||||||
|
static char ID;
|
||||||
|
GenericBinaryError(const Twine &Msg);
|
||||||
|
GenericBinaryError(const Twine &Msg, object_error ECOverride);
|
||||||
|
const std::string &getMessage() const { return Msg; }
|
||||||
|
void log(raw_ostream &OS) const override;
|
||||||
|
private:
|
||||||
|
std::string Msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// isNotObjectErrorInvalidFileType() is used when looping through the children
|
||||||
|
/// of an archive after calling getAsBinary() on the child and it returns an
|
||||||
|
/// llvm::Error. In the cases we want to loop through the children and ignore the
|
||||||
|
/// non-objects in the archive this is used to test the error to see if an
|
||||||
|
/// error() function needs to called on the llvm::Error.
|
||||||
|
Error isNotObjectErrorInvalidFileType(llvm::Error Err);
|
||||||
|
|
||||||
|
inline Error createError(const Twine &Err) {
|
||||||
|
return make_error<StringError>(Err, object_error::parse_failed);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace object.
|
||||||
|
|
||||||
|
} // end namespace llvm.
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <>
|
||||||
|
struct is_error_code_enum<llvm::object::object_error> : std::true_type {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,665 @@
|
|||||||
|
//===- ObjectFile.h - File format independent object file -------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file declares a file format independent ObjectFile class.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_OBJECT_OBJECTFILE_H
|
||||||
|
#define LLVM_OBJECT_OBJECTFILE_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/Hashing.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/ADT/iterator_range.h"
|
||||||
|
#include "llvm/BinaryFormat/Magic.h"
|
||||||
|
#include "llvm/BinaryFormat/Swift.h"
|
||||||
|
#include "llvm/Object/Binary.h"
|
||||||
|
#include "llvm/Object/Error.h"
|
||||||
|
#include "llvm/Object/SymbolicFile.h"
|
||||||
|
#include "llvm/Support/Casting.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
#include "llvm/Support/MemoryBufferRef.h"
|
||||||
|
#include "llvm/TargetParser/Triple.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class SubtargetFeatures;
|
||||||
|
|
||||||
|
namespace object {
|
||||||
|
|
||||||
|
class COFFObjectFile;
|
||||||
|
class MachOObjectFile;
|
||||||
|
class ObjectFile;
|
||||||
|
class SectionRef;
|
||||||
|
class SymbolRef;
|
||||||
|
class symbol_iterator;
|
||||||
|
class WasmObjectFile;
|
||||||
|
|
||||||
|
using section_iterator = content_iterator<SectionRef>;
|
||||||
|
|
||||||
|
typedef std::function<bool(const SectionRef &)> SectionFilterPredicate;
|
||||||
|
/// This is a value type class that represents a single relocation in the list
|
||||||
|
/// of relocations in the object file.
|
||||||
|
class RelocationRef {
|
||||||
|
DataRefImpl RelocationPimpl;
|
||||||
|
const ObjectFile *OwningObject = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RelocationRef() = default;
|
||||||
|
RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
|
||||||
|
|
||||||
|
bool operator==(const RelocationRef &Other) const;
|
||||||
|
|
||||||
|
void moveNext();
|
||||||
|
|
||||||
|
uint64_t getOffset() const;
|
||||||
|
symbol_iterator getSymbol() const;
|
||||||
|
uint64_t getType() const;
|
||||||
|
|
||||||
|
/// Get a string that represents the type of this relocation.
|
||||||
|
///
|
||||||
|
/// This is for display purposes only.
|
||||||
|
void getTypeName(SmallVectorImpl<char> &Result) const;
|
||||||
|
|
||||||
|
DataRefImpl getRawDataRefImpl() const;
|
||||||
|
const ObjectFile *getObject() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
using relocation_iterator = content_iterator<RelocationRef>;
|
||||||
|
|
||||||
|
/// This is a value type class that represents a single section in the list of
|
||||||
|
/// sections in the object file.
|
||||||
|
class SectionRef {
|
||||||
|
friend class SymbolRef;
|
||||||
|
|
||||||
|
DataRefImpl SectionPimpl;
|
||||||
|
const ObjectFile *OwningObject = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SectionRef() = default;
|
||||||
|
SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
|
||||||
|
|
||||||
|
bool operator==(const SectionRef &Other) const;
|
||||||
|
bool operator!=(const SectionRef &Other) const;
|
||||||
|
bool operator<(const SectionRef &Other) const;
|
||||||
|
|
||||||
|
void moveNext();
|
||||||
|
|
||||||
|
Expected<StringRef> getName() const;
|
||||||
|
uint64_t getAddress() const;
|
||||||
|
uint64_t getIndex() const;
|
||||||
|
uint64_t getSize() const;
|
||||||
|
Expected<StringRef> getContents() const;
|
||||||
|
|
||||||
|
/// Get the alignment of this section.
|
||||||
|
Align getAlignment() const;
|
||||||
|
|
||||||
|
bool isCompressed() const;
|
||||||
|
/// Whether this section contains instructions.
|
||||||
|
bool isText() const;
|
||||||
|
/// Whether this section contains data, not instructions.
|
||||||
|
bool isData() const;
|
||||||
|
/// Whether this section contains BSS uninitialized data.
|
||||||
|
bool isBSS() const;
|
||||||
|
bool isVirtual() const;
|
||||||
|
bool isBitcode() const;
|
||||||
|
bool isStripped() const;
|
||||||
|
|
||||||
|
/// Whether this section will be placed in the text segment, according to the
|
||||||
|
/// Berkeley size format. This is true if the section is allocatable, and
|
||||||
|
/// contains either code or readonly data.
|
||||||
|
bool isBerkeleyText() const;
|
||||||
|
/// Whether this section will be placed in the data segment, according to the
|
||||||
|
/// Berkeley size format. This is true if the section is allocatable and
|
||||||
|
/// contains data (e.g. PROGBITS), but is not text.
|
||||||
|
bool isBerkeleyData() const;
|
||||||
|
|
||||||
|
/// Whether this section is a debug section.
|
||||||
|
bool isDebugSection() const;
|
||||||
|
|
||||||
|
bool containsSymbol(SymbolRef S) const;
|
||||||
|
|
||||||
|
relocation_iterator relocation_begin() const;
|
||||||
|
relocation_iterator relocation_end() const;
|
||||||
|
iterator_range<relocation_iterator> relocations() const {
|
||||||
|
return make_range(relocation_begin(), relocation_end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the related section if this section contains relocations. The
|
||||||
|
/// returned section may or may not have applied its relocations.
|
||||||
|
Expected<section_iterator> getRelocatedSection() const;
|
||||||
|
|
||||||
|
DataRefImpl getRawDataRefImpl() const;
|
||||||
|
const ObjectFile *getObject() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SectionedAddress {
|
||||||
|
const static uint64_t UndefSection = UINT64_MAX;
|
||||||
|
|
||||||
|
uint64_t Address = 0;
|
||||||
|
uint64_t SectionIndex = UndefSection;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator<(const SectionedAddress &LHS,
|
||||||
|
const SectionedAddress &RHS) {
|
||||||
|
return std::tie(LHS.SectionIndex, LHS.Address) <
|
||||||
|
std::tie(RHS.SectionIndex, RHS.Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const SectionedAddress &LHS,
|
||||||
|
const SectionedAddress &RHS) {
|
||||||
|
return std::tie(LHS.SectionIndex, LHS.Address) ==
|
||||||
|
std::tie(RHS.SectionIndex, RHS.Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_ostream &operator<<(raw_ostream &OS, const SectionedAddress &Addr);
|
||||||
|
|
||||||
|
/// This is a value type class that represents a single symbol in the list of
|
||||||
|
/// symbols in the object file.
|
||||||
|
class SymbolRef : public BasicSymbolRef {
|
||||||
|
friend class SectionRef;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
ST_Unknown, // Type not specified
|
||||||
|
ST_Other,
|
||||||
|
ST_Data,
|
||||||
|
ST_Debug,
|
||||||
|
ST_File,
|
||||||
|
ST_Function,
|
||||||
|
};
|
||||||
|
|
||||||
|
SymbolRef() = default;
|
||||||
|
SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
|
||||||
|
SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
|
||||||
|
assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Expected<StringRef> getName() const;
|
||||||
|
/// Returns the symbol virtual address (i.e. address at which it will be
|
||||||
|
/// mapped).
|
||||||
|
Expected<uint64_t> getAddress() const;
|
||||||
|
|
||||||
|
/// Return the value of the symbol depending on the object this can be an
|
||||||
|
/// offset or a virtual address.
|
||||||
|
Expected<uint64_t> getValue() const;
|
||||||
|
|
||||||
|
/// Get the alignment of this symbol as the actual value (not log 2).
|
||||||
|
uint32_t getAlignment() const;
|
||||||
|
uint64_t getCommonSize() const;
|
||||||
|
Expected<SymbolRef::Type> getType() const;
|
||||||
|
|
||||||
|
/// Get section this symbol is defined in reference to. Result is
|
||||||
|
/// end_sections() if it is undefined or is an absolute symbol.
|
||||||
|
Expected<section_iterator> getSection() const;
|
||||||
|
|
||||||
|
const ObjectFile *getObject() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class symbol_iterator : public basic_symbol_iterator {
|
||||||
|
public:
|
||||||
|
symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
|
||||||
|
symbol_iterator(const basic_symbol_iterator &B)
|
||||||
|
: basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
|
||||||
|
cast<ObjectFile>(B->getObject()))) {}
|
||||||
|
|
||||||
|
const SymbolRef *operator->() const {
|
||||||
|
const BasicSymbolRef &P = basic_symbol_iterator::operator *();
|
||||||
|
return static_cast<const SymbolRef*>(&P);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SymbolRef &operator*() const {
|
||||||
|
const BasicSymbolRef &P = basic_symbol_iterator::operator *();
|
||||||
|
return static_cast<const SymbolRef&>(P);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// This class is the base class for all object file types. Concrete instances
|
||||||
|
/// of this object are created by createObjectFile, which figures out which type
|
||||||
|
/// to create.
|
||||||
|
class ObjectFile : public SymbolicFile {
|
||||||
|
virtual void anchor();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ObjectFile(unsigned int Type, MemoryBufferRef Source);
|
||||||
|
|
||||||
|
const uint8_t *base() const {
|
||||||
|
return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
// These functions are for SymbolRef to call internally. The main goal of
|
||||||
|
// this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
|
||||||
|
// entry in the memory mapped object file. SymbolPimpl cannot contain any
|
||||||
|
// virtual functions because then it could not point into the memory mapped
|
||||||
|
// file.
|
||||||
|
//
|
||||||
|
// Implementations assume that the DataRefImpl is valid and has not been
|
||||||
|
// modified externally. It's UB otherwise.
|
||||||
|
friend class SymbolRef;
|
||||||
|
|
||||||
|
virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
|
||||||
|
Error printSymbolName(raw_ostream &OS,
|
||||||
|
DataRefImpl Symb) const override;
|
||||||
|
virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
|
||||||
|
virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
|
||||||
|
virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
|
||||||
|
virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
|
||||||
|
virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
|
||||||
|
virtual Expected<section_iterator>
|
||||||
|
getSymbolSection(DataRefImpl Symb) const = 0;
|
||||||
|
|
||||||
|
// Same as above for SectionRef.
|
||||||
|
friend class SectionRef;
|
||||||
|
|
||||||
|
virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
|
||||||
|
virtual Expected<StringRef> getSectionName(DataRefImpl Sec) const = 0;
|
||||||
|
virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
|
||||||
|
virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
|
||||||
|
virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
|
||||||
|
virtual Expected<ArrayRef<uint8_t>>
|
||||||
|
getSectionContents(DataRefImpl Sec) const = 0;
|
||||||
|
virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
|
||||||
|
virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
|
||||||
|
virtual bool isSectionText(DataRefImpl Sec) const = 0;
|
||||||
|
virtual bool isSectionData(DataRefImpl Sec) const = 0;
|
||||||
|
virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
|
||||||
|
// A section is 'virtual' if its contents aren't present in the object image.
|
||||||
|
virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
|
||||||
|
virtual bool isSectionBitcode(DataRefImpl Sec) const;
|
||||||
|
virtual bool isSectionStripped(DataRefImpl Sec) const;
|
||||||
|
virtual bool isBerkeleyText(DataRefImpl Sec) const;
|
||||||
|
virtual bool isBerkeleyData(DataRefImpl Sec) const;
|
||||||
|
virtual bool isDebugSection(DataRefImpl Sec) const;
|
||||||
|
virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
|
||||||
|
virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
|
||||||
|
virtual Expected<section_iterator> getRelocatedSection(DataRefImpl Sec) const;
|
||||||
|
|
||||||
|
// Same as above for RelocationRef.
|
||||||
|
friend class RelocationRef;
|
||||||
|
virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
|
||||||
|
virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
|
||||||
|
virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
|
||||||
|
virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
|
||||||
|
virtual void getRelocationTypeName(DataRefImpl Rel,
|
||||||
|
SmallVectorImpl<char> &Result) const = 0;
|
||||||
|
|
||||||
|
virtual llvm::binaryformat::Swift5ReflectionSectionKind
|
||||||
|
mapReflectionSectionNameToEnumValue(StringRef SectionName) const {
|
||||||
|
return llvm::binaryformat::Swift5ReflectionSectionKind::unknown;
|
||||||
|
};
|
||||||
|
|
||||||
|
Expected<uint64_t> getSymbolValue(DataRefImpl Symb) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ObjectFile() = delete;
|
||||||
|
ObjectFile(const ObjectFile &other) = delete;
|
||||||
|
|
||||||
|
uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
|
||||||
|
Expected<uint32_t> SymbolFlagsOrErr = getSymbolFlags(Symb);
|
||||||
|
if (!SymbolFlagsOrErr)
|
||||||
|
// TODO: Actually report errors helpfully.
|
||||||
|
report_fatal_error(SymbolFlagsOrErr.takeError());
|
||||||
|
assert(*SymbolFlagsOrErr & SymbolRef::SF_Common);
|
||||||
|
return getCommonSymbolSizeImpl(Symb);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::vector<SectionRef> dynamic_relocation_sections() const {
|
||||||
|
return std::vector<SectionRef>();
|
||||||
|
}
|
||||||
|
|
||||||
|
using symbol_iterator_range = iterator_range<symbol_iterator>;
|
||||||
|
symbol_iterator_range symbols() const {
|
||||||
|
return symbol_iterator_range(symbol_begin(), symbol_end());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual section_iterator section_begin() const = 0;
|
||||||
|
virtual section_iterator section_end() const = 0;
|
||||||
|
|
||||||
|
using section_iterator_range = iterator_range<section_iterator>;
|
||||||
|
section_iterator_range sections() const {
|
||||||
|
return section_iterator_range(section_begin(), section_end());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool hasDebugInfo() const;
|
||||||
|
|
||||||
|
/// The number of bytes used to represent an address in this object
|
||||||
|
/// file format.
|
||||||
|
virtual uint8_t getBytesInAddress() const = 0;
|
||||||
|
|
||||||
|
virtual StringRef getFileFormatName() const = 0;
|
||||||
|
virtual Triple::ArchType getArch() const = 0;
|
||||||
|
virtual Expected<SubtargetFeatures> getFeatures() const = 0;
|
||||||
|
virtual std::optional<StringRef> tryGetCPUName() const {
|
||||||
|
return std::nullopt;
|
||||||
|
};
|
||||||
|
virtual void setARMSubArch(Triple &TheTriple) const { }
|
||||||
|
virtual Expected<uint64_t> getStartAddress() const {
|
||||||
|
return errorCodeToError(object_error::parse_failed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Create a triple from the data in this object file.
|
||||||
|
Triple makeTriple() const;
|
||||||
|
|
||||||
|
/// Maps a debug section name to a standard DWARF section name.
|
||||||
|
virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
|
||||||
|
|
||||||
|
/// True if this is a relocatable object (.o/.obj).
|
||||||
|
virtual bool isRelocatableObject() const = 0;
|
||||||
|
|
||||||
|
/// True if the reflection section can be stripped by the linker.
|
||||||
|
bool isReflectionSectionStrippable(
|
||||||
|
llvm::binaryformat::Swift5ReflectionSectionKind ReflectionSectionKind)
|
||||||
|
const;
|
||||||
|
|
||||||
|
/// @returns Pointer to ObjectFile subclass to handle this type of object.
|
||||||
|
/// @param ObjectPath The path to the object file. ObjectPath.isObject must
|
||||||
|
/// return true.
|
||||||
|
/// Create ObjectFile from path.
|
||||||
|
static Expected<OwningBinary<ObjectFile>>
|
||||||
|
createObjectFile(StringRef ObjectPath);
|
||||||
|
|
||||||
|
static Expected<std::unique_ptr<ObjectFile>>
|
||||||
|
createObjectFile(MemoryBufferRef Object, llvm::file_magic Type,
|
||||||
|
bool InitContent = true);
|
||||||
|
static Expected<std::unique_ptr<ObjectFile>>
|
||||||
|
createObjectFile(MemoryBufferRef Object) {
|
||||||
|
return createObjectFile(Object, llvm::file_magic::unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool classof(const Binary *v) {
|
||||||
|
return v->isObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Expected<std::unique_ptr<COFFObjectFile>>
|
||||||
|
createCOFFObjectFile(MemoryBufferRef Object);
|
||||||
|
|
||||||
|
static Expected<std::unique_ptr<ObjectFile>>
|
||||||
|
createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
|
||||||
|
|
||||||
|
static Expected<std::unique_ptr<ObjectFile>>
|
||||||
|
createELFObjectFile(MemoryBufferRef Object, bool InitContent = true);
|
||||||
|
|
||||||
|
static Expected<std::unique_ptr<MachOObjectFile>>
|
||||||
|
createMachOObjectFile(MemoryBufferRef Object,
|
||||||
|
uint32_t UniversalCputype = 0,
|
||||||
|
uint32_t UniversalIndex = 0);
|
||||||
|
|
||||||
|
static Expected<std::unique_ptr<ObjectFile>>
|
||||||
|
createGOFFObjectFile(MemoryBufferRef Object);
|
||||||
|
|
||||||
|
static Expected<std::unique_ptr<WasmObjectFile>>
|
||||||
|
createWasmObjectFile(MemoryBufferRef Object);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A filtered iterator for SectionRefs that skips sections based on some given
|
||||||
|
/// predicate.
|
||||||
|
class SectionFilterIterator {
|
||||||
|
public:
|
||||||
|
SectionFilterIterator(SectionFilterPredicate Pred,
|
||||||
|
const section_iterator &Begin,
|
||||||
|
const section_iterator &End)
|
||||||
|
: Predicate(std::move(Pred)), Iterator(Begin), End(End) {
|
||||||
|
scanPredicate();
|
||||||
|
}
|
||||||
|
const SectionRef &operator*() const { return *Iterator; }
|
||||||
|
SectionFilterIterator &operator++() {
|
||||||
|
++Iterator;
|
||||||
|
scanPredicate();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool operator!=(const SectionFilterIterator &Other) const {
|
||||||
|
return Iterator != Other.Iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void scanPredicate() {
|
||||||
|
while (Iterator != End && !Predicate(*Iterator)) {
|
||||||
|
++Iterator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionFilterPredicate Predicate;
|
||||||
|
section_iterator Iterator;
|
||||||
|
section_iterator End;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Creates an iterator range of SectionFilterIterators for a given Object and
|
||||||
|
/// predicate.
|
||||||
|
class SectionFilter {
|
||||||
|
public:
|
||||||
|
SectionFilter(SectionFilterPredicate Pred, const ObjectFile &Obj)
|
||||||
|
: Predicate(std::move(Pred)), Object(Obj) {}
|
||||||
|
SectionFilterIterator begin() {
|
||||||
|
return SectionFilterIterator(Predicate, Object.section_begin(),
|
||||||
|
Object.section_end());
|
||||||
|
}
|
||||||
|
SectionFilterIterator end() {
|
||||||
|
return SectionFilterIterator(Predicate, Object.section_end(),
|
||||||
|
Object.section_end());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SectionFilterPredicate Predicate;
|
||||||
|
const ObjectFile &Object;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Inline function definitions.
|
||||||
|
inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
|
||||||
|
: BasicSymbolRef(SymbolP, Owner) {}
|
||||||
|
|
||||||
|
inline Expected<StringRef> SymbolRef::getName() const {
|
||||||
|
return getObject()->getSymbolName(getRawDataRefImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Expected<uint64_t> SymbolRef::getAddress() const {
|
||||||
|
return getObject()->getSymbolAddress(getRawDataRefImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Expected<uint64_t> SymbolRef::getValue() const {
|
||||||
|
return getObject()->getSymbolValue(getRawDataRefImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t SymbolRef::getAlignment() const {
|
||||||
|
return getObject()->getSymbolAlignment(getRawDataRefImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64_t SymbolRef::getCommonSize() const {
|
||||||
|
return getObject()->getCommonSymbolSize(getRawDataRefImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Expected<section_iterator> SymbolRef::getSection() const {
|
||||||
|
return getObject()->getSymbolSection(getRawDataRefImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Expected<SymbolRef::Type> SymbolRef::getType() const {
|
||||||
|
return getObject()->getSymbolType(getRawDataRefImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ObjectFile *SymbolRef::getObject() const {
|
||||||
|
const SymbolicFile *O = BasicSymbolRef::getObject();
|
||||||
|
return cast<ObjectFile>(O);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// SectionRef
|
||||||
|
inline SectionRef::SectionRef(DataRefImpl SectionP,
|
||||||
|
const ObjectFile *Owner)
|
||||||
|
: SectionPimpl(SectionP)
|
||||||
|
, OwningObject(Owner) {}
|
||||||
|
|
||||||
|
inline bool SectionRef::operator==(const SectionRef &Other) const {
|
||||||
|
return OwningObject == Other.OwningObject &&
|
||||||
|
SectionPimpl == Other.SectionPimpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::operator!=(const SectionRef &Other) const {
|
||||||
|
return !(*this == Other);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::operator<(const SectionRef &Other) const {
|
||||||
|
assert(OwningObject == Other.OwningObject);
|
||||||
|
return SectionPimpl < Other.SectionPimpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SectionRef::moveNext() {
|
||||||
|
return OwningObject->moveSectionNext(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Expected<StringRef> SectionRef::getName() const {
|
||||||
|
return OwningObject->getSectionName(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64_t SectionRef::getAddress() const {
|
||||||
|
return OwningObject->getSectionAddress(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64_t SectionRef::getIndex() const {
|
||||||
|
return OwningObject->getSectionIndex(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64_t SectionRef::getSize() const {
|
||||||
|
return OwningObject->getSectionSize(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Expected<StringRef> SectionRef::getContents() const {
|
||||||
|
Expected<ArrayRef<uint8_t>> Res =
|
||||||
|
OwningObject->getSectionContents(SectionPimpl);
|
||||||
|
if (!Res)
|
||||||
|
return Res.takeError();
|
||||||
|
return StringRef(reinterpret_cast<const char *>(Res->data()), Res->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Align SectionRef::getAlignment() const {
|
||||||
|
return MaybeAlign(OwningObject->getSectionAlignment(SectionPimpl))
|
||||||
|
.valueOrOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::isCompressed() const {
|
||||||
|
return OwningObject->isSectionCompressed(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::isText() const {
|
||||||
|
return OwningObject->isSectionText(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::isData() const {
|
||||||
|
return OwningObject->isSectionData(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::isBSS() const {
|
||||||
|
return OwningObject->isSectionBSS(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::isVirtual() const {
|
||||||
|
return OwningObject->isSectionVirtual(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::isBitcode() const {
|
||||||
|
return OwningObject->isSectionBitcode(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::isStripped() const {
|
||||||
|
return OwningObject->isSectionStripped(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::isBerkeleyText() const {
|
||||||
|
return OwningObject->isBerkeleyText(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::isBerkeleyData() const {
|
||||||
|
return OwningObject->isBerkeleyData(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SectionRef::isDebugSection() const {
|
||||||
|
return OwningObject->isDebugSection(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline relocation_iterator SectionRef::relocation_begin() const {
|
||||||
|
return OwningObject->section_rel_begin(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline relocation_iterator SectionRef::relocation_end() const {
|
||||||
|
return OwningObject->section_rel_end(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Expected<section_iterator> SectionRef::getRelocatedSection() const {
|
||||||
|
return OwningObject->getRelocatedSection(SectionPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline DataRefImpl SectionRef::getRawDataRefImpl() const {
|
||||||
|
return SectionPimpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ObjectFile *SectionRef::getObject() const {
|
||||||
|
return OwningObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// RelocationRef
|
||||||
|
inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
|
||||||
|
const ObjectFile *Owner)
|
||||||
|
: RelocationPimpl(RelocationP)
|
||||||
|
, OwningObject(Owner) {}
|
||||||
|
|
||||||
|
inline bool RelocationRef::operator==(const RelocationRef &Other) const {
|
||||||
|
return RelocationPimpl == Other.RelocationPimpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RelocationRef::moveNext() {
|
||||||
|
return OwningObject->moveRelocationNext(RelocationPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64_t RelocationRef::getOffset() const {
|
||||||
|
return OwningObject->getRelocationOffset(RelocationPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline symbol_iterator RelocationRef::getSymbol() const {
|
||||||
|
return OwningObject->getRelocationSymbol(RelocationPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64_t RelocationRef::getType() const {
|
||||||
|
return OwningObject->getRelocationType(RelocationPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
|
||||||
|
return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
|
||||||
|
return RelocationPimpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ObjectFile *RelocationRef::getObject() const {
|
||||||
|
return OwningObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace object
|
||||||
|
|
||||||
|
template <> struct DenseMapInfo<object::SectionRef> {
|
||||||
|
static bool isEqual(const object::SectionRef &A,
|
||||||
|
const object::SectionRef &B) {
|
||||||
|
return A == B;
|
||||||
|
}
|
||||||
|
static object::SectionRef getEmptyKey() {
|
||||||
|
return object::SectionRef({}, nullptr);
|
||||||
|
}
|
||||||
|
static object::SectionRef getTombstoneKey() {
|
||||||
|
object::DataRefImpl TS;
|
||||||
|
TS.p = (uintptr_t)-1;
|
||||||
|
return object::SectionRef(TS, nullptr);
|
||||||
|
}
|
||||||
|
static unsigned getHashValue(const object::SectionRef &Sec) {
|
||||||
|
object::DataRefImpl Raw = Sec.getRawDataRefImpl();
|
||||||
|
return hash_combine(Raw.p, Raw.d.a, Raw.d.b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_OBJECT_OBJECTFILE_H
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
//===- SymbolicFile.h - Interface that only provides symbols ----*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file declares the SymbolicFile interface.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_OBJECT_SYMBOLICFILE_H
|
||||||
|
#define LLVM_OBJECT_SYMBOLICFILE_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/iterator_range.h"
|
||||||
|
#include "llvm/BinaryFormat/Magic.h"
|
||||||
|
#include "llvm/Object/Binary.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
#include "llvm/Support/Format.h"
|
||||||
|
#include "llvm/Support/MemoryBufferRef.h"
|
||||||
|
#include <cinttypes>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class LLVMContext;
|
||||||
|
class raw_ostream;
|
||||||
|
|
||||||
|
namespace object {
|
||||||
|
|
||||||
|
union DataRefImpl {
|
||||||
|
// This entire union should probably be a
|
||||||
|
// char[max(8, sizeof(uintptr_t))] and require the impl to cast.
|
||||||
|
struct {
|
||||||
|
uint32_t a, b;
|
||||||
|
} d;
|
||||||
|
uintptr_t p;
|
||||||
|
|
||||||
|
DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename OStream>
|
||||||
|
OStream& operator<<(OStream &OS, const DataRefImpl &D) {
|
||||||
|
OS << "(" << format("0x%08" PRIxPTR, D.p) << " (" << format("0x%08x", D.d.a)
|
||||||
|
<< ", " << format("0x%08x", D.d.b) << "))";
|
||||||
|
return OS;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
|
||||||
|
// Check bitwise identical. This is the only legal way to compare a union w/o
|
||||||
|
// knowing which member is in use.
|
||||||
|
return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
|
||||||
|
return !operator==(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
|
||||||
|
// Check bitwise identical. This is the only legal way to compare a union w/o
|
||||||
|
// knowing which member is in use.
|
||||||
|
return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class content_type> class content_iterator {
|
||||||
|
content_type Current;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
using value_type = content_type;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = value_type *;
|
||||||
|
using reference = value_type &;
|
||||||
|
|
||||||
|
content_iterator(content_type symb) : Current(std::move(symb)) {}
|
||||||
|
|
||||||
|
const content_type *operator->() const { return &Current; }
|
||||||
|
|
||||||
|
const content_type &operator*() const { return Current; }
|
||||||
|
|
||||||
|
bool operator==(const content_iterator &other) const {
|
||||||
|
return Current == other.Current;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const content_iterator &other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
content_iterator &operator++() { // preincrement
|
||||||
|
Current.moveNext();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SymbolicFile;
|
||||||
|
|
||||||
|
/// This is a value type class that represents a single symbol in the list of
|
||||||
|
/// symbols in the object file.
|
||||||
|
class BasicSymbolRef {
|
||||||
|
DataRefImpl SymbolPimpl;
|
||||||
|
const SymbolicFile *OwningObject = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Flags : unsigned {
|
||||||
|
SF_None = 0,
|
||||||
|
SF_Undefined = 1U << 0, // Symbol is defined in another object file
|
||||||
|
SF_Global = 1U << 1, // Global symbol
|
||||||
|
SF_Weak = 1U << 2, // Weak symbol
|
||||||
|
SF_Absolute = 1U << 3, // Absolute symbol
|
||||||
|
SF_Common = 1U << 4, // Symbol has common linkage
|
||||||
|
SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
|
||||||
|
SF_Exported = 1U << 6, // Symbol is visible to other DSOs
|
||||||
|
SF_FormatSpecific = 1U << 7, // Specific to the object file format
|
||||||
|
// (e.g. section symbols)
|
||||||
|
SF_Thumb = 1U << 8, // Thumb symbol in a 32-bit ARM binary
|
||||||
|
SF_Hidden = 1U << 9, // Symbol has hidden visibility
|
||||||
|
SF_Const = 1U << 10, // Symbol value is constant
|
||||||
|
SF_Executable = 1U << 11, // Symbol points to an executable section
|
||||||
|
// (IR only)
|
||||||
|
};
|
||||||
|
|
||||||
|
BasicSymbolRef() = default;
|
||||||
|
BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
|
||||||
|
|
||||||
|
bool operator==(const BasicSymbolRef &Other) const;
|
||||||
|
bool operator<(const BasicSymbolRef &Other) const;
|
||||||
|
|
||||||
|
void moveNext();
|
||||||
|
|
||||||
|
Error printName(raw_ostream &OS) const;
|
||||||
|
|
||||||
|
/// Get symbol flags (bitwise OR of SymbolRef::Flags)
|
||||||
|
Expected<uint32_t> getFlags() const;
|
||||||
|
|
||||||
|
DataRefImpl getRawDataRefImpl() const;
|
||||||
|
const SymbolicFile *getObject() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
using basic_symbol_iterator = content_iterator<BasicSymbolRef>;
|
||||||
|
|
||||||
|
class SymbolicFile : public Binary {
|
||||||
|
public:
|
||||||
|
SymbolicFile(unsigned int Type, MemoryBufferRef Source);
|
||||||
|
~SymbolicFile() override;
|
||||||
|
|
||||||
|
// virtual interface.
|
||||||
|
virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
|
||||||
|
|
||||||
|
virtual Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const = 0;
|
||||||
|
|
||||||
|
virtual Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const = 0;
|
||||||
|
|
||||||
|
virtual basic_symbol_iterator symbol_begin() const = 0;
|
||||||
|
|
||||||
|
virtual basic_symbol_iterator symbol_end() const = 0;
|
||||||
|
|
||||||
|
virtual bool is64Bit() const = 0;
|
||||||
|
|
||||||
|
// convenience wrappers.
|
||||||
|
using basic_symbol_iterator_range = iterator_range<basic_symbol_iterator>;
|
||||||
|
basic_symbol_iterator_range symbols() const {
|
||||||
|
return basic_symbol_iterator_range(symbol_begin(), symbol_end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// construction aux.
|
||||||
|
static Expected<std::unique_ptr<SymbolicFile>>
|
||||||
|
createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
|
||||||
|
LLVMContext *Context, bool InitContent = true);
|
||||||
|
|
||||||
|
static Expected<std::unique_ptr<SymbolicFile>>
|
||||||
|
createSymbolicFile(MemoryBufferRef Object) {
|
||||||
|
return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool classof(const Binary *v) {
|
||||||
|
return v->isSymbolic();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSymbolicFile(file_magic Type, const LLVMContext *Context);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
|
||||||
|
const SymbolicFile *Owner)
|
||||||
|
: SymbolPimpl(SymbolP), OwningObject(Owner) {}
|
||||||
|
|
||||||
|
inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
|
||||||
|
return SymbolPimpl == Other.SymbolPimpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
|
||||||
|
return SymbolPimpl < Other.SymbolPimpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void BasicSymbolRef::moveNext() {
|
||||||
|
return OwningObject->moveSymbolNext(SymbolPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Error BasicSymbolRef::printName(raw_ostream &OS) const {
|
||||||
|
return OwningObject->printSymbolName(OS, SymbolPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Expected<uint32_t> BasicSymbolRef::getFlags() const {
|
||||||
|
return OwningObject->getSymbolFlags(SymbolPimpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
|
||||||
|
return SymbolPimpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const SymbolicFile *BasicSymbolRef::getObject() const {
|
||||||
|
return OwningObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace object
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_OBJECT_SYMBOLICFILE_H
|
||||||
@@ -0,0 +1,270 @@
|
|||||||
|
//===- BinaryByteStream.h ---------------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// A BinaryStream which stores data in a single continguous memory buffer.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_BINARYBYTESTREAM_H
|
||||||
|
#define LLVM_SUPPORT_BINARYBYTESTREAM_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/BinaryStream.h"
|
||||||
|
#include "llvm/Support/BinaryStreamError.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
#include "llvm/Support/FileOutputBuffer.h"
|
||||||
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
/// An implementation of BinaryStream which holds its entire data set
|
||||||
|
/// in a single contiguous buffer. BinaryByteStream guarantees that no read
|
||||||
|
/// operation will ever incur a copy. Note that BinaryByteStream does not
|
||||||
|
/// own the underlying buffer.
|
||||||
|
class BinaryByteStream : public BinaryStream {
|
||||||
|
public:
|
||||||
|
BinaryByteStream() = default;
|
||||||
|
BinaryByteStream(ArrayRef<uint8_t> Data, llvm::support::endianness Endian)
|
||||||
|
: Endian(Endian), Data(Data) {}
|
||||||
|
BinaryByteStream(StringRef Data, llvm::support::endianness Endian)
|
||||||
|
: Endian(Endian), Data(Data.bytes_begin(), Data.bytes_end()) {}
|
||||||
|
|
||||||
|
llvm::support::endianness getEndian() const override { return Endian; }
|
||||||
|
|
||||||
|
Error readBytes(uint64_t Offset, uint64_t Size,
|
||||||
|
ArrayRef<uint8_t> &Buffer) override {
|
||||||
|
if (auto EC = checkOffsetForRead(Offset, Size))
|
||||||
|
return EC;
|
||||||
|
Buffer = Data.slice(Offset, Size);
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error readLongestContiguousChunk(uint64_t Offset,
|
||||||
|
ArrayRef<uint8_t> &Buffer) override {
|
||||||
|
if (auto EC = checkOffsetForRead(Offset, 1))
|
||||||
|
return EC;
|
||||||
|
Buffer = Data.slice(Offset);
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLength() override { return Data.size(); }
|
||||||
|
|
||||||
|
ArrayRef<uint8_t> data() const { return Data; }
|
||||||
|
|
||||||
|
StringRef str() const {
|
||||||
|
const char *CharData = reinterpret_cast<const char *>(Data.data());
|
||||||
|
return StringRef(CharData, Data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
llvm::support::endianness Endian;
|
||||||
|
ArrayRef<uint8_t> Data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An implementation of BinaryStream whose data is backed by an llvm
|
||||||
|
/// MemoryBuffer object. MemoryBufferByteStream owns the MemoryBuffer in
|
||||||
|
/// question. As with BinaryByteStream, reading from a MemoryBufferByteStream
|
||||||
|
/// will never cause a copy.
|
||||||
|
class MemoryBufferByteStream : public BinaryByteStream {
|
||||||
|
public:
|
||||||
|
MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer,
|
||||||
|
llvm::support::endianness Endian)
|
||||||
|
: BinaryByteStream(Buffer->getBuffer(), Endian),
|
||||||
|
MemBuffer(std::move(Buffer)) {}
|
||||||
|
|
||||||
|
std::unique_ptr<MemoryBuffer> MemBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An implementation of BinaryStream which holds its entire data set
|
||||||
|
/// in a single contiguous buffer. As with BinaryByteStream, the mutable
|
||||||
|
/// version also guarantees that no read operation will ever incur a copy,
|
||||||
|
/// and similarly it does not own the underlying buffer.
|
||||||
|
class MutableBinaryByteStream : public WritableBinaryStream {
|
||||||
|
public:
|
||||||
|
MutableBinaryByteStream() = default;
|
||||||
|
MutableBinaryByteStream(MutableArrayRef<uint8_t> Data,
|
||||||
|
llvm::support::endianness Endian)
|
||||||
|
: Data(Data), ImmutableStream(Data, Endian) {}
|
||||||
|
|
||||||
|
llvm::support::endianness getEndian() const override {
|
||||||
|
return ImmutableStream.getEndian();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error readBytes(uint64_t Offset, uint64_t Size,
|
||||||
|
ArrayRef<uint8_t> &Buffer) override {
|
||||||
|
return ImmutableStream.readBytes(Offset, Size, Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error readLongestContiguousChunk(uint64_t Offset,
|
||||||
|
ArrayRef<uint8_t> &Buffer) override {
|
||||||
|
return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLength() override { return ImmutableStream.getLength(); }
|
||||||
|
|
||||||
|
Error writeBytes(uint64_t Offset, ArrayRef<uint8_t> Buffer) override {
|
||||||
|
if (Buffer.empty())
|
||||||
|
return Error::success();
|
||||||
|
|
||||||
|
if (auto EC = checkOffsetForWrite(Offset, Buffer.size()))
|
||||||
|
return EC;
|
||||||
|
|
||||||
|
uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
|
||||||
|
::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error commit() override { return Error::success(); }
|
||||||
|
|
||||||
|
MutableArrayRef<uint8_t> data() const { return Data; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
MutableArrayRef<uint8_t> Data;
|
||||||
|
BinaryByteStream ImmutableStream;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An implementation of WritableBinaryStream which can write at its end
|
||||||
|
/// causing the underlying data to grow. This class owns the underlying data.
|
||||||
|
class AppendingBinaryByteStream : public WritableBinaryStream {
|
||||||
|
std::vector<uint8_t> Data;
|
||||||
|
llvm::support::endianness Endian = llvm::support::little;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AppendingBinaryByteStream() = default;
|
||||||
|
AppendingBinaryByteStream(llvm::support::endianness Endian)
|
||||||
|
: Endian(Endian) {}
|
||||||
|
|
||||||
|
void clear() { Data.clear(); }
|
||||||
|
|
||||||
|
llvm::support::endianness getEndian() const override { return Endian; }
|
||||||
|
|
||||||
|
Error readBytes(uint64_t Offset, uint64_t Size,
|
||||||
|
ArrayRef<uint8_t> &Buffer) override {
|
||||||
|
if (auto EC = checkOffsetForWrite(Offset, Buffer.size()))
|
||||||
|
return EC;
|
||||||
|
|
||||||
|
Buffer = ArrayRef(Data).slice(Offset, Size);
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(uint64_t Offset, ArrayRef<uint8_t> Bytes) {
|
||||||
|
Data.insert(Data.begin() + Offset, Bytes.begin(), Bytes.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
Error readLongestContiguousChunk(uint64_t Offset,
|
||||||
|
ArrayRef<uint8_t> &Buffer) override {
|
||||||
|
if (auto EC = checkOffsetForWrite(Offset, 1))
|
||||||
|
return EC;
|
||||||
|
|
||||||
|
Buffer = ArrayRef(Data).slice(Offset);
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLength() override { return Data.size(); }
|
||||||
|
|
||||||
|
Error writeBytes(uint64_t Offset, ArrayRef<uint8_t> Buffer) override {
|
||||||
|
if (Buffer.empty())
|
||||||
|
return Error::success();
|
||||||
|
|
||||||
|
// This is well-defined for any case except where offset is strictly
|
||||||
|
// greater than the current length. If offset is equal to the current
|
||||||
|
// length, we can still grow. If offset is beyond the current length, we
|
||||||
|
// would have to decide how to deal with the intermediate uninitialized
|
||||||
|
// bytes. So we punt on that case for simplicity and just say it's an
|
||||||
|
// error.
|
||||||
|
if (Offset > getLength())
|
||||||
|
return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
|
||||||
|
|
||||||
|
uint64_t RequiredSize = Offset + Buffer.size();
|
||||||
|
if (RequiredSize > Data.size())
|
||||||
|
Data.resize(RequiredSize);
|
||||||
|
|
||||||
|
::memcpy(Data.data() + Offset, Buffer.data(), Buffer.size());
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error commit() override { return Error::success(); }
|
||||||
|
|
||||||
|
/// Return the properties of this stream.
|
||||||
|
BinaryStreamFlags getFlags() const override { return BSF_Write | BSF_Append; }
|
||||||
|
|
||||||
|
MutableArrayRef<uint8_t> data() { return Data; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An implementation of WritableBinaryStream backed by an llvm
|
||||||
|
/// FileOutputBuffer.
|
||||||
|
class FileBufferByteStream : public WritableBinaryStream {
|
||||||
|
private:
|
||||||
|
class StreamImpl : public MutableBinaryByteStream {
|
||||||
|
public:
|
||||||
|
StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer,
|
||||||
|
llvm::support::endianness Endian)
|
||||||
|
: MutableBinaryByteStream(
|
||||||
|
MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
|
||||||
|
Buffer->getBufferEnd()),
|
||||||
|
Endian),
|
||||||
|
FileBuffer(std::move(Buffer)) {}
|
||||||
|
|
||||||
|
Error commit() override {
|
||||||
|
if (FileBuffer->commit())
|
||||||
|
return make_error<BinaryStreamError>(
|
||||||
|
stream_error_code::filesystem_error);
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a pointer to the start of the buffer.
|
||||||
|
uint8_t *getBufferStart() const { return FileBuffer->getBufferStart(); }
|
||||||
|
|
||||||
|
/// Returns a pointer to the end of the buffer.
|
||||||
|
uint8_t *getBufferEnd() const { return FileBuffer->getBufferEnd(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<FileOutputBuffer> FileBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer,
|
||||||
|
llvm::support::endianness Endian)
|
||||||
|
: Impl(std::move(Buffer), Endian) {}
|
||||||
|
|
||||||
|
llvm::support::endianness getEndian() const override {
|
||||||
|
return Impl.getEndian();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error readBytes(uint64_t Offset, uint64_t Size,
|
||||||
|
ArrayRef<uint8_t> &Buffer) override {
|
||||||
|
return Impl.readBytes(Offset, Size, Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error readLongestContiguousChunk(uint64_t Offset,
|
||||||
|
ArrayRef<uint8_t> &Buffer) override {
|
||||||
|
return Impl.readLongestContiguousChunk(Offset, Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLength() override { return Impl.getLength(); }
|
||||||
|
|
||||||
|
Error writeBytes(uint64_t Offset, ArrayRef<uint8_t> Data) override {
|
||||||
|
return Impl.writeBytes(Offset, Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error commit() override { return Impl.commit(); }
|
||||||
|
|
||||||
|
/// Returns a pointer to the start of the buffer.
|
||||||
|
uint8_t *getBufferStart() const { return Impl.getBufferStart(); }
|
||||||
|
|
||||||
|
/// Returns a pointer to the end of the buffer.
|
||||||
|
uint8_t *getBufferEnd() const { return Impl.getBufferEnd(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
StreamImpl Impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_SUPPORT_BINARYBYTESTREAM_H
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
//===- BinaryStream.h - Base interface for a stream of data -----*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_BINARYSTREAM_H
|
||||||
|
#define LLVM_SUPPORT_BINARYSTREAM_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/BitmaskEnum.h"
|
||||||
|
#include "llvm/Support/BinaryStreamError.h"
|
||||||
|
#include "llvm/Support/Endian.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
enum BinaryStreamFlags {
|
||||||
|
BSF_None = 0,
|
||||||
|
BSF_Write = 1, // Stream supports writing.
|
||||||
|
BSF_Append = 2, // Writing can occur at offset == length.
|
||||||
|
LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ BSF_Append)
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An interface for accessing data in a stream-like format, but which
|
||||||
|
/// discourages copying. Instead of specifying a buffer in which to copy
|
||||||
|
/// data on a read, the API returns an ArrayRef to data owned by the stream's
|
||||||
|
/// implementation. Since implementations may not necessarily store data in a
|
||||||
|
/// single contiguous buffer (or even in memory at all), in such cases a it may
|
||||||
|
/// be necessary for an implementation to cache such a buffer so that it can
|
||||||
|
/// return it.
|
||||||
|
class BinaryStream {
|
||||||
|
public:
|
||||||
|
virtual ~BinaryStream() = default;
|
||||||
|
|
||||||
|
virtual llvm::support::endianness getEndian() const = 0;
|
||||||
|
|
||||||
|
/// Given an offset into the stream and a number of bytes, attempt to
|
||||||
|
/// read the bytes and set the output ArrayRef to point to data owned by the
|
||||||
|
/// stream.
|
||||||
|
virtual Error readBytes(uint64_t Offset, uint64_t Size,
|
||||||
|
ArrayRef<uint8_t> &Buffer) = 0;
|
||||||
|
|
||||||
|
/// Given an offset into the stream, read as much as possible without
|
||||||
|
/// copying any data.
|
||||||
|
virtual Error readLongestContiguousChunk(uint64_t Offset,
|
||||||
|
ArrayRef<uint8_t> &Buffer) = 0;
|
||||||
|
|
||||||
|
/// Return the number of bytes of data in this stream.
|
||||||
|
virtual uint64_t getLength() = 0;
|
||||||
|
|
||||||
|
/// Return the properties of this stream.
|
||||||
|
virtual BinaryStreamFlags getFlags() const { return BSF_None; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Error checkOffsetForRead(uint64_t Offset, uint64_t DataSize) {
|
||||||
|
if (Offset > getLength())
|
||||||
|
return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
|
||||||
|
if (getLength() < DataSize + Offset)
|
||||||
|
return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A BinaryStream which can be read from as well as written to. Note
|
||||||
|
/// that writing to a BinaryStream always necessitates copying from the input
|
||||||
|
/// buffer to the stream's backing store. Streams are assumed to be buffered
|
||||||
|
/// so that to be portable it is necessary to call commit() on the stream when
|
||||||
|
/// all data has been written.
|
||||||
|
class WritableBinaryStream : public BinaryStream {
|
||||||
|
public:
|
||||||
|
~WritableBinaryStream() override = default;
|
||||||
|
|
||||||
|
/// Attempt to write the given bytes into the stream at the desired
|
||||||
|
/// offset. This will always necessitate a copy. Cannot shrink or grow the
|
||||||
|
/// stream, only writes into existing allocated space.
|
||||||
|
virtual Error writeBytes(uint64_t Offset, ArrayRef<uint8_t> Data) = 0;
|
||||||
|
|
||||||
|
/// For buffered streams, commits changes to the backing store.
|
||||||
|
virtual Error commit() = 0;
|
||||||
|
|
||||||
|
/// Return the properties of this stream.
|
||||||
|
BinaryStreamFlags getFlags() const override { return BSF_Write; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Error checkOffsetForWrite(uint64_t Offset, uint64_t DataSize) {
|
||||||
|
if (!(getFlags() & BSF_Append))
|
||||||
|
return checkOffsetForRead(Offset, DataSize);
|
||||||
|
|
||||||
|
if (Offset > getLength())
|
||||||
|
return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_SUPPORT_BINARYSTREAM_H
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
//===- BinaryStreamError.h - Error extensions for Binary Streams *- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_BINARYSTREAMERROR_H
|
||||||
|
#define LLVM_SUPPORT_BINARYSTREAMERROR_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
enum class stream_error_code {
|
||||||
|
unspecified,
|
||||||
|
stream_too_short,
|
||||||
|
invalid_array_size,
|
||||||
|
invalid_offset,
|
||||||
|
filesystem_error
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Base class for errors originating when parsing raw PDB files
|
||||||
|
class BinaryStreamError : public ErrorInfo<BinaryStreamError> {
|
||||||
|
public:
|
||||||
|
static char ID;
|
||||||
|
explicit BinaryStreamError(stream_error_code C);
|
||||||
|
explicit BinaryStreamError(StringRef Context);
|
||||||
|
BinaryStreamError(stream_error_code C, StringRef Context);
|
||||||
|
|
||||||
|
void log(raw_ostream &OS) const override;
|
||||||
|
std::error_code convertToErrorCode() const override;
|
||||||
|
|
||||||
|
StringRef getErrorMessage() const;
|
||||||
|
|
||||||
|
stream_error_code getErrorCode() const { return Code; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string ErrMsg;
|
||||||
|
stream_error_code Code;
|
||||||
|
};
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_SUPPORT_BINARYSTREAMERROR_H
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
//===- llvm/Support/CBindingWrapping.h - C Interface Wrapping ---*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file declares the wrapping macros for the C interface.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_CBINDINGWRAPPING_H
|
||||||
|
#define LLVM_SUPPORT_CBINDINGWRAPPING_H
|
||||||
|
|
||||||
|
#include "llvm-c/Types.h"
|
||||||
|
#include "llvm/Support/Casting.h"
|
||||||
|
|
||||||
|
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
|
||||||
|
inline ty *unwrap(ref P) { \
|
||||||
|
return reinterpret_cast<ty*>(P); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
inline ref wrap(const ty *P) { \
|
||||||
|
return reinterpret_cast<ref>(const_cast<ty*>(P)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_ISA_CONVERSION_FUNCTIONS(ty, ref) \
|
||||||
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
|
||||||
|
\
|
||||||
|
template<typename T> \
|
||||||
|
inline T *unwrap(ref P) { \
|
||||||
|
return cast<T>(unwrap(P)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_STDCXX_CONVERSION_FUNCTIONS(ty, ref) \
|
||||||
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
|
||||||
|
\
|
||||||
|
template<typename T> \
|
||||||
|
inline T *unwrap(ref P) { \
|
||||||
|
T *Q = (T*)unwrap(P); \
|
||||||
|
assert(Q && "Invalid cast!"); \
|
||||||
|
return Q; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,348 @@
|
|||||||
|
/*===--- ConvertUTF.h - Universal Character Names conversions ---------------===
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*==------------------------------------------------------------------------==*/
|
||||||
|
/*
|
||||||
|
* Copyright © 1991-2015 Unicode, Inc. All rights reserved.
|
||||||
|
* Distributed under the Terms of Use in
|
||||||
|
* http://www.unicode.org/copyright.html.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of the Unicode data files and any associated documentation
|
||||||
|
* (the "Data Files") or Unicode software and any associated documentation
|
||||||
|
* (the "Software") to deal in the Data Files or Software
|
||||||
|
* without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, and/or sell copies of
|
||||||
|
* the Data Files or Software, and to permit persons to whom the Data Files
|
||||||
|
* or Software are furnished to do so, provided that
|
||||||
|
* (a) this copyright and permission notice appear with all copies
|
||||||
|
* of the Data Files or Software,
|
||||||
|
* (b) this copyright and permission notice appear in associated
|
||||||
|
* documentation, and
|
||||||
|
* (c) there is clear notice in each modified Data File or in the Software
|
||||||
|
* as well as in the documentation associated with the Data File(s) or
|
||||||
|
* Software that the data or software has been modified.
|
||||||
|
*
|
||||||
|
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||||
|
* ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
|
||||||
|
* NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
|
||||||
|
* DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THE DATA FILES OR SOFTWARE.
|
||||||
|
*
|
||||||
|
* Except as contained in this notice, the name of a copyright holder
|
||||||
|
* shall not be used in advertising or otherwise to promote the sale,
|
||||||
|
* use or other dealings in these Data Files or Software without prior
|
||||||
|
* written authorization of the copyright holder.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
Conversions between UTF32, UTF-16, and UTF-8. Header file.
|
||||||
|
|
||||||
|
Several funtions are included here, forming a complete set of
|
||||||
|
conversions between the three formats. UTF-7 is not included
|
||||||
|
here, but is handled in a separate source file.
|
||||||
|
|
||||||
|
Each of these routines takes pointers to input buffers and output
|
||||||
|
buffers. The input buffers are const.
|
||||||
|
|
||||||
|
Each routine converts the text between *sourceStart and sourceEnd,
|
||||||
|
putting the result into the buffer between *targetStart and
|
||||||
|
targetEnd. Note: the end pointers are *after* the last item: e.g.
|
||||||
|
*(sourceEnd - 1) is the last item.
|
||||||
|
|
||||||
|
The return result indicates whether the conversion was successful,
|
||||||
|
and if not, whether the problem was in the source or target buffers.
|
||||||
|
(Only the first encountered problem is indicated.)
|
||||||
|
|
||||||
|
After the conversion, *sourceStart and *targetStart are both
|
||||||
|
updated to point to the end of last text successfully converted in
|
||||||
|
the respective buffers.
|
||||||
|
|
||||||
|
Input parameters:
|
||||||
|
sourceStart - pointer to a pointer to the source buffer.
|
||||||
|
The contents of this are modified on return so that
|
||||||
|
it points at the next thing to be converted.
|
||||||
|
targetStart - similarly, pointer to pointer to the target buffer.
|
||||||
|
sourceEnd, targetEnd - respectively pointers to the ends of the
|
||||||
|
two buffers, for overflow checking only.
|
||||||
|
|
||||||
|
These conversion functions take a ConversionFlags argument. When this
|
||||||
|
flag is set to strict, both irregular sequences and isolated surrogates
|
||||||
|
will cause an error. When the flag is set to lenient, both irregular
|
||||||
|
sequences and isolated surrogates are converted.
|
||||||
|
|
||||||
|
Whether the flag is strict or lenient, all illegal sequences will cause
|
||||||
|
an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
|
||||||
|
or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
|
||||||
|
must check for illegal sequences.
|
||||||
|
|
||||||
|
When the flag is set to lenient, characters over 0x10FFFF are converted
|
||||||
|
to the replacement character; otherwise (when the flag is set to strict)
|
||||||
|
they constitute an error.
|
||||||
|
|
||||||
|
Output parameters:
|
||||||
|
The value "sourceIllegal" is returned from some routines if the input
|
||||||
|
sequence is malformed. When "sourceIllegal" is returned, the source
|
||||||
|
value will point to the illegal value that caused the problem. E.g.,
|
||||||
|
in UTF-8 when a sequence is malformed, it points to the start of the
|
||||||
|
malformed sequence.
|
||||||
|
|
||||||
|
Author: Mark E. Davis, 1994.
|
||||||
|
Rev History: Rick McGowan, fixes & updates May 2001.
|
||||||
|
Fixes & updates, Sept 2001.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_CONVERTUTF_H
|
||||||
|
#define LLVM_SUPPORT_CONVERTUTF_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <system_error>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Wrap everything in namespace llvm so that programs can link with llvm and
|
||||||
|
// their own version of the unicode libraries.
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------
|
||||||
|
The following 4 definitions are compiler-specific.
|
||||||
|
The C standard does not guarantee that wchar_t has at least
|
||||||
|
16 bits, so wchar_t is no less portable than unsigned short!
|
||||||
|
All should be unsigned values to avoid sign extension during
|
||||||
|
bit mask & shift operations.
|
||||||
|
------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
typedef unsigned int UTF32; /* at least 32 bits */
|
||||||
|
typedef unsigned short UTF16; /* at least 16 bits */
|
||||||
|
typedef unsigned char UTF8; /* typically 8 bits */
|
||||||
|
typedef unsigned char Boolean; /* 0 or 1 */
|
||||||
|
|
||||||
|
/* Some fundamental constants */
|
||||||
|
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
|
||||||
|
#define UNI_MAX_BMP (UTF32)0x0000FFFF
|
||||||
|
#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
|
||||||
|
#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
|
||||||
|
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
|
||||||
|
|
||||||
|
#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4
|
||||||
|
|
||||||
|
#define UNI_UTF16_BYTE_ORDER_MARK_NATIVE 0xFEFF
|
||||||
|
#define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
|
||||||
|
|
||||||
|
#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE 0x0000FEFF
|
||||||
|
#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE0000
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
conversionOK, /* conversion successful */
|
||||||
|
sourceExhausted, /* partial character in source, but hit end */
|
||||||
|
targetExhausted, /* insuff. room in target for conversion */
|
||||||
|
sourceIllegal /* source sequence is illegal/malformed */
|
||||||
|
} ConversionResult;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
strictConversion = 0,
|
||||||
|
lenientConversion
|
||||||
|
} ConversionFlags;
|
||||||
|
|
||||||
|
ConversionResult ConvertUTF8toUTF16 (
|
||||||
|
const UTF8** sourceStart, const UTF8* sourceEnd,
|
||||||
|
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a partial UTF8 sequence to UTF32. If the sequence ends in an
|
||||||
|
* incomplete code unit sequence, returns \c sourceExhausted.
|
||||||
|
*/
|
||||||
|
ConversionResult ConvertUTF8toUTF32Partial(
|
||||||
|
const UTF8** sourceStart, const UTF8* sourceEnd,
|
||||||
|
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a partial UTF8 sequence to UTF32. If the sequence ends in an
|
||||||
|
* incomplete code unit sequence, returns \c sourceIllegal.
|
||||||
|
*/
|
||||||
|
ConversionResult ConvertUTF8toUTF32(
|
||||||
|
const UTF8** sourceStart, const UTF8* sourceEnd,
|
||||||
|
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
|
||||||
|
|
||||||
|
ConversionResult ConvertUTF16toUTF8 (
|
||||||
|
const UTF16** sourceStart, const UTF16* sourceEnd,
|
||||||
|
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
|
||||||
|
|
||||||
|
ConversionResult ConvertUTF32toUTF8 (
|
||||||
|
const UTF32** sourceStart, const UTF32* sourceEnd,
|
||||||
|
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
|
||||||
|
|
||||||
|
ConversionResult ConvertUTF16toUTF32 (
|
||||||
|
const UTF16** sourceStart, const UTF16* sourceEnd,
|
||||||
|
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
|
||||||
|
|
||||||
|
ConversionResult ConvertUTF32toUTF16 (
|
||||||
|
const UTF32** sourceStart, const UTF32* sourceEnd,
|
||||||
|
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
|
||||||
|
|
||||||
|
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
|
||||||
|
|
||||||
|
Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd);
|
||||||
|
|
||||||
|
unsigned getUTF8SequenceSize(const UTF8 *source, const UTF8 *sourceEnd);
|
||||||
|
|
||||||
|
unsigned getNumBytesForUTF8(UTF8 firstByte);
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Below are LLVM-specific wrappers of the functions above. */
|
||||||
|
|
||||||
|
template <typename T> class ArrayRef;
|
||||||
|
template <typename T> class SmallVectorImpl;
|
||||||
|
class StringRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on
|
||||||
|
* WideCharWidth. The converted data is written to ResultPtr, which needs to
|
||||||
|
* point to at least WideCharWidth * (Source.Size() + 1) bytes. On success,
|
||||||
|
* ResultPtr will point one after the end of the copied string. On failure,
|
||||||
|
* ResultPtr will not be changed, and ErrorPtr will be set to the location of
|
||||||
|
* the first character which could not be converted.
|
||||||
|
* \return true on success.
|
||||||
|
*/
|
||||||
|
bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
|
||||||
|
char *&ResultPtr, const UTF8 *&ErrorPtr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a UTF-8 StringRef to a std::wstring.
|
||||||
|
* \return true on success.
|
||||||
|
*/
|
||||||
|
bool ConvertUTF8toWide(llvm::StringRef Source, std::wstring &Result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a UTF-8 C-string to a std::wstring.
|
||||||
|
* \return true on success.
|
||||||
|
*/
|
||||||
|
bool ConvertUTF8toWide(const char *Source, std::wstring &Result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a std::wstring to a UTF-8 encoded std::string.
|
||||||
|
* \return true on success.
|
||||||
|
*/
|
||||||
|
bool convertWideToUTF8(const std::wstring &Source, std::string &Result);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an Unicode code point to UTF8 sequence.
|
||||||
|
*
|
||||||
|
* \param Source a Unicode code point.
|
||||||
|
* \param [in,out] ResultPtr pointer to the output buffer, needs to be at least
|
||||||
|
* \c UNI_MAX_UTF8_BYTES_PER_CODE_POINT bytes. On success \c ResultPtr is
|
||||||
|
* updated one past end of the converted sequence.
|
||||||
|
*
|
||||||
|
* \returns true on success.
|
||||||
|
*/
|
||||||
|
bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the first UTF8 sequence in the given source buffer to a UTF32
|
||||||
|
* code point.
|
||||||
|
*
|
||||||
|
* \param [in,out] source A pointer to the source buffer. If the conversion
|
||||||
|
* succeeds, this pointer will be updated to point to the byte just past the
|
||||||
|
* end of the converted sequence.
|
||||||
|
* \param sourceEnd A pointer just past the end of the source buffer.
|
||||||
|
* \param [out] target The converted code
|
||||||
|
* \param flags Whether the conversion is strict or lenient.
|
||||||
|
*
|
||||||
|
* \returns conversionOK on success
|
||||||
|
*
|
||||||
|
* \sa ConvertUTF8toUTF32
|
||||||
|
*/
|
||||||
|
inline ConversionResult convertUTF8Sequence(const UTF8 **source,
|
||||||
|
const UTF8 *sourceEnd,
|
||||||
|
UTF32 *target,
|
||||||
|
ConversionFlags flags) {
|
||||||
|
if (*source == sourceEnd)
|
||||||
|
return sourceExhausted;
|
||||||
|
unsigned size = getNumBytesForUTF8(**source);
|
||||||
|
if ((ptrdiff_t)size > sourceEnd - *source)
|
||||||
|
return sourceExhausted;
|
||||||
|
return ConvertUTF8toUTF32(source, *source + size, &target, target + 1, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if a blob of text starts with a UTF-16 big or little endian byte
|
||||||
|
* order mark.
|
||||||
|
*/
|
||||||
|
bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string.
|
||||||
|
*
|
||||||
|
* \param [in] SrcBytes A buffer of what is assumed to be UTF-16 encoded text.
|
||||||
|
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||||
|
* \returns true on success
|
||||||
|
*/
|
||||||
|
bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a UTF16 string into a UTF8 std::string.
|
||||||
|
*
|
||||||
|
* \param [in] Src A buffer of UTF-16 encoded text.
|
||||||
|
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||||
|
* \returns true on success
|
||||||
|
*/
|
||||||
|
bool convertUTF16ToUTF8String(ArrayRef<UTF16> Src, std::string &Out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
|
||||||
|
*
|
||||||
|
* \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
|
||||||
|
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||||
|
* \returns true on success
|
||||||
|
*/
|
||||||
|
bool convertUTF32ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a UTF32 string into a UTF8 std::string.
|
||||||
|
*
|
||||||
|
* \param [in] Src A buffer of UTF-32 encoded text.
|
||||||
|
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||||
|
* \returns true on success
|
||||||
|
*/
|
||||||
|
bool convertUTF32ToUTF8String(ArrayRef<UTF32> Src, std::string &Out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a UTF-8 string into a UTF-16 string with native endianness.
|
||||||
|
*
|
||||||
|
* \returns true on success
|
||||||
|
*/
|
||||||
|
bool convertUTF8ToUTF16String(StringRef SrcUTF8,
|
||||||
|
SmallVectorImpl<UTF16> &DstUTF16);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
namespace sys {
|
||||||
|
namespace windows {
|
||||||
|
std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
|
||||||
|
/// Convert to UTF16 from the current code page used in the system
|
||||||
|
std::error_code CurCPToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
|
||||||
|
std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
||||||
|
SmallVectorImpl<char> &utf8);
|
||||||
|
/// Convert from UTF16 to the current code page used in the system
|
||||||
|
std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
|
||||||
|
SmallVectorImpl<char> &utf8);
|
||||||
|
} // namespace windows
|
||||||
|
} // namespace sys
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} /* end namespace llvm */
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
//===-- llvm/Support/DataTypes.h - Define fixed size types ------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Due to layering constraints (Support depends on llvm-c) this is a thin
|
||||||
|
// wrapper around the implementation that lives in llvm-c, though most clients
|
||||||
|
// can/should think of this as being provided by Support for simplicity (not
|
||||||
|
// many clients are aware of their dependency on llvm-c).
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_DATATYPES_H
|
||||||
|
#define LLVM_SUPPORT_DATATYPES_H
|
||||||
|
|
||||||
|
#include "llvm-c/DataTypes.h"
|
||||||
|
|
||||||
|
#endif // LLVM_SUPPORT_DATATYPES_H
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
//===- llvm/Support/Debug.h - Easy way to add debug output ------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file implements a handy way of adding debugging information to your
|
||||||
|
// code, without it being enabled all of the time, and without having to add
|
||||||
|
// command line options to enable it.
|
||||||
|
//
|
||||||
|
// In particular, just wrap your code with the LLVM_DEBUG() macro, and it will
|
||||||
|
// be enabled automatically if you specify '-debug' on the command-line.
|
||||||
|
// LLVM_DEBUG() requires the DEBUG_TYPE macro to be defined. Set it to "foo"
|
||||||
|
// specify that your debug code belongs to class "foo". Be careful that you only
|
||||||
|
// do this after including Debug.h and not around any #include of headers.
|
||||||
|
// Headers should define and undef the macro acround the code that needs to use
|
||||||
|
// the LLVM_DEBUG() macro. Then, on the command line, you can specify
|
||||||
|
// '-debug-only=foo' to enable JUST the debug information for the foo class.
|
||||||
|
//
|
||||||
|
// When compiling without assertions, the -debug-* options and all code in
|
||||||
|
// LLVM_DEBUG() statements disappears, so it does not affect the runtime of the
|
||||||
|
// code.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_DEBUG_H
|
||||||
|
#define LLVM_SUPPORT_DEBUG_H
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class raw_ostream;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
|
||||||
|
/// isCurrentDebugType - Return true if the specified string is the debug type
|
||||||
|
/// specified on the command line, or if none was specified on the command line
|
||||||
|
/// with the -debug-only=X option.
|
||||||
|
///
|
||||||
|
bool isCurrentDebugType(const char *Type);
|
||||||
|
|
||||||
|
/// setCurrentDebugType - Set the current debug type, as if the -debug-only=X
|
||||||
|
/// option were specified. Note that DebugFlag also needs to be set to true for
|
||||||
|
/// debug output to be produced.
|
||||||
|
///
|
||||||
|
void setCurrentDebugType(const char *Type);
|
||||||
|
|
||||||
|
/// setCurrentDebugTypes - Set the current debug type, as if the
|
||||||
|
/// -debug-only=X,Y,Z option were specified. Note that DebugFlag
|
||||||
|
/// also needs to be set to true for debug output to be produced.
|
||||||
|
///
|
||||||
|
void setCurrentDebugTypes(const char **Types, unsigned Count);
|
||||||
|
|
||||||
|
/// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug
|
||||||
|
/// information. In the '-debug' option is specified on the commandline, and if
|
||||||
|
/// this is a debug build, then the code specified as the option to the macro
|
||||||
|
/// will be executed. Otherwise it will not be. Example:
|
||||||
|
///
|
||||||
|
/// DEBUG_WITH_TYPE("bitset", dbgs() << "Bitset contains: " << Bitset << "\n");
|
||||||
|
///
|
||||||
|
/// This will emit the debug information if -debug is present, and -debug-only
|
||||||
|
/// is not specified, or is specified as "bitset".
|
||||||
|
#define DEBUG_WITH_TYPE(TYPE, X) \
|
||||||
|
do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)) { X; } \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define isCurrentDebugType(X) (false)
|
||||||
|
#define setCurrentDebugType(X) do { (void)(X); } while (false)
|
||||||
|
#define setCurrentDebugTypes(X, N) do { (void)(X); (void)(N); } while (false)
|
||||||
|
#define DEBUG_WITH_TYPE(TYPE, X) do { } while (false)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// This boolean is set to true if the '-debug' command line option
|
||||||
|
/// is specified. This should probably not be referenced directly, instead, use
|
||||||
|
/// the DEBUG macro below.
|
||||||
|
///
|
||||||
|
extern bool DebugFlag;
|
||||||
|
|
||||||
|
/// EnableDebugBuffering - This defaults to false. If true, the debug
|
||||||
|
/// stream will install signal handlers to dump any buffered debug
|
||||||
|
/// output. It allows clients to selectively allow the debug stream
|
||||||
|
/// to install signal handlers if they are certain there will be no
|
||||||
|
/// conflict.
|
||||||
|
///
|
||||||
|
extern bool EnableDebugBuffering;
|
||||||
|
|
||||||
|
/// dbgs() - This returns a reference to a raw_ostream for debugging
|
||||||
|
/// messages. If debugging is disabled it returns errs(). Use it
|
||||||
|
/// like: dbgs() << "foo" << "bar";
|
||||||
|
raw_ostream &dbgs();
|
||||||
|
|
||||||
|
// DEBUG macro - This macro should be used by passes to emit debug information.
|
||||||
|
// In the '-debug' option is specified on the commandline, and if this is a
|
||||||
|
// debug build, then the code specified as the option to the macro will be
|
||||||
|
// executed. Otherwise it will not be. Example:
|
||||||
|
//
|
||||||
|
// LLVM_DEBUG(dbgs() << "Bitset contains: " << Bitset << "\n");
|
||||||
|
//
|
||||||
|
#define LLVM_DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X)
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_SUPPORT_DEBUG_H
|
||||||
@@ -0,0 +1,427 @@
|
|||||||
|
//===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file declares generic functions to read and write endian specific data.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_ENDIAN_H
|
||||||
|
#define LLVM_SUPPORT_ENDIAN_H
|
||||||
|
|
||||||
|
#include "llvm/Support/Compiler.h"
|
||||||
|
#include "llvm/Support/SwapByteOrder.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace support {
|
||||||
|
|
||||||
|
enum endianness {big, little, native};
|
||||||
|
|
||||||
|
// These are named values for common alignments.
|
||||||
|
enum {aligned = 0, unaligned = 1};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
/// ::value is either alignment, or alignof(T) if alignment is 0.
|
||||||
|
template<class T, int alignment>
|
||||||
|
struct PickAlignment {
|
||||||
|
enum { value = alignment == 0 ? alignof(T) : alignment };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace detail
|
||||||
|
|
||||||
|
namespace endian {
|
||||||
|
|
||||||
|
constexpr endianness system_endianness() {
|
||||||
|
return sys::IsBigEndianHost ? big : little;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename value_type>
|
||||||
|
inline value_type byte_swap(value_type value, endianness endian) {
|
||||||
|
if ((endian != native) && (endian != system_endianness()))
|
||||||
|
sys::swapByteOrder(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Swap the bytes of value to match the given endianness.
|
||||||
|
template<typename value_type, endianness endian>
|
||||||
|
inline value_type byte_swap(value_type value) {
|
||||||
|
return byte_swap(value, endian);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a value of a particular endianness from memory.
|
||||||
|
template <typename value_type, std::size_t alignment>
|
||||||
|
inline value_type read(const void *memory, endianness endian) {
|
||||||
|
value_type ret;
|
||||||
|
|
||||||
|
memcpy(&ret,
|
||||||
|
LLVM_ASSUME_ALIGNED(
|
||||||
|
memory, (detail::PickAlignment<value_type, alignment>::value)),
|
||||||
|
sizeof(value_type));
|
||||||
|
return byte_swap<value_type>(ret, endian);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename value_type,
|
||||||
|
endianness endian,
|
||||||
|
std::size_t alignment>
|
||||||
|
inline value_type read(const void *memory) {
|
||||||
|
return read<value_type, alignment>(memory, endian);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a value of a particular endianness from a buffer, and increment the
|
||||||
|
/// buffer past that value.
|
||||||
|
template <typename value_type, std::size_t alignment, typename CharT>
|
||||||
|
inline value_type readNext(const CharT *&memory, endianness endian) {
|
||||||
|
value_type ret = read<value_type, alignment>(memory, endian);
|
||||||
|
memory += sizeof(value_type);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename value_type, endianness endian, std::size_t alignment,
|
||||||
|
typename CharT>
|
||||||
|
inline value_type readNext(const CharT *&memory) {
|
||||||
|
return readNext<value_type, alignment, CharT>(memory, endian);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a value to memory with a particular endianness.
|
||||||
|
template <typename value_type, std::size_t alignment>
|
||||||
|
inline void write(void *memory, value_type value, endianness endian) {
|
||||||
|
value = byte_swap<value_type>(value, endian);
|
||||||
|
memcpy(LLVM_ASSUME_ALIGNED(
|
||||||
|
memory, (detail::PickAlignment<value_type, alignment>::value)),
|
||||||
|
&value, sizeof(value_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename value_type,
|
||||||
|
endianness endian,
|
||||||
|
std::size_t alignment>
|
||||||
|
inline void write(void *memory, value_type value) {
|
||||||
|
write<value_type, alignment>(memory, value, endian);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename value_type>
|
||||||
|
using make_unsigned_t = std::make_unsigned_t<value_type>;
|
||||||
|
|
||||||
|
/// Read a value of a particular endianness from memory, for a location
|
||||||
|
/// that starts at the given bit offset within the first byte.
|
||||||
|
template <typename value_type, endianness endian, std::size_t alignment>
|
||||||
|
inline value_type readAtBitAlignment(const void *memory, uint64_t startBit) {
|
||||||
|
assert(startBit < 8);
|
||||||
|
if (startBit == 0)
|
||||||
|
return read<value_type, endian, alignment>(memory);
|
||||||
|
else {
|
||||||
|
// Read two values and compose the result from them.
|
||||||
|
value_type val[2];
|
||||||
|
memcpy(&val[0],
|
||||||
|
LLVM_ASSUME_ALIGNED(
|
||||||
|
memory, (detail::PickAlignment<value_type, alignment>::value)),
|
||||||
|
sizeof(value_type) * 2);
|
||||||
|
val[0] = byte_swap<value_type, endian>(val[0]);
|
||||||
|
val[1] = byte_swap<value_type, endian>(val[1]);
|
||||||
|
|
||||||
|
// Shift bits from the lower value into place.
|
||||||
|
make_unsigned_t<value_type> lowerVal = val[0] >> startBit;
|
||||||
|
// Mask off upper bits after right shift in case of signed type.
|
||||||
|
make_unsigned_t<value_type> numBitsFirstVal =
|
||||||
|
(sizeof(value_type) * 8) - startBit;
|
||||||
|
lowerVal &= ((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1;
|
||||||
|
|
||||||
|
// Get the bits from the upper value.
|
||||||
|
make_unsigned_t<value_type> upperVal =
|
||||||
|
val[1] & (((make_unsigned_t<value_type>)1 << startBit) - 1);
|
||||||
|
// Shift them in to place.
|
||||||
|
upperVal <<= numBitsFirstVal;
|
||||||
|
|
||||||
|
return lowerVal | upperVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a value to memory with a particular endianness, for a location
|
||||||
|
/// that starts at the given bit offset within the first byte.
|
||||||
|
template <typename value_type, endianness endian, std::size_t alignment>
|
||||||
|
inline void writeAtBitAlignment(void *memory, value_type value,
|
||||||
|
uint64_t startBit) {
|
||||||
|
assert(startBit < 8);
|
||||||
|
if (startBit == 0)
|
||||||
|
write<value_type, endian, alignment>(memory, value);
|
||||||
|
else {
|
||||||
|
// Read two values and shift the result into them.
|
||||||
|
value_type val[2];
|
||||||
|
memcpy(&val[0],
|
||||||
|
LLVM_ASSUME_ALIGNED(
|
||||||
|
memory, (detail::PickAlignment<value_type, alignment>::value)),
|
||||||
|
sizeof(value_type) * 2);
|
||||||
|
val[0] = byte_swap<value_type, endian>(val[0]);
|
||||||
|
val[1] = byte_swap<value_type, endian>(val[1]);
|
||||||
|
|
||||||
|
// Mask off any existing bits in the upper part of the lower value that
|
||||||
|
// we want to replace.
|
||||||
|
val[0] &= ((make_unsigned_t<value_type>)1 << startBit) - 1;
|
||||||
|
make_unsigned_t<value_type> numBitsFirstVal =
|
||||||
|
(sizeof(value_type) * 8) - startBit;
|
||||||
|
make_unsigned_t<value_type> lowerVal = value;
|
||||||
|
if (startBit > 0) {
|
||||||
|
// Mask off the upper bits in the new value that are not going to go into
|
||||||
|
// the lower value. This avoids a left shift of a negative value, which
|
||||||
|
// is undefined behavior.
|
||||||
|
lowerVal &= (((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1);
|
||||||
|
// Now shift the new bits into place
|
||||||
|
lowerVal <<= startBit;
|
||||||
|
}
|
||||||
|
val[0] |= lowerVal;
|
||||||
|
|
||||||
|
// Mask off any existing bits in the lower part of the upper value that
|
||||||
|
// we want to replace.
|
||||||
|
val[1] &= ~(((make_unsigned_t<value_type>)1 << startBit) - 1);
|
||||||
|
// Next shift the bits that go into the upper value into position.
|
||||||
|
make_unsigned_t<value_type> upperVal = value >> numBitsFirstVal;
|
||||||
|
// Mask off upper bits after right shift in case of signed type.
|
||||||
|
upperVal &= ((make_unsigned_t<value_type>)1 << startBit) - 1;
|
||||||
|
val[1] |= upperVal;
|
||||||
|
|
||||||
|
// Finally, rewrite values.
|
||||||
|
val[0] = byte_swap<value_type, endian>(val[0]);
|
||||||
|
val[1] = byte_swap<value_type, endian>(val[1]);
|
||||||
|
memcpy(LLVM_ASSUME_ALIGNED(
|
||||||
|
memory, (detail::PickAlignment<value_type, alignment>::value)),
|
||||||
|
&val[0], sizeof(value_type) * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace endian
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename ValueType, endianness Endian, std::size_t Alignment,
|
||||||
|
std::size_t ALIGN = PickAlignment<ValueType, Alignment>::value>
|
||||||
|
struct packed_endian_specific_integral {
|
||||||
|
using value_type = ValueType;
|
||||||
|
static constexpr endianness endian = Endian;
|
||||||
|
static constexpr std::size_t alignment = Alignment;
|
||||||
|
|
||||||
|
packed_endian_specific_integral() = default;
|
||||||
|
|
||||||
|
explicit packed_endian_specific_integral(value_type val) { *this = val; }
|
||||||
|
|
||||||
|
operator value_type() const {
|
||||||
|
return endian::read<value_type, endian, alignment>(
|
||||||
|
(const void*)Value.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(value_type newValue) {
|
||||||
|
endian::write<value_type, endian, alignment>(
|
||||||
|
(void*)Value.buffer, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
packed_endian_specific_integral &operator+=(value_type newValue) {
|
||||||
|
*this = *this + newValue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
packed_endian_specific_integral &operator-=(value_type newValue) {
|
||||||
|
*this = *this - newValue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
packed_endian_specific_integral &operator|=(value_type newValue) {
|
||||||
|
*this = *this | newValue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
packed_endian_specific_integral &operator&=(value_type newValue) {
|
||||||
|
*this = *this & newValue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct {
|
||||||
|
alignas(ALIGN) char buffer[sizeof(value_type)];
|
||||||
|
} Value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct ref {
|
||||||
|
explicit ref(void *Ptr) : Ptr(Ptr) {}
|
||||||
|
|
||||||
|
operator value_type() const {
|
||||||
|
return endian::read<value_type, endian, alignment>(Ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(value_type NewValue) {
|
||||||
|
endian::write<value_type, endian, alignment>(Ptr, NewValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void *Ptr;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace detail
|
||||||
|
|
||||||
|
using ulittle16_t =
|
||||||
|
detail::packed_endian_specific_integral<uint16_t, little, unaligned>;
|
||||||
|
using ulittle32_t =
|
||||||
|
detail::packed_endian_specific_integral<uint32_t, little, unaligned>;
|
||||||
|
using ulittle64_t =
|
||||||
|
detail::packed_endian_specific_integral<uint64_t, little, unaligned>;
|
||||||
|
|
||||||
|
using little16_t =
|
||||||
|
detail::packed_endian_specific_integral<int16_t, little, unaligned>;
|
||||||
|
using little32_t =
|
||||||
|
detail::packed_endian_specific_integral<int32_t, little, unaligned>;
|
||||||
|
using little64_t =
|
||||||
|
detail::packed_endian_specific_integral<int64_t, little, unaligned>;
|
||||||
|
|
||||||
|
using aligned_ulittle16_t =
|
||||||
|
detail::packed_endian_specific_integral<uint16_t, little, aligned>;
|
||||||
|
using aligned_ulittle32_t =
|
||||||
|
detail::packed_endian_specific_integral<uint32_t, little, aligned>;
|
||||||
|
using aligned_ulittle64_t =
|
||||||
|
detail::packed_endian_specific_integral<uint64_t, little, aligned>;
|
||||||
|
|
||||||
|
using aligned_little16_t =
|
||||||
|
detail::packed_endian_specific_integral<int16_t, little, aligned>;
|
||||||
|
using aligned_little32_t =
|
||||||
|
detail::packed_endian_specific_integral<int32_t, little, aligned>;
|
||||||
|
using aligned_little64_t =
|
||||||
|
detail::packed_endian_specific_integral<int64_t, little, aligned>;
|
||||||
|
|
||||||
|
using ubig16_t =
|
||||||
|
detail::packed_endian_specific_integral<uint16_t, big, unaligned>;
|
||||||
|
using ubig32_t =
|
||||||
|
detail::packed_endian_specific_integral<uint32_t, big, unaligned>;
|
||||||
|
using ubig64_t =
|
||||||
|
detail::packed_endian_specific_integral<uint64_t, big, unaligned>;
|
||||||
|
|
||||||
|
using big16_t =
|
||||||
|
detail::packed_endian_specific_integral<int16_t, big, unaligned>;
|
||||||
|
using big32_t =
|
||||||
|
detail::packed_endian_specific_integral<int32_t, big, unaligned>;
|
||||||
|
using big64_t =
|
||||||
|
detail::packed_endian_specific_integral<int64_t, big, unaligned>;
|
||||||
|
|
||||||
|
using aligned_ubig16_t =
|
||||||
|
detail::packed_endian_specific_integral<uint16_t, big, aligned>;
|
||||||
|
using aligned_ubig32_t =
|
||||||
|
detail::packed_endian_specific_integral<uint32_t, big, aligned>;
|
||||||
|
using aligned_ubig64_t =
|
||||||
|
detail::packed_endian_specific_integral<uint64_t, big, aligned>;
|
||||||
|
|
||||||
|
using aligned_big16_t =
|
||||||
|
detail::packed_endian_specific_integral<int16_t, big, aligned>;
|
||||||
|
using aligned_big32_t =
|
||||||
|
detail::packed_endian_specific_integral<int32_t, big, aligned>;
|
||||||
|
using aligned_big64_t =
|
||||||
|
detail::packed_endian_specific_integral<int64_t, big, aligned>;
|
||||||
|
|
||||||
|
using unaligned_uint16_t =
|
||||||
|
detail::packed_endian_specific_integral<uint16_t, native, unaligned>;
|
||||||
|
using unaligned_uint32_t =
|
||||||
|
detail::packed_endian_specific_integral<uint32_t, native, unaligned>;
|
||||||
|
using unaligned_uint64_t =
|
||||||
|
detail::packed_endian_specific_integral<uint64_t, native, unaligned>;
|
||||||
|
|
||||||
|
using unaligned_int16_t =
|
||||||
|
detail::packed_endian_specific_integral<int16_t, native, unaligned>;
|
||||||
|
using unaligned_int32_t =
|
||||||
|
detail::packed_endian_specific_integral<int32_t, native, unaligned>;
|
||||||
|
using unaligned_int64_t =
|
||||||
|
detail::packed_endian_specific_integral<int64_t, native, unaligned>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using little_t = detail::packed_endian_specific_integral<T, little, unaligned>;
|
||||||
|
template <typename T>
|
||||||
|
using big_t = detail::packed_endian_specific_integral<T, big, unaligned>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using aligned_little_t =
|
||||||
|
detail::packed_endian_specific_integral<T, little, aligned>;
|
||||||
|
template <typename T>
|
||||||
|
using aligned_big_t = detail::packed_endian_specific_integral<T, big, aligned>;
|
||||||
|
|
||||||
|
namespace endian {
|
||||||
|
|
||||||
|
template <typename T> inline T read(const void *P, endianness E) {
|
||||||
|
return read<T, unaligned>(P, E);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, endianness E> inline T read(const void *P) {
|
||||||
|
return *(const detail::packed_endian_specific_integral<T, E, unaligned> *)P;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint16_t read16(const void *P, endianness E) {
|
||||||
|
return read<uint16_t>(P, E);
|
||||||
|
}
|
||||||
|
inline uint32_t read32(const void *P, endianness E) {
|
||||||
|
return read<uint32_t>(P, E);
|
||||||
|
}
|
||||||
|
inline uint64_t read64(const void *P, endianness E) {
|
||||||
|
return read<uint64_t>(P, E);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <endianness E> inline uint16_t read16(const void *P) {
|
||||||
|
return read<uint16_t, E>(P);
|
||||||
|
}
|
||||||
|
template <endianness E> inline uint32_t read32(const void *P) {
|
||||||
|
return read<uint32_t, E>(P);
|
||||||
|
}
|
||||||
|
template <endianness E> inline uint64_t read64(const void *P) {
|
||||||
|
return read<uint64_t, E>(P);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint16_t read16le(const void *P) { return read16<little>(P); }
|
||||||
|
inline uint32_t read32le(const void *P) { return read32<little>(P); }
|
||||||
|
inline uint64_t read64le(const void *P) { return read64<little>(P); }
|
||||||
|
inline uint16_t read16be(const void *P) { return read16<big>(P); }
|
||||||
|
inline uint32_t read32be(const void *P) { return read32<big>(P); }
|
||||||
|
inline uint64_t read64be(const void *P) { return read64<big>(P); }
|
||||||
|
|
||||||
|
template <typename T> inline void write(void *P, T V, endianness E) {
|
||||||
|
write<T, unaligned>(P, V, E);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, endianness E> inline void write(void *P, T V) {
|
||||||
|
*(detail::packed_endian_specific_integral<T, E, unaligned> *)P = V;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void write16(void *P, uint16_t V, endianness E) {
|
||||||
|
write<uint16_t>(P, V, E);
|
||||||
|
}
|
||||||
|
inline void write32(void *P, uint32_t V, endianness E) {
|
||||||
|
write<uint32_t>(P, V, E);
|
||||||
|
}
|
||||||
|
inline void write64(void *P, uint64_t V, endianness E) {
|
||||||
|
write<uint64_t>(P, V, E);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <endianness E> inline void write16(void *P, uint16_t V) {
|
||||||
|
write<uint16_t, E>(P, V);
|
||||||
|
}
|
||||||
|
template <endianness E> inline void write32(void *P, uint32_t V) {
|
||||||
|
write<uint32_t, E>(P, V);
|
||||||
|
}
|
||||||
|
template <endianness E> inline void write64(void *P, uint64_t V) {
|
||||||
|
write<uint64_t, E>(P, V);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void write16le(void *P, uint16_t V) { write16<little>(P, V); }
|
||||||
|
inline void write32le(void *P, uint32_t V) { write32<little>(P, V); }
|
||||||
|
inline void write64le(void *P, uint64_t V) { write64<little>(P, V); }
|
||||||
|
inline void write16be(void *P, uint16_t V) { write16<big>(P, V); }
|
||||||
|
inline void write32be(void *P, uint32_t V) { write32<big>(P, V); }
|
||||||
|
inline void write64be(void *P, uint64_t V) { write64<big>(P, V); }
|
||||||
|
|
||||||
|
} // end namespace endian
|
||||||
|
|
||||||
|
} // end namespace support
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_SUPPORT_ENDIAN_H
|
||||||
1405
include/swift/RemoteInspection/RuntimeHeaders/llvm/Support/Error.h
Normal file
1405
include/swift/RemoteInspection/RuntimeHeaders/llvm/Support/Error.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,271 @@
|
|||||||
|
//===- llvm/Support/ErrorOr.h - Error Smart Pointer -------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
///
|
||||||
|
/// \file
|
||||||
|
///
|
||||||
|
/// Provides ErrorOr<T> smart pointer.
|
||||||
|
///
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_ERROROR_H
|
||||||
|
#define LLVM_SUPPORT_ERROROR_H
|
||||||
|
|
||||||
|
#include "llvm/Support/AlignOf.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <system_error>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
/// Represents either an error or a value T.
|
||||||
|
///
|
||||||
|
/// ErrorOr<T> is a pointer-like class that represents the result of an
|
||||||
|
/// operation. The result is either an error, or a value of type T. This is
|
||||||
|
/// designed to emulate the usage of returning a pointer where nullptr indicates
|
||||||
|
/// failure. However instead of just knowing that the operation failed, we also
|
||||||
|
/// have an error_code and optional user data that describes why it failed.
|
||||||
|
///
|
||||||
|
/// It is used like the following.
|
||||||
|
/// \code
|
||||||
|
/// ErrorOr<Buffer> getBuffer();
|
||||||
|
///
|
||||||
|
/// auto buffer = getBuffer();
|
||||||
|
/// if (error_code ec = buffer.getError())
|
||||||
|
/// return ec;
|
||||||
|
/// buffer->write("adena");
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// Implicit conversion to bool returns true if there is a usable value. The
|
||||||
|
/// unary * and -> operators provide pointer like access to the value. Accessing
|
||||||
|
/// the value when there is an error has undefined behavior.
|
||||||
|
///
|
||||||
|
/// When T is a reference type the behavior is slightly different. The reference
|
||||||
|
/// is held in a std::reference_wrapper<std::remove_reference<T>::type>, and
|
||||||
|
/// there is special handling to make operator -> work as if T was not a
|
||||||
|
/// reference.
|
||||||
|
///
|
||||||
|
/// T cannot be a rvalue reference.
|
||||||
|
template<class T>
|
||||||
|
class ErrorOr {
|
||||||
|
template <class OtherT> friend class ErrorOr;
|
||||||
|
|
||||||
|
static constexpr bool isRef = std::is_reference_v<T>;
|
||||||
|
|
||||||
|
using wrap = std::reference_wrapper<std::remove_reference_t<T>>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using storage_type = std::conditional_t<isRef, wrap, T>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
using reference = std::remove_reference_t<T> &;
|
||||||
|
using const_reference = const std::remove_reference_t<T> &;
|
||||||
|
using pointer = std::remove_reference_t<T> *;
|
||||||
|
using const_pointer = const std::remove_reference_t<T> *;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <class E>
|
||||||
|
ErrorOr(E ErrorCode,
|
||||||
|
std::enable_if_t<std::is_error_code_enum<E>::value ||
|
||||||
|
std::is_error_condition_enum<E>::value,
|
||||||
|
void *> = nullptr)
|
||||||
|
: HasError(true) {
|
||||||
|
new (getErrorStorage()) std::error_code(make_error_code(ErrorCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr(std::error_code EC) : HasError(true) {
|
||||||
|
new (getErrorStorage()) std::error_code(EC);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherT>
|
||||||
|
ErrorOr(OtherT &&Val,
|
||||||
|
std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)
|
||||||
|
: HasError(false) {
|
||||||
|
new (getStorage()) storage_type(std::forward<OtherT>(Val));
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr(const ErrorOr &Other) {
|
||||||
|
copyConstruct(Other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherT>
|
||||||
|
ErrorOr(const ErrorOr<OtherT> &Other,
|
||||||
|
std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr) {
|
||||||
|
copyConstruct(Other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherT>
|
||||||
|
explicit ErrorOr(
|
||||||
|
const ErrorOr<OtherT> &Other,
|
||||||
|
std::enable_if_t<!std::is_convertible_v<OtherT, const T &>> * = nullptr) {
|
||||||
|
copyConstruct(Other);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr(ErrorOr &&Other) {
|
||||||
|
moveConstruct(std::move(Other));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherT>
|
||||||
|
ErrorOr(ErrorOr<OtherT> &&Other,
|
||||||
|
std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr) {
|
||||||
|
moveConstruct(std::move(Other));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This might eventually need SFINAE but it's more complex than is_convertible
|
||||||
|
// & I'm too lazy to write it right now.
|
||||||
|
template <class OtherT>
|
||||||
|
explicit ErrorOr(
|
||||||
|
ErrorOr<OtherT> &&Other,
|
||||||
|
std::enable_if_t<!std::is_convertible_v<OtherT, T>> * = nullptr) {
|
||||||
|
moveConstruct(std::move(Other));
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr &operator=(const ErrorOr &Other) {
|
||||||
|
copyAssign(Other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr &operator=(ErrorOr &&Other) {
|
||||||
|
moveAssign(std::move(Other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ErrorOr() {
|
||||||
|
if (!HasError)
|
||||||
|
getStorage()->~storage_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return false if there is an error.
|
||||||
|
explicit operator bool() const {
|
||||||
|
return !HasError;
|
||||||
|
}
|
||||||
|
|
||||||
|
reference get() { return *getStorage(); }
|
||||||
|
const_reference get() const { return const_cast<ErrorOr<T> *>(this)->get(); }
|
||||||
|
|
||||||
|
std::error_code getError() const {
|
||||||
|
return HasError ? *getErrorStorage() : std::error_code();
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer operator ->() {
|
||||||
|
return toPointer(getStorage());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_pointer operator->() const { return toPointer(getStorage()); }
|
||||||
|
|
||||||
|
reference operator *() {
|
||||||
|
return *getStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference operator*() const { return *getStorage(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <class OtherT>
|
||||||
|
void copyConstruct(const ErrorOr<OtherT> &Other) {
|
||||||
|
if (!Other.HasError) {
|
||||||
|
// Get the other value.
|
||||||
|
HasError = false;
|
||||||
|
new (getStorage()) storage_type(*Other.getStorage());
|
||||||
|
} else {
|
||||||
|
// Get other's error.
|
||||||
|
HasError = true;
|
||||||
|
new (getErrorStorage()) std::error_code(Other.getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T1>
|
||||||
|
static bool compareThisIfSameType(const T1 &a, const T1 &b) {
|
||||||
|
return &a == &b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
static bool compareThisIfSameType(const T1 &a, const T2 &b) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherT>
|
||||||
|
void copyAssign(const ErrorOr<OtherT> &Other) {
|
||||||
|
if (compareThisIfSameType(*this, Other))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->~ErrorOr();
|
||||||
|
new (this) ErrorOr(Other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherT>
|
||||||
|
void moveConstruct(ErrorOr<OtherT> &&Other) {
|
||||||
|
if (!Other.HasError) {
|
||||||
|
// Get the other value.
|
||||||
|
HasError = false;
|
||||||
|
new (getStorage()) storage_type(std::move(*Other.getStorage()));
|
||||||
|
} else {
|
||||||
|
// Get other's error.
|
||||||
|
HasError = true;
|
||||||
|
new (getErrorStorage()) std::error_code(Other.getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherT>
|
||||||
|
void moveAssign(ErrorOr<OtherT> &&Other) {
|
||||||
|
if (compareThisIfSameType(*this, Other))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->~ErrorOr();
|
||||||
|
new (this) ErrorOr(std::move(Other));
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer toPointer(pointer Val) {
|
||||||
|
return Val;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_pointer toPointer(const_pointer Val) const { return Val; }
|
||||||
|
|
||||||
|
pointer toPointer(wrap *Val) {
|
||||||
|
return &Val->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_pointer toPointer(const wrap *Val) const { return &Val->get(); }
|
||||||
|
|
||||||
|
storage_type *getStorage() {
|
||||||
|
assert(!HasError && "Cannot get value when an error exists!");
|
||||||
|
return reinterpret_cast<storage_type *>(&TStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
const storage_type *getStorage() const {
|
||||||
|
assert(!HasError && "Cannot get value when an error exists!");
|
||||||
|
return reinterpret_cast<const storage_type *>(&TStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::error_code *getErrorStorage() {
|
||||||
|
assert(HasError && "Cannot get error when a value exists!");
|
||||||
|
return reinterpret_cast<std::error_code *>(&ErrorStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::error_code *getErrorStorage() const {
|
||||||
|
return const_cast<ErrorOr<T> *>(this)->getErrorStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
union {
|
||||||
|
AlignedCharArrayUnion<storage_type> TStorage;
|
||||||
|
AlignedCharArrayUnion<std::error_code> ErrorStorage;
|
||||||
|
};
|
||||||
|
bool HasError : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class E>
|
||||||
|
std::enable_if_t<std::is_error_code_enum<E>::value ||
|
||||||
|
std::is_error_condition_enum<E>::value,
|
||||||
|
bool>
|
||||||
|
operator==(const ErrorOr<T> &Err, E Code) {
|
||||||
|
return Err.getError() == Code;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_SUPPORT_ERROROR_H
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
//=== FileOutputBuffer.h - File Output Buffer -------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Utility for creating a in-memory buffer that will be written to a file.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H
|
||||||
|
#define LLVM_SUPPORT_FILEOUTPUTBUFFER_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
/// FileOutputBuffer - This interface provides simple way to create an in-memory
|
||||||
|
/// buffer which will be written to a file. During the lifetime of these
|
||||||
|
/// objects, the content or existence of the specified file is undefined. That
|
||||||
|
/// is, creating an OutputBuffer for a file may immediately remove the file.
|
||||||
|
/// If the FileOutputBuffer is committed, the target file's content will become
|
||||||
|
/// the buffer content at the time of the commit. If the FileOutputBuffer is
|
||||||
|
/// not committed, the file will be deleted in the FileOutputBuffer destructor.
|
||||||
|
class FileOutputBuffer {
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
/// Set the 'x' bit on the resulting file.
|
||||||
|
F_executable = 1,
|
||||||
|
|
||||||
|
/// Don't use mmap and instead write an in-memory buffer to a file when this
|
||||||
|
/// buffer is closed.
|
||||||
|
F_no_mmap = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Factory method to create an OutputBuffer object which manages a read/write
|
||||||
|
/// buffer of the specified size. When committed, the buffer will be written
|
||||||
|
/// to the file at the specified path.
|
||||||
|
///
|
||||||
|
/// When F_modify is specified and \p FilePath refers to an existing on-disk
|
||||||
|
/// file \p Size may be set to -1, in which case the entire file is used.
|
||||||
|
/// Otherwise, the file shrinks or grows as necessary based on the value of
|
||||||
|
/// \p Size. It is an error to specify F_modify and Size=-1 if \p FilePath
|
||||||
|
/// does not exist.
|
||||||
|
static Expected<std::unique_ptr<FileOutputBuffer>>
|
||||||
|
create(StringRef FilePath, size_t Size, unsigned Flags = 0);
|
||||||
|
|
||||||
|
/// Returns a pointer to the start of the buffer.
|
||||||
|
virtual uint8_t *getBufferStart() const = 0;
|
||||||
|
|
||||||
|
/// Returns a pointer to the end of the buffer.
|
||||||
|
virtual uint8_t *getBufferEnd() const = 0;
|
||||||
|
|
||||||
|
/// Returns size of the buffer.
|
||||||
|
virtual size_t getBufferSize() const = 0;
|
||||||
|
|
||||||
|
/// Returns path where file will show up if buffer is committed.
|
||||||
|
StringRef getPath() const { return FinalPath; }
|
||||||
|
|
||||||
|
/// Flushes the content of the buffer to its file and deallocates the
|
||||||
|
/// buffer. If commit() is not called before this object's destructor
|
||||||
|
/// is called, the file is deleted in the destructor. The optional parameter
|
||||||
|
/// is used if it turns out you want the file size to be smaller than
|
||||||
|
/// initially requested.
|
||||||
|
virtual Error commit() = 0;
|
||||||
|
|
||||||
|
/// If this object was previously committed, the destructor just deletes
|
||||||
|
/// this object. If this object was not committed, the destructor
|
||||||
|
/// deallocates the buffer and the target file is never written.
|
||||||
|
virtual ~FileOutputBuffer() = default;
|
||||||
|
|
||||||
|
/// This removes the temporary file (unless it already was committed)
|
||||||
|
/// but keeps the memory mapping alive.
|
||||||
|
virtual void discard() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FileOutputBuffer(StringRef Path) : FinalPath(Path) {}
|
||||||
|
|
||||||
|
std::string FinalPath;
|
||||||
|
};
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,260 @@
|
|||||||
|
//===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file implements the format() function, which can be used with other
|
||||||
|
// LLVM subsystems to provide printf-style formatting. This gives all the power
|
||||||
|
// and risk of printf. This can be used like this (with raw_ostreams as an
|
||||||
|
// example):
|
||||||
|
//
|
||||||
|
// OS << "mynumber: " << format("%4.5f", 1234.412) << '\n';
|
||||||
|
//
|
||||||
|
// Or if you prefer:
|
||||||
|
//
|
||||||
|
// OS << format("mynumber: %4.5f\n", 1234.412);
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_FORMAT_H
|
||||||
|
#define LLVM_SUPPORT_FORMAT_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <optional>
|
||||||
|
#include <tuple>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
/// This is a helper class used for handling formatted output. It is the
|
||||||
|
/// abstract base class of a templated derived class.
|
||||||
|
class format_object_base {
|
||||||
|
protected:
|
||||||
|
const char *Fmt;
|
||||||
|
~format_object_base() = default; // Disallow polymorphic deletion.
|
||||||
|
format_object_base(const format_object_base &) = default;
|
||||||
|
virtual void home(); // Out of line virtual method.
|
||||||
|
|
||||||
|
/// Call snprintf() for this object, on the given buffer and size.
|
||||||
|
virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
format_object_base(const char *fmt) : Fmt(fmt) {}
|
||||||
|
|
||||||
|
/// Format the object into the specified buffer. On success, this returns
|
||||||
|
/// the length of the formatted string. If the buffer is too small, this
|
||||||
|
/// returns a length to retry with, which will be larger than BufferSize.
|
||||||
|
unsigned print(char *Buffer, unsigned BufferSize) const {
|
||||||
|
assert(BufferSize && "Invalid buffer size!");
|
||||||
|
|
||||||
|
// Print the string, leaving room for the terminating null.
|
||||||
|
int N = snprint(Buffer, BufferSize);
|
||||||
|
|
||||||
|
// VC++ and old GlibC return negative on overflow, just double the size.
|
||||||
|
if (N < 0)
|
||||||
|
return BufferSize * 2;
|
||||||
|
|
||||||
|
// Other implementations yield number of bytes needed, not including the
|
||||||
|
// final '\0'.
|
||||||
|
if (unsigned(N) >= BufferSize)
|
||||||
|
return N + 1;
|
||||||
|
|
||||||
|
// Otherwise N is the length of output (not including the final '\0').
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// These are templated helper classes used by the format function that
|
||||||
|
/// capture the object to be formatted and the format string. When actually
|
||||||
|
/// printed, this synthesizes the string into a temporary buffer provided and
|
||||||
|
/// returns whether or not it is big enough.
|
||||||
|
|
||||||
|
// Helper to validate that format() parameters are scalars or pointers.
|
||||||
|
template <typename... Args> struct validate_format_parameters;
|
||||||
|
template <typename Arg, typename... Args>
|
||||||
|
struct validate_format_parameters<Arg, Args...> {
|
||||||
|
static_assert(std::is_scalar_v<Arg>,
|
||||||
|
"format can't be used with non fundamental / non pointer type");
|
||||||
|
validate_format_parameters() { validate_format_parameters<Args...>(); }
|
||||||
|
};
|
||||||
|
template <> struct validate_format_parameters<> {};
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
class format_object final : public format_object_base {
|
||||||
|
std::tuple<Ts...> Vals;
|
||||||
|
|
||||||
|
template <std::size_t... Is>
|
||||||
|
int snprint_tuple(char *Buffer, unsigned BufferSize,
|
||||||
|
std::index_sequence<Is...>) const {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
return _snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
|
||||||
|
#else
|
||||||
|
return snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
format_object(const char *fmt, const Ts &... vals)
|
||||||
|
: format_object_base(fmt), Vals(vals...) {
|
||||||
|
validate_format_parameters<Ts...>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int snprint(char *Buffer, unsigned BufferSize) const override {
|
||||||
|
return snprint_tuple(Buffer, BufferSize, std::index_sequence_for<Ts...>());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// These are helper functions used to produce formatted output. They use
|
||||||
|
/// template type deduction to construct the appropriate instance of the
|
||||||
|
/// format_object class to simplify their construction.
|
||||||
|
///
|
||||||
|
/// This is typically used like:
|
||||||
|
/// \code
|
||||||
|
/// OS << format("%0.4f", myfloat) << '\n';
|
||||||
|
/// \endcode
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
inline format_object<Ts...> format(const char *Fmt, const Ts &... Vals) {
|
||||||
|
return format_object<Ts...>(Fmt, Vals...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is a helper class for left_justify, right_justify, and center_justify.
|
||||||
|
class FormattedString {
|
||||||
|
public:
|
||||||
|
enum Justification { JustifyNone, JustifyLeft, JustifyRight, JustifyCenter };
|
||||||
|
FormattedString(StringRef S, unsigned W, Justification J)
|
||||||
|
: Str(S), Width(W), Justify(J) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
StringRef Str;
|
||||||
|
unsigned Width;
|
||||||
|
Justification Justify;
|
||||||
|
friend class raw_ostream;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// left_justify - append spaces after string so total output is
|
||||||
|
/// \p Width characters. If \p Str is larger that \p Width, full string
|
||||||
|
/// is written with no padding.
|
||||||
|
inline FormattedString left_justify(StringRef Str, unsigned Width) {
|
||||||
|
return FormattedString(Str, Width, FormattedString::JustifyLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// right_justify - add spaces before string so total output is
|
||||||
|
/// \p Width characters. If \p Str is larger that \p Width, full string
|
||||||
|
/// is written with no padding.
|
||||||
|
inline FormattedString right_justify(StringRef Str, unsigned Width) {
|
||||||
|
return FormattedString(Str, Width, FormattedString::JustifyRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// center_justify - add spaces before and after string so total output is
|
||||||
|
/// \p Width characters. If \p Str is larger that \p Width, full string
|
||||||
|
/// is written with no padding.
|
||||||
|
inline FormattedString center_justify(StringRef Str, unsigned Width) {
|
||||||
|
return FormattedString(Str, Width, FormattedString::JustifyCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is a helper class used for format_hex() and format_decimal().
|
||||||
|
class FormattedNumber {
|
||||||
|
uint64_t HexValue;
|
||||||
|
int64_t DecValue;
|
||||||
|
unsigned Width;
|
||||||
|
bool Hex;
|
||||||
|
bool Upper;
|
||||||
|
bool HexPrefix;
|
||||||
|
friend class raw_ostream;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U,
|
||||||
|
bool Prefix)
|
||||||
|
: HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U),
|
||||||
|
HexPrefix(Prefix) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// format_hex - Output \p N as a fixed width hexadecimal. If number will not
|
||||||
|
/// fit in width, full number is still printed. Examples:
|
||||||
|
/// OS << format_hex(255, 4) => 0xff
|
||||||
|
/// OS << format_hex(255, 4, true) => 0xFF
|
||||||
|
/// OS << format_hex(255, 6) => 0x00ff
|
||||||
|
/// OS << format_hex(255, 2) => 0xff
|
||||||
|
inline FormattedNumber format_hex(uint64_t N, unsigned Width,
|
||||||
|
bool Upper = false) {
|
||||||
|
assert(Width <= 18 && "hex width must be <= 18");
|
||||||
|
return FormattedNumber(N, 0, Width, true, Upper, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// format_hex_no_prefix - Output \p N as a fixed width hexadecimal. Does not
|
||||||
|
/// prepend '0x' to the outputted string. If number will not fit in width,
|
||||||
|
/// full number is still printed. Examples:
|
||||||
|
/// OS << format_hex_no_prefix(255, 2) => ff
|
||||||
|
/// OS << format_hex_no_prefix(255, 2, true) => FF
|
||||||
|
/// OS << format_hex_no_prefix(255, 4) => 00ff
|
||||||
|
/// OS << format_hex_no_prefix(255, 1) => ff
|
||||||
|
inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width,
|
||||||
|
bool Upper = false) {
|
||||||
|
assert(Width <= 16 && "hex width must be <= 16");
|
||||||
|
return FormattedNumber(N, 0, Width, true, Upper, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// format_decimal - Output \p N as a right justified, fixed-width decimal. If
|
||||||
|
/// number will not fit in width, full number is still printed. Examples:
|
||||||
|
/// OS << format_decimal(0, 5) => " 0"
|
||||||
|
/// OS << format_decimal(255, 5) => " 255"
|
||||||
|
/// OS << format_decimal(-1, 3) => " -1"
|
||||||
|
/// OS << format_decimal(12345, 3) => "12345"
|
||||||
|
inline FormattedNumber format_decimal(int64_t N, unsigned Width) {
|
||||||
|
return FormattedNumber(0, N, Width, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FormattedBytes {
|
||||||
|
ArrayRef<uint8_t> Bytes;
|
||||||
|
|
||||||
|
// If not std::nullopt, display offsets for each line relative to starting
|
||||||
|
// value.
|
||||||
|
std::optional<uint64_t> FirstByteOffset;
|
||||||
|
uint32_t IndentLevel; // Number of characters to indent each line.
|
||||||
|
uint32_t NumPerLine; // Number of bytes to show per line.
|
||||||
|
uint8_t ByteGroupSize; // How many hex bytes are grouped without spaces
|
||||||
|
bool Upper; // Show offset and hex bytes as upper case.
|
||||||
|
bool ASCII; // Show the ASCII bytes for the hex bytes to the right.
|
||||||
|
friend class raw_ostream;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FormattedBytes(ArrayRef<uint8_t> B, uint32_t IL, std::optional<uint64_t> O,
|
||||||
|
uint32_t NPL, uint8_t BGS, bool U, bool A)
|
||||||
|
: Bytes(B), FirstByteOffset(O), IndentLevel(IL), NumPerLine(NPL),
|
||||||
|
ByteGroupSize(BGS), Upper(U), ASCII(A) {
|
||||||
|
|
||||||
|
if (ByteGroupSize > NumPerLine)
|
||||||
|
ByteGroupSize = NumPerLine;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline FormattedBytes
|
||||||
|
format_bytes(ArrayRef<uint8_t> Bytes,
|
||||||
|
std::optional<uint64_t> FirstByteOffset = std::nullopt,
|
||||||
|
uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4,
|
||||||
|
uint32_t IndentLevel = 0, bool Upper = false) {
|
||||||
|
return FormattedBytes(Bytes, IndentLevel, FirstByteOffset, NumPerLine,
|
||||||
|
ByteGroupSize, Upper, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FormattedBytes
|
||||||
|
format_bytes_with_ascii(ArrayRef<uint8_t> Bytes,
|
||||||
|
std::optional<uint64_t> FirstByteOffset = std::nullopt,
|
||||||
|
uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4,
|
||||||
|
uint32_t IndentLevel = 0, bool Upper = false) {
|
||||||
|
return FormattedBytes(Bytes, IndentLevel, FirstByteOffset, NumPerLine,
|
||||||
|
ByteGroupSize, Upper, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
//===- llvm/Support/Memory.h - Memory Support -------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file declares the llvm::sys::Memory class.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_MEMORY_H
|
||||||
|
#define LLVM_SUPPORT_MEMORY_H
|
||||||
|
|
||||||
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
// Forward declare raw_ostream: it is used for debug dumping below.
|
||||||
|
class raw_ostream;
|
||||||
|
|
||||||
|
namespace sys {
|
||||||
|
|
||||||
|
/// This class encapsulates the notion of a memory block which has an address
|
||||||
|
/// and a size. It is used by the Memory class (a friend) as the result of
|
||||||
|
/// various memory allocation operations.
|
||||||
|
/// @see Memory
|
||||||
|
/// Memory block abstraction.
|
||||||
|
class MemoryBlock {
|
||||||
|
public:
|
||||||
|
MemoryBlock() : Address(nullptr), AllocatedSize(0) {}
|
||||||
|
MemoryBlock(void *addr, size_t allocatedSize)
|
||||||
|
: Address(addr), AllocatedSize(allocatedSize) {}
|
||||||
|
void *base() const { return Address; }
|
||||||
|
/// The size as it was allocated. This is always greater or equal to the
|
||||||
|
/// size that was originally requested.
|
||||||
|
size_t allocatedSize() const { return AllocatedSize; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void *Address; ///< Address of first byte of memory area
|
||||||
|
size_t AllocatedSize; ///< Size, in bytes of the memory area
|
||||||
|
unsigned Flags = 0;
|
||||||
|
friend class Memory;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// This class provides various memory handling functions that manipulate
|
||||||
|
/// MemoryBlock instances.
|
||||||
|
/// @since 1.4
|
||||||
|
/// An abstraction for memory operations.
|
||||||
|
class Memory {
|
||||||
|
public:
|
||||||
|
enum ProtectionFlags {
|
||||||
|
MF_READ = 0x1000000,
|
||||||
|
MF_WRITE = 0x2000000,
|
||||||
|
MF_EXEC = 0x4000000,
|
||||||
|
MF_RWE_MASK = 0x7000000,
|
||||||
|
|
||||||
|
/// The \p MF_HUGE_HINT flag is used to indicate that the request for
|
||||||
|
/// a memory block should be satisfied with large pages if possible.
|
||||||
|
/// This is only a hint and small pages will be used as fallback.
|
||||||
|
///
|
||||||
|
/// The presence or absence of this flag in the returned memory block
|
||||||
|
/// is (at least currently) *not* a reliable indicator that the memory
|
||||||
|
/// block will use or will not use large pages. On some systems a request
|
||||||
|
/// without this flag can be backed by large pages without this flag being
|
||||||
|
/// set, and on some other systems a request with this flag can fallback
|
||||||
|
/// to small pages without this flag being cleared.
|
||||||
|
MF_HUGE_HINT = 0x0000001
|
||||||
|
};
|
||||||
|
|
||||||
|
/// This method allocates a block of memory that is suitable for loading
|
||||||
|
/// dynamically generated code (e.g. JIT). An attempt to allocate
|
||||||
|
/// \p NumBytes bytes of virtual memory is made.
|
||||||
|
/// \p NearBlock may point to an existing allocation in which case
|
||||||
|
/// an attempt is made to allocate more memory near the existing block.
|
||||||
|
/// The actual allocated address is not guaranteed to be near the requested
|
||||||
|
/// address.
|
||||||
|
/// \p Flags is used to set the initial protection flags for the block
|
||||||
|
/// of the memory.
|
||||||
|
/// \p EC [out] returns an object describing any error that occurs.
|
||||||
|
///
|
||||||
|
/// This method may allocate more than the number of bytes requested. The
|
||||||
|
/// actual number of bytes allocated is indicated in the returned
|
||||||
|
/// MemoryBlock.
|
||||||
|
///
|
||||||
|
/// The start of the allocated block must be aligned with the
|
||||||
|
/// system allocation granularity (64K on Windows, page size on Linux).
|
||||||
|
/// If the address following \p NearBlock is not so aligned, it will be
|
||||||
|
/// rounded up to the next allocation granularity boundary.
|
||||||
|
///
|
||||||
|
/// \r a non-null MemoryBlock if the function was successful,
|
||||||
|
/// otherwise a null MemoryBlock is with \p EC describing the error.
|
||||||
|
///
|
||||||
|
/// Allocate mapped memory.
|
||||||
|
static MemoryBlock allocateMappedMemory(size_t NumBytes,
|
||||||
|
const MemoryBlock *const NearBlock,
|
||||||
|
unsigned Flags,
|
||||||
|
std::error_code &EC);
|
||||||
|
|
||||||
|
/// This method releases a block of memory that was allocated with the
|
||||||
|
/// allocateMappedMemory method. It should not be used to release any
|
||||||
|
/// memory block allocated any other way.
|
||||||
|
/// \p Block describes the memory to be released.
|
||||||
|
///
|
||||||
|
/// \r error_success if the function was successful, or an error_code
|
||||||
|
/// describing the failure if an error occurred.
|
||||||
|
///
|
||||||
|
/// Release mapped memory.
|
||||||
|
static std::error_code releaseMappedMemory(MemoryBlock &Block);
|
||||||
|
|
||||||
|
/// This method sets the protection flags for a block of memory to the
|
||||||
|
/// state specified by /p Flags. The behavior is not specified if the
|
||||||
|
/// memory was not allocated using the allocateMappedMemory method.
|
||||||
|
/// \p Block describes the memory block to be protected.
|
||||||
|
/// \p Flags specifies the new protection state to be assigned to the block.
|
||||||
|
///
|
||||||
|
/// If \p Flags is MF_WRITE, the actual behavior varies
|
||||||
|
/// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the
|
||||||
|
/// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386).
|
||||||
|
///
|
||||||
|
/// \r error_success if the function was successful, or an error_code
|
||||||
|
/// describing the failure if an error occurred.
|
||||||
|
///
|
||||||
|
/// Set memory protection state.
|
||||||
|
static std::error_code protectMappedMemory(const MemoryBlock &Block,
|
||||||
|
unsigned Flags);
|
||||||
|
|
||||||
|
/// InvalidateInstructionCache - Before the JIT can run a block of code
|
||||||
|
/// that has been emitted it must invalidate the instruction cache on some
|
||||||
|
/// platforms.
|
||||||
|
static void InvalidateInstructionCache(const void *Addr, size_t Len);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Owning version of MemoryBlock.
|
||||||
|
class OwningMemoryBlock {
|
||||||
|
public:
|
||||||
|
OwningMemoryBlock() = default;
|
||||||
|
explicit OwningMemoryBlock(MemoryBlock M) : M(M) {}
|
||||||
|
OwningMemoryBlock(OwningMemoryBlock &&Other) {
|
||||||
|
M = Other.M;
|
||||||
|
Other.M = MemoryBlock();
|
||||||
|
}
|
||||||
|
OwningMemoryBlock& operator=(OwningMemoryBlock &&Other) {
|
||||||
|
M = Other.M;
|
||||||
|
Other.M = MemoryBlock();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
~OwningMemoryBlock() {
|
||||||
|
if (M.base())
|
||||||
|
Memory::releaseMappedMemory(M);
|
||||||
|
}
|
||||||
|
void *base() const { return M.base(); }
|
||||||
|
/// The size as it was allocated. This is always greater or equal to the
|
||||||
|
/// size that was originally requested.
|
||||||
|
size_t allocatedSize() const { return M.allocatedSize(); }
|
||||||
|
MemoryBlock getMemoryBlock() const { return M; }
|
||||||
|
std::error_code release() {
|
||||||
|
std::error_code EC;
|
||||||
|
if (M.base()) {
|
||||||
|
EC = Memory::releaseMappedMemory(M);
|
||||||
|
M = MemoryBlock();
|
||||||
|
}
|
||||||
|
return EC;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
MemoryBlock M;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
/// Debugging output for Memory::ProtectionFlags.
|
||||||
|
raw_ostream &operator<<(raw_ostream &OS, const Memory::ProtectionFlags &PF);
|
||||||
|
|
||||||
|
/// Debugging output for MemoryBlock.
|
||||||
|
raw_ostream &operator<<(raw_ostream &OS, const MemoryBlock &MB);
|
||||||
|
#endif // ifndef NDEBUG
|
||||||
|
} // end namespace sys
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
//===--- MemoryBuffer.h - Memory Buffer Interface ---------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file defines the MemoryBuffer interface.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
|
||||||
|
#define LLVM_SUPPORT_MEMORYBUFFER_H
|
||||||
|
|
||||||
|
#include "llvm-c/Types.h"
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/ADT/Twine.h"
|
||||||
|
#include "llvm/Support/Alignment.h"
|
||||||
|
#include "llvm/Support/CBindingWrapping.h"
|
||||||
|
#include "llvm/Support/ErrorOr.h"
|
||||||
|
#include "llvm/Support/MemoryBufferRef.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace sys {
|
||||||
|
namespace fs {
|
||||||
|
// Duplicated from FileSystem.h to avoid a dependency.
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// A Win32 HANDLE is a typedef of void*
|
||||||
|
using file_t = void *;
|
||||||
|
#else
|
||||||
|
using file_t = int;
|
||||||
|
#endif
|
||||||
|
} // namespace fs
|
||||||
|
} // namespace sys
|
||||||
|
|
||||||
|
/// This interface provides simple read-only access to a block of memory, and
|
||||||
|
/// provides simple methods for reading files and standard input into a memory
|
||||||
|
/// buffer. In addition to basic access to the characters in the file, this
|
||||||
|
/// interface guarantees you can read one character past the end of the file,
|
||||||
|
/// and that this character will read as '\0'.
|
||||||
|
///
|
||||||
|
/// The '\0' guarantee is needed to support an optimization -- it's intended to
|
||||||
|
/// be more efficient for clients which are reading all the data to stop
|
||||||
|
/// reading when they encounter a '\0' than to continually check the file
|
||||||
|
/// position to see if it has reached the end of the file.
|
||||||
|
class MemoryBuffer {
|
||||||
|
const char *BufferStart; // Start of the buffer.
|
||||||
|
const char *BufferEnd; // End of the buffer.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MemoryBuffer() = default;
|
||||||
|
|
||||||
|
void init(const char *BufStart, const char *BufEnd,
|
||||||
|
bool RequiresNullTerminator);
|
||||||
|
|
||||||
|
public:
|
||||||
|
MemoryBuffer(const MemoryBuffer &) = delete;
|
||||||
|
MemoryBuffer &operator=(const MemoryBuffer &) = delete;
|
||||||
|
virtual ~MemoryBuffer();
|
||||||
|
|
||||||
|
const char *getBufferStart() const { return BufferStart; }
|
||||||
|
const char *getBufferEnd() const { return BufferEnd; }
|
||||||
|
size_t getBufferSize() const { return BufferEnd-BufferStart; }
|
||||||
|
|
||||||
|
StringRef getBuffer() const {
|
||||||
|
return StringRef(BufferStart, getBufferSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return an identifier for this buffer, typically the filename it was read
|
||||||
|
/// from.
|
||||||
|
virtual StringRef getBufferIdentifier() const { return "Unknown buffer"; }
|
||||||
|
|
||||||
|
/// For read-only MemoryBuffer_MMap, mark the buffer as unused in the near
|
||||||
|
/// future and the kernel can free resources associated with it. Further
|
||||||
|
/// access is supported but may be expensive. This calls
|
||||||
|
/// madvise(MADV_DONTNEED) on read-only file mappings on *NIX systems. This
|
||||||
|
/// function should not be called on a writable buffer.
|
||||||
|
virtual void dontNeedIfMmap() {}
|
||||||
|
|
||||||
|
/// Open the specified file as a MemoryBuffer, returning a new MemoryBuffer
|
||||||
|
/// if successful, otherwise returning null.
|
||||||
|
///
|
||||||
|
/// \param IsText Set to true to indicate that the file should be read in
|
||||||
|
/// text mode.
|
||||||
|
///
|
||||||
|
/// \param IsVolatile Set to true to indicate that the contents of the file
|
||||||
|
/// can change outside the user's control, e.g. when libclang tries to parse
|
||||||
|
/// while the user is editing/updating the file or if the file is on an NFS.
|
||||||
|
///
|
||||||
|
/// \param Alignment Set to indicate that the buffer should be aligned to at
|
||||||
|
/// least the specified alignment.
|
||||||
|
static ErrorOr<std::unique_ptr<MemoryBuffer>>
|
||||||
|
getFile(const Twine &Filename, bool IsText = false,
|
||||||
|
bool RequiresNullTerminator = true, bool IsVolatile = false,
|
||||||
|
std::optional<Align> Alignment = std::nullopt);
|
||||||
|
|
||||||
|
/// Read all of the specified file into a MemoryBuffer as a stream
|
||||||
|
/// (i.e. until EOF reached). This is useful for special files that
|
||||||
|
/// look like a regular file but have 0 size (e.g. /proc/cpuinfo on Linux).
|
||||||
|
static ErrorOr<std::unique_ptr<MemoryBuffer>>
|
||||||
|
getFileAsStream(const Twine &Filename);
|
||||||
|
|
||||||
|
/// Given an already-open file descriptor, map some slice of it into a
|
||||||
|
/// MemoryBuffer. The slice is specified by an \p Offset and \p MapSize.
|
||||||
|
/// Since this is in the middle of a file, the buffer is not null terminated.
|
||||||
|
static ErrorOr<std::unique_ptr<MemoryBuffer>>
|
||||||
|
getOpenFileSlice(sys::fs::file_t FD, const Twine &Filename, uint64_t MapSize,
|
||||||
|
int64_t Offset, bool IsVolatile = false,
|
||||||
|
std::optional<Align> Alignment = std::nullopt);
|
||||||
|
|
||||||
|
/// Given an already-open file descriptor, read the file and return a
|
||||||
|
/// MemoryBuffer.
|
||||||
|
///
|
||||||
|
/// \param IsVolatile Set to true to indicate that the contents of the file
|
||||||
|
/// can change outside the user's control, e.g. when libclang tries to parse
|
||||||
|
/// while the user is editing/updating the file or if the file is on an NFS.
|
||||||
|
///
|
||||||
|
/// \param Alignment Set to indicate that the buffer should be aligned to at
|
||||||
|
/// least the specified alignment.
|
||||||
|
static ErrorOr<std::unique_ptr<MemoryBuffer>>
|
||||||
|
getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize,
|
||||||
|
bool RequiresNullTerminator = true, bool IsVolatile = false,
|
||||||
|
std::optional<Align> Alignment = std::nullopt);
|
||||||
|
|
||||||
|
/// Open the specified memory range as a MemoryBuffer. Note that InputData
|
||||||
|
/// must be null terminated if RequiresNullTerminator is true.
|
||||||
|
static std::unique_ptr<MemoryBuffer>
|
||||||
|
getMemBuffer(StringRef InputData, StringRef BufferName = "",
|
||||||
|
bool RequiresNullTerminator = true);
|
||||||
|
|
||||||
|
static std::unique_ptr<MemoryBuffer>
|
||||||
|
getMemBuffer(MemoryBufferRef Ref, bool RequiresNullTerminator = true);
|
||||||
|
|
||||||
|
/// Open the specified memory range as a MemoryBuffer, copying the contents
|
||||||
|
/// and taking ownership of it. InputData does not have to be null terminated.
|
||||||
|
static std::unique_ptr<MemoryBuffer>
|
||||||
|
getMemBufferCopy(StringRef InputData, const Twine &BufferName = "");
|
||||||
|
|
||||||
|
/// Read all of stdin into a file buffer, and return it.
|
||||||
|
static ErrorOr<std::unique_ptr<MemoryBuffer>> getSTDIN();
|
||||||
|
|
||||||
|
/// Open the specified file as a MemoryBuffer, or open stdin if the Filename
|
||||||
|
/// is "-".
|
||||||
|
static ErrorOr<std::unique_ptr<MemoryBuffer>>
|
||||||
|
getFileOrSTDIN(const Twine &Filename, bool IsText = false,
|
||||||
|
bool RequiresNullTerminator = true,
|
||||||
|
std::optional<Align> Alignment = std::nullopt);
|
||||||
|
|
||||||
|
/// Map a subrange of the specified file as a MemoryBuffer.
|
||||||
|
static ErrorOr<std::unique_ptr<MemoryBuffer>>
|
||||||
|
getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset,
|
||||||
|
bool IsVolatile = false,
|
||||||
|
std::optional<Align> Alignment = std::nullopt);
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
// Provided for performance analysis.
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// The kind of memory backing used to support the MemoryBuffer.
|
||||||
|
enum BufferKind {
|
||||||
|
MemoryBuffer_Malloc,
|
||||||
|
MemoryBuffer_MMap
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Return information on the memory mechanism used to support the
|
||||||
|
/// MemoryBuffer.
|
||||||
|
virtual BufferKind getBufferKind() const = 0;
|
||||||
|
|
||||||
|
MemoryBufferRef getMemBufferRef() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// This class is an extension of MemoryBuffer, which allows copy-on-write
|
||||||
|
/// access to the underlying contents. It only supports creation methods that
|
||||||
|
/// are guaranteed to produce a writable buffer. For example, mapping a file
|
||||||
|
/// read-only is not supported.
|
||||||
|
class WritableMemoryBuffer : public MemoryBuffer {
|
||||||
|
protected:
|
||||||
|
WritableMemoryBuffer() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using MemoryBuffer::getBuffer;
|
||||||
|
using MemoryBuffer::getBufferEnd;
|
||||||
|
using MemoryBuffer::getBufferStart;
|
||||||
|
|
||||||
|
// const_cast is well-defined here, because the underlying buffer is
|
||||||
|
// guaranteed to have been initialized with a mutable buffer.
|
||||||
|
char *getBufferStart() {
|
||||||
|
return const_cast<char *>(MemoryBuffer::getBufferStart());
|
||||||
|
}
|
||||||
|
char *getBufferEnd() {
|
||||||
|
return const_cast<char *>(MemoryBuffer::getBufferEnd());
|
||||||
|
}
|
||||||
|
MutableArrayRef<char> getBuffer() {
|
||||||
|
return {getBufferStart(), getBufferEnd()};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ErrorOr<std::unique_ptr<WritableMemoryBuffer>>
|
||||||
|
getFile(const Twine &Filename, bool IsVolatile = false,
|
||||||
|
std::optional<Align> Alignment = std::nullopt);
|
||||||
|
|
||||||
|
/// Map a subrange of the specified file as a WritableMemoryBuffer.
|
||||||
|
static ErrorOr<std::unique_ptr<WritableMemoryBuffer>>
|
||||||
|
getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset,
|
||||||
|
bool IsVolatile = false,
|
||||||
|
std::optional<Align> Alignment = std::nullopt);
|
||||||
|
|
||||||
|
/// Allocate a new MemoryBuffer of the specified size that is not initialized.
|
||||||
|
/// Note that the caller should initialize the memory allocated by this
|
||||||
|
/// method. The memory is owned by the MemoryBuffer object.
|
||||||
|
///
|
||||||
|
/// \param Alignment Set to indicate that the buffer should be aligned to at
|
||||||
|
/// least the specified alignment.
|
||||||
|
static std::unique_ptr<WritableMemoryBuffer>
|
||||||
|
getNewUninitMemBuffer(size_t Size, const Twine &BufferName = "",
|
||||||
|
std::optional<Align> Alignment = std::nullopt);
|
||||||
|
|
||||||
|
/// Allocate a new zero-initialized MemoryBuffer of the specified size. Note
|
||||||
|
/// that the caller need not initialize the memory allocated by this method.
|
||||||
|
/// The memory is owned by the MemoryBuffer object.
|
||||||
|
static std::unique_ptr<WritableMemoryBuffer>
|
||||||
|
getNewMemBuffer(size_t Size, const Twine &BufferName = "");
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Hide these base class factory function so one can't write
|
||||||
|
// WritableMemoryBuffer::getXXX()
|
||||||
|
// and be surprised that he got a read-only Buffer.
|
||||||
|
using MemoryBuffer::getFileAsStream;
|
||||||
|
using MemoryBuffer::getFileOrSTDIN;
|
||||||
|
using MemoryBuffer::getMemBuffer;
|
||||||
|
using MemoryBuffer::getMemBufferCopy;
|
||||||
|
using MemoryBuffer::getOpenFile;
|
||||||
|
using MemoryBuffer::getOpenFileSlice;
|
||||||
|
using MemoryBuffer::getSTDIN;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// This class is an extension of MemoryBuffer, which allows write access to
|
||||||
|
/// the underlying contents and committing those changes to the original source.
|
||||||
|
/// It only supports creation methods that are guaranteed to produce a writable
|
||||||
|
/// buffer. For example, mapping a file read-only is not supported.
|
||||||
|
class WriteThroughMemoryBuffer : public MemoryBuffer {
|
||||||
|
protected:
|
||||||
|
WriteThroughMemoryBuffer() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using MemoryBuffer::getBuffer;
|
||||||
|
using MemoryBuffer::getBufferEnd;
|
||||||
|
using MemoryBuffer::getBufferStart;
|
||||||
|
|
||||||
|
// const_cast is well-defined here, because the underlying buffer is
|
||||||
|
// guaranteed to have been initialized with a mutable buffer.
|
||||||
|
char *getBufferStart() {
|
||||||
|
return const_cast<char *>(MemoryBuffer::getBufferStart());
|
||||||
|
}
|
||||||
|
char *getBufferEnd() {
|
||||||
|
return const_cast<char *>(MemoryBuffer::getBufferEnd());
|
||||||
|
}
|
||||||
|
MutableArrayRef<char> getBuffer() {
|
||||||
|
return {getBufferStart(), getBufferEnd()};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ErrorOr<std::unique_ptr<WriteThroughMemoryBuffer>>
|
||||||
|
getFile(const Twine &Filename, int64_t FileSize = -1);
|
||||||
|
|
||||||
|
/// Map a subrange of the specified file as a ReadWriteMemoryBuffer.
|
||||||
|
static ErrorOr<std::unique_ptr<WriteThroughMemoryBuffer>>
|
||||||
|
getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Hide these base class factory function so one can't write
|
||||||
|
// WritableMemoryBuffer::getXXX()
|
||||||
|
// and be surprised that he got a read-only Buffer.
|
||||||
|
using MemoryBuffer::getFileAsStream;
|
||||||
|
using MemoryBuffer::getFileOrSTDIN;
|
||||||
|
using MemoryBuffer::getMemBuffer;
|
||||||
|
using MemoryBuffer::getMemBufferCopy;
|
||||||
|
using MemoryBuffer::getOpenFile;
|
||||||
|
using MemoryBuffer::getOpenFileSlice;
|
||||||
|
using MemoryBuffer::getSTDIN;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||||
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef)
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_SUPPORT_MEMORYBUFFER_H
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
//===- MemoryBufferRef.h - Memory Buffer Reference --------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file defines the MemoryBuffer interface.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_SUPPORT_MEMORYBUFFERREF_H
|
||||||
|
#define LLVM_SUPPORT_MEMORYBUFFERREF_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class MemoryBuffer;
|
||||||
|
|
||||||
|
class MemoryBufferRef {
|
||||||
|
StringRef Buffer;
|
||||||
|
StringRef Identifier;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MemoryBufferRef() = default;
|
||||||
|
MemoryBufferRef(const MemoryBuffer &Buffer);
|
||||||
|
MemoryBufferRef(StringRef Buffer, StringRef Identifier)
|
||||||
|
: Buffer(Buffer), Identifier(Identifier) {}
|
||||||
|
|
||||||
|
StringRef getBuffer() const { return Buffer; }
|
||||||
|
StringRef getBufferIdentifier() const { return Identifier; }
|
||||||
|
|
||||||
|
const char *getBufferStart() const { return Buffer.begin(); }
|
||||||
|
const char *getBufferEnd() const { return Buffer.end(); }
|
||||||
|
size_t getBufferSize() const { return Buffer.size(); }
|
||||||
|
|
||||||
|
/// Check pointer identity (not value) of identifier and data.
|
||||||
|
friend bool operator==(const MemoryBufferRef &LHS,
|
||||||
|
const MemoryBufferRef &RHS) {
|
||||||
|
return LHS.Buffer.begin() == RHS.Buffer.begin() &&
|
||||||
|
LHS.Buffer.end() == RHS.Buffer.end() &&
|
||||||
|
LHS.Identifier.begin() == RHS.Identifier.begin() &&
|
||||||
|
LHS.Identifier.end() == RHS.Identifier.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const MemoryBufferRef &LHS,
|
||||||
|
const MemoryBufferRef &RHS) {
|
||||||
|
return !(LHS == RHS);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_SUPPORT_MEMORYBUFFERREF_H
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
//===- VersionTuple.h - Version Number Handling -----------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
///
|
||||||
|
/// \file
|
||||||
|
/// Defines the llvm::VersionTuple class, which represents a version in
|
||||||
|
/// the form major[.minor[.subminor]].
|
||||||
|
///
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
#ifndef LLVM_SUPPORT_VERSIONTUPLE_H
|
||||||
|
#define LLVM_SUPPORT_VERSIONTUPLE_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/DenseMapInfo.h"
|
||||||
|
#include "llvm/ADT/Hashing.h"
|
||||||
|
#include "llvm/Support/Endian.h"
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
template <typename HasherT, support::endianness Endianness>
|
||||||
|
class HashBuilderImpl;
|
||||||
|
class raw_ostream;
|
||||||
|
class StringRef;
|
||||||
|
|
||||||
|
/// Represents a version number in the form major[.minor[.subminor[.build]]].
|
||||||
|
class VersionTuple {
|
||||||
|
unsigned Major : 32;
|
||||||
|
|
||||||
|
unsigned Minor : 31;
|
||||||
|
unsigned HasMinor : 1;
|
||||||
|
|
||||||
|
unsigned Subminor : 31;
|
||||||
|
unsigned HasSubminor : 1;
|
||||||
|
|
||||||
|
unsigned Build : 31;
|
||||||
|
unsigned HasBuild : 1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr VersionTuple()
|
||||||
|
: Major(0), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false),
|
||||||
|
Build(0), HasBuild(false) {}
|
||||||
|
|
||||||
|
explicit constexpr VersionTuple(unsigned Major)
|
||||||
|
: Major(Major), Minor(0), HasMinor(false), Subminor(0),
|
||||||
|
HasSubminor(false), Build(0), HasBuild(false) {}
|
||||||
|
|
||||||
|
explicit constexpr VersionTuple(unsigned Major, unsigned Minor)
|
||||||
|
: Major(Major), Minor(Minor), HasMinor(true), Subminor(0),
|
||||||
|
HasSubminor(false), Build(0), HasBuild(false) {}
|
||||||
|
|
||||||
|
explicit constexpr VersionTuple(unsigned Major, unsigned Minor,
|
||||||
|
unsigned Subminor)
|
||||||
|
: Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
|
||||||
|
HasSubminor(true), Build(0), HasBuild(false) {}
|
||||||
|
|
||||||
|
explicit constexpr VersionTuple(unsigned Major, unsigned Minor,
|
||||||
|
unsigned Subminor, unsigned Build)
|
||||||
|
: Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
|
||||||
|
HasSubminor(true), Build(Build), HasBuild(true) {}
|
||||||
|
|
||||||
|
/// Determine whether this version information is empty
|
||||||
|
/// (e.g., all version components are zero).
|
||||||
|
bool empty() const {
|
||||||
|
return Major == 0 && Minor == 0 && Subminor == 0 && Build == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether this is a non-empty version tuple.
|
||||||
|
explicit operator bool () const { return !empty(); }
|
||||||
|
|
||||||
|
/// Retrieve the major version number.
|
||||||
|
unsigned getMajor() const { return Major; }
|
||||||
|
|
||||||
|
/// Retrieve the minor version number, if provided.
|
||||||
|
std::optional<unsigned> getMinor() const {
|
||||||
|
if (!HasMinor)
|
||||||
|
return std::nullopt;
|
||||||
|
return Minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the subminor version number, if provided.
|
||||||
|
std::optional<unsigned> getSubminor() const {
|
||||||
|
if (!HasSubminor)
|
||||||
|
return std::nullopt;
|
||||||
|
return Subminor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the build version number, if provided.
|
||||||
|
std::optional<unsigned> getBuild() const {
|
||||||
|
if (!HasBuild)
|
||||||
|
return std::nullopt;
|
||||||
|
return Build;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a version tuple that contains only the first 3 version components.
|
||||||
|
VersionTuple withoutBuild() const {
|
||||||
|
if (HasBuild)
|
||||||
|
return VersionTuple(Major, Minor, Subminor);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a version tuple that contains a different major version but
|
||||||
|
/// everything else is the same.
|
||||||
|
VersionTuple withMajorReplaced(unsigned NewMajor) const {
|
||||||
|
return VersionTuple(NewMajor, Minor, Subminor, Build);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a version tuple that contains only components that are non-zero.
|
||||||
|
VersionTuple normalize() const {
|
||||||
|
VersionTuple Result = *this;
|
||||||
|
if (Result.Build == 0) {
|
||||||
|
Result.HasBuild = false;
|
||||||
|
if (Result.Subminor == 0) {
|
||||||
|
Result.HasSubminor = false;
|
||||||
|
if (Result.Minor == 0)
|
||||||
|
Result.HasMinor = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine if two version numbers are equivalent. If not
|
||||||
|
/// provided, minor and subminor version numbers are considered to be zero.
|
||||||
|
friend bool operator==(const VersionTuple &X, const VersionTuple &Y) {
|
||||||
|
return X.Major == Y.Major && X.Minor == Y.Minor &&
|
||||||
|
X.Subminor == Y.Subminor && X.Build == Y.Build;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine if two version numbers are not equivalent.
|
||||||
|
///
|
||||||
|
/// If not provided, minor and subminor version numbers are considered to be
|
||||||
|
/// zero.
|
||||||
|
friend bool operator!=(const VersionTuple &X, const VersionTuple &Y) {
|
||||||
|
return !(X == Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether one version number precedes another.
|
||||||
|
///
|
||||||
|
/// If not provided, minor and subminor version numbers are considered to be
|
||||||
|
/// zero.
|
||||||
|
friend bool operator<(const VersionTuple &X, const VersionTuple &Y) {
|
||||||
|
return std::tie(X.Major, X.Minor, X.Subminor, X.Build) <
|
||||||
|
std::tie(Y.Major, Y.Minor, Y.Subminor, Y.Build);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether one version number follows another.
|
||||||
|
///
|
||||||
|
/// If not provided, minor and subminor version numbers are considered to be
|
||||||
|
/// zero.
|
||||||
|
friend bool operator>(const VersionTuple &X, const VersionTuple &Y) {
|
||||||
|
return Y < X;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether one version number precedes or is
|
||||||
|
/// equivalent to another.
|
||||||
|
///
|
||||||
|
/// If not provided, minor and subminor version numbers are considered to be
|
||||||
|
/// zero.
|
||||||
|
friend bool operator<=(const VersionTuple &X, const VersionTuple &Y) {
|
||||||
|
return !(Y < X);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether one version number follows or is
|
||||||
|
/// equivalent to another.
|
||||||
|
///
|
||||||
|
/// If not provided, minor and subminor version numbers are considered to be
|
||||||
|
/// zero.
|
||||||
|
friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) {
|
||||||
|
return !(X < Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend hash_code hash_value(const VersionTuple &VT) {
|
||||||
|
return hash_combine(VT.Major, VT.Minor, VT.Subminor, VT.Build);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename HasherT, llvm::support::endianness Endianness>
|
||||||
|
friend void addHash(HashBuilderImpl<HasherT, Endianness> &HBuilder,
|
||||||
|
const VersionTuple &VT) {
|
||||||
|
HBuilder.add(VT.Major, VT.Minor, VT.Subminor, VT.Build);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve a string representation of the version number.
|
||||||
|
std::string getAsString() const;
|
||||||
|
|
||||||
|
/// Try to parse the given string as a version number.
|
||||||
|
/// \returns \c true if the string does not match the regular expression
|
||||||
|
/// [0-9]+(\.[0-9]+){0,3}
|
||||||
|
bool tryParse(StringRef string);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Print a version number.
|
||||||
|
raw_ostream &operator<<(raw_ostream &Out, const VersionTuple &V);
|
||||||
|
|
||||||
|
// Provide DenseMapInfo for version tuples.
|
||||||
|
template <> struct DenseMapInfo<VersionTuple> {
|
||||||
|
static inline VersionTuple getEmptyKey() { return VersionTuple(0x7FFFFFFF); }
|
||||||
|
static inline VersionTuple getTombstoneKey() {
|
||||||
|
return VersionTuple(0x7FFFFFFE);
|
||||||
|
}
|
||||||
|
static unsigned getHashValue(const VersionTuple &Value) {
|
||||||
|
unsigned Result = Value.getMajor();
|
||||||
|
if (auto Minor = Value.getMinor())
|
||||||
|
Result = detail::combineHashValue(Result, *Minor);
|
||||||
|
if (auto Subminor = Value.getSubminor())
|
||||||
|
Result = detail::combineHashValue(Result, *Subminor);
|
||||||
|
if (auto Build = Value.getBuild())
|
||||||
|
Result = detail::combineHashValue(Result, *Build);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isEqual(const VersionTuple &LHS, const VersionTuple &RHS) {
|
||||||
|
return LHS == RHS;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
#endif // LLVM_SUPPORT_VERSIONTUPLE_H
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user