blob: 070b7175f53be7cc1f4dd36046ffaf7f2279ec2e [file] [log] [blame]
Logan3f3d31f2010-11-27 13:52:03 +08001/*
Stephen Hinescc366e52012-02-21 17:22:04 -08002 * Copyright 2010-2012, The Android Open Source Project
Logan3f3d31f2010-11-27 13:52:03 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef BCC_SCRIPT_H
18#define BCC_SCRIPT_H
19
20#include <bcc/bcc.h>
Loganf340bf72011-01-14 17:51:40 +080021#include "bcc_internal.h"
Logan3f3d31f2010-11-27 13:52:03 +080022
Loganecf4cbd2011-01-06 05:34:11 +080023#include "Compiler.h"
24
Shih-wei Liao8afed382012-01-10 15:57:24 +080025#include <llvm/Support/CodeGen.h>
26
Logan Chien7890d432011-08-03 14:55:17 +080027#include <vector>
28#include <string>
29
Loganbe79ada2011-01-13 01:33:45 +080030#include <stddef.h>
31
Loganeaa0cc32010-12-29 01:04:20 +080032namespace llvm {
33 class Module;
Daniel Malea094881f2011-12-14 17:39:16 -050034 class GDBJITRegistrar;
Loganeaa0cc32010-12-29 01:04:20 +080035}
36
Logan3f3d31f2010-11-27 13:52:03 +080037namespace bcc {
Logancf3e5212010-12-29 01:44:55 +080038 class ScriptCompiled;
39 class ScriptCached;
Logan474cbd22011-01-31 01:47:44 +080040 class SourceInfo;
Zonr Chang2fcbd022012-01-06 21:04:31 +080041 struct CompilerOption;
Logancf3e5212010-12-29 01:44:55 +080042
43 namespace ScriptStatus {
44 enum StatusType {
45 Unknown,
46 Compiled,
Logan35849002011-01-15 07:30:43 +080047#if USE_CACHE
Loganf7f0ac52011-01-07 03:53:43 +080048 Cached,
Logan35849002011-01-15 07:30:43 +080049#endif
Logancf3e5212010-12-29 01:44:55 +080050 };
51 }
Logan3f3d31f2010-11-27 13:52:03 +080052
Zonr Chang4ea08862012-01-17 17:26:49 +080053 namespace ScriptObject {
54 enum ObjectType {
55 Unknown,
56 Relocatable,
Shih-wei Liaoa471ebb2012-02-05 00:49:58 -080057 SharedObject,
Zonr Chang4ea08862012-01-17 17:26:49 +080058 Executable,
59 };
60 }
61
Logan0647e9e2010-12-29 00:21:31 +080062 class Script {
Logan39736412010-12-29 00:24:04 +080063 private:
Loganf340bf72011-01-14 17:51:40 +080064 int mErrorCode;
Logan39736412010-12-29 00:24:04 +080065
Logancf3e5212010-12-29 01:44:55 +080066 ScriptStatus::StatusType mStatus;
Zonr Chang4ea08862012-01-17 17:26:49 +080067 ScriptObject::ObjectType mObjectType;
Logancf3e5212010-12-29 01:44:55 +080068
69 union {
70 ScriptCompiled *mCompiled;
Logan35849002011-01-15 07:30:43 +080071#if USE_CACHE
Logancf3e5212010-12-29 01:44:55 +080072 ScriptCached *mCached;
Logan35849002011-01-15 07:30:43 +080073#endif
Logancf3e5212010-12-29 01:44:55 +080074 };
75
Logan Chien311c26f2011-07-11 14:30:34 +080076#if USE_CACHE
77 std::string mCacheDir;
78 std::string mCacheName;
Zonr Chang4ea08862012-01-17 17:26:49 +080079
80 inline std::string getCachedObjectPath() const {
81#if USE_OLD_JIT
82 return std::string(mCacheDir + mCacheName + ".jit-image");
83#elif USE_MCJIT
84 std::string objPath(mCacheDir + mCacheName);
85
86 // Append suffix depends on the object type
87 switch (mObjectType) {
88 case ScriptObject::Relocatable:
89 case ScriptObject::Executable: {
90 objPath.append(".o");
91 break;
92 }
Shih-wei Liaoa471ebb2012-02-05 00:49:58 -080093
94 case ScriptObject::SharedObject: {
95 objPath.append(".so");
96 break;
97 }
98
Zonr Chang4ea08862012-01-17 17:26:49 +080099 default: {
Shih-wei Liao2b7db0e2012-01-17 17:49:46 -0800100 assert(false && "Unknown object type!");
Zonr Chang4ea08862012-01-17 17:26:49 +0800101 }
102 }
103 return objPath;
104#endif
105 }
106
107 inline std::string getCacheInfoPath() const {
108#if USE_OLD_JIT
Zonr Chang6692ab52012-01-17 17:29:13 +0800109 return getCachedObjectPath().append(".oBCC");
Zonr Chang4ea08862012-01-17 17:26:49 +0800110#elif USE_MCJIT
Zonr Chang6692ab52012-01-17 17:29:13 +0800111 return getCachedObjectPath().append(".info");
Zonr Chang4ea08862012-01-17 17:26:49 +0800112#endif
113 }
Logan Chien311c26f2011-07-11 14:30:34 +0800114#endif
Loganecf4cbd2011-01-06 05:34:11 +0800115
Logan42598052011-01-26 22:41:13 +0800116 bool mIsContextSlotNotAvail;
117
Logan474cbd22011-01-31 01:47:44 +0800118 // Source List
119 SourceInfo *mSourceList[2];
120 // Note: mSourceList[0] (main source)
121 // Note: mSourceList[1] (library source)
122 // TODO(logan): Generalize this, use vector or SmallVector instead!
Logan3133c412011-01-06 06:15:40 +0800123
Logan Chien7890d432011-08-03 14:55:17 +0800124 // External Function List
125 std::vector<char const *> mUserDefinedExternalSymbols;
126
Loganecf4cbd2011-01-06 05:34:11 +0800127 // Register Symbol Lookup Function
Logancf3e5212010-12-29 01:44:55 +0800128 BCCSymbolLookupFn mpExtSymbolLookupFn;
Loganf340bf72011-01-14 17:51:40 +0800129 void *mpExtSymbolLookupFnContext;
Loganeaa0cc32010-12-29 01:04:20 +0800130
Logan3f3d31f2010-11-27 13:52:03 +0800131 public:
Logan033f46e2011-01-06 05:51:24 +0800132 Script() : mErrorCode(BCC_NO_ERROR), mStatus(ScriptStatus::Unknown),
Zonr Chang4ea08862012-01-17 17:26:49 +0800133 mObjectType(ScriptObject::Unknown), mIsContextSlotNotAvail(false),
Logan65719812011-01-07 11:17:14 +0800134 mpExtSymbolLookupFn(NULL), mpExtSymbolLookupFnContext(NULL) {
Loganecf4cbd2011-01-06 05:34:11 +0800135 Compiler::GlobalInitialization();
Logan474cbd22011-01-31 01:47:44 +0800136
137 mSourceList[0] = NULL;
138 mSourceList[1] = NULL;
Logan3f3d31f2010-11-27 13:52:03 +0800139 }
140
Logancf3e5212010-12-29 01:44:55 +0800141 ~Script();
Loganeaa0cc32010-12-29 01:04:20 +0800142
Logan474cbd22011-01-31 01:47:44 +0800143 int addSourceBC(size_t idx,
144 char const *resName,
145 const char *bitcode,
146 size_t bitcodeSize,
147 unsigned long flags);
Loganeaa0cc32010-12-29 01:04:20 +0800148
Logan474cbd22011-01-31 01:47:44 +0800149 int addSourceModule(size_t idx,
150 llvm::Module *module,
151 unsigned long flags);
Loganecf4cbd2011-01-06 05:34:11 +0800152
Logan474cbd22011-01-31 01:47:44 +0800153 int addSourceFile(size_t idx,
154 char const *path,
155 unsigned long flags);
Loganeaa0cc32010-12-29 01:04:20 +0800156
Logan Chien7890d432011-08-03 14:55:17 +0800157 void markExternalSymbol(char const *name) {
158 mUserDefinedExternalSymbols.push_back(name);
159 }
160
161 std::vector<char const *> const &getUserDefinedExternalSymbols() const {
162 return mUserDefinedExternalSymbols;
163 }
164
Logan Chien311c26f2011-07-11 14:30:34 +0800165 int prepareExecutable(char const *cacheDir,
166 char const *cacheName,
167 unsigned long flags);
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800168 int writeCache();
Loganeaa0cc32010-12-29 01:04:20 +0800169
Shih-wei Liaoa471ebb2012-02-05 00:49:58 -0800170 /*
171 * Link the given bitcodes in mSourceList to shared object (.so).
172 *
173 * Currently, it requires one to provide the relocatable object files with
174 * given bitcodes to output a shared object.
175 *
176 * The usage of this function is flexible. You can have a relocatable object
177 * compiled before and pass it in objPath to generate shared object. If the
178 * objPath is NULL, we'll invoke prepareRelocatable() to get .o first (if
179 * you haven't done that yet) and then link the output relocatable object
180 * file. The latter case will have libbcc compile with USE_CACHE enabled.
181 *
182 * TODO: Currently, we only support to link the bitcodes in mSourceList[0].
183 *
184 */
185 int prepareSharedObject(char const *cacheDir,
186 char const *cacheName,
187 char const *objPath,
188 char const *dsoPath,
189 unsigned long flags);
190
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800191 int prepareRelocatable(char const *objPath,
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -0800192 llvm::Reloc::Model RelocModel,
193 unsigned long flags);
Joseph Wen34c600a2011-07-25 17:59:17 -0700194
Logancf3e5212010-12-29 01:44:55 +0800195 char const *getCompilerErrorMessage();
Loganeaa0cc32010-12-29 01:04:20 +0800196
Logancf3e5212010-12-29 01:44:55 +0800197 void *lookup(const char *name);
Loganeaa0cc32010-12-29 01:04:20 +0800198
Loganeaa0cc32010-12-29 01:04:20 +0800199
Loganbe79ada2011-01-13 01:33:45 +0800200 size_t getExportVarCount() const;
Loganeaa0cc32010-12-29 01:04:20 +0800201
Loganbe79ada2011-01-13 01:33:45 +0800202 size_t getExportFuncCount() const;
Loganeaa0cc32010-12-29 01:04:20 +0800203
Stephen Hinescc366e52012-02-21 17:22:04 -0800204 size_t getExportForEachCount() const;
205
Loganbe79ada2011-01-13 01:33:45 +0800206 size_t getPragmaCount() const;
Loganeaa0cc32010-12-29 01:04:20 +0800207
Loganbe79ada2011-01-13 01:33:45 +0800208 size_t getFuncCount() const;
Loganeaa0cc32010-12-29 01:04:20 +0800209
Stephen Hines071288a2011-01-27 14:38:26 -0800210 size_t getObjectSlotCount() const;
Loganbe79ada2011-01-13 01:33:45 +0800211
212 void getExportVarList(size_t size, void **list);
213
214 void getExportFuncList(size_t size, void **list);
215
Stephen Hinescc366e52012-02-21 17:22:04 -0800216 void getExportForEachList(size_t size, void **list);
217
Joseph Wenf36637f2011-07-06 18:27:12 -0700218 void getExportVarNameList(std::vector<std::string> &list);
219
220 void getExportFuncNameList(std::vector<std::string> &list);
221
Stephen Hinescc366e52012-02-21 17:22:04 -0800222 void getExportForEachNameList(std::vector<std::string> &list);
223
Loganbe79ada2011-01-13 01:33:45 +0800224 void getPragmaList(size_t size,
225 char const **keyList,
226 char const **valueList);
227
Loganf340bf72011-01-14 17:51:40 +0800228 void getFuncInfoList(size_t size, FuncInfo *list);
Loganbe79ada2011-01-13 01:33:45 +0800229
Stephen Hines071288a2011-01-27 14:38:26 -0800230 void getObjectSlotList(size_t size, uint32_t *list);
231
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700232 size_t getELFSize() const;
233
234 const char *getELF() const;
Logan02286cb2011-01-07 00:30:47 +0800235
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800236 int registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext);
Loganeaa0cc32010-12-29 01:04:20 +0800237
Logan Chiend2a5f302011-07-19 20:32:25 +0800238#if USE_OLD_JIT
Loganbe79ada2011-01-13 01:33:45 +0800239 char *getContext();
Logan Chiend2a5f302011-07-19 20:32:25 +0800240#endif
Loganbe79ada2011-01-13 01:33:45 +0800241
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800242 bool isCacheable() const;
Loganeaa0cc32010-12-29 01:04:20 +0800243
Loganf340bf72011-01-14 17:51:40 +0800244 void setError(int error) {
Logan39736412010-12-29 00:24:04 +0800245 if (mErrorCode == BCC_NO_ERROR && error != BCC_NO_ERROR) {
246 mErrorCode = error;
Logan3f3d31f2010-11-27 13:52:03 +0800247 }
248 }
249
Loganf340bf72011-01-14 17:51:40 +0800250 int getError() {
251 int result = mErrorCode;
Logan39736412010-12-29 00:24:04 +0800252 mErrorCode = BCC_NO_ERROR;
Logan3f3d31f2010-11-27 13:52:03 +0800253 return result;
254 }
Logan033f46e2011-01-06 05:51:24 +0800255
256 private:
Logan35849002011-01-15 07:30:43 +0800257#if USE_CACHE
Zonr Chang743dd712012-01-19 10:13:52 +0800258 //
259 // It returns 0 if there's a cache hit.
260 //
261 // Side effect: it will set mCacheDir, mCacheName and mObjectType.
262 int internalLoadCache(char const *cacheDir, char const *cacheName,
263 ScriptObject::ObjectType objectType, bool checkOnly);
Logan35849002011-01-15 07:30:43 +0800264#endif
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800265 int internalCompile(const CompilerOption&);
Logan3f3d31f2010-11-27 13:52:03 +0800266 };
267
268} // namespace bcc
269
270#endif // BCC_SCRIPT_H