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