1 //===- ELF AttributeParser.h - ELF Attribute Parser -------------*- C++ -*-===//
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 
9 #ifndef LLVM_SUPPORT_ELFATTRIBUTEPARSER_H
10 #define LLVM_SUPPORT_ELFATTRIBUTEPARSER_H
11 
12 #include "ELFAttributes.h"
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/Support/DataExtractor.h"
15 #include "llvm/Support/Error.h"
16 
17 #include <optional>
18 #include <unordered_map>
19 
20 namespace llvm {
21 class StringRef;
22 class ScopedPrinter;
23 
24 class ELFAttributeParser {
25   StringRef vendor;
26   std::unordered_map<unsigned, unsigned> attributes;
27   std::unordered_map<unsigned, StringRef> attributesStr;
28 
29   virtual Error handler(uint64_t tag, bool &handled) = 0;
30 
31 protected:
32   ScopedPrinter *sw;
33   TagNameMap tagToStringMap;
34   DataExtractor de{ArrayRef<uint8_t>{}, true, 0};
35   DataExtractor::Cursor cursor{0};
36 
37   void printAttribute(unsigned tag, unsigned value, StringRef valueDesc);
38 
39   Error parseStringAttribute(const char *name, unsigned tag,
40                              ArrayRef<const char *> strings);
41   Error parseAttributeList(uint32_t length);
42   void parseIndexList(SmallVectorImpl<uint8_t> &indexList);
43   Error parseSubsection(uint32_t length);
44 
45   void setAttributeString(unsigned tag, StringRef value) {
46     attributesStr.emplace(tag, value);
47   }
48 
49 public:
50   virtual ~ELFAttributeParser() { static_cast<void>(!cursor.takeError()); }
51   Error integerAttribute(unsigned tag);
52   Error stringAttribute(unsigned tag);
53 
54   ELFAttributeParser(ScopedPrinter *sw, TagNameMap tagNameMap, StringRef vendor)
55       : vendor(vendor), sw(sw), tagToStringMap(tagNameMap) {}
56 
57   ELFAttributeParser(TagNameMap tagNameMap, StringRef vendor)
58       : vendor(vendor), sw(nullptr), tagToStringMap(tagNameMap) {}
59 
60   Error parse(ArrayRef<uint8_t> section, llvm::endianness endian);
61 
62   std::optional<unsigned> getAttributeValue(unsigned tag) const {
63     auto I = attributes.find(tag);
64     if (I == attributes.end())
65       return std::nullopt;
66     return I->second;
67   }
68   std::optional<StringRef> getAttributeString(unsigned tag) const {
69     auto I = attributesStr.find(tag);
70     if (I == attributesStr.end())
71       return std::nullopt;
72     return I->second;
73   }
74 };
75 
76 } // namespace llvm
77 #endif
78