ELFAttributeData.h revision f33f6de54db174aa679a4b6d1e040d37e95541c0
131a217290cf376d0573fc36e21c8940987485019George Mount//===- ELFAttributeData.h -------------------------------------------------===//
231a217290cf376d0573fc36e21c8940987485019George Mount//
331a217290cf376d0573fc36e21c8940987485019George Mount//                     The MCLinker Project
431a217290cf376d0573fc36e21c8940987485019George Mount//
531a217290cf376d0573fc36e21c8940987485019George Mount// This file is distributed under the University of Illinois Open Source
631a217290cf376d0573fc36e21c8940987485019George Mount// License. See LICENSE.TXT for details.
731a217290cf376d0573fc36e21c8940987485019George Mount//
831a217290cf376d0573fc36e21c8940987485019George Mount//===----------------------------------------------------------------------===//
931a217290cf376d0573fc36e21c8940987485019George Mount#ifndef MCLD_TARGET_ELFATTRIBUTEDATA_H
1031a217290cf376d0573fc36e21c8940987485019George Mount#define MCLD_TARGET_ELFATTRIBUTEDATA_H
1131a217290cf376d0573fc36e21c8940987485019George Mount#ifdef ENABLE_UNITTEST
1231a217290cf376d0573fc36e21c8940987485019George Mount#include <gtest.h>
1331a217290cf376d0573fc36e21c8940987485019George Mount#endif
1431a217290cf376d0573fc36e21c8940987485019George Mount
1531a217290cf376d0573fc36e21c8940987485019George Mount#include <stdint.h>
1631a217290cf376d0573fc36e21c8940987485019George Mount#include <string>
1731a217290cf376d0573fc36e21c8940987485019George Mount#include <utility>
1862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
1962ab9b78b77b7dd851c47115f4d8d7611d657585George Mountnamespace mcld {
2062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
2162ab9b78b77b7dd851c47115f4d8d7611d657585George Mountclass ELFAttributeValue;
2285b764e22babfe5508286fbad5d7fee12345704fCraig Mautnerclass Input;
237bf379c8af399626d5b8b568fe1d4f96f56badccDake Guclass LinkerConfig;
247bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu
2562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount/** \class ELFAttributeData
268cab50afda0d8485436f72a93d668697f549d3b3George Mount *  \brief ELFAttributeData handles data in vendor attribute subsection.
2731a217290cf376d0573fc36e21c8940987485019George Mount */
2862ab9b78b77b7dd851c47115f4d8d7611d657585George Mountclass ELFAttributeData
2962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount{
3031a217290cf376d0573fc36e21c8940987485019George Mountpublic:
3162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  typedef uint32_t TagType;
3231a217290cf376d0573fc36e21c8940987485019George Mount
33e678ab686643127b4b297ae7a1e4869b4cfc6e53George Mount  // Generic attribute tags shared between all vendors
34c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount  enum {
3531a217290cf376d0573fc36e21c8940987485019George Mount    Tag_NULL          = 0,
3631a217290cf376d0573fc36e21c8940987485019George Mount    Tag_File          = 1,
3731a217290cf376d0573fc36e21c8940987485019George Mount    Tag_Section       = 2,
3831a217290cf376d0573fc36e21c8940987485019George Mount    Tag_Symbol        = 3,
3931a217290cf376d0573fc36e21c8940987485019George Mount  };
4031a217290cf376d0573fc36e21c8940987485019George Mount
4131a217290cf376d0573fc36e21c8940987485019George Mountpublic:
4231a217290cf376d0573fc36e21c8940987485019George Mount  ELFAttributeData(const char* pVendor) : m_Vendor(pVendor) { }
4331a217290cf376d0573fc36e21c8940987485019George Mount
4431a217290cf376d0573fc36e21c8940987485019George Mount  virtual ~ELFAttributeData() { }
458cab50afda0d8485436f72a93d668697f549d3b3George Mount
4631a217290cf376d0573fc36e21c8940987485019George Mountpublic:
4762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  inline const std::string &getVendorName() const { return m_Vendor; }
4831a217290cf376d0573fc36e21c8940987485019George Mount
4962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// getAttributeValue - query the data store for the attribute value of the
5031a217290cf376d0573fc36e21c8940987485019George Mount  /// given tag.
5162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  virtual const ELFAttributeValue *getAttributeValue(TagType pTag) const = 0;
5231a217290cf376d0573fc36e21c8940987485019George Mount
5362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// getOrCreateAttributeValue - obtain attribute value for the given tag and
5431a217290cf376d0573fc36e21c8940987485019George Mount  /// create if it does not exist.
5562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  ///
5631a217290cf376d0573fc36e21c8940987485019George Mount  /// It returns a pair containing the attribute value instance (guaranteed to
5762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// be non-NULL) and a boolean value indicating whether the instance is newly
5862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// created (true) or not (false.)
5962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  virtual std::pair<ELFAttributeValue*, bool>
6062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount      getOrCreateAttributeValue(TagType pTag) = 0;
6162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
6262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// preMerge - hooks to call before starting merge the attribute data in an
638cab50afda0d8485436f72a93d668697f549d3b3George Mount  /// input.
648cab50afda0d8485436f72a93d668697f549d3b3George Mount  virtual bool preMerge(const Input &pInput) { return true; }
658cab50afda0d8485436f72a93d668697f549d3b3George Mount
668cab50afda0d8485436f72a93d668697f549d3b3George Mount  /// merge - implement logics to merge input attribute to the output.
67c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount  virtual bool merge(const LinkerConfig& pConfig, const Input &pInput,
68c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                     TagType pTag, const ELFAttributeValue& pInAttr) = 0;
69700db2a325bced35cebc403f272f988fad522892George Mount
70700db2a325bced35cebc403f272f988fad522892George Mount  /// postMerge - hooks to call after finishing merge the attribute data from an
71b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount  /// input.
72b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount  virtual bool postMerge(const LinkerConfig& pConfig, const Input &pInput)
7362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  { return true; }
741fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount
75fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount  /// sizeOutput - obtain number of bytes required to encode the attribute data.
761fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount  virtual size_t sizeOutput() const = 0;
7760625b02ac099bacc96a387ec270751745dafae0George Mount
78a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount  /// emit - write out attribute data to the buffer and return the number of
7962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// bytes written
8031a217290cf376d0573fc36e21c8940987485019George Mount  virtual size_t emit(char *pBuf) const = 0;
8131a217290cf376d0573fc36e21c8940987485019George Mount
826558056e8fccc32f9e1dc59e46d09f8d916b7538George Mountpublic:
83d80154fba1c23834b5139aa764f9426bbf38a721George Mount  /// ReadTag - read an attribute tag from input buffer.
84800d72b0e05049e4a8f90ea96ec165fc975264ceGeorge Mount  ///
85800d72b0e05049e4a8f90ea96ec165fc975264ceGeorge Mount  /// If the read succeeds, pBuf moves to the new position just pass the end of
8631a217290cf376d0573fc36e21c8940987485019George Mount  /// the tag in the buffer and pBufSize decreases the size of tag in the
8762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// buffer. Otherwise, this function will return false and change nothing
8862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// except leaving undefined value in pTag.
8962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  static bool ReadTag(TagType& pTag, const char* &pBuf, size_t &pBufSize);
90fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
9162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// ReadValue - read an attribute value from input buffer
9262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  ///
9362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// Similar with ReadTag() while this reads attribute value from the input
9462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// buffer. Note that the value type of the attribute must be properly set in
9562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// pValue prior the call.
9662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  static bool ReadValue(ELFAttributeValue& pValue, const char* &pBuf,
9762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                        size_t &pBufSize);
9862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
9962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// WriteAttribute - write an attribute tag plus value to buffer.
100fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount  ///
10162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// On success, the pBuf moves to the new position just pass the end of the
10262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// attribute data just written. Otherwise, it returns false and leaves pBuf
10362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// in an undefined position. Note that buffer is guaranteed to be able to
10462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  /// contain the attribute data.
10562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount  static bool WriteAttribute(TagType pTag, const ELFAttributeValue& pValue,
106fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                             char* &pBuf);
10762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
10862ab9b78b77b7dd851c47115f4d8d7611d657585George Mountprivate:
109c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount  const std::string m_Vendor;
110c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount};
11167d924341a1d0994ac68b3b7898d5576edd987b4George Mount
11267d924341a1d0994ac68b3b7898d5576edd987b4George Mount} // namespace of mcld
11367d924341a1d0994ac68b3b7898d5576edd987b4George Mount
11467d924341a1d0994ac68b3b7898d5576edd987b4George Mount#endif
11567d924341a1d0994ac68b3b7898d5576edd987b4George Mount