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