/// Update object reference linking for the given object load request. /// /// @param[in] pRequest Load request to update. /// /// @return True if linking still requires processing, false if it is complete. bool GameObjectLoader::TickLink( LoadRequest* pRequest ) { HELIUM_ASSERT( pRequest ); HELIUM_ASSERT( !( pRequest->stateFlags & ( LOAD_FLAG_PRECACHED | LOAD_FLAG_LOADED ) ) ); // Make sure each dependency has finished its preload process. bool bHavePendingLinkEntries = false; DynArray< LinkEntry >& rLinkTable = pRequest->linkTable; size_t linkTableSize = rLinkTable.GetSize(); for( size_t linkIndex = 0; linkIndex < linkTableSize; ++linkIndex ) { LinkEntry& rLinkEntry = rLinkTable[ linkIndex ]; if( IsValid( rLinkEntry.loadId ) ) { LoadRequest* pLinkRequest = m_loadRequestPool.GetObject( rLinkEntry.loadId ); HELIUM_ASSERT( pLinkRequest ); if( pLinkRequest->stateFlags & LOAD_FLAG_PRELOADED ) { rLinkEntry.spObject = pLinkRequest->spObject; } else { bHavePendingLinkEntries = true; } } } if( bHavePendingLinkEntries ) { return false; } // Ready to link. GameObject* pObject = pRequest->spObject; if( pObject ) { uint32_t objectFlags = pObject->GetFlags(); if( !( objectFlags & GameObject::FLAG_LINKED ) ) { if( !( objectFlags & GameObject::FLAG_BROKEN ) ) { Linker linker; linker.Prepare( rLinkTable.GetData(), static_cast< uint32_t >( linkTableSize ) ); if( !linker.Serialize( pObject ) ) { pObject->SetFlags( GameObject::FLAG_BROKEN ); } } pObject->SetFlags( GameObject::FLAG_LINKED ); } } AtomicOrRelease( pRequest->stateFlags, LOAD_FLAG_LINKED ); return true; }
// %MCLinker --shared -soname=libplasma.so -Bsymbolic // -mtriple="armv7-none-linux-gnueabi" // -L=%p/../../../libs/ARM/Android/android-14 // %p/../../../libs/ARM/Android/android-14/crtbegin_so.o // %p/plasma.o // -lm -llog -ljnigraphics -lc // %p/../../../libs/ARM/Android/android-14/crtend_so.o // -o libplasma.so TEST_F( LinkerTest, plasma) { Initialize(); Linker linker; LinkerScript script; ///< --mtriple="armv7-none-linux-gnueabi" LinkerConfig config("armv7-none-linux-gnueabi"); /// -L=${TOPDIR}/test/libs/ARM/Android/android-14 Path search_dir(TOPDIR); search_dir.append("test/libs/ARM/Android/android-14"); script.directories().insert(search_dir); /// To configure linker before setting options. Linker::config sets up /// default target-dependent configuration to LinkerConfig. linker.emulate(script, config); config.setCodeGenType(LinkerConfig::DynObj); ///< --shared config.options().setSOName("libplasma.so"); ///< --soname=libplasma.so config.options().setBsymbolic(); ///< -Bsymbolic Module module("libplasma.so", script); IRBuilder builder(module, config); /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtbegin_so.o Path crtbegin(search_dir); crtbegin.append("crtbegin_so.o"); builder.ReadInput("crtbegin", crtbegin); /// ${TOPDIR}/test/Android/Plasma/ARM/plasma.o Path plasma(TOPDIR); plasma.append("test/Android/Plasma/ARM/plasma.o"); builder.ReadInput("plasma", plasma); // -lm -llog -ljnigraphics -lc builder.ReadInput("m"); builder.ReadInput("log"); builder.ReadInput("jnigraphics"); builder.ReadInput("c"); /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtend_so.o Path crtend(search_dir); crtend.append("crtend_so.o"); builder.ReadInput("crtend", crtend); if (linker.link(module, builder)) { linker.emit("libplasma.so"); ///< -o libplasma.so } Finalize(); }
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, const cl::list<std::string> &Files, unsigned Flags) { // Filter out flags that don't apply to the first file we load. unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc; for (const auto &File : Files) { std::unique_ptr<Module> M = loadFile(argv0, File, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << File << "'\n"; return false; } if (verifyModule(*M, &errs())) { errs() << argv0 << ": " << File << ": error: input module is broken!\n"; return false; } if (Verbose) errs() << "Linking in '" << File << "'\n"; if (L.linkInModule(M.get(), ApplicableFlags)) return false; // All linker flags apply to linking of subsequent files. ApplicableFlags = Flags; } return true; }
int main() { char *fileName = "monkey.wrl"; //Model name int numLayer = 1; //Number of layers used in this application int numInterator = 0; // Transfer the OF data to CybParameters structure CybDataObtainer<cybSurfaceTriTraits> data(numLayer, numInterator); CybViewMono view; //Access the parameters information of scene and graphical objects CybParameters *cybCore = CybParameters::getInstance(); sMesh *mesh = new sMesh[numLayer]; mfReaderModel<cybSurfaceTriTraits> in; in.read(&mesh[0], fileName); data.loadModel(mesh); cout << "loadModel()" << endl; /*Load the model from VRML file (layerID, fileName)*/ //data.loadModel(0, fileName); /*Initialize the meshes parameters*/ data.startParameters(numLayer); //Set the object color (layerID, r, g, b,a) cybCore->setColor(0,1,1,0.7,0.9); //Set the window name view.setWindowName("Simple Visualization"); Provider * provider = new Provider(); CybBayesianNetwork* net = new CybBayesianNetwork(3); CybNetworkIO* netIO = new CybNetworkIO ("/root/Desktop/teste"); Linker* linker = new Linker(net, provider, netIO); linker->init(); /*Initialize visualization*/ view.init(); delete provider; delete net; delete netIO; delete linker; }
C_NNFW_API NnfwLinker* NnfwIteratorGetLinker( NnfwIterator* itera, int i ) { Linker* ln; switch( itera->type ) { case 0: return 0; break; case 1: ln = itera->linkvec->at(i); break; case 2: if ( dynamic_cast<Cluster*>(itera->upvec->at(i)) ) { return 0; } ln = (Linker*)(itera->upvec->at(i)); break; default: return 0; } if ( linkmap.count( ln ) == 0 ) { NnfwLinker* nln = new NnfwLinker(); nln->linker = ln; nln->myup = nln->linker; Cluster* cl = ln->from(); if ( clmap.count( cl ) == 0 ) { NnfwCluster* ncl = new NnfwCluster(); ncl->cluster = cl; ncl->myup = ncl->cluster; ncl->func = new NnfwOutputFunction(); ncl->func->func = cl->getFunction(); clmap[cl] = ncl; } nln->from = clmap[cl]; cl = ln->to(); if ( clmap.count( cl ) == 0 ) { NnfwCluster* ncl = new NnfwCluster(); ncl->cluster = cl; ncl->myup = ncl->cluster; ncl->func = new NnfwOutputFunction(); ncl->func->func = cl->getFunction(); clmap[cl] = ncl; } nln->to = clmap[cl]; linkmap[ln] = nln; } return linkmap[ln]; }
void init() { output_type = OUPUT_EXE; subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; lib_path = get_lib_path(); linker.init(); }
int main(int argc, char** argv) { int opind; char *ext; init(); opind = process_command(argc, argv); if (opind == 0) { return 0; } for (int src_idx = 0; src_idx < static_cast<int>(src_files.size()); src_idx++) { filename = src_files[src_idx]; ext = get_file_ext(filename); if (!strcmp(ext, "c")) { compile(filename); } if (!strcmp(ext, "obj")) { linker.load_obj_file(filename); } } if (!outfile) { printf("usage: scc [-c infile] [-o outfile] [-lib] [infile] infile2...\n"); return -1; } if (output_type == OUTPUT_OBJ) { syntax.coff.write_obj(outfile); } else linker.pe_output_file(outfile); getchar(); return 0; }
//===----------------------------------------------------------------------===// // Testcases //===----------------------------------------------------------------------===// TEST_F( LinkerTest, set_up_n_clean_up) { Initialize(); LinkerConfig config("arm-none-linux-gnueabi"); LinkerScript script; Module module("test", script); config.setCodeGenType(LinkerConfig::DynObj); Linker linker; linker.emulate(script, config); IRBuilder builder(module, config); // create inputs here // builder.CreateInput("./test.o"); if (linker.link(module, builder)) linker.emit("./test.so"); Finalize(); }
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, const cl::list<std::string> &Files, unsigned Flags) { // Filter out flags that don't apply to the first file we load. unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc; for (const auto &File : Files) { std::unique_ptr<Module> M = loadFile(argv0, File, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << File << "'\n"; return false; } // Note that when ODR merging types cannot verify input files in here When // doing that debug metadata in the src module might already be pointing to // the destination. if (DisableDITypeMap && verifyModule(*M, &errs())) { errs() << argv0 << ": " << File << ": error: input module is broken!\n"; return false; } // If a module summary index is supplied, load it so linkInModule can treat // local functions/variables as exported and promote if necessary. if (!SummaryIndex.empty()) { std::unique_ptr<ModuleSummaryIndex> Index = ExitOnErr(llvm::getModuleSummaryIndexForFile(SummaryIndex)); // Conservatively mark all internal values as promoted, since this tool // does not do the ThinLink that would normally determine what values to // promote. for (auto &I : *Index) { for (auto &S : I.second) { if (GlobalValue::isLocalLinkage(S->linkage())) S->setLinkage(GlobalValue::ExternalLinkage); } } // Promotion if (renameModuleForThinLTO(*M, *Index)) return true; } if (Verbose) errs() << "Linking in '" << File << "'\n"; if (L.linkInModule(std::move(M), ApplicableFlags)) return false; // All linker flags apply to linking of subsequent files. ApplicableFlags = Flags; } return true; }
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, const cl::list<std::string> &Files, unsigned Flags) { // Filter out flags that don't apply to the first file we load. unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc; for (const auto &File : Files) { std::unique_ptr<Module> M = loadFile(argv0, File, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << File << "'\n"; return false; } if (verifyModule(*M, &errs())) { errs() << argv0 << ": " << File << ": error: input module is broken!\n"; return false; } // If a function index is supplied, load it so linkInModule can treat // local functions/variables as exported and promote if necessary. std::unique_ptr<FunctionInfoIndex> Index; if (!FunctionIndex.empty()) { ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler); std::error_code EC = IndexOrErr.getError(); if (EC) { errs() << EC.message() << '\n'; return false; } Index = std::move(IndexOrErr.get()); } if (Verbose) errs() << "Linking in '" << File << "'\n"; if (L.linkInModule(std::move(M), ApplicableFlags, Index.get())) return false; // All linker flags apply to linking of subsequent files. ApplicableFlags = Flags; // If requested for testing, preserve modules by releasing them from // the unique_ptr before the are freed. This can help catch any // cross-module references from e.g. unneeded metadata references // that aren't properly set to null but instead mapped to the source // module version. The bitcode writer will assert if it finds any such // cross-module references. if (PreserveModules) M.release(); } return true; }
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, const cl::list<std::string> &Files, unsigned Flags) { // Filter out flags that don't apply to the first file we load. unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc; for (const auto &File : Files) { std::unique_ptr<Module> M = loadFile(argv0, File, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << File << "'\n"; return false; } // Note that when ODR merging types cannot verify input files in here When // doing that debug metadata in the src module might already be pointing to // the destination. if (DisableDITypeMap && verifyModule(*M, &errs())) { errs() << argv0 << ": " << File << ": error: input module is broken!\n"; return false; } // If a module summary index is supplied, load it so linkInModule can treat // local functions/variables as exported and promote if necessary. if (!SummaryIndex.empty()) { ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr = llvm::getModuleSummaryIndexForFile(SummaryIndex, diagnosticHandler); std::error_code EC = IndexOrErr.getError(); if (EC) { errs() << EC.message() << '\n'; return false; } auto Index = std::move(IndexOrErr.get()); // Promotion if (renameModuleForThinLTO(*M, *Index)) return true; } if (Verbose) errs() << "Linking in '" << File << "'\n"; if (L.linkInModule(std::move(M), ApplicableFlags)) return false; // All linker flags apply to linking of subsequent files. ApplicableFlags = Flags; } return true; }
int main(int argc, char* argv[]) { printf("main()\n"); #if WIN32 linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/ncrt0.o")); //linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/main.o")); linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/OBJ/Browser/Browser.o")); linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/OBJ/Browser/BrowserFrame.o")); linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/libui.a")); linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/libdraw.a")); linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/libxmlparse.a")); linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/liblfc.a")); linker.m_files.push_back(new StringA("C:/cygwin/usr/local/amiga/lib/gcc/m68k-amigaos/3.4.0/libgcc.a")); linker.m_files.push_back(new StringA("C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libstdc++.a")); linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libm.a")); linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnix.a")); linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnixmain.a")); // linker.m_files.push_back(new StringA("C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libamiga.a")); linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libstubs.a")); #else if (true) { linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/ncrt0.o")); // linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/main.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/LDebugger.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/mainfrm.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/SourceEdit.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/SourceEditFrame.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/DisassemblyWnd.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/WatchWnd.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/CallStackWnd.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/FileDialog.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/DebugSession.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libui.a")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libdraw.a")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libxmlparse.a")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libcode.a")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/liblfc.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/lib/gcc/m68k-amigaos/3.4.0/libgcc.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libstdc++.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libm.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnix.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnixmain.a")); // linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libamiga.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libstubs.a")); } else { linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/ncrt0.o")); // linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/main.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/Browser/Browser.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/Browser/BrowserFrame.o")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libui.a")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libdraw.a")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libxmlparse.a")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libcode.a")); linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/liblfc.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/lib/gcc/m68k-amigaos/3.4.0/libgcc.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libstdc++.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libm.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnix.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnixmain.a")); // linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libamiga.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libstubs.a")); /* linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/ncrt0.o")); linker.m_files.push_back(new StringA("WINHD_C:/MMStudio/Amiga68k/main.o")); linker.m_files.push_back(new StringA("WINHD_C:/cygwin/home/Sigurd Lerstad/lib/libnix/libnix.a")); linker.m_files.push_back(new StringA("WINHD_C:/cygwin/home/Sigurd Lerstad/lib/libnix/libnixmain.a")); linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libnix/libstubs.a")); */ } #endif printf("pass1\n"); linker.pass1(); /* GlobalSymbol* pSymbol = linker.m_globsyms[new StringA("_main")]; pSymbol->m_defined = true; pSymbol->ResolvedValue = (DWORD)MyMain; */ // linker.AddSymbol(new StringA("_main"), (DWORD)MyMain); printf("loading first object file\n"); #if 1 linker.LoadObjectFile(linker.m_objectFiles[0]); if (true) { for (int i = 1; i < linker.m_objectFiles.size(); i++) { printf("loading %d object file\n", i); linker.LoadObjectFile(linker.m_objectFiles[i]); } } printf("Here\n"); TRACE("\n\n"); { for (int i = 0; i < linker.m_loadedObjectFiles.size(); i++) { OFile2* ofile = linker.m_loadedObjectFiles[i]; if (ofile->m_afilename) TRACE("%s:%s\n", ofile->m_afilename->c_str(), ofile->m_ofilename->c_str()); else TRACE("%s\n", ofile->m_ofilename->c_str()); } } #endif printf("before sets\n"); linker.sets(); printf("LoadObjectfile2\n"); OFile* pOFile = linker.LoadObjectFile2(linker.m_objectFiles[0]); if (true) { for (int i = 1; i < linker.m_objectFiles.size(); i++) { linker.LoadObjectFile2(linker.m_objectFiles[i]); } } /* { GlobalSymbol* psym = linker.m_globsyms[new StringA("_DOSBase")]; int x = *(long*)psym->ResolvedValue; } */ printf("done\n"); if (linker.m_undefinedReferenceCount) { printf("undefined reference count: %d\n", linker.m_undefinedReferenceCount); TRACE("undefined reference count: %d\n", linker.m_undefinedReferenceCount); } else { #if AMIGA GlobalSymbol* sym = linker.m_globsyms[new StringA("_plinker")]; ASSERT(sym); ASSERT(sym->m_syms.size()); *(Linker**)sym->m_syms[0]->ResolvedValue = &linker; #endif #if WIN32 /* { gsymmap_t::iterator it2 = linker.m_globsyms.begin(); while (it2 != linker.m_globsyms.end()) { // "__ZTI14red_black_nodeIPN6System7StringAEPNS0_9NamespaceEE" GlobalSymbol* sym = (*it2).second; if (strstr(sym->m_name->c_str(), "TI") && strstr(sym->m_name->c_str(), "red_black_node") && strstr(sym->m_name->c_str(), "StringA")) { MessageBeep(-1); } ++it2; } } */ TypeArchive* ar = new TypeArchive(TypeArchive::Mode_Load, new FileByteStream(new StringA("C:/test.typeinfo"), FileMode_Read)); int ntypes; *ar >> ntypes; printf("%d\n", ntypes); for (int i = 0; i < ntypes; i++) { NamedType* pType; *ar >> pType; BufferImp<char> buffer; StringBuilderA strbuilder(&buffer); pType->Write(strbuilder); pType->m_qname = buffer.DetachToString(); if (*pType->m_qname == "second_argument_type") { MessageBeep(-1); } //if (pType->m_qname) { StringBuilderA strbuilder(&buffer); strbuilder << "__ZTI"; // type info Mangler mangler; mangler.MangleType(pType, strbuilder); StringA* name = buffer.DetachToString(); gsymmap_t::iterator it2 = linker.m_globsyms.find(name); //map<StringA*, DWORD, Ref_Less<StringA> >::iterator it2 = symbols.find(name); if (it2 != linker.m_globsyms.end()) { GlobalSymbol* globsym = (*it2).second; //TRACE("%s\n", name->c_str()); if (!strcmp(globsym->m_name->c_str(), "__ZTI9IAddChild")) { MessageBeep(-1); } for (int j = 0; j < globsym->m_syms.size(); j++) { Symbol* sym = globsym->m_syms[j]; } #if AMIGA __type_info2* ti = (__type_info2*)sym->ResolvedValue; printf("%s\n", ti->__type_name); // int len = strlen(ti->__type_name); /* char* newname = malloc(len+1+4); strcpy(newname+4, ti->__type_name); ti->__type_name = newname+4; *(Type**)newname = pType; */ #endif #if 0 TypeDescriptor* typedesc = (TypeDescriptor*)(*it2).second; //VERIFY(typedesc->_m_data == NULL); if (pType->GetKind() == type_class) { ((ClassType*)pType)->m_typedesc = (Type_Info*)typedesc; } else if (pType->GetKind() == type_enum) { ((EnumType*)pType)->m_typedesc = (Type_Info*)typedesc; } typedesc->_m_data = pType2; AddPersistentLiveRoot((Object**)&typedesc->_m_data); #endif } else { TRACE("-----%s\n", name->c_str()); } } } #endif { #if 1 ULONG heapsize = heap->m_next - (heap->m_data); #else ULONG heapsize = heap->m_next - (heap->m_data+heap->m_size); #endif printf("heapsize: %f MB\n", heapsize / (1024.0*1024)); } #if AMIGA printf("Calling"); char* line = strdup("programname parameter0 parameter1"); entrypoint_hook(pOFile->m_textdata, line, strlen(line)); #endif } #if 0 if (argc <= 1) { printf("Usage:\n"); printf("loader objectfile\n"); return -10; } Linker linker; for (int i = 1; i < argc; i++) { linker.m_files.Add(new StringA(argv[i])); } printf("pass1..."); linker.pass1(); // linker.pass2(); /* GlobalSymbol* globsym = linker.globsyms["_main2"]; FileByteStream file(globsym->m_filename); linker.LoadObjectFile(file); printf("Calling..."); ((dllentrypoint)globsym->Value)(); printf("done\n"); */ printf("done\n"); printf("loading..."); fflush(stdout); // FileByteStream* file = new FileByteStream(linker.m_files[0]); // printf("sdfsdf\n"); // fflush(stdout); linker.LoadObjectFile(linker.m_objectFiles[0]); linker.sets(); OFile* pOFile = linker.LoadObjectFile2(linker.m_objectFiles[0]); printf("done\n"); if (linker.m_undefinedReferenceCount) { printf("undefined reference count: %d\n", linker.m_undefinedReferenceCount); TRACE("undefined reference count: %d\n", linker.m_undefinedReferenceCount); } else { #if AMIGA char* line = strdup("programname parameter0 parameter1"); entrypoint_hook(pOFile->m_textdata, line, strlen(line)); #endif } #endif return 0; }
/// Import any functions requested via the -import option. static bool importFunctions(const char *argv0, LLVMContext &Context, Linker &L) { for (const auto &Import : Imports) { // Identify the requested function and its bitcode source file. size_t Idx = Import.find(':'); if (Idx == std::string::npos) { errs() << "Import parameter bad format: " << Import << "\n"; return false; } std::string FunctionName = Import.substr(0, Idx); std::string FileName = Import.substr(Idx + 1, std::string::npos); // Load the specified source module. std::unique_ptr<Module> M = loadFile(argv0, FileName, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << FileName << "'\n"; return false; } if (verifyModule(*M, &errs())) { errs() << argv0 << ": " << FileName << ": error: input module is broken!\n"; return false; } Function *F = M->getFunction(FunctionName); if (!F) { errs() << "Ignoring import request for non-existent function " << FunctionName << " from " << FileName << "\n"; continue; } // We cannot import weak_any functions without possibly affecting the // order they are seen and selected by the linker, changing program // semantics. if (F->hasWeakAnyLinkage()) { errs() << "Ignoring import request for weak-any function " << FunctionName << " from " << FileName << "\n"; continue; } if (Verbose) errs() << "Importing " << FunctionName << " from " << FileName << "\n"; std::unique_ptr<FunctionInfoIndex> Index; if (!FunctionIndex.empty()) { ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler); std::error_code EC = IndexOrErr.getError(); if (EC) { errs() << EC.message() << '\n'; return false; } Index = std::move(IndexOrErr.get()); } // Link in the specified function. DenseSet<const GlobalValue *> FunctionsToImport; FunctionsToImport.insert(F); if (L.linkInModule(*M, Linker::Flags::None, Index.get(), &FunctionsToImport)) return false; } return true; }
// This testcase put IRBuilder in the heap TEST_F( LinkerTest, plasma_twice_irbuilder_heap) { Initialize(); Linker linker; ///< --mtriple="armv7-none-linux-gnueabi" LinkerConfig config1("armv7-none-linux-gnueabi"); LinkerScript script1; /// -L=${TOPDIR}/test/libs/ARM/Android/android-14 Path search_dir(TOPDIR); search_dir.append("test/libs/ARM/Android/android-14"); script1.directories().insert(search_dir); /// To configure linker before setting options. Linker::config sets up /// default target-dependent configuration to LinkerConfig. linker.emulate(script1, config1); config1.setCodeGenType(LinkerConfig::DynObj); ///< --shared config1.options().setSOName("libplasma.once.so"); ///< --soname=libplasma.twice.so config1.options().setBsymbolic(false); ///< -Bsymbolic Module module1("libplasma.once.so", script1); IRBuilder *builder1 = new IRBuilder(module1, config1); /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtbegin_so.o Path crtbegin(search_dir); crtbegin.append("crtbegin_so.o"); builder1->ReadInput("crtbegin", crtbegin); /// ${TOPDIR}/test/Android/Plasma/ARM/plasma.o Path plasma(TOPDIR); plasma.append("test/Android/Plasma/ARM/plasma.o"); builder1->ReadInput("plasma", plasma); // -lm -llog -ljnigraphics -lc builder1->ReadInput("m"); builder1->ReadInput("log"); builder1->ReadInput("jnigraphics"); builder1->ReadInput("c"); /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtend_so.o Path crtend(search_dir); crtend.append("crtend_so.o"); builder1->ReadInput("crtend", crtend); if (linker.link(module1, *builder1)) { linker.emit("libplasma.once.so"); ///< -o libplasma.so } // Can not delete builder until emit the output. Dynamic string table // needs the file name of the input files, and the inputs' life is // controlled by IRBuilder delete builder1; Finalize(); linker.reset(); Initialize(); ///< --mtriple="armv7-none-linux-gnueabi" LinkerConfig config2("armv7-none-linux-gnueabi"); LinkerScript script2; /// -L=${TOPDIR}/test/libs/ARM/Android/android-14 script2.directories().insert(search_dir); /// To configure linker before setting options. Linker::config sets up /// default target-dependent configuration to LinkerConfig. linker.emulate(script2, config2); config2.setCodeGenType(LinkerConfig::DynObj); ///< --shared config2.options().setSOName("libplasma.twice.so"); ///< --soname=libplasma.twice.exe config2.options().setBsymbolic(); ///< -Bsymbolic Module module2("libplasma.so", script2); IRBuilder* builder2 = new IRBuilder(module2, config2); /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtbegin_so.o builder2->ReadInput("crtbegin", crtbegin); /// ${TOPDIR}/test/Android/Plasma/ARM/plasma.o builder2->ReadInput("plasma", plasma); // -lm -llog -ljnigraphics -lc builder2->ReadInput("m"); builder2->ReadInput("log"); builder2->ReadInput("jnigraphics"); builder2->ReadInput("c"); /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtend_so.o builder2->ReadInput("crtend", crtend); if (linker.link(module2, *builder2)) { linker.emit("libplasma.twice.so"); ///< -o libplasma.exe } delete builder2; Finalize(); }
// %MCLinker --shared -soname=libgotplt.so -mtriple arm-none-linux-gnueabi // gotplt.o -o libgotplt.so TEST_F( LinkerTest, plasma_object) { Initialize(); Linker linker; ///< --mtriple="armv7-none-linux-gnueabi" LinkerConfig config("armv7-none-linux-gnueabi"); LinkerScript script; /// To configure linker before setting options. Linker::config sets up /// default target-dependent configuration to LinkerConfig. linker.emulate(script, config); config.setCodeGenType(LinkerConfig::DynObj); ///< --shared config.options().setSOName("libgotplt.so"); ///< --soname=libgotplt.so Module module(script); IRBuilder builder(module, config); Path gotplt_o(TOPDIR); gotplt_o.append("test/PLT/gotplt.o"); Input* input = builder.CreateInput("gotplt.o", gotplt_o, Input::Object); /// Sections /// [ 0] NULL 00000000 000000 000000 00 0 0 0 builder.CreateELFHeader(*input, "", LDFileFormat::Null, llvm::ELF::SHT_NULL, 0x0); /// [ 1] .text PROGBITS 00000000 000034 000010 00 AX 0 0 4 LDSection* text = builder.CreateELFHeader(*input, ".text", llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 4); SectionData* text_data = builder.CreateSectionData(*text); static uint8_t text_content[] = { 0x00, 0x48, 0x2d, 0xe9, 0xfe, 0xff, 0xff, 0xeb, 0x00, 0x48, 0xbd, 0xe8, 0x0e, 0xf0, 0xa0, 0xe1 }; Fragment* text_frag = builder.CreateRegion(text_content, 0x10); builder.AppendFragment(*text_frag, *text_data); /// [ 2] .rel.text REL 00000000 0002ac 000008 08 7 1 4 LDSection* rel_text = builder.CreateELFHeader(*input, ".rel.text", llvm::ELF::SHT_REL, 0x0, 4); rel_text->setLink(text); builder.CreateRelocData(*rel_text); /// [ 3] .data PROGBITS 00000000 000044 000000 00 WA 0 0 4 LDSection* data = builder.CreateELFHeader(*input, ".data", llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 4); /// [ 4] .bss NOBITS 00000000 000044 000000 00 WA 0 0 4 LDSection* bss = builder.CreateELFHeader(*input, ".bss", llvm::ELF::SHT_NOBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 4); builder.CreateBSS(*bss); /// [ 5] .ARM.attributes ARM_ATTRIBUTES 00000000 000044 000020 00 0 0 1 LDSection* attr = builder.CreateELFHeader(*input, ".ARM.attributes", llvm::ELF::SHT_ARM_ATTRIBUTES, 0x0, 1); SectionData* attr_data = builder.CreateSectionData(*attr); static uint8_t attr_content[] = { 0x41, 0x1f, 0x00, 0x00, 0x00, 0x61, 0x65, 0x61, 0x62, 0x69, 0x00, 0x01, 0x15, 0x00, 0x00, 0x00, 0x06, 0x02, 0x08, 0x01, 0x09, 0x01, 0x14, 0x01, 0x15, 0x01, 0x17, 0x03, 0x18, 0x01, 0x19, 0x01 }; Fragment* attr_frag = builder.CreateRegion(attr_content, 0x20); builder.AppendFragment(*attr_frag, *attr_data); /// Symbols /// 1: 00000000 0 FILE LOCAL DEFAULT ABS Output/gotplt.bc builder.AddSymbol(*input, "Output/gotplt.bc", ResolveInfo::File, ResolveInfo::Define, ResolveInfo::Local, 0); /// 2: 00000000 0 SECTION LOCAL DEFAULT 1 builder.AddSymbol(*input, ".text", ResolveInfo::Section, ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, text); /// 3: 00000000 0 SECTION LOCAL DEFAULT 3 builder.AddSymbol(*input, ".data", ResolveInfo::Section, ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, data); /// 4: 00000000 0 SECTION LOCAL DEFAULT 4 builder.AddSymbol(*input, ".bss", ResolveInfo::Section, ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, bss); /// 5: 00000000 0 SECTION LOCAL DEFAULT 5 builder.AddSymbol(*input, ".ARM.attributes", ResolveInfo::Section, ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, attr); /// 6: 00000000 16 FUNC GLOBAL DEFAULT 1 _Z1fv builder.AddSymbol(*input, "_Z1fv", ResolveInfo::Function, ResolveInfo::Define, ResolveInfo::Global, 16, 0x0, text); /// 7: 00000000 0 NOTYPE GLOBAL DEFAULT UND _Z1gv LDSymbol* z1gv = builder.AddSymbol(*input, "_Z1gv", ResolveInfo::NoType, ResolveInfo::Undefined, ResolveInfo::Global, 0); /// Relocations /// Offset Info Type Sym.Value Sym. Name /// 00000004 0000071b R_ARM_PLT32 00000000 _Z1gv builder.AddRelocation(*rel_text, llvm::ELF::R_ARM_PLT32, *z1gv, 0x4); if (linker.link(module, builder)) { linker.emit("libgotplt.so"); ///< -o libgotplt.so } Finalize(); }
/// Import any functions requested via the -import option. static bool importFunctions(const char *argv0, LLVMContext &Context, Linker &L) { StringMap<std::unique_ptr<DenseMap<unsigned, MDNode *>>> ModuleToTempMDValsMap; for (const auto &Import : Imports) { // Identify the requested function and its bitcode source file. size_t Idx = Import.find(':'); if (Idx == std::string::npos) { errs() << "Import parameter bad format: " << Import << "\n"; return false; } std::string FunctionName = Import.substr(0, Idx); std::string FileName = Import.substr(Idx + 1, std::string::npos); // Load the specified source module. std::unique_ptr<Module> M = loadFile(argv0, FileName, Context, false); if (!M.get()) { errs() << argv0 << ": error loading file '" << FileName << "'\n"; return false; } if (verifyModule(*M, &errs())) { errs() << argv0 << ": " << FileName << ": error: input module is broken!\n"; return false; } Function *F = M->getFunction(FunctionName); if (!F) { errs() << "Ignoring import request for non-existent function " << FunctionName << " from " << FileName << "\n"; continue; } // We cannot import weak_any functions without possibly affecting the // order they are seen and selected by the linker, changing program // semantics. if (F->hasWeakAnyLinkage()) { errs() << "Ignoring import request for weak-any function " << FunctionName << " from " << FileName << "\n"; continue; } if (Verbose) errs() << "Importing " << FunctionName << " from " << FileName << "\n"; std::unique_ptr<FunctionInfoIndex> Index; if (!FunctionIndex.empty()) { ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler); std::error_code EC = IndexOrErr.getError(); if (EC) { errs() << EC.message() << '\n'; return false; } Index = std::move(IndexOrErr.get()); } // Save the mapping of value ids to temporary metadata created when // importing this function. If we have already imported from this module, // add new temporary metadata to the existing mapping. auto &TempMDVals = ModuleToTempMDValsMap[FileName]; if (!TempMDVals) TempMDVals = llvm::make_unique<DenseMap<unsigned, MDNode *>>(); // Link in the specified function. DenseSet<const GlobalValue *> FunctionsToImport; FunctionsToImport.insert(F); if (L.linkInModule(std::move(M), Linker::Flags::None, Index.get(), &FunctionsToImport, TempMDVals.get())) return false; } // Now link in metadata for all modules from which we imported functions. for (StringMapEntry<std::unique_ptr<DenseMap<unsigned, MDNode *>>> &SME : ModuleToTempMDValsMap) { // Load the specified source module. std::unique_ptr<Module> M = loadFile(argv0, SME.getKey(), Context, true); if (!M.get()) { errs() << argv0 << ": error loading file '" << SME.getKey() << "'\n"; return false; } if (verifyModule(*M, &errs())) { errs() << argv0 << ": " << SME.getKey() << ": error: input module is broken!\n"; return false; } // Link in all necessary metadata from this module. if (L.linkInMetadata(*M, SME.getValue().get())) return false; } return true; }
/// Import any functions requested via the -import option. static bool importFunctions(const char *argv0, LLVMContext &Context, Linker &L) { if (SummaryIndex.empty()) return true; std::unique_ptr<ModuleSummaryIndex> Index = ExitOnErr(llvm::getModuleSummaryIndexForFile(SummaryIndex)); // Map of Module -> List of globals to import from the Module std::map<StringRef, DenseSet<const GlobalValue *>> ModuleToGlobalsToImportMap; auto ModuleLoader = [&Context](const char *argv0, const std::string &Identifier) { return loadFile(argv0, Identifier, Context, false); }; ModuleLazyLoaderCache ModuleLoaderCache(ModuleLoader); for (const auto &Import : Imports) { // Identify the requested function and its bitcode source file. size_t Idx = Import.find(':'); if (Idx == std::string::npos) { errs() << "Import parameter bad format: " << Import << "\n"; return false; } std::string FunctionName = Import.substr(0, Idx); std::string FileName = Import.substr(Idx + 1, std::string::npos); // Load the specified source module. auto &SrcModule = ModuleLoaderCache(argv0, FileName); if (verifyModule(SrcModule, &errs())) { errs() << argv0 << ": " << FileName << ": error: input module is broken!\n"; return false; } Function *F = SrcModule.getFunction(FunctionName); if (!F) { errs() << "Ignoring import request for non-existent function " << FunctionName << " from " << FileName << "\n"; continue; } // We cannot import weak_any functions without possibly affecting the // order they are seen and selected by the linker, changing program // semantics. if (F->hasWeakAnyLinkage()) { errs() << "Ignoring import request for weak-any function " << FunctionName << " from " << FileName << "\n"; continue; } if (Verbose) errs() << "Importing " << FunctionName << " from " << FileName << "\n"; auto &Entry = ModuleToGlobalsToImportMap[SrcModule.getModuleIdentifier()]; Entry.insert(F); ExitOnErr(F->materialize()); } // Do the actual import of globals now, one Module at a time for (auto &GlobalsToImportPerModule : ModuleToGlobalsToImportMap) { // Get the module for the import auto &GlobalsToImport = GlobalsToImportPerModule.second; std::unique_ptr<Module> SrcModule = ModuleLoaderCache.takeModule(GlobalsToImportPerModule.first); assert(&Context == &SrcModule->getContext() && "Context mismatch"); // If modules were created with lazy metadata loading, materialize it // now, before linking it (otherwise this will be a noop). ExitOnErr(SrcModule->materializeMetadata()); UpgradeDebugInfo(*SrcModule); // Linkage Promotion and renaming if (renameModuleForThinLTO(*SrcModule, *Index, &GlobalsToImport)) return true; // Instruct the linker to not automatically import linkonce defintion. unsigned Flags = Linker::Flags::DontForceLinkLinkonceODR; if (L.linkInModule(std::move(SrcModule), Flags, &GlobalsToImport)) return false; } return true; }