blob: 7d9d30d1c394011420d24607bf8a87be827b1222 [file] [log] [blame]
//===- ELFAttribute.h -----------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_TARGET_ELFATTRIBUTE_H
#define MCLD_TARGET_ELFATTRIBUTE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include <mcld/Support/MemoryRegion.h>
#include <mcld/Target/ELFAttributeData.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/StringRef.h>
namespace mcld {
class ELFAttributeData;
class GNULDBackend;
class Input;
class LDSection;
class LinkerConfig;
/** \class ELFAttribute
* \brief ELFAttribute is the attribute section in an ELF file.
*/
class ELFAttribute
{
public:
// ARM [ABI-addenda], 2.2.3.
static const char FormatVersion = 'A';
static const size_t FormatVersionFieldSize = sizeof(FormatVersion); // a byte
static const size_t SubsectionLengthFieldSize = 4; // a 4-byte integer
// MinimalELFAttributeSubsectionSize is the minimal number of bytes a valid
// subsection in ELF attribute section should have.
static const size_t MinimalELFAttributeSubsectionSize
= 1 /* Tag_File, see ARM [ABI-addenda], 2.2.4 */ +
4 /* byte-size, see ARM [ABI-addenda], 2.2.4 */;
// MinimalELFAttributeSectionSize is the minimal number of bytes a valid ELF
// attribute section should have.
static const size_t MinimalELFAttributeSectionSize
= FormatVersionFieldSize + SubsectionLengthFieldSize +
2 /* vendor-name, a char plus '\0', see ARM [ABI-addenda], 2.2.3 */ +
1 * MinimalELFAttributeSubsectionSize;
public:
ELFAttribute(const GNULDBackend &pBackend, const LinkerConfig& pConfig)
: m_Backend(pBackend), m_Config(pConfig) { }
~ELFAttribute();
public:
/// merge - merge attributes from input (attribute) section
bool merge(const Input &pInput, LDSection &pInputAttrSectHdr);
/// sizeOutput - calculate the number of bytes required to encode this
/// attribute data section
size_t sizeOutput() const;
/// emit - encode and write out this attribute section
size_t emit(MemoryRegion &pRegion) const;
inline const GNULDBackend &backend() const { return m_Backend; }
inline const LinkerConfig &config() const { return m_Config; }
// Place vendor's attribute data under the management.
void registerAttributeData(ELFAttributeData& pAttrData);
private:
/** \class Subsection
* \brief A helper class to wrap ELFAttributeData and to provide general
* interfaces for ELFAttribute to operate on
*/
class Subsection {
public:
Subsection(ELFAttribute &pParent, ELFAttributeData &pAttrData)
: m_Parent(pParent), m_AttrData(pAttrData) { }
public:
bool isMyAttribute(llvm::StringRef pVendorName) const
{
return (m_AttrData.getVendorName() == pVendorName);
}
/// merge - Merge the attributes from the section in the input data.
bool merge(const Input &pInput, ConstAddress pData, size_t pSize);
/// sizeOutput - calculate the number of bytes required to encode this
/// subsection
size_t sizeOutput() const;
/// emit - write out this attribute subsection to the buffer.
size_t emit(char *pBuf) const;
private:
// The attribute section this subsection belongs to
ELFAttribute &m_Parent;
// The attribute data containing in this subsection
ELFAttributeData &m_AttrData;
};
// Obtain the corresponding subsection of the specified vendor
Subsection *getSubsection(llvm::StringRef pVendorName) const;
private:
const GNULDBackend &m_Backend;
const LinkerConfig &m_Config;
// There is at most two subsections ("aeabi" and "gnu") in most cases.
llvm::SmallVector<Subsection*, 2> m_Subsections;
};
} // namespace of mcld
#endif