1+ #include " llvm-c/Object.h"
12#include " llvm/IR/Intrinsics.h"
23#include " llvm/IR/Function.h"
34#include " llvm/Support/ARMTargetParser.h"
5+ #include " llvm/Object/MachOUniversal.h"
6+ #include " llvm/Object/ObjectFile.h"
7+ #include " llvm/ADT/SmallVector.h"
48
59extern " C" {
10+ typedef struct LLVMOpaqueBinary *LLVMBinaryRef;
11+
612 size_t LLVMSwiftCountIntrinsics (void );
713 const char *LLVMSwiftGetIntrinsicAtIndex (size_t index);
814 unsigned LLVMLookupIntrinsicID (const char *Name, size_t NameLen);
@@ -17,6 +23,180 @@ extern "C" {
1723
1824 LLVMARMProfileKind LLVMARMParseArchProfile (const char *Name, size_t NameLen);
1925 unsigned LLVMARMParseArchVersion (const char *Name, size_t NameLen);
26+
27+ typedef enum {
28+ LLVMBinaryTypeArchive,
29+ LLVMBinaryTypeMachOUniversalBinary,
30+ LLVMBinaryTypeCOFFImportFile,
31+ // LLVM IR
32+ LLVMBinaryTypeIR,
33+ LLVMBinaryTypeMinidump,
34+
35+ // Windows resource (.res) file.
36+ LLVMBinaryTypeWinRes,
37+
38+ // Object and children.
39+ LLVMBinaryTypeCOFF,
40+
41+ // ELF 32-bit, little endian
42+ LLVMBinaryTypeELF32L,
43+ // ELF 32-bit, big endian
44+ LLVMBinaryTypeELF32B,
45+ // ELF 64-bit, little endian
46+ LLVMBinaryTypeELF64L,
47+ // ELF 64-bit, big endian
48+ LLVMBinaryTypeELF64B,
49+
50+ // MachO 32-bit, little endian
51+ LLVMBinaryTypeMachO32L,
52+ // MachO 32-bit, big endian
53+ LLVMBinaryTypeMachO32B,
54+ // MachO 64-bit, little endian
55+ LLVMBinaryTypeMachO64L,
56+ // MachO 64-bit, big endian
57+ LLVMBinaryTypeMachO64B,
58+
59+ LLVMBinaryTypeWasm,
60+ } LLVMBinaryType;
61+
62+ LLVMBinaryType LLVMBinaryGetType (LLVMBinaryRef BR);
63+ LLVMBinaryRef LLVMCreateBinary (LLVMMemoryBufferRef MemBuf, LLVMContextRef Context);
64+ void LLVMDisposeBinary (LLVMBinaryRef BR);
65+
66+ LLVMBinaryRef LLVMUniversalBinaryGetObjectForArchitecture (LLVMBinaryRef BR, const char *Arch, size_t ArchLen);
67+
68+ LLVMSectionIteratorRef LLVMObjectFileGetSections (LLVMBinaryRef BR);
69+
70+ LLVMBool LLVMObjectFileIsSectionIteratorAtEnd (LLVMBinaryRef BR,
71+ LLVMSectionIteratorRef SI);
72+ LLVMSymbolIteratorRef LLVMObjectFileGetSymbols (LLVMBinaryRef BR);
73+
74+ LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd (LLVMBinaryRef BR,
75+ LLVMSymbolIteratorRef SI);
76+ }
77+
78+ using namespace llvm ;
79+ using namespace llvm ::object;
80+
81+ inline Binary *unwrap (LLVMBinaryRef OF) {
82+ return reinterpret_cast <Binary *>(OF);
83+ }
84+
85+ inline static LLVMBinaryRef wrap (const Binary *OF) {
86+ return reinterpret_cast <LLVMBinaryRef>(const_cast <Binary *>(OF));
87+ }
88+
89+ inline static section_iterator *unwrap (LLVMSectionIteratorRef SI) {
90+ return reinterpret_cast <section_iterator*>(SI);
91+ }
92+
93+ inline static LLVMSectionIteratorRef
94+ wrap (const section_iterator *SI) {
95+ return reinterpret_cast <LLVMSectionIteratorRef>
96+ (const_cast <section_iterator*>(SI));
97+ }
98+
99+ inline static symbol_iterator *unwrap (LLVMSymbolIteratorRef SI) {
100+ return reinterpret_cast <symbol_iterator*>(SI);
101+ }
102+
103+ inline static LLVMSymbolIteratorRef
104+ wrap (const symbol_iterator *SI) {
105+ return reinterpret_cast <LLVMSymbolIteratorRef>
106+ (const_cast <symbol_iterator*>(SI));
107+ }
108+
109+ LLVMBinaryType LLVMBinaryGetType (LLVMBinaryRef BR) {
110+ switch (unwrap (BR)->getType ()) {
111+ case 0 : // ID_Archive:
112+ return LLVMBinaryTypeArchive;
113+ case 1 : // ID_MachOUniversalBinary:
114+ return LLVMBinaryTypeMachOUniversalBinary;
115+ case 2 : // ID_COFFImportFile:
116+ return LLVMBinaryTypeCOFFImportFile;
117+ case 3 : // ID_IR:
118+ return LLVMBinaryTypeIR;
119+ case 4 : // ID_Minidump:
120+ return LLVMBinaryTypeMinidump;
121+ case 5 : // ID_WinRes:
122+ return LLVMBinaryTypeWinRes;
123+ case 7 : // ID_COFF:
124+ return LLVMBinaryTypeCOFF;
125+ case 8 : // ID_ELF32L:
126+ return LLVMBinaryTypeELF32L;
127+ case 9 : // ID_ELF32B:
128+ return LLVMBinaryTypeELF32B;
129+ case 10 : // ID_ELF64L:
130+ return LLVMBinaryTypeELF64L;
131+ case 11 : // ID_ELF64B:
132+ return LLVMBinaryTypeELF64B;
133+ case 12 : // ID_MachO32L:
134+ return LLVMBinaryTypeMachO32L;
135+ case 13 : // ID_MachO32B:
136+ return LLVMBinaryTypeMachO32B;
137+ case 14 : // ID_MachO64L:
138+ return LLVMBinaryTypeMachO64L;
139+ case 15 : // ID_MachO64B:
140+ return LLVMBinaryTypeMachO64B;
141+ case 16 : // ID_Wasm:
142+ return LLVMBinaryTypeWasm;
143+ default :
144+ llvm_unreachable (" Unknown binary kind!" );
145+ }
146+ }
147+
148+ LLVMBinaryRef LLVMCreateBinary (LLVMMemoryBufferRef MemBuf, LLVMContextRef Context) {
149+ std::unique_ptr<llvm::MemoryBuffer> Buf (unwrap (MemBuf));
150+ Expected<std::unique_ptr<Binary>> ObjOrErr (
151+ createBinary (Buf->getMemBufferRef (), unwrap (Context)));
152+ if (!ObjOrErr) {
153+ // TODO: Actually report errors helpfully.
154+ consumeError (ObjOrErr.takeError ());
155+ return nullptr ;
156+ }
157+
158+ return wrap (ObjOrErr.get ().release ());
159+ }
160+
161+ void LLVMDisposeBinary (LLVMBinaryRef BR) {
162+ delete unwrap (BR);
163+ }
164+
165+ LLVMBinaryRef LLVMUniversalBinaryGetObjectForArchitecture (LLVMBinaryRef BR, const char *Arch, size_t ArchLen) {
166+ assert (LLVMBinaryGetType (BR) == LLVMBinaryTypeMachOUniversalBinary);
167+ auto universal = cast<MachOUniversalBinary>(unwrap (BR));
168+ Expected<std::unique_ptr<ObjectFile>> ObjOrErr (
169+ universal->getObjectForArch ({Arch, ArchLen}));
170+ if (!ObjOrErr) {
171+ // TODO: Actually report errors helpfully.
172+ consumeError (ObjOrErr.takeError ());
173+ return nullptr ;
174+ }
175+ return wrap (ObjOrErr.get ().release ());
176+ }
177+
178+ LLVMSectionIteratorRef LLVMObjectFileGetSections (LLVMBinaryRef BR) {
179+ auto OF = cast<ObjectFile>(unwrap (BR));
180+ section_iterator SI = OF->section_begin ();
181+ return wrap (new section_iterator (SI));
182+ }
183+
184+ LLVMBool LLVMObjectFileIsSectionIteratorAtEnd (LLVMBinaryRef BR,
185+ LLVMSectionIteratorRef SI) {
186+ auto OF = cast<ObjectFile>(unwrap (BR));
187+ return (*unwrap (SI) == OF->section_end ()) ? 1 : 0 ;
188+ }
189+
190+ LLVMSymbolIteratorRef LLVMObjectFileGetSymbols (LLVMBinaryRef BR) {
191+ auto OF = cast<ObjectFile>(unwrap (BR));
192+ symbol_iterator SI = OF->symbol_begin ();
193+ return wrap (new symbol_iterator (SI));
194+ }
195+
196+ LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd (LLVMBinaryRef BR,
197+ LLVMSymbolIteratorRef SI) {
198+ auto OF = cast<ObjectFile>(unwrap (BR));
199+ return (*unwrap (SI) == OF->symbol_end ()) ? 1 : 0 ;
20200}
21201
22202size_t LLVMSwiftCountIntrinsics (void ) {
@@ -42,3 +222,5 @@ unsigned LLVMARMParseArchVersion(const char *Name, size_t NameLen) {
42222const char *LLVMGetARMCanonicalArchName (const char *Name, size_t NameLen) {
43223 return llvm::ARM::getCanonicalArchName ({Name, NameLen}).data ();
44224}
225+
226+
0 commit comments