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 using namespace mcld;
     17 
     18 bool ELFAttributeData::ReadTag(TagType& pTag, const char* &pBuf,
     19                                size_t &pBufSize)
     20 {
     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, const char* &pBuf,
     36                                  size_t &pBufSize)
     37 {
     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 {
     68   // Write the attribute tag.
     69   leb128::encode<uint32_t>(pBuf, pTag);
     70 
     71   // Write the attribute value.
     72   if (pValue.isIntValue())
     73     leb128::encode<uint32_t>(pBuf, pValue.getIntValue());
     74 
     75   if (pValue.isStringValue()) {
     76     // Write string data.
     77     size_t str_val_len = pValue.getStringValue().length();
     78 
     79     if (str_val_len > 0)
     80       ::memcpy(pBuf, pValue.getStringValue().c_str(), str_val_len);
     81     pBuf += str_val_len;
     82 
     83     // Write NULL-terminator.
     84     *pBuf++ = '\0';
     85   }
     86 
     87   return true;
     88 }
     89