Index: tools/gold/gold-plugin.cpp |
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp |
index b7d8c5e14c688ee3fc350a992742aa41cba3b79a..24a40829e9d6ec05f167413a8f6db130ebb85ea1 100644 |
--- a/tools/gold/gold-plugin.cpp |
+++ b/tools/gold/gold-plugin.cpp |
@@ -78,6 +78,14 @@ static std::list<claimed_file> Modules; |
static std::vector<std::string> Cleanup; |
static llvm::TargetOptions TargetOpts; |
+// @LOCALMOD-BEGIN |
+// Callback for getting the number of --wrap'd symbols. |
+static ld_plugin_get_num_wrapped get_num_wrapped = NULL; |
+ |
+// Callback for getting the name of a wrapped symbol. |
+static ld_plugin_get_wrapped get_wrapped = NULL; |
+// @LOCALMOD-END |
+ |
namespace options { |
enum OutputType { |
OT_NORMAL, |
@@ -223,6 +231,14 @@ ld_plugin_status onload(ld_plugin_tv *tv) { |
case LDPT_GET_VIEW: |
get_view = tv->tv_u.tv_get_view; |
break; |
+ // @LOCALMOD-BEGIN |
+ case LDPT_GET_WRAPPED: |
+ get_wrapped = tv->tv_u.tv_get_wrapped; |
+ break; |
+ case LDPT_GET_NUM_WRAPPED: |
+ get_num_wrapped = tv->tv_u.tv_get_num_wrapped; |
+ break; |
+ // @LOCALMOD-END |
case LDPT_MESSAGE: |
message = tv->tv_u.tv_message; |
break; |
@@ -543,11 +559,9 @@ static Constant *mapConstantToLocalCopy(Constant *C, ValueToValueMapTy &VM, |
} |
static std::unique_ptr<Module> |
-getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile, |
+getModuleForFile(LLVMContext &Context, claimed_file &F, |
+ off_t Filesize, raw_fd_ostream *ApiFile, |
StringSet<> &Internalize, StringSet<> &Maybe) { |
- ld_plugin_input_file File; |
- if (get_input_file(F.handle, &File) != LDPS_OK) |
- message(LDPL_FATAL, "Failed to get file information"); |
if (get_symbols(F.handle, F.syms.size(), &F.syms[0]) != LDPS_OK) |
message(LDPL_FATAL, "Failed to get symbol information"); |
@@ -558,7 +572,7 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile, |
llvm::ErrorOr<MemoryBufferRef> MBOrErr = |
object::IRObjectFile::findBitcodeInMemBuffer( |
- MemoryBufferRef(StringRef((const char *)View, File.filesize), "")); |
+ MemoryBufferRef(StringRef((const char *)View, Filesize), "")); |
if (std::error_code EC = MBOrErr.getError()) |
message(LDPL_FATAL, "Could not read bitcode from file : %s", |
EC.message().c_str()); |
@@ -566,9 +580,6 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile, |
std::unique_ptr<MemoryBuffer> Buffer = |
MemoryBuffer::getMemBuffer(MBOrErr->getBuffer(), "", false); |
- if (release_input_file(F.handle) != LDPS_OK) |
- message(LDPL_FATAL, "Failed to release file information"); |
- |
ErrorOr<Module *> MOrErr = getLazyBitcodeModule(std::move(Buffer), Context); |
if (std::error_code EC = MOrErr.getError()) |
@@ -760,6 +771,34 @@ static void codegen(Module &M) { |
Cleanup.push_back(Filename.c_str()); |
} |
+// @LOCALMOD-BEGIN |
+static void wrapSymbol(Module *M, const char *sym) { |
+ std::string wrapSymName("__wrap_"); |
+ wrapSymName += sym; |
+ std::string realSymName("__real_"); |
+ realSymName += sym; |
+ |
+ Constant *SymGV = M->getNamedValue(sym); |
+ |
+ // Replace uses of "sym" with "__wrap_sym". |
+ if (SymGV) { |
+ Constant *WrapGV = M->getNamedValue(wrapSymName); |
+ if (!WrapGV) |
+ WrapGV = M->getOrInsertGlobal(wrapSymName, SymGV->getType()); |
+ SymGV->replaceAllUsesWith( |
+ ConstantExpr::getBitCast(WrapGV, SymGV->getType())); |
+ } |
+ |
+ // Replace uses of "__real_sym" with "sym". |
+ if (Constant *RealGV = M->getNamedValue(realSymName)) { |
+ if (!SymGV) |
+ SymGV = M->getOrInsertGlobal(sym, RealGV->getType()); |
+ RealGV->replaceAllUsesWith( |
+ ConstantExpr::getBitCast(SymGV, RealGV->getType())); |
+ } |
+} |
+// @LOCALMOD-END |
+ |
/// gold informs us that all symbols have been read. At this point, we use |
/// get_symbols to see if any of our definitions have been overridden by a |
/// native object file. Then, perform optimization and codegen. |
@@ -776,8 +815,12 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { |
StringSet<> Internalize; |
StringSet<> Maybe; |
for (claimed_file &F : Modules) { |
+ ld_plugin_input_file File; |
+ if (get_input_file(F.handle, &File) != LDPS_OK) |
+ message(LDPL_FATAL, "Failed to get file information"); |
std::unique_ptr<Module> M = |
- getModuleForFile(Context, F, ApiFile, Internalize, Maybe); |
+ getModuleForFile(Context, F, File.filesize, ApiFile, |
+ Internalize, Maybe); |
if (!options::triple.empty()) |
M->setTargetTriple(options::triple.c_str()); |
else if (M->getTargetTriple().empty()) { |
@@ -786,6 +829,8 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { |
if (L.linkInModule(M.get())) |
message(LDPL_FATAL, "Failed to link module"); |
+ if (release_input_file(F.handle) != LDPS_OK) |
+ message(LDPL_FATAL, "Failed to release file information"); |
} |
for (const auto &Name : Internalize) { |
@@ -803,6 +848,23 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { |
internalize(*GV); |
} |
+ // @LOCALMOD-BEGIN |
+ // Perform symbol wrapping. |
+ unsigned num_wrapped; |
+ if ((*get_num_wrapped)(&num_wrapped) != LDPS_OK) { |
+ (*message)(LDPL_ERROR, "Unable to get the number of wrapped symbols."); |
+ return LDPS_ERR; |
+ } |
+ for (unsigned i = 0; i < num_wrapped; ++i) { |
+ const char *sym; |
+ if ((*get_wrapped)(i, &sym) != LDPS_OK) { |
+ (*message)(LDPL_ERROR, "Unable to wrap symbol %u/%u.", i, num_wrapped); |
+ return LDPS_ERR; |
+ } |
+ wrapSymbol(Combined.get(), sym); |
+ } |
+ // @LOCALMOD-END |
+ |
if (options::TheOutputType == options::OT_DISABLE) |
return LDPS_OK; |