LLVM  15.0.0git
ELFAttributeParser.cpp
Go to the documentation of this file.
1 //===--- ELFAttributeParser.cpp - ELF Attribute Parser --------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/ADT/StringExtras.h"
11 #include "llvm/Support/Errc.h"
13 
14 using namespace llvm;
15 using namespace llvm::ELFAttrs;
16 
17 static constexpr EnumEntry<unsigned> tagNames[] = {
18  {"Tag_File", ELFAttrs::File},
19  {"Tag_Section", ELFAttrs::Section},
20  {"Tag_Symbol", ELFAttrs::Symbol},
21 };
22 
24  ArrayRef<const char *> strings) {
25  uint64_t value = de.getULEB128(cursor);
26  if (value >= strings.size()) {
27  printAttribute(tag, value, "");
29  "unknown " + Twine(name) +
30  " value: " + Twine(value));
31  }
32  printAttribute(tag, value, strings[value]);
33  return Error::success();
34 }
35 
37  StringRef tagName =
38  ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false);
39  uint64_t value = de.getULEB128(cursor);
40  attributes.insert(std::make_pair(tag, value));
41 
42  if (sw) {
43  DictScope scope(*sw, "Attribute");
44  sw->printNumber("Tag", tag);
45  if (!tagName.empty())
46  sw->printString("TagName", tagName);
47  sw->printNumber("Value", value);
48  }
49  return Error::success();
50 }
51 
53  StringRef tagName =
54  ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false);
55  StringRef desc = de.getCStrRef(cursor);
56  attributesStr.insert(std::make_pair(tag, desc));
57 
58  if (sw) {
59  DictScope scope(*sw, "Attribute");
60  sw->printNumber("Tag", tag);
61  if (!tagName.empty())
62  sw->printString("TagName", tagName);
63  sw->printString("Value", desc);
64  }
65  return Error::success();
66 }
67 
68 void ELFAttributeParser::printAttribute(unsigned tag, unsigned value,
69  StringRef valueDesc) {
70  attributes.insert(std::make_pair(tag, value));
71 
72  if (sw) {
73  StringRef tagName = ELFAttrs::attrTypeAsString(tag, tagToStringMap,
74  /*hasTagPrefix=*/false);
75  DictScope as(*sw, "Attribute");
76  sw->printNumber("Tag", tag);
77  sw->printNumber("Value", value);
78  if (!tagName.empty())
79  sw->printString("TagName", tagName);
80  if (!valueDesc.empty())
81  sw->printString("Description", valueDesc);
82  }
83 }
84 
86  for (;;) {
87  uint64_t value = de.getULEB128(cursor);
88  if (!cursor || !value)
89  break;
90  indexList.push_back(value);
91  }
92 }
93 
95  uint64_t pos;
96  uint64_t end = cursor.tell() + length;
97  while ((pos = cursor.tell()) < end) {
98  uint64_t tag = de.getULEB128(cursor);
99  bool handled;
100  if (Error e = handler(tag, handled))
101  return e;
102 
103  if (!handled) {
104  if (tag < 32) {
106  "invalid tag 0x" + Twine::utohexstr(tag) +
107  " at offset 0x" + Twine::utohexstr(pos));
108  }
109 
110  if (tag % 2 == 0) {
111  if (Error e = integerAttribute(tag))
112  return e;
113  } else {
114  if (Error e = stringAttribute(tag))
115  return e;
116  }
117  }
118  }
119  return Error::success();
120 }
121 
123  uint64_t end = cursor.tell() - sizeof(length) + length;
124  StringRef vendorName = de.getCStrRef(cursor);
125  if (sw) {
126  sw->printNumber("SectionLength", length);
127  sw->printString("Vendor", vendorName);
128  }
129 
130  // Ignore unrecognized vendor-name.
131  if (vendorName.lower() != vendor)
133  "unrecognized vendor-name: " + vendorName);
134 
135  while (cursor.tell() < end) {
136  /// Tag_File | Tag_Section | Tag_Symbol uleb128:byte-size
137  uint8_t tag = de.getU8(cursor);
138  uint32_t size = de.getU32(cursor);
139  if (!cursor)
140  return cursor.takeError();
141 
142  if (sw) {
143  sw->printEnum("Tag", tag, makeArrayRef(tagNames));
144  sw->printNumber("Size", size);
145  }
146  if (size < 5)
148  "invalid attribute size " + Twine(size) +
149  " at offset 0x" +
150  Twine::utohexstr(cursor.tell() - 5));
151 
152  StringRef scopeName, indexName;
153  SmallVector<uint8_t, 8> indicies;
154  switch (tag) {
155  case ELFAttrs::File:
156  scopeName = "FileAttributes";
157  break;
158  case ELFAttrs::Section:
159  scopeName = "SectionAttributes";
160  indexName = "Sections";
161  parseIndexList(indicies);
162  break;
163  case ELFAttrs::Symbol:
164  scopeName = "SymbolAttributes";
165  indexName = "Symbols";
166  parseIndexList(indicies);
167  break;
168  default:
170  "unrecognized tag 0x" + Twine::utohexstr(tag) +
171  " at offset 0x" +
172  Twine::utohexstr(cursor.tell() - 5));
173  }
174 
175  if (sw) {
176  DictScope scope(*sw, scopeName);
177  if (!indicies.empty())
178  sw->printList(indexName, indicies);
179  if (Error e = parseAttributeList(size - 5))
180  return e;
181  } else if (Error e = parseAttributeList(size - 5))
182  return e;
183  }
184  return Error::success();
185 }
186 
189  unsigned sectionNumber = 0;
190  de = DataExtractor(section, endian == support::little, 0);
191 
192  // For early returns, we have more specific errors, consume the Error in
193  // cursor.
194  struct ClearCursorError {
195  DataExtractor::Cursor &cursor;
196  ~ClearCursorError() { consumeError(cursor.takeError()); }
197  } clear{cursor};
198 
199  // Unrecognized format-version.
200  uint8_t formatVersion = de.getU8(cursor);
201  if (formatVersion != ELFAttrs::Format_Version)
203  "unrecognized format-version: 0x" +
204  utohexstr(formatVersion));
205 
206  while (!de.eof(cursor)) {
207  uint32_t sectionLength = de.getU32(cursor);
208  if (!cursor)
209  return cursor.takeError();
210 
211  if (sw) {
212  sw->startLine() << "Section " << ++sectionNumber << " {\n";
213  sw->indent();
214  }
215 
216  if (sectionLength < 4 || cursor.tell() - 4 + sectionLength > section.size())
218  "invalid section length " +
219  Twine(sectionLength) + " at offset 0x" +
220  utohexstr(cursor.tell() - 4));
221 
222  if (Error e = parseSubsection(sectionLength))
223  return e;
224  if (sw) {
225  sw->unindent();
226  sw->startLine() << "}\n";
227  }
228  }
229 
230  return cursor.takeError();
231 }
llvm::errc::invalid_argument
@ invalid_argument
as
compiles conv shl5 shl ret i32 or10 it would be better as
Definition: README.txt:615
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::ELFAttributeParser::parseStringAttribute
Error parseStringAttribute(const char *name, unsigned tag, ArrayRef< const char * > strings)
Definition: ELFAttributeParser.cpp:23
llvm::ELFAttributeParser::printAttribute
void printAttribute(unsigned tag, unsigned value, StringRef valueDesc)
Definition: ELFAttributeParser.cpp:68
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
Errc.h
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:235
attributes
Deduce and propagate attributes
Definition: Attributor.cpp:3469
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
llvm::EnumEntry
Definition: EnumTables.h:18
clear
static void clear(coro::Shape &Shape)
Definition: Coroutines.cpp:149
llvm::support::endian
Definition: Endian.h:42
llvm::DataExtractor::Cursor::takeError
Error takeError()
Return error contained inside this Cursor, if any.
Definition: DataExtractor.h:78
llvm::support::little
@ little
Definition: Endian.h:27
llvm::ELFAttributeParser::parseAttributeList
Error parseAttributeList(uint32_t length)
Definition: ELFAttributeParser.cpp:94
llvm::ELFAttrs::Format_Version
@ Format_Version
Definition: ELFAttributes.h:33
llvm::ELFAttrs::Symbol
@ Symbol
Definition: ELFAttributes.h:26
llvm::Twine::utohexstr
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:408
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
uint64_t
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
StringExtras.h
llvm::StringRef::lower
LLVM_NODISCARD std::string lower() const
Definition: StringRef.cpp:112
llvm::DataExtractor::Cursor
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
Definition: DataExtractor.h:54
ELFAttributeParser.h
llvm::size
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1598
llvm::DictScope
Definition: ScopedPrinter.h:799
llvm::ELFAttributeParser::parse
Error parse(ArrayRef< uint8_t > section, support::endianness endian)
Definition: ELFAttributeParser.cpp:187
llvm::ArrayRef< const char * >
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
uint32_t
llvm::ELFAttributeParser::integerAttribute
Error integerAttribute(unsigned tag)
Definition: ELFAttributeParser.cpp:36
name
static const char * name
Definition: SVEIntrinsicOpts.cpp:74
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1239
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
tagNames
static constexpr EnumEntry< unsigned > tagNames[]
Definition: ELFAttributeParser.cpp:17
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:475
llvm::ELFAttrs::Section
@ Section
Definition: ELFAttributes.h:26
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::ELFAttributeParser::parseSubsection
Error parseSubsection(uint32_t length)
Definition: ELFAttributeParser.cpp:122
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
llvm::ELFAttrs::File
@ File
Definition: ELFAttributes.h:26
llvm::support::endianness
endianness
Definition: Endian.h:27
llvm::SmallVectorImpl< uint8_t >
llvm::ELFAttributeParser::stringAttribute
Error stringAttribute(unsigned tag)
Definition: ELFAttributeParser.cpp:52
llvm::ELFAttrs
Definition: ELFAttributes.h:24
llvm::ELFAttributeParser::parseIndexList
void parseIndexList(SmallVectorImpl< uint8_t > &indexList)
Definition: ELFAttributeParser.cpp:85
llvm::ELFAttrs::attrTypeAsString
StringRef attrTypeAsString(unsigned attr, TagNameMap tagNameMap, bool hasTagPrefix=true)
Definition: ELFAttributes.cpp:14
ScopedPrinter.h