Merge pull request #69163 from apple/rebranch

Merge `rebranch` into `main` to support `stable/20230725` llvm-project branch
This commit is contained in:
Mishal Shah
2023-10-23 09:26:37 -07:00
committed by GitHub
395 changed files with 19840 additions and 2445 deletions

View File

@@ -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

View File

@@ -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})

View File

@@ -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()

View File

@@ -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 {

View File

@@ -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(),

View File

@@ -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>

View File

@@ -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;
} }

View File

@@ -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 {

View File

@@ -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

View File

@@ -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) {

View File

@@ -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"

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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.

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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;

View 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

View File

@@ -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"

View File

@@ -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),

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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>

View File

@@ -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"

View File

@@ -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>

View File

@@ -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);

View File

@@ -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();
} }

View File

@@ -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;

View File

@@ -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"

View File

@@ -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>

View File

@@ -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;
}; };

View File

@@ -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,

View File

@@ -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

View File

@@ -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>,

View File

@@ -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

View File

@@ -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 */

View 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

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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")

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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