187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===- ELFAttribute.h -----------------------------------------------------===//
287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//
387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//                     The MCLinker Project
487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//
587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// This file is distributed under the University of Illinois Open Source
687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// License. See LICENSE.TXT for details.
787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//
887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_TARGET_ELFATTRIBUTE_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_TARGET_ELFATTRIBUTE_H_
1187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryRegion.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/ELFAttributeData.h"
1487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/ADT/SmallVector.h>
1687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/ADT/StringRef.h>
1787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesnamespace mcld {
1987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFAttributeData;
2187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass GNULDBackend;
2287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass Input;
2387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass LDSection;
2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass LinkerConfig;
2587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/** \class ELFAttribute
2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines *  \brief ELFAttribute is the attribute section in an ELF file.
2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass ELFAttribute {
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
3187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // ARM [ABI-addenda], 2.2.3.
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static const char FormatVersion = 'A';
3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static const size_t FormatVersionFieldSize = sizeof(FormatVersion);  // a byte
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static const size_t SubsectionLengthFieldSize = 4;  // a 4-byte integer
3587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // MinimalELFAttributeSubsectionSize is the minimal number of bytes a valid
3787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // subsection in ELF attribute section should have.
3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static const size_t MinimalELFAttributeSubsectionSize =
3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      1 /* Tag_File, see ARM [ABI-addenda], 2.2.4 */ +
4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      4 /* byte-size, see ARM [ABI-addenda], 2.2.4 */;
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // MinimalELFAttributeSectionSize is the minimal number of bytes a valid ELF
4387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // attribute section should have.
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static const size_t MinimalELFAttributeSectionSize =
4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FormatVersionFieldSize + SubsectionLengthFieldSize +
4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      2 /* vendor-name, a char plus '\0', see ARM [ABI-addenda], 2.2.3 */ +
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      1 * MinimalELFAttributeSubsectionSize;
4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  ELFAttribute(const GNULDBackend& pBackend, const LinkerConfig& pConfig)
5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      : m_Backend(pBackend), m_Config(pConfig) {}
5287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ~ELFAttribute();
5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// merge - merge attributes from input (attribute) section
5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool merge(const Input& pInput, LDSection& pInputAttrSectHdr);
5887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// sizeOutput - calculate the number of bytes required to encode this
6087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// attribute data section
6187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t sizeOutput() const;
6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
6387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emit - encode and write out this attribute section
6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t emit(MemoryRegion& pRegion) const;
6587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  inline const GNULDBackend& backend() const { return m_Backend; }
6787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  inline const LinkerConfig& config() const { return m_Config; }
6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // Place vendor's attribute data under the management.
7187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void registerAttributeData(ELFAttributeData& pAttrData);
7287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /** \class Subsection
7587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines   *  \brief A helper class to wrap ELFAttributeData and to provide general
7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines   *  interfaces for ELFAttribute to operate on
7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines   */
7887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  class Subsection {
7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines   public:
8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    Subsection(ELFAttribute& pParent, ELFAttributeData& pAttrData)
8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        : m_Parent(pParent), m_AttrData(pAttrData) {}
8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines   public:
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    bool isMyAttribute(llvm::StringRef pVendorName) const {
8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return (m_AttrData.getVendorName() == pVendorName);
8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
8887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    /// merge -  Merge the attributes from the section in the input data.
8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    bool merge(const Input& pInput, ConstAddress pData, size_t pSize);
9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    /// sizeOutput - calculate the number of bytes required to encode this
9287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    /// subsection
9387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    size_t sizeOutput() const;
9487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
9587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    /// emit - write out this attribute subsection to the buffer.
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    size_t emit(char* pBuf) const;
9787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines   private:
9987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // The attribute section this subsection belongs to
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ELFAttribute& m_Parent;
10187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // The attribute data containing in this subsection
10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ELFAttributeData& m_AttrData;
10487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
10587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
10687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // Obtain the corresponding subsection of the specified vendor
10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  Subsection* getSubsection(llvm::StringRef pVendorName) const;
10887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const GNULDBackend& m_Backend;
11187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const LinkerConfig& m_Config;
11387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
11487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // There is at most two subsections ("aeabi" and "gnu") in most cases.
11587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::SmallVector<Subsection*, 2> m_Subsections;
11687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines};
11787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
11837b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
11987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_TARGET_ELFATTRIBUTE_H_
121