187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===- ELFAttributeData.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_ELFATTRIBUTEDATA_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_TARGET_ELFATTRIBUTEDATA_H_
1187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <stdint.h>
1387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <string>
1487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <utility>
1587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesnamespace mcld {
1787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFAttributeValue;
1987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass Input;
2087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass LinkerConfig;
2187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/** \class ELFAttributeData
2387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines *  \brief ELFAttributeData handles data in vendor attribute subsection.
2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */
2537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass ELFAttributeData {
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef uint32_t TagType;
2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // Generic attribute tags shared between all vendors
3087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  enum {
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    Tag_NULL = 0,
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    Tag_File = 1,
3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    Tag_Section = 2,
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    Tag_Symbol = 3,
3587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  explicit ELFAttributeData(const char* pVendor) : m_Vendor(pVendor) {}
3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual ~ELFAttributeData() {}
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  inline const std::string& getVendorName() const { return m_Vendor; }
4487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// getAttributeValue - query the data store for the attribute value of the
4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// given tag.
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual const ELFAttributeValue* getAttributeValue(TagType pTag) const = 0;
4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// getOrCreateAttributeValue - obtain attribute value for the given tag and
5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// create if it does not exist.
5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ///
5287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// It returns a pair containing the attribute value instance (guaranteed to
5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// be non-NULL) and a boolean value indicating whether the instance is newly
5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// created (true) or not (false.)
5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual std::pair<ELFAttributeValue*, bool> getOrCreateAttributeValue(
5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      TagType pTag) = 0;
5787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// preMerge - hooks to call before starting merge the attribute data in an
5987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// input.
6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual bool preMerge(const Input& pInput) { return true; }
6187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// merge - implement logics to merge input attribute to the output.
6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual bool merge(const LinkerConfig& pConfig,
6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                     const Input& pInput,
6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                     TagType pTag,
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                     const ELFAttributeValue& pInAttr) = 0;
6787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// postMerge - hooks to call after finishing merge the attribute data from an
6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// input.
7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual bool postMerge(const LinkerConfig& pConfig, const Input& pInput) {
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return true;
7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
7387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// sizeOutput - obtain number of bytes required to encode the attribute data.
7587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual size_t sizeOutput() const = 0;
7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emit - write out attribute data to the buffer and return the number of
7887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// bytes written
7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual size_t emit(char* pBuf) const = 0;
8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// ReadTag - read an attribute tag from input buffer.
8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ///
8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// If the read succeeds, pBuf moves to the new position just pass the end of
8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// the tag in the buffer and pBufSize decreases the size of tag in the
8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// buffer. Otherwise, this function will return false and change nothing
8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// except leaving undefined value in pTag.
8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static bool ReadTag(TagType& pTag, const char*& pBuf, size_t& pBufSize);
8987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// ReadValue - read an attribute value from input buffer
9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ///
9287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// Similar with ReadTag() while this reads attribute value from the input
9387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// buffer. Note that the value type of the attribute must be properly set in
9487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// pValue prior the call.
9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static bool ReadValue(ELFAttributeValue& pValue,
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                        const char*& pBuf,
9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                        size_t& pBufSize);
9887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
9987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// WriteAttribute - write an attribute tag plus value to buffer.
10087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ///
10187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// On success, the pBuf moves to the new position just pass the end of the
10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// attribute data just written. Otherwise, it returns false and leaves pBuf
10387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// in an undefined position. Note that buffer is guaranteed to be able to
10487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// contain the attribute data.
10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static bool WriteAttribute(TagType pTag,
10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                             const ELFAttributeValue& pValue,
10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                             char*& pBuf);
10887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
11087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const std::string m_Vendor;
11187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines};
11287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
11487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_TARGET_ELFATTRIBUTEDATA_H_
116