123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- //===--- ELFAttributeParser.cpp - ELF Attribute Parser --------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/Support/ELFAttributeParser.h"
- #include "llvm/ADT/StringExtras.h"
- #include "llvm/Support/Errc.h"
- #include "llvm/Support/ScopedPrinter.h"
- using namespace llvm;
- using namespace llvm::ELFAttrs;
- static constexpr EnumEntry<unsigned> tagNames[] = {
- {"Tag_File", ELFAttrs::File},
- {"Tag_Section", ELFAttrs::Section},
- {"Tag_Symbol", ELFAttrs::Symbol},
- };
- Error ELFAttributeParser::parseStringAttribute(const char *name, unsigned tag,
- ArrayRef<const char *> strings) {
- uint64_t value = de.getULEB128(cursor);
- if (value >= strings.size()) {
- printAttribute(tag, value, "");
- return createStringError(errc::invalid_argument,
- "unknown " + Twine(name) +
- " value: " + Twine(value));
- }
- printAttribute(tag, value, strings[value]);
- return Error::success();
- }
- Error ELFAttributeParser::integerAttribute(unsigned tag) {
- StringRef tagName =
- ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false);
- uint64_t value = de.getULEB128(cursor);
- attributes.insert(std::make_pair(tag, value));
- if (sw) {
- DictScope scope(*sw, "Attribute");
- sw->printNumber("Tag", tag);
- if (!tagName.empty())
- sw->printString("TagName", tagName);
- sw->printNumber("Value", value);
- }
- return Error::success();
- }
- Error ELFAttributeParser::stringAttribute(unsigned tag) {
- StringRef tagName =
- ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false);
- StringRef desc = de.getCStrRef(cursor);
- attributesStr.insert(std::make_pair(tag, desc));
- if (sw) {
- DictScope scope(*sw, "Attribute");
- sw->printNumber("Tag", tag);
- if (!tagName.empty())
- sw->printString("TagName", tagName);
- sw->printString("Value", desc);
- }
- return Error::success();
- }
- void ELFAttributeParser::printAttribute(unsigned tag, unsigned value,
- StringRef valueDesc) {
- attributes.insert(std::make_pair(tag, value));
- if (sw) {
- StringRef tagName = ELFAttrs::attrTypeAsString(tag, tagToStringMap,
- /*hasTagPrefix=*/false);
- DictScope as(*sw, "Attribute");
- sw->printNumber("Tag", tag);
- sw->printNumber("Value", value);
- if (!tagName.empty())
- sw->printString("TagName", tagName);
- if (!valueDesc.empty())
- sw->printString("Description", valueDesc);
- }
- }
- void ELFAttributeParser::parseIndexList(SmallVectorImpl<uint8_t> &indexList) {
- for (;;) {
- uint64_t value = de.getULEB128(cursor);
- if (!cursor || !value)
- break;
- indexList.push_back(value);
- }
- }
- Error ELFAttributeParser::parseAttributeList(uint32_t length) {
- uint64_t pos;
- uint64_t end = cursor.tell() + length;
- while ((pos = cursor.tell()) < end) {
- uint64_t tag = de.getULEB128(cursor);
- bool handled;
- if (Error e = handler(tag, handled))
- return e;
- if (!handled) {
- if (tag < 32) {
- return createStringError(errc::invalid_argument,
- "invalid tag 0x" + Twine::utohexstr(tag) +
- " at offset 0x" + Twine::utohexstr(pos));
- }
- if (tag % 2 == 0) {
- if (Error e = integerAttribute(tag))
- return e;
- } else {
- if (Error e = stringAttribute(tag))
- return e;
- }
- }
- }
- return Error::success();
- }
- Error ELFAttributeParser::parseSubsection(uint32_t length) {
- uint64_t end = cursor.tell() - sizeof(length) + length;
- StringRef vendorName = de.getCStrRef(cursor);
- if (sw) {
- sw->printNumber("SectionLength", length);
- sw->printString("Vendor", vendorName);
- }
- // Ignore unrecognized vendor-name.
- if (vendorName.lower() != vendor)
- return createStringError(errc::invalid_argument,
- "unrecognized vendor-name: " + vendorName);
- while (cursor.tell() < end) {
- /// Tag_File | Tag_Section | Tag_Symbol uleb128:byte-size
- uint8_t tag = de.getU8(cursor);
- uint32_t size = de.getU32(cursor);
- if (!cursor)
- return cursor.takeError();
- if (sw) {
- sw->printEnum("Tag", tag, makeArrayRef(tagNames));
- sw->printNumber("Size", size);
- }
- if (size < 5)
- return createStringError(errc::invalid_argument,
- "invalid attribute size " + Twine(size) +
- " at offset 0x" +
- Twine::utohexstr(cursor.tell() - 5));
- StringRef scopeName, indexName;
- SmallVector<uint8_t, 8> indicies;
- switch (tag) {
- case ELFAttrs::File:
- scopeName = "FileAttributes";
- break;
- case ELFAttrs::Section:
- scopeName = "SectionAttributes";
- indexName = "Sections";
- parseIndexList(indicies);
- break;
- case ELFAttrs::Symbol:
- scopeName = "SymbolAttributes";
- indexName = "Symbols";
- parseIndexList(indicies);
- break;
- default:
- return createStringError(errc::invalid_argument,
- "unrecognized tag 0x" + Twine::utohexstr(tag) +
- " at offset 0x" +
- Twine::utohexstr(cursor.tell() - 5));
- }
- if (sw) {
- DictScope scope(*sw, scopeName);
- if (!indicies.empty())
- sw->printList(indexName, indicies);
- if (Error e = parseAttributeList(size - 5))
- return e;
- } else if (Error e = parseAttributeList(size - 5))
- return e;
- }
- return Error::success();
- }
- Error ELFAttributeParser::parse(ArrayRef<uint8_t> section,
- support::endianness endian) {
- unsigned sectionNumber = 0;
- de = DataExtractor(section, endian == support::little, 0);
- // For early returns, we have more specific errors, consume the Error in
- // cursor.
- struct ClearCursorError {
- DataExtractor::Cursor &cursor;
- ~ClearCursorError() { consumeError(cursor.takeError()); }
- } clear{cursor};
- // Unrecognized format-version.
- uint8_t formatVersion = de.getU8(cursor);
- if (formatVersion != ELFAttrs::Format_Version)
- return createStringError(errc::invalid_argument,
- "unrecognized format-version: 0x" +
- utohexstr(formatVersion));
- while (!de.eof(cursor)) {
- uint32_t sectionLength = de.getU32(cursor);
- if (!cursor)
- return cursor.takeError();
- if (sw) {
- sw->startLine() << "Section " << ++sectionNumber << " {\n";
- sw->indent();
- }
- if (sectionLength < 4 || cursor.tell() - 4 + sectionLength > section.size())
- return createStringError(errc::invalid_argument,
- "invalid section length " +
- Twine(sectionLength) + " at offset 0x" +
- utohexstr(cursor.tell() - 4));
- if (Error e = parseSubsection(sectionLength))
- return e;
- if (sw) {
- sw->unindent();
- sw->startLine() << "}\n";
- }
- }
- return cursor.takeError();
- }
|