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 <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 public:
46   virtual ~ELFAttributeParser() { static_cast<void>(!cursor.takeError()); }
47   Error integerAttribute(unsigned tag);
48   Error stringAttribute(unsigned tag);
49 
50   ELFAttributeParser(ScopedPrinter *sw, TagNameMap tagNameMap, StringRef vendor)
51       : vendor(vendor), sw(sw), tagToStringMap(tagNameMap) {}
52 
53   ELFAttributeParser(TagNameMap tagNameMap, StringRef vendor)
54       : vendor(vendor), sw(nullptr), tagToStringMap(tagNameMap) {}
55 
56   Error parse(ArrayRef<uint8_t> section, support::endianness endian);
57 
58   Optional<unsigned> getAttributeValue(unsigned tag) const {
59     auto I = attributes.find(tag);
60     if (I == attributes.end())
61       return None;
62     return I->second;
63   }
64   Optional<StringRef> getAttributeString(unsigned tag) const {
65     auto I = attributesStr.find(tag);
66     if (I == attributesStr.end())
67       return None;
68     return I->second;
69   }
70 };
71 
72 } // namespace llvm
73 #endif
74