//===- 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> 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; } } // namespace mcld