1 //===-- TapiUniversal.h - Text-based Dynamic Library Stub -------*- 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 // This file declares the TapiUniversal interface.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_OBJECT_TAPIUNIVERSAL_H
14 #define LLVM_OBJECT_TAPIUNIVERSAL_H
15 
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/Object/Binary.h"
18 #include "llvm/Support/Error.h"
19 #include "llvm/Support/MemoryBufferRef.h"
20 #include "llvm/TextAPI/Architecture.h"
21 #include "llvm/TextAPI/InterfaceFile.h"
22 
23 namespace llvm {
24 namespace object {
25 
26 class TapiFile;
27 
28 class TapiUniversal : public Binary {
29 public:
30   class ObjectForArch {
31     const TapiUniversal *Parent;
32     int Index;
33 
34   public:
35     ObjectForArch(const TapiUniversal *Parent, int Index)
36         : Parent(Parent), Index(Index) {}
37 
38     ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
39 
40     bool operator==(const ObjectForArch &Other) const {
41       return (Parent == Other.Parent) && (Index == Other.Index);
42     }
43 
44     uint32_t getCPUType() const {
45       auto Result =
46           MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
47       return Result.first;
48     }
49 
50     uint32_t getCPUSubType() const {
51       auto Result =
52           MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
53       return Result.second;
54     }
55 
56     StringRef getArchFlagName() const {
57       return MachO::getArchitectureName(Parent->Libraries[Index].Arch);
58     }
59 
60     std::string getInstallName() const {
61       return std::string(Parent->Libraries[Index].InstallName);
62     }
63 
64     bool isTopLevelLib() const {
65       return Parent->ParsedFile->getInstallName() == getInstallName();
66     }
67 
68     Expected<std::unique_ptr<TapiFile>> getAsObjectFile() const;
69   };
70 
71   class object_iterator {
72     ObjectForArch Obj;
73 
74   public:
75     object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
76     const ObjectForArch *operator->() const { return &Obj; }
77     const ObjectForArch &operator*() const { return Obj; }
78 
79     bool operator==(const object_iterator &Other) const {
80       return Obj == Other.Obj;
81     }
82     bool operator!=(const object_iterator &Other) const {
83       return !(*this == Other);
84     }
85 
86     object_iterator &operator++() { // Preincrement
87       Obj = Obj.getNext();
88       return *this;
89     }
90   };
91 
92   TapiUniversal(MemoryBufferRef Source, Error &Err);
93   static Expected<std::unique_ptr<TapiUniversal>>
94   create(MemoryBufferRef Source);
95   ~TapiUniversal() override;
96 
97   object_iterator begin_objects() const { return ObjectForArch(this, 0); }
98   object_iterator end_objects() const {
99     return ObjectForArch(this, Libraries.size());
100   }
101 
102   iterator_range<object_iterator> objects() const {
103     return make_range(begin_objects(), end_objects());
104   }
105 
106   const MachO::InterfaceFile &getInterfaceFile() { return *ParsedFile; }
107 
108   uint32_t getNumberOfObjects() const { return Libraries.size(); }
109 
110   static bool classof(const Binary *v) { return v->isTapiUniversal(); }
111 
112 private:
113   struct Library {
114     StringRef InstallName;
115     MachO::Architecture Arch;
116   };
117 
118   std::unique_ptr<MachO::InterfaceFile> ParsedFile;
119   std::vector<Library> Libraries;
120 };
121 
122 } // end namespace object.
123 } // end namespace llvm.
124 
125 #endif // LLVM_OBJECT_TAPIUNIVERSAL_H
126