Home | History | Annotate | Download | only in Target
      1 //===- ELFAttributeData.cpp -----------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #include "mcld/Target/ELFAttributeData.h"
     10 
     11 #include "mcld/Support/LEB128.h"
     12 #include "mcld/Target/ELFAttributeValue.h"
     13 #include <cstring>
     14 #include <cassert>
     15 
     16 namespace mcld {
     17 
     18 bool ELFAttributeData::ReadTag(TagType& pTag,
     19                                const char*& pBuf,
     20                                size_t& pBufSize) {
     21   size_t size = 0;
     22 
     23   pTag = static_cast<ELFAttributeData::TagType>(
     24       leb128::decode<uint64_t>(pBuf, size));
     25 
     26   if (size > pBufSize)
     27     return false;
     28 
     29   pBuf += size;
     30   pBufSize -= size;
     31 
     32   return true;
     33 }
     34 
     35 bool ELFAttributeData::ReadValue(ELFAttributeValue& pValue,
     36                                  const char*& pBuf,
     37                                  size_t& pBufSize) {
     38   // An ULEB128-encoded value
     39   if (pValue.isIntValue()) {
     40     size_t size = 0;
     41     uint64_t int_value = leb128::decode<uint64_t>(pBuf, size);
     42     pValue.setIntValue(static_cast<unsigned int>(int_value));
     43 
     44     if (size > pBufSize)
     45       return false;
     46 
     47     pBuf += size;
     48     pBufSize -= size;
     49   }
     50 
     51   // A null-terminated byte string
     52   if (pValue.isStringValue()) {
     53     pValue.setStringValue(pBuf);
     54 
     55     size_t size = pValue.getStringValue().length() + 1 /* '\0' */;
     56     assert(size <= pBufSize);
     57     pBuf += size;
     58     pBufSize -= size;
     59   }
     60 
     61   return true;
     62 }
     63 
     64 bool ELFAttributeData::WriteAttribute(TagType pTag,
     65                                       const ELFAttributeValue& pValue,
     66                                       char*& pBuf) {
     67   // Write the attribute tag.
     68   leb128::encode<uint32_t>(pBuf, pTag);
     69 
     70   // Write the attribute value.
     71   if (pValue.isIntValue())
     72     leb128::encode<uint32_t>(pBuf, pValue.getIntValue());
     73 
     74   if (pValue.isStringValue()) {
     75     // Write string data.
     76     size_t str_val_len = pValue.getStringValue().length();
     77 
     78     if (str_val_len > 0)
     79       ::memcpy(pBuf, pValue.getStringValue().c_str(), str_val_len);
     80     pBuf += str_val_len;
     81 
     82     // Write NULL-terminator.
     83     *pBuf++ = '\0';
     84   }
     85 
     86   return true;
     87 }
     88 
     89 }  // namespace mcld
     90