You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.2 KiB
90 lines
2.2 KiB
//===- 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
|