| 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;
|
|
|
|
|