Ejemplo n.º 1
0
/*!
  Deletes the linkFile(), leaving any file() untouched.

    \sa removeFiles()
*/
void AppLnk::removeLinkFile()
{
    if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) {
#ifndef QT_NO_COP
  QCopEnvelope e("QPE/System", "linkChanged(QString)");
  e << linkFile();
#endif
    }
}
Ejemplo n.º 2
0
/*!
  \reimp
*/
void DocLnk::invoke(const QStringList& args) const
{
    MimeType mt(type());
    const AppLnk* app = mt.application();
    if ( app ) {
  QStringList a = args;
  if ( linkFileKnown() && QFile::exists( linkFile() ) )
      a.append(linkFile());
  else
      a.append(file());
  app->execute(a);
    }
}
Ejemplo n.º 3
0
/*!
  Sets the property named \a key to \a value.

  \sa property()
*/
void AppLnk::setProperty(const QString& key, const QString& value)
{
    if ( ensureLinkExists() ) {
  Config cfg(linkFile(), Config::File);
  cfg.writeEntry(key,value);
    }
}
Ejemplo n.º 4
0
/*!
  Returns the property named \a key.

  \sa setProperty()
*/
QString AppLnk::property(const QString& key) const
{
    QString lf = linkFile();
    if ( !QFile::exists(lf) )
  return QString::null;
    Config cfg(lf, Config::File);
    return cfg.readEntry(key);
}
Ejemplo n.º 5
0
/*!
  Deletes both the linkFile() and the file() associated with this AppLnk.

  \sa removeLinkFile()
*/
void AppLnk::removeFiles()
{
    bool valid = isValid();
    if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) {
  if ( QFile::remove(file()) ) {
#ifndef QT_NO_COP
      QCopEnvelope e("QPE/System", "linkChanged(QString)");
      if ( linkFileKnown() )
    e << linkFile();
      else
    e << file();
#endif
  } else if ( valid ) {
      // restore link
      writeLink();
  }
    }
}
Ejemplo n.º 6
0
/*!
  Commits the AppLnk to disk. Returns TRUE if the operation succeeded;
  otherwise returns FALSE.

  In addition, the "linkChanged(QString)" message is sent to the
  "QPE/System" \link qcop.html QCop\endlink channel.
*/
bool AppLnk::writeLink() const
{
    // Only re-writes settable parts
    QString lf = linkFile();
    if ( !ensureLinkExists() )
  return FALSE;
    storeLink();
    return TRUE;
}
Ejemplo n.º 7
0
void seissol::checkpoint::h5::Fault::load(int &timestepFault)
{
	if (numSides() == 0)
		return;

	logInfo(rank()) << "Loading fault checkpoint";

	seissol::checkpoint::CheckPoint::load();

	hid_t h5file = open(linkFile());
	checkH5Err(h5file);

	// Attributes
	hid_t h5attr = H5Aopen(h5file, "timestep_fault", H5P_DEFAULT);
	checkH5Err(h5attr);
	checkH5Err(H5Aread(h5attr, H5T_NATIVE_INT, &timestepFault));
	checkH5Err(H5Aclose(h5attr));

	// Set the memory space (this is the same for all variables)
	hsize_t count[2] = {numSides(), numBndGP()};
	hid_t h5memSpace = H5Screate_simple(2, count, 0L);
	checkH5Err(h5memSpace);
	checkH5Err(H5Sselect_all(h5memSpace));

	// Offset for the file space
	hsize_t fStart[2] = {fileOffset(), 0};

	// Read the data
	for (unsigned int i = 0; i < NUM_VARIABLES; i++) {
		hid_t h5data = H5Dopen(h5file, VAR_NAMES[i], H5P_DEFAULT);
		checkH5Err(h5data);
		hid_t h5fSpace = H5Dget_space(h5data);
		checkH5Err(h5fSpace);

		// Read the data
		checkH5Err(H5Sselect_hyperslab(h5fSpace, H5S_SELECT_SET, fStart, 0L, count, 0L));

		checkH5Err(H5Dread(h5data, H5T_NATIVE_DOUBLE, h5memSpace, h5fSpace,
				h5XferList(), data(i)));

		checkH5Err(H5Sclose(h5fSpace));
		checkH5Err(H5Dclose(h5data));
	}

	checkH5Err(H5Sclose(h5memSpace));
	checkH5Err(H5Fclose(h5file));
}
// This function extends the standard link function by linking directories and all their contents
// and subdirectories recursively.
static bool linkDirectory(const char* sourceDirectoryPath, const char* targetDirectoryPath)
{
    if (!createDirectoryChain(sourceDirectoryPath))
        return false;
    DIR* directory = opendir(sourceDirectoryPath);
    if (!directory) {
        fprintf(stderr, "Couldn't open directory %s: %s\n", sourceDirectoryPath, strerror(errno));
        return false;
    }

    while (struct dirent *directoryInfo = readdir(directory)) {
        char* fileName = directoryInfo->d_name;
        // We must not link '.' and ".." into the sandbox.
        if (!strcmp(fileName, ".") || !strcmp(fileName, ".."))
            continue;
        char sourceFile[maximumPathLength];
        char targetFile[maximumPathLength];
        appendDirectoryComponent(sourceFile, sourceDirectoryPath, fileName);
        appendDirectoryComponent(targetFile, targetDirectoryPath, fileName);

        bool returnValue;
        if (directoryInfo->d_type == DT_DIR) {
            strncat(sourceFile, "/", 1);
            strncat(targetFile, "/", 1);
            returnValue = linkDirectory(sourceFile, targetFile);
        } else
            returnValue = linkFile(sourceFile, targetFile);
        if (!returnValue)
            return false;
    }

    // Restore the original modification time of the directories because
    // it could have meaning e.g. in the hash generation of cache files.
    struct stat fileStat;
    if (lstat(sourceDirectoryPath, &fileStat) == -1) {
        fprintf(stderr, "Failed to obtain information about the directory '%s': %s\n", sourceDirectoryPath, strerror(errno));
        return false;
    }
    struct utimbuf times;
    times.actime = fileStat.st_atime;
    times.modtime = fileStat.st_mtime;
    if (utime(targetDirectoryPath, &times) == -1) {
        fprintf(stderr, "Couldn't set back the last modification time of '%s': %s\n", targetDirectoryPath, strerror(errno));
        return false;
    }
    return true;
}
Ejemplo n.º 9
0
void seissol::checkpoint::sionlib::Wavefield::load(real* dofs)
{
	logInfo(rank()) << "Loading wave field checkpoint";

	seissol::checkpoint::CheckPoint::setLoaded();

	int file = open(linkFile(), readMode());
	checkErr(file);

	// Read header
	checkErr(sion_coll_fread(header().data(), header().size(), 1, file), 1);

	// Read dofs
	checkErr(sion_coll_fread(dofs, sizeof(double), numDofs(), file), numDofs());

	// Close the file
	sionClose(file);
}
static bool collectRunTimeDependencies()
{
    // The list of empirically gathered library dependencies.
    const char* runtimeDependencies[] = {
        "libnss_dns.so",
        "libresolv.so",
        "libssl.so",
        "libcrypto.so"
    };

    for (int i = 0; i < sizeof(runtimeDependencies) / sizeof(runtimeDependencies[0]); ++i) {
        // To obtain the path of the runtime dependencies we open them with dlopen.
        // With the handle supplied by dlopen we can obtain information about the dynamically
        // linked libraries, so the path where are they installed.
        void* handle = dlopen(runtimeDependencies[i], RTLD_LAZY);
        if (!handle) {
            fprintf(stderr, "Couldn't get the handler of %s: %s\n", runtimeDependencies[i], dlerror());
            return false;
        }

        struct link_map* linkMap;
        if (dlinfo(handle, RTLD_DI_LINKMAP, &linkMap) == -1) {
            fprintf(stderr, "Couldn't get information about %s: %s\n", runtimeDependencies[i], dlerror());
            return false;
        }

        if (!linkMap) {
            fprintf(stderr, "Couldn't get the linkmap of %s: %s.\n", runtimeDependencies[i], strerror(errno));
            return false;
        }

        char pathOfTheLibraryInSandbox[maximumPathLength];
        appendDirectoryComponent(pathOfTheLibraryInSandbox, sandboxDirectory, linkMap->l_name);
        if (!linkFile(linkMap->l_name, pathOfTheLibraryInSandbox)) {
            fprintf(stderr, "Linking runtime dependency: %s failed: %s\n", linkMap->l_name, strerror(errno));
            dlclose(handle);
            return false;
        }
        dlclose(handle);
    }
    return true;
}
Ejemplo n.º 11
0
void seissol::checkpoint::sionlib::Fault::load(int &timestepFault) {
#ifdef USE_SIONLIB
  if (numSides() == 0)
    return;  
  seissol::checkpoint::CheckPoint::load();
  int file; FILE *file_ptr; char fname[1023], *newfname=NULL;
  int globalrank,numFiles;  unsigned long lidentifier;  
  sion_int32 fsblksize= utils::Env::get<sion_int32>("SEISSOL_CHECKPOINT_BLOCK_SIZE", 0);
  m_gComm = comm(); m_lComm = m_gComm;	
  globalrank  = rank(); numFiles = 0;
  file = sion_paropen_mpi(const_cast<char*>(linkFile().c_str()), "br", &numFiles, m_gComm, &m_lComm,
			  &m_chunksize, &fsblksize, &globalrank, &file_ptr, &newfname);
  checkErr(file);
  checkErr(sion_fread(&lidentifier, sizeof(unsigned long),1,file));
  checkErr(sion_fread(&timestepFault, sizeof(timestepFault),1,file));
  for (int i = 0; i < NUM_VARIABLES; i++)
    checkErr(sion_fread(data(i),sizeof(real),this->numSides()*this->numBndGP(),file));
  if (ferror (file_ptr))
    logWarning(rank())<<"Error reading fault data SIONlib-checkpoint\n";
  checkErr(sion_parclose_mpi(file));
#endif
}
Ejemplo n.º 12
0
void seissol::checkpoint::h5::Wavefield::load(double &time, int &timestepWavefield, real* dofs)
{
	logInfo(rank()) << "Loading wave field checkpoint";

	seissol::checkpoint::CheckPoint::setLoaded();

	hid_t h5file = open(linkFile());
	checkH5Err(h5file);

	// Attributes
	hid_t h5attr = H5Aopen(h5file, "time", H5P_DEFAULT);
	checkH5Err(h5attr);
	checkH5Err(H5Aread(h5attr, H5T_NATIVE_DOUBLE, &time));
	checkH5Err(H5Aclose(h5attr));

	h5attr = H5Aopen(h5file, "timestep_wavefield", H5P_DEFAULT);
	checkH5Err(h5attr);
	checkH5Err(H5Aread(h5attr, H5T_NATIVE_INT, &timestepWavefield));
	checkH5Err(H5Aclose(h5attr));

	// Get dataset
	hid_t h5data = H5Dopen(h5file, "values", H5P_DEFAULT);
	checkH5Err(h5data);
	hid_t h5fSpace = H5Dget_space(h5data);
	checkH5Err(h5fSpace);

	// Read the data
	unsigned int offset = 0;
	hsize_t fStart = fileOffset();
	hsize_t count = dofsPerIteration();
	hid_t h5memSpace = H5Screate_simple(1, &count, 0L);
	checkH5Err(h5memSpace);
	checkH5Err(H5Sselect_all(h5memSpace));
	for (unsigned int i = 0; i < totalIterations()-1; i++) {
		checkH5Err(H5Sselect_hyperslab(h5fSpace, H5S_SELECT_SET, &fStart, 0L, &count, 0L));

		checkH5Err(H5Dread(h5data, H5T_NATIVE_DOUBLE, h5memSpace, h5fSpace,
				h5XferList(), &dofs[offset]));

		// We are finished in less iterations, read data twice
		// so everybody needs the same number of iterations
		if (i < iterations()-1) {
			fStart += count;
			offset += count;
		}
	}
	checkH5Err(H5Sclose(h5memSpace));

	// Read reminding data in the last iteration
	count = numDofs() - (iterations() - 1) * count;
	h5memSpace = H5Screate_simple(1, &count, 0L);
	checkH5Err(h5memSpace);
	checkH5Err(H5Sselect_all(h5memSpace));
	checkH5Err(H5Sselect_hyperslab(h5fSpace, H5S_SELECT_SET, &fStart, 0L, &count, 0L));
	checkH5Err(H5Dread(h5data, H5T_NATIVE_DOUBLE, h5memSpace, h5fSpace,
			h5XferList(), &dofs[offset]));
	checkH5Err(H5Sclose(h5memSpace));

	checkH5Err(H5Sclose(h5fSpace));
	checkH5Err(H5Dclose(h5data));
	checkH5Err(H5Fclose(h5file));
}
Ejemplo n.º 13
0
/*
 * transfer_relfile()
 *
 * Copy or link file from old cluster to new one.
 */
static void
transfer_relfile(FileNameMap *map, const char *type_suffix)
{
	const char *msg;
	char		old_file[MAXPGPATH];
	char		new_file[MAXPGPATH];
	int			fd;
	int			segno;
	char		extent_suffix[65];

	/*
	 * Now copy/link any related segments as well. Remember, PG breaks large
	 * files into 1GB segments, the first segment has no extension, subsequent
	 * segments are named relfilenode.1, relfilenode.2, relfilenode.3. copied.
	 */
	for (segno = 0;; segno++)
	{
		if (segno == 0)
			extent_suffix[0] = '\0';
		else
			snprintf(extent_suffix, sizeof(extent_suffix), ".%d", segno);

		snprintf(old_file, sizeof(old_file), "%s%s/%u/%u%s%s",
				 map->old_tablespace,
				 map->old_tablespace_suffix,
				 map->old_db_oid,
				 map->old_relfilenode,
				 type_suffix,
				 extent_suffix);
		snprintf(new_file, sizeof(new_file), "%s%s/%u/%u%s%s",
				 map->new_tablespace,
				 map->new_tablespace_suffix,
				 map->new_db_oid,
				 map->new_relfilenode,
				 type_suffix,
				 extent_suffix);

		/* Is it an extent, fsm, or vm file? */
		if (type_suffix[0] != '\0' || segno != 0)
		{
			/* Did file open fail? */
			if ((fd = open(old_file, O_RDONLY, 0)) == -1)
			{
				/* File does not exist?  That's OK, just return */
				if (errno == ENOENT)
					return;
				else
					pg_fatal("error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
							 map->nspname, map->relname, old_file, new_file,
							 getErrorText());
			}
			close(fd);
		}

		unlink(new_file);

		/* Copying files might take some time, so give feedback. */
		pg_log(PG_STATUS, "%s", old_file);

		if (user_opts.transfer_mode == TRANSFER_MODE_COPY)
		{
			pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"\n", old_file, new_file);

			if ((msg = copyFile(old_file, new_file, true)) != NULL)
				pg_fatal("error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
						 map->nspname, map->relname, old_file, new_file, msg);
		}
		else
		{
			pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"\n", old_file, new_file);

			if ((msg = linkFile(old_file, new_file)) != NULL)
				pg_fatal("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
						 map->nspname, map->relname, old_file, new_file, msg);
		}
	}

	return;
}
Ejemplo n.º 14
0
/*
 * transfer_relfile()
 *
 * Copy or link file from old cluster to new one.  If vm_must_add_frozenbit
 * is true, visibility map forks are converted and rewritten, even in link
 * mode.
 */
static void
transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_frozenbit)
{
	char		old_file[MAXPGPATH];
	char		new_file[MAXPGPATH];
	int			segno;
	char		extent_suffix[65];
	struct stat statbuf;

	/*
	 * Now copy/link any related segments as well. Remember, PG breaks large
	 * files into 1GB segments, the first segment has no extension, subsequent
	 * segments are named relfilenode.1, relfilenode.2, relfilenode.3.
	 */
	for (segno = 0;; segno++)
	{
		if (segno == 0)
			extent_suffix[0] = '\0';
		else
			snprintf(extent_suffix, sizeof(extent_suffix), ".%d", segno);

		snprintf(old_file, sizeof(old_file), "%s%s/%u/%u%s%s",
				 map->old_tablespace,
				 map->old_tablespace_suffix,
				 map->old_db_oid,
				 map->old_relfilenode,
				 type_suffix,
				 extent_suffix);
		snprintf(new_file, sizeof(new_file), "%s%s/%u/%u%s%s",
				 map->new_tablespace,
				 map->new_tablespace_suffix,
				 map->new_db_oid,
				 map->new_relfilenode,
				 type_suffix,
				 extent_suffix);

		/* Is it an extent, fsm, or vm file? */
		if (type_suffix[0] != '\0' || segno != 0)
		{
			/* Did file open fail? */
			if (stat(old_file, &statbuf) != 0)
			{
				/* File does not exist?  That's OK, just return */
				if (errno == ENOENT)
					return;
				else
					pg_fatal("error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
							 map->nspname, map->relname, old_file, new_file,
							 strerror(errno));
			}

			/* If file is empty, just return */
			if (statbuf.st_size == 0)
				return;
		}

		unlink(new_file);

		/* Copying files might take some time, so give feedback. */
		pg_log(PG_STATUS, "%s", old_file);

		if (vm_must_add_frozenbit && strcmp(type_suffix, "_vm") == 0)
		{
			/* Need to rewrite visibility map format */
			pg_log(PG_VERBOSE, "rewriting \"%s\" to \"%s\"\n",
				   old_file, new_file);
			rewriteVisibilityMap(old_file, new_file, map->nspname, map->relname);
		}
		else if (user_opts.transfer_mode == TRANSFER_MODE_COPY)
		{
			pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"\n",
				   old_file, new_file);
			copyFile(old_file, new_file, map->nspname, map->relname);
		}
		else
		{
			pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"\n",
				   old_file, new_file);
			linkFile(old_file, new_file, map->nspname, map->relname);
		}
	}
}
Ejemplo n.º 15
0
int
Generator::run(std::vector<const char *> *file_paths,
               std::vector<const char *> *bc_file_paths,
               std::vector<const char *> *compile_lib_paths,
               std::vector<const char *> *include_paths,
               std::vector<const char *> *module_paths,
               std::vector<const char *> *static_module_names,
               std::vector<const char *> *cto_module_names,
               const char *module_name,
               int debug,
               int produce,
               int optlevel,
               int remove_macros,
               int no_common,
               int no_dale_stdlib,
               int static_mods_all,
               int enable_cto,
               std::vector<std::string> *shared_object_paths,
               FILE *output_file)
{
    if (!file_paths->size()) {
        return 0;
    }

    NativeTypes nt;
    TypeRegister tr;
    llvm::ExecutionEngine *ee = NULL;

    std::set<std::string> cto_modules;
    for (std::vector<const char*>::iterator
            b = cto_module_names->begin(),
            e = cto_module_names->end();
            b != e;
            ++b) {
        cto_modules.insert(std::string(*b));
    }

    /* On OS X, SYSTEM_PROCESSOR is i386 even when the underlying
     * processor is x86-64, hence the extra check here. */
    bool is_x86_64 =
        ((!strcmp(SYSTEM_PROCESSOR, "x86_64"))
         || ((!strcmp(SYSTEM_PROCESSOR, "amd64")))
         || ((!strcmp(SYSTEM_NAME, "Darwin"))
             && (sizeof(char *) == 8)));

    init_introspection_functions();

    llvm::Module *last_module = NULL;

    Module::Reader mr(module_paths, shared_object_paths, include_paths);
    for (std::vector<const char*>::iterator b = compile_lib_paths->begin(),
                                            e = compile_lib_paths->end();
            b != e;
            ++b) {
        mr.addDynamicLibrary((*b), false, false);
    }

    const char *libdrt_path = NULL;
    if (!no_dale_stdlib) {
        FILE *drt_file = NULL;
        if ((drt_file = fopen(DALE_LIBRARY_PATH "/libdrt.so", "r"))) {
            libdrt_path = DALE_LIBRARY_PATH "/libdrt.so";
        } else if ((drt_file = fopen("./libdrt.so", "r"))) {
            libdrt_path = "./libdrt.so";
        } else {
            error("unable to find libdrt.so");
        }
        mr.addDynamicLibrary(libdrt_path, false, false);
        int res = fclose(drt_file);
        if (res != 0) {
            error("unable to close %s", libdrt_path, true);
        }
    }
    if (!module_name && libdrt_path) {
        shared_object_paths->push_back(libdrt_path);
    }

    Units units(&mr);
    units.cto            = enable_cto;
    units.no_common      = no_common;
    units.no_dale_stdlib = no_dale_stdlib;

    Context *ctx         = NULL;
    llvm::Module *mod    = NULL;
    llvm::Linker *linker = NULL;

    ErrorReporter er("");
    if (module_name) {
        const char *last_slash = strrchr(module_name, '/');
        std::string bare_module_name;
        if (!last_slash) {
            last_slash = module_name;
            bare_module_name = std::string(last_slash);
        } else {
            bare_module_name = std::string(last_slash + 1);
        }
        if (bare_module_name.length() > 0) {
            if (!isValidModuleName(&bare_module_name)) {
                Error *e = new Error(
                    ErrorInst::InvalidModuleName, NULL,
                    bare_module_name.c_str()
                );
                er.addError(e);
                return 0;
            }
        }
        int diff = last_slash - module_name;
        units.module_name = std::string(module_name);
        units.module_name.replace(diff + 1, 0, "lib");
    }

    for (std::vector<const char*>::iterator b = file_paths->begin(),
                                            e = file_paths->end();
            b != e;
            ++b) {
        const char *filename = *b;
        assert(!units.size());

        Unit *unit = new Unit(filename, &units, &er, &nt, &tr, NULL, is_x86_64);
        units.push(unit);
        ctx    = unit->ctx;
        mod    = unit->module;
        linker = unit->linker;

        llvm::Triple triple(mod->getTargetTriple());
        if (triple.getTriple().empty()) {
            triple.setTriple(getTriple());
        }
        mod->setDataLayout((is_x86_64) ? x86_64_layout : x86_32_layout);

        llvm::EngineBuilder eb = llvm::EngineBuilder(mod);
        eb.setEngineKind(llvm::EngineKind::JIT);
        ee = eb.create();
        assert(ee);
        ee->InstallLazyFunctionCreator(&lazyFunctionCreator);

        unit->ee = ee;
        unit->mp->ee = ee;

        CommonDecl::addVarargsFunctions(unit);

        if (!no_common) {
            if (no_dale_stdlib) {
                unit->addCommonDeclarations();
            } else {
                std::vector<const char*> import_forms;
                mr.run(ctx, mod, nullNode(), "drt", &import_forms);
                units.top()->mp->setPoolfree();
            }
        }

        std::vector<Node*> nodes;
        for (;;) {
            int error_count = er.getErrorTypeCount(ErrorType::Error);
            Node *top = units.top()->parser->getNextList();
            if (top) {
                nodes.push_back(top);
            }

            if (er.getErrorTypeCount(ErrorType::Error) > error_count) {
                er.flush();
                continue;
            }
            if (!top) {
                er.flush();
                break;
            }

            if (!top->is_token && !top->is_list) {
                units.pop();
                if (!units.empty()) {
                    Unit *unit = units.top();
                    ctx    = unit->ctx;
                    mod    = unit->module;
                    linker = unit->linker;
                    continue;
                }
                break;
            }
            FormTopLevelInstParse(&units, top);
            er.flush();
        }

        if (remove_macros) {
            ctx->eraseLLVMMacros();
        }

        if (dale::pool_free_fptr) {
            ee->freeMachineCodeForFunction(dale::pool_free_fn);
        }

        if (last_module) {
            linkModule(linker, last_module);
        }

        last_module = mod;

        for (std::vector<Node *>::iterator b = nodes.begin(),
                                           e = nodes.end();
                b != e;
                ++b) {
            delete (*b);
        }
    }

    if (remove_macros) {
        ctx->eraseLLVMMacros();
    }

    if (er.getErrorTypeCount(ErrorType::Error)) {
        return 0;
    }

    if (bc_file_paths) {
        for (std::vector<const char*>::iterator b = bc_file_paths->begin(),
                                                e = bc_file_paths->end();
                b != e;
                ++b) {
            linkFile(linker, *b);
        }
    }

    /* At optlevel 3, things go quite awry when making libraries, due
     * to the argumentPromotionPass. So set it to 2, unless LTO has
     * also been requested (optlevel == 4). */
    bool lto = false;
    if (optlevel == 3) {
        optlevel = 2;
    } else if (optlevel == 4) {
        optlevel = 3;
        lto = true;
    }

    llvm::TargetMachine *target_machine = getTargetMachine(last_module);
    llvm::raw_fd_ostream ostream(fileno(output_file), false);

    llvm::PassManager pass_manager;
    addDataLayout(&pass_manager, mod);
    pass_manager.add(llvm::createPostDomTree());

    llvm::PassManagerBuilder pass_manager_builder;
    pass_manager_builder.OptLevel = optlevel;
    pass_manager_builder.DisableUnitAtATime = true;

    if (optlevel > 0) {
        if (lto) {
            pass_manager_builder.DisableUnitAtATime = false;
        }
        pass_manager_builder.populateModulePassManager(pass_manager);
        if (lto) {
            pass_manager_builder.populateLTOPassManager(pass_manager, true, true);
        }
    }

    if (units.module_name.size() > 0) {
        Module::Writer mw(units.module_name, ctx, mod, &pass_manager,
                          &(mr.included_once_tags), &(mr.included_modules),
                          units.cto);
        mw.run();
        return 1;
    }

    std::map<std::string, llvm::Module*> *dtm_modules = &(mr.dtm_modules);
    std::map<std::string, std::string> *dtm_nm_modules = &(mr.dtm_nm_modules);

    bool reget_pointers = true;
    std::map<std::string, llvm::Module *> static_dtm_modules;
    if (static_mods_all || (static_module_names->size() > 0)) {
        if (remove_macros) {
            for (std::map<std::string, std::string>::iterator
                    b = dtm_nm_modules->begin(),
                    e = dtm_nm_modules->end();
                    b != e; ++b) {
                static_dtm_modules.insert(
                    std::pair<std::string, llvm::Module*>(
                        b->first,
                        mr.loadModule(&(b->second))
                    )
                );
            }
        } else {
            static_dtm_modules = *dtm_modules;
        }
        reget_pointers = false;
    }

    if (static_mods_all) {
        for (std::map<std::string, llvm::Module *>::iterator
                b = static_dtm_modules.begin(),
                e = static_dtm_modules.end();
                b != e; ++b) {
            if (cto_modules.find(b->first) == cto_modules.end()) {
                linkModule(linker, b->second);
            }
        }
    } else if (static_module_names->size() > 0) {
        for (std::vector<const char *>::iterator b =
                    static_module_names->begin(), e =
                    static_module_names->end();
                b != e; ++b) {
            std::map<std::string, llvm::Module *>::iterator
            found = static_dtm_modules.find(std::string(*b));
            if (found != static_dtm_modules.end()) {
                linkModule(linker, found->second);
            }
        }
        reget_pointers = false;
    }

    if (reget_pointers) {
        ctx->regetPointers(mod);
    }
    if (remove_macros) {
        ctx->eraseLLVMMacrosAndCTOFunctions();
    }

    llvm::formatted_raw_ostream *ostream_formatted =
        new llvm::formatted_raw_ostream(
            ostream,
            llvm::formatted_raw_ostream::DELETE_STREAM
        );

    if (produce == IR) {
        addPrintModulePass(&pass_manager, &ostream);
    } else if (produce == ASM) {
        target_machine->setAsmVerbosityDefault(true);
        llvm::CodeGenOpt::Level level = llvm::CodeGenOpt::Default;
        bool res = target_machine->addPassesToEmitFile(
            pass_manager, *ostream_formatted,
            llvm::TargetMachine::CGFT_AssemblyFile,
            level, NULL);
        assert(!res && "unable to add passes to emit file");
        _unused(res);
    }

    if (debug) {
        mod->dump();
    }
    if (debug) {
        llvm::verifyModule(*mod);
    }
    pass_manager.run(*mod);

    if (produce == BitCode) {
        llvm::WriteBitcodeToFile(mod, ostream);
    }

    ostream_formatted->flush();
    ostream.flush();

    return 1;
}
Ejemplo n.º 16
0
/*!
  Attempts to ensure that the link file for this AppLnk exists,
  including creating any required directories. Returns TRUE if
  successful; otherwise returns FALSE.

  You should not need to use this function.
*/
bool AppLnk::ensureLinkExists() const
{
    QString lf = linkFile();
    return prepareDirectories(lf);
}