forked from OSchip/llvm-project
110 lines
4.0 KiB
C++
110 lines
4.0 KiB
C++
//===- lib/ReaderWriter/ELF/CreateELF.h -----------------------------------===//
|
|
//
|
|
// The LLVM Linker
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// \brief This file provides a simple way to create an object templated on
|
|
/// ELFType depending on the runtime type needed.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef LLD_READER_WRITER_ELF_CREATE_ELF_H
|
|
#define LLD_READER_WRITER_ELF_CREATE_ELF_H
|
|
|
|
#include "llvm/Object/ELF.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
|
|
namespace {
|
|
using llvm::object::ELFType;
|
|
|
|
/// \func createELF
|
|
/// \brief Create an object depending on the runtime attributes and alignment
|
|
/// of an ELF file.
|
|
///
|
|
/// \param Traits
|
|
/// Traits::result_type must be a type convertable from what create returns.
|
|
/// Traits::create must be a template function which takes an ELFType and
|
|
/// returns something convertable to Traits::result_type.
|
|
///
|
|
/// \param ident pair of EI_CLASS and EI_DATA.
|
|
/// \param maxAlignment the maximum alignment of the file.
|
|
/// \param args arguments forwarded to CreateELFTraits<T>::create.
|
|
|
|
#define LLVM_CREATE_ELF_CreateELFTraits(endian, align, is64, ...) \
|
|
Traits::template create<ELFType<llvm::support::endian, align, is64>>( \
|
|
__VA_ARGS__);
|
|
|
|
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
|
|
# define LLVM_CREATE_ELF_MaxAlignCheck(normal, low, endian, is64, ...) \
|
|
if (maxAlignment >= normal) \
|
|
return LLVM_CREATE_ELF_CreateELFTraits(endian, normal, is64, __VA_ARGS__) \
|
|
else if (maxAlignment >= low) \
|
|
return LLVM_CREATE_ELF_CreateELFTraits(endian, low, is64, __VA_ARGS__) \
|
|
else \
|
|
llvm_unreachable("Invalid alignment for ELF file!");
|
|
#else
|
|
# define LLVM_CREATE_ELF_MaxAlignCheck(normal, low, endian, is64, ...) \
|
|
if (maxAlignment >= low) \
|
|
return LLVM_CREATE_ELF_CreateELFTraits(endian, low, is64, __VA_ARGS__) \
|
|
else \
|
|
llvm_unreachable("Invalid alignment for ELF file!");
|
|
#endif
|
|
|
|
#define LLVM_CREATE_ELF_IMPL(...) \
|
|
if (ident.first == llvm::ELF::ELFCLASS32 && \
|
|
ident.second == llvm::ELF::ELFDATA2LSB) { \
|
|
LLVM_CREATE_ELF_MaxAlignCheck(4, 2, little, false, __VA_ARGS__) \
|
|
} else if (ident.first == llvm::ELF::ELFCLASS32 && \
|
|
ident.second == llvm::ELF::ELFDATA2MSB) { \
|
|
LLVM_CREATE_ELF_MaxAlignCheck(4, 2, big, false, __VA_ARGS__) \
|
|
} else if (ident.first == llvm::ELF::ELFCLASS64 && \
|
|
ident.second == llvm::ELF::ELFDATA2MSB) { \
|
|
LLVM_CREATE_ELF_MaxAlignCheck(8, 2, big, true, __VA_ARGS__) \
|
|
} else if (ident.first == llvm::ELF::ELFCLASS64 && \
|
|
ident.second == llvm::ELF::ELFDATA2LSB) { \
|
|
LLVM_CREATE_ELF_MaxAlignCheck(8, 2, little, true, __VA_ARGS__) \
|
|
} \
|
|
llvm_unreachable("Invalid ELF type!");
|
|
|
|
#if LLVM_HAS_VARIADIC_TEMPLATES
|
|
template <class Traits, class ...Args>
|
|
typename Traits::result_type createELF(
|
|
std::pair<unsigned char, unsigned char> ident, std::size_t maxAlignment,
|
|
Args &&...args) {
|
|
LLVM_CREATE_ELF_IMPL(std::forward<Args>(args)...)
|
|
}
|
|
#else
|
|
template <class Traits, class T1>
|
|
typename Traits::result_type createELF(
|
|
std::pair<unsigned char, unsigned char> ident, std::size_t maxAlignment,
|
|
T1 &&t1) {
|
|
LLVM_CREATE_ELF_IMPL(std::forward<T1>(t1))
|
|
}
|
|
|
|
template <class Traits, class T1, class T2>
|
|
typename Traits::result_type createELF(
|
|
std::pair<unsigned char, unsigned char> ident, std::size_t maxAlignment,
|
|
T1 &&t1, T2 &&t2) {
|
|
LLVM_CREATE_ELF_IMPL(std::forward<T1>(t1), std::forward<T2>(t2))
|
|
}
|
|
|
|
template <class Traits, class T1, class T2, class T3>
|
|
typename Traits::result_type createELF(
|
|
std::pair<unsigned char, unsigned char> ident, std::size_t maxAlignment,
|
|
T1 &&t1, T2 &&t2, T3 &&t3) {
|
|
LLVM_CREATE_ELF_IMPL(std::forward<T1>(t1), std::forward<T2>(t2),
|
|
std::forward<T3>(t3))
|
|
}
|
|
#endif // LLVM_HAS_VARIADIC_TEMPLATES
|
|
} // end anon namespace
|
|
|
|
#undef LLVM_CREATE_ELF_CreateELFTraits
|
|
#undef LLVM_CREATE_ELF_MaxAlignCheck
|
|
#undef LLVM_CREATE_ELF_IMPL
|
|
|
|
#endif
|