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