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 
ReadTag(TagType & pTag,const char * & pBuf,size_t & pBufSize)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 
ReadValue(ELFAttributeValue & pValue,const char * & pBuf,size_t & pBufSize)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 
WriteAttribute(TagType pTag,const ELFAttributeValue & pValue,char * & pBuf)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