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