| //===- ELFAttributeData.cpp -----------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #include <mcld/Target/ELFAttributeData.h> |
| |
| #include <mcld/Support/LEB128.h> |
| #include <mcld/Target/ELFAttributeValue.h> |
| #include <cstring> |
| #include <cassert> |
| |
| using namespace mcld; |
| |
| bool ELFAttributeData::ReadTag(TagType& pTag, const char* &pBuf, |
| size_t &pBufSize) |
| { |
| size_t size = 0; |
| |
| pTag = static_cast<ELFAttributeData::TagType>( |
| leb128::decode<uint64_t>(pBuf, size)); |
| |
| if (size > pBufSize) |
| return false; |
| |
| pBuf += size; |
| pBufSize -= size; |
| |
| return true; |
| } |
| |
| bool ELFAttributeData::ReadValue(ELFAttributeValue& pValue, const char* &pBuf, |
| size_t &pBufSize) |
| { |
| // An ULEB128-encoded value |
| if (pValue.isIntValue()) { |
| size_t size = 0; |
| uint64_t int_value = leb128::decode<uint64_t>(pBuf, size); |
| pValue.setIntValue(static_cast<unsigned int>(int_value)); |
| |
| if (size > pBufSize) |
| return false; |
| |
| pBuf += size; |
| pBufSize -= size; |
| } |
| |
| // A null-terminated byte string |
| if (pValue.isStringValue()) { |
| pValue.setStringValue(pBuf); |
| |
| size_t size = pValue.getStringValue().length() + 1 /* '\0' */; |
| assert(size <= pBufSize); |
| pBuf += size; |
| pBufSize -= size; |
| } |
| |
| return true; |
| } |
| |
| bool ELFAttributeData::WriteAttribute(TagType pTag, |
| const ELFAttributeValue& pValue, |
| char* &pBuf) |
| { |
| // Write the attribute tag. |
| leb128::encode<uint32_t>(pBuf, pTag); |
| |
| // Write the attribute value. |
| if (pValue.isIntValue()) |
| leb128::encode<uint32_t>(pBuf, pValue.getIntValue()); |
| |
| if (pValue.isStringValue()) { |
| // Write string data. |
| size_t str_val_len = pValue.getStringValue().length(); |
| |
| if (str_val_len > 0) |
| ::memcpy(pBuf, pValue.getStringValue().c_str(), str_val_len); |
| pBuf += str_val_len; |
| |
| // Write NULL-terminator. |
| *pBuf++ = '\0'; |
| } |
| |
| return true; |
| } |