#include #include DIVINE_RELAX_WARNINGS #include DIVINE_UNRELAX_WARNINGS #include namespace divine { namespace rt { void DiosCC::link_dios_config( std::string n, std::string lamp ) { link_entire_archive( "rst" ); auto mod = load_object( find_object( "config/" + n ) ); link( std::move( mod ) ); if ( !lamp.empty() ) link( load_object( find_object( "lamp/" + lamp ) ) ); else link( load_object( find_object( "lamp/empty" ) ) ); for ( int i = 0; i < 3; ++i ) { link_lib( "sys" ); link_lib( "arch_divm" ); link_libs( default_libs ); } } void add_dios_header_paths( std::vector< std::string >& paths ) { paths.insert( paths.end(), { "-isystem", "/dios/libcxx/include" , "-isystem", "/dios/libcxxabi/include" , "-isystem", "/dios/libunwind/include" , "-isystem", "/dios/include" } ); } void add_dios_defines( std::vector< std::string >& flags ) { flags.insert( flags.end(), { "-D_LITTLE_ENDIAN=1234" , "-D_BYTE_ORDER=1234" , "-D__ELF__" , "-D__unix__" , "-D__divine__=4" , "-U__x86_64" , "-U__x86_64__" }); } DiosCC::DiosCC( Options opts, context_ptr ctx ) : driver( opts, ctx ) { map_files( rt::each ); add_dios_header_paths( common_flags ); add_dios_defines( common_flags ); } void DiosCC::build( divcc::ParsedOpts po ) { driver::build( po ); if ( linker->hasModule() ) link_libs( default_libs ); } NativeDiosCC::NativeDiosCC( const std::vector< std::string >& opts ) : Native( opts ) { add_dios_header_paths( _po.opts ); add_dios_defines( _po.opts ); divine::rt::each( [&]( auto path, auto c ) { _clang.map_file( path, c ); } ); _missing_bc_fatal = true; } auto NativeDiosCC::link_dios_native( bool cxx ) { brq::TempDir tmpdir( ".divcc.XXXXXX", brq::AutoDelete::Yes, brq::UseSystemTemp::Yes ); auto hostlib = tmpdir.path + "/libdios-host.a", cxxlib = tmpdir.path + "/libc++.a", cxxabi = tmpdir.path + "/libc++abi.a"; if ( cxx ) { _ld_args.push_back( "-stdlib=libc++" ); _ld_args.push_back( "-L" + tmpdir.path ); brq::write_file( cxxlib, rt::libcxx() ); brq::write_file( cxxabi, rt::libcxxabi() ); } brq::write_file( hostlib, rt::dios_host() ); _ld_args.push_back( hostlib ); return tmpdir; } std::unique_ptr< llvm::Module > NativeDiosCC::link_bitcode() { auto drv = std::make_unique< DiosCC >( _clang.context() ); std::unique_ptr< llvm::Module > m = Native::do_link_bitcode< rt::DiosCC >(); drv->link( std::move( m ) ); if ( !_po.shared ) drv->link_libs( DiosCC::default_libs ); m = drv->take_linked(); if ( !_po.shared ) { for ( auto& func : *m ) if ( func.isDeclaration() && !divcc::whitelisted( func ) ) brq::raise< divcc::compile_error >() << "Symbol undefined (function): " << func.getName().str(); for ( auto& val : m->globals() ) if ( auto G = llvm::dyn_cast< llvm::GlobalVariable >( &val ) ) if ( !G->hasInitializer() && !divcc::whitelisted( *G ) ) brq::raise< divcc::compile_error >() << "Symbol undefined (global variable): " << G->getName().str(); } verifyModule( *m ); return m; } void NativeDiosCC::link() { init_ld_args(); auto tmpdir = link_dios_native( _cxx ); Native::link(); } } // cc } // divine