blob: a50e13e82a4618300f433cf4c4df3ec30881f22b [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_
#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 mcld
#endif // MCLD_TARGET_ELFATTRIBUTE_H_