mirror of
https://github.com/rui314/mold.git
synced 2024-09-11 21:17:28 +03:00
Fix more compile errors for Windows
This commit is contained in:
parent
76f4c28a1b
commit
ed1166a08f
@ -14,8 +14,11 @@
|
||||
#include <tbb/parallel_for_each.h>
|
||||
#include <unordered_set>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#ifdef _WIN32
|
||||
# include <direct.h>
|
||||
# define _chdir chdir
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace mold::elf {
|
||||
@ -384,7 +387,7 @@ static int elf_main(int argc, char **argv) {
|
||||
install_signal_handler();
|
||||
|
||||
if (!ctx.arg.directory.empty())
|
||||
if (chdir(ctx.arg.directory.c_str()) == -1)
|
||||
if (_chdir(ctx.arg.directory.c_str()) == -1)
|
||||
Fatal(ctx) << "chdir failed: " << ctx.arg.directory
|
||||
<< ": " << errno_string();
|
||||
|
||||
|
@ -98,7 +98,7 @@ struct LTOPlugin {
|
||||
|
||||
LTOModule *(*module_create_from_fd_at_offset)(int fd, const char *path,
|
||||
size_t file_size,
|
||||
size_t map_size, off_t offset);
|
||||
size_t map_size, uint64_t offset);
|
||||
|
||||
void (*module_dispose)(LTOModule *mod);
|
||||
|
||||
|
@ -15,8 +15,8 @@
|
||||
#include <tbb/parallel_for_each.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
namespace mold::macho {
|
||||
@ -656,11 +656,11 @@ static void compute_uuid(Context<E> &ctx) {
|
||||
tbb::parallel_for((i64)0, num_shards, [&](i64 i) {
|
||||
u8 *begin = ctx.buf + shard_size * i;
|
||||
u8 *end = (i == num_shards - 1) ? ctx.buf + filesize : begin + shard_size;
|
||||
SHA256(begin, end - begin, shards.data() + i * SHA256_SIZE);
|
||||
sha256_hash(begin, end - begin, shards.data() + i * SHA256_SIZE);
|
||||
});
|
||||
|
||||
u8 buf[SHA256_SIZE];
|
||||
SHA256(shards.data(), shards.size(), buf);
|
||||
sha256_hash(shards.data(), shards.size(), buf);
|
||||
memcpy(ctx.uuid, buf, 16);
|
||||
ctx.mach_hdr.copy_buf(ctx);
|
||||
}
|
||||
|
141
output-file-unix.h
Normal file
141
output-file-unix.h
Normal file
@ -0,0 +1,141 @@
|
||||
#include "mold.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <filesystem>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace mold {
|
||||
|
||||
inline u32 get_umask() {
|
||||
u32 orig_umask = umask(0);
|
||||
umask(orig_umask);
|
||||
return orig_umask;
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
static std::pair<i64, char *>
|
||||
open_or_create_file(C &ctx, std::string path, i64 filesize, i64 perm) {
|
||||
std::string tmpl = filepath(path).parent_path() / ".mold-XXXXXX";
|
||||
char *path2 = (char *)save_string(ctx, tmpl).data();
|
||||
|
||||
i64 fd = mkstemp(path2);
|
||||
if (fd == -1)
|
||||
Fatal(ctx) << "cannot open " << path2 << ": " << errno_string();
|
||||
|
||||
// Reuse an existing file if exists and writable because on Linux,
|
||||
// writing to an existing file is much faster than creating a fresh
|
||||
// file and writing to it.
|
||||
if (ctx.overwrite_output_file && rename(path.c_str(), path2) == 0) {
|
||||
::close(fd);
|
||||
fd = ::open(path2, O_RDWR | O_CREAT, perm);
|
||||
if (fd != -1 && !ftruncate(fd, filesize) && !fchmod(fd, perm & ~get_umask()))
|
||||
return {fd, path2};
|
||||
|
||||
unlink(path2);
|
||||
fd = ::open(path2, O_RDWR | O_CREAT, perm);
|
||||
if (fd == -1)
|
||||
Fatal(ctx) << "cannot open " << path2 << ": " << errno_string();
|
||||
}
|
||||
|
||||
if (ftruncate(fd, filesize))
|
||||
Fatal(ctx) << "ftruncate failed: " << errno_string();
|
||||
|
||||
if (fchmod(fd, (perm & ~get_umask())) == -1)
|
||||
Fatal(ctx) << "fchmod failed: " << errno_string();
|
||||
return {fd, path2};
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
class MemoryMappedOutputFile : public OutputFile<C> {
|
||||
public:
|
||||
MemoryMappedOutputFile(C &ctx, std::string path, i64 filesize, i64 perm)
|
||||
: OutputFile<C>(path, filesize, true) {
|
||||
i64 fd;
|
||||
std::tie(fd, output_tmpfile) = open_or_create_file(ctx, path, filesize, perm);
|
||||
|
||||
this->buf = (u8 *)mmap(nullptr, filesize, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (this->buf == MAP_FAILED)
|
||||
Fatal(ctx) << path << ": mmap failed: " << errno_string();
|
||||
::close(fd);
|
||||
|
||||
mold::output_buffer_start = this->buf;
|
||||
mold::output_buffer_end = this->buf + filesize;
|
||||
}
|
||||
|
||||
void close(C &ctx) override {
|
||||
Timer t(ctx, "close_file");
|
||||
|
||||
if (!this->is_unmapped)
|
||||
munmap(this->buf, this->filesize);
|
||||
|
||||
if (rename(output_tmpfile, this->path.c_str()) == -1)
|
||||
Fatal(ctx) << this->path << ": rename failed: " << errno_string();
|
||||
output_tmpfile = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
class MallocOutputFile : public OutputFile<C> {
|
||||
public:
|
||||
MallocOutputFile(C &ctx, std::string path, i64 filesize, i64 perm)
|
||||
: OutputFile<C>(path, filesize, false), perm(perm) {
|
||||
this->buf = (u8 *)mmap(NULL, filesize, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
if (this->buf == MAP_FAILED)
|
||||
Fatal(ctx) << "mmap failed: " << errno_string();
|
||||
}
|
||||
|
||||
void close(C &ctx) override {
|
||||
Timer t(ctx, "close_file");
|
||||
|
||||
if (this->path == "-") {
|
||||
fwrite(this->buf, this->filesize, 1, stdout);
|
||||
fclose(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
i64 fd = ::open(this->path.c_str(), O_RDWR | O_CREAT, perm);
|
||||
if (fd == -1)
|
||||
Fatal(ctx) << "cannot open " << this->path << ": " << errno_string();
|
||||
|
||||
FILE *fp = fdopen(fd, "w");
|
||||
fwrite(this->buf, this->filesize, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
private:
|
||||
i64 perm;
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
std::unique_ptr<OutputFile<C>>
|
||||
OutputFile<C>::open(C &ctx, std::string path, i64 filesize, i64 perm) {
|
||||
Timer t(ctx, "open_file");
|
||||
|
||||
if (path.starts_with('/') && !ctx.arg.chroot.empty())
|
||||
path = ctx.arg.chroot + "/" + path_clean(path);
|
||||
|
||||
bool is_special = false;
|
||||
if (path == "-") {
|
||||
is_special = true;
|
||||
} else {
|
||||
struct stat st;
|
||||
if (stat(path.c_str(), &st) == 0 && (st.st_mode & S_IFMT) != S_IFREG)
|
||||
is_special = true;
|
||||
}
|
||||
|
||||
OutputFile<C> *file;
|
||||
if (is_special)
|
||||
file = new MallocOutputFile<C>(ctx, path, filesize, perm);
|
||||
else
|
||||
file = new MemoryMappedOutputFile<C>(ctx, path, filesize, perm);
|
||||
|
||||
if (ctx.arg.filler != -1)
|
||||
memset(file->buf, ctx.arg.filler, filesize);
|
||||
return std::unique_ptr<OutputFile<C>>(file);
|
||||
}
|
||||
|
||||
} // namespace mold
|
132
output-file-win32.h
Normal file
132
output-file-win32.h
Normal file
@ -0,0 +1,132 @@
|
||||
#include "mold.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <filesystem>
|
||||
|
||||
namespace mold {
|
||||
|
||||
template <typename C>
|
||||
static std::pair<i64, char *>
|
||||
open_or_create_file(C &ctx, std::string path, i64 filesize, i64 perm) {
|
||||
std::string tmpl = filepath(path).parent_path() / ".mold-XXXXXX";
|
||||
char *path2 = (char *)save_string(ctx, tmpl).data();
|
||||
|
||||
i64 fd = mkstemp(path2);
|
||||
if (fd == -1)
|
||||
Fatal(ctx) << "cannot open " << path2 << ": " << errno_string();
|
||||
|
||||
// Reuse an existing file if exists and writable because on Linux,
|
||||
// writing to an existing file is much faster than creating a fresh
|
||||
// file and writing to it.
|
||||
if (ctx.overwrite_output_file && rename(path.c_str(), path2) == 0) {
|
||||
::close(fd);
|
||||
fd = ::open(path2, O_RDWR | O_CREAT, perm);
|
||||
if (fd != -1 && !ftruncate(fd, filesize) && !fchmod(fd, perm & ~get_umask()))
|
||||
return {fd, path2};
|
||||
|
||||
unlink(path2);
|
||||
fd = ::open(path2, O_RDWR | O_CREAT, perm);
|
||||
if (fd == -1)
|
||||
Fatal(ctx) << "cannot open " << path2 << ": " << errno_string();
|
||||
}
|
||||
|
||||
if (ftruncate(fd, filesize))
|
||||
Fatal(ctx) << "ftruncate failed: " << errno_string();
|
||||
|
||||
if (fchmod(fd, (perm & ~get_umask())) == -1)
|
||||
Fatal(ctx) << "fchmod failed: " << errno_string();
|
||||
return {fd, path2};
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
class MemoryMappedOutputFile : public OutputFile<C> {
|
||||
public:
|
||||
MemoryMappedOutputFile(C &ctx, std::string path, i64 filesize, i64 perm)
|
||||
: OutputFile<C>(path, filesize, true) {
|
||||
i64 fd;
|
||||
std::tie(fd, output_tmpfile) = open_or_create_file(ctx, path, filesize, perm);
|
||||
|
||||
this->buf = (u8 *)mmap(nullptr, filesize, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (this->buf == MAP_FAILED)
|
||||
Fatal(ctx) << path << ": mmap failed: " << errno_string();
|
||||
::close(fd);
|
||||
|
||||
mold::output_buffer_start = this->buf;
|
||||
mold::output_buffer_end = this->buf + filesize;
|
||||
}
|
||||
|
||||
void close(C &ctx) override {
|
||||
Timer t(ctx, "close_file");
|
||||
|
||||
if (!this->is_unmapped)
|
||||
munmap(this->buf, this->filesize);
|
||||
|
||||
if (rename(output_tmpfile, this->path.c_str()) == -1)
|
||||
Fatal(ctx) << this->path << ": rename failed: " << errno_string();
|
||||
output_tmpfile = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
class MallocOutputFile : public OutputFile<C> {
|
||||
public:
|
||||
MallocOutputFile(C &ctx, std::string path, i64 filesize, i64 perm)
|
||||
: OutputFile<C>(path, filesize, false), perm(perm) {
|
||||
this->buf = (u8 *)mmap(NULL, filesize, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
if (this->buf == MAP_FAILED)
|
||||
Fatal(ctx) << "mmap failed: " << errno_string();
|
||||
}
|
||||
|
||||
void close(C &ctx) override {
|
||||
Timer t(ctx, "close_file");
|
||||
|
||||
if (this->path == "-") {
|
||||
fwrite(this->buf, this->filesize, 1, stdout);
|
||||
fclose(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
i64 fd = ::open(this->path.c_str(), O_RDWR | O_CREAT, perm);
|
||||
if (fd == -1)
|
||||
Fatal(ctx) << "cannot open " << this->path << ": " << errno_string();
|
||||
|
||||
FILE *fp = fdopen(fd, "w");
|
||||
fwrite(this->buf, this->filesize, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
private:
|
||||
i64 perm;
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
std::unique_ptr<OutputFile<C>>
|
||||
OutputFile<C>::open(C &ctx, std::string path, i64 filesize, i64 perm) {
|
||||
Timer t(ctx, "open_file");
|
||||
|
||||
if (path.starts_with('/') && !ctx.arg.chroot.empty())
|
||||
path = ctx.arg.chroot + "/" + path_clean(path);
|
||||
|
||||
bool is_special = false;
|
||||
if (path == "-") {
|
||||
is_special = true;
|
||||
} else {
|
||||
struct stat st;
|
||||
if (stat(path.c_str(), &st) == 0 && (st.st_mode & S_IFMT) != S_IFREG)
|
||||
is_special = true;
|
||||
}
|
||||
|
||||
OutputFile<C> *file;
|
||||
if (is_special)
|
||||
file = new MallocOutputFile<C>(ctx, path, filesize, perm);
|
||||
else
|
||||
file = new MemoryMappedOutputFile<C>(ctx, path, filesize, perm);
|
||||
|
||||
if (ctx.arg.filler != -1)
|
||||
memset(file->buf, ctx.arg.filler, filesize);
|
||||
return std::unique_ptr<OutputFile<C>>(file);
|
||||
}
|
||||
|
||||
} // namespace mold
|
147
output-file.h
147
output-file.h
@ -1,144 +1,5 @@
|
||||
#include "mold.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <filesystem>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#if _WIN32
|
||||
# include "output-file-win32.h"
|
||||
#else
|
||||
# include "output-file-unix.h"
|
||||
#endif
|
||||
|
||||
namespace mold {
|
||||
|
||||
inline u32 get_umask() {
|
||||
u32 orig_umask = umask(0);
|
||||
umask(orig_umask);
|
||||
return orig_umask;
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
static std::pair<i64, char *>
|
||||
open_or_create_file(C &ctx, std::string path, i64 filesize, i64 perm) {
|
||||
std::string tmpl = filepath(path).parent_path() / ".mold-XXXXXX";
|
||||
char *path2 = (char *)save_string(ctx, tmpl).data();
|
||||
|
||||
i64 fd = mkstemp(path2);
|
||||
if (fd == -1)
|
||||
Fatal(ctx) << "cannot open " << path2 << ": " << errno_string();
|
||||
|
||||
// Reuse an existing file if exists and writable because on Linux,
|
||||
// writing to an existing file is much faster than creating a fresh
|
||||
// file and writing to it.
|
||||
if (ctx.overwrite_output_file && rename(path.c_str(), path2) == 0) {
|
||||
::close(fd);
|
||||
fd = ::open(path2, O_RDWR | O_CREAT, perm);
|
||||
if (fd != -1 && !ftruncate(fd, filesize) && !fchmod(fd, perm & ~get_umask()))
|
||||
return {fd, path2};
|
||||
|
||||
unlink(path2);
|
||||
fd = ::open(path2, O_RDWR | O_CREAT, perm);
|
||||
if (fd == -1)
|
||||
Fatal(ctx) << "cannot open " << path2 << ": " << errno_string();
|
||||
}
|
||||
|
||||
if (ftruncate(fd, filesize))
|
||||
Fatal(ctx) << "ftruncate failed: " << errno_string();
|
||||
|
||||
if (fchmod(fd, (perm & ~get_umask())) == -1)
|
||||
Fatal(ctx) << "fchmod failed: " << errno_string();
|
||||
return {fd, path2};
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
class MemoryMappedOutputFile : public OutputFile<C> {
|
||||
public:
|
||||
MemoryMappedOutputFile(C &ctx, std::string path, i64 filesize, i64 perm)
|
||||
: OutputFile<C>(path, filesize, true) {
|
||||
i64 fd;
|
||||
std::tie(fd, output_tmpfile) = open_or_create_file(ctx, path, filesize, perm);
|
||||
|
||||
this->buf = (u8 *)mmap(nullptr, filesize, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (this->buf == MAP_FAILED)
|
||||
Fatal(ctx) << path << ": mmap failed: " << errno_string();
|
||||
::close(fd);
|
||||
|
||||
mold::output_buffer_start = this->buf;
|
||||
mold::output_buffer_end = this->buf + filesize;
|
||||
}
|
||||
|
||||
void close(C &ctx) override {
|
||||
Timer t(ctx, "close_file");
|
||||
|
||||
if (!this->is_unmapped)
|
||||
munmap(this->buf, this->filesize);
|
||||
|
||||
if (rename(output_tmpfile, this->path.c_str()) == -1)
|
||||
Fatal(ctx) << this->path << ": rename failed: " << errno_string();
|
||||
output_tmpfile = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
class MallocOutputFile : public OutputFile<C> {
|
||||
public:
|
||||
MallocOutputFile(C &ctx, std::string path, i64 filesize, i64 perm)
|
||||
: OutputFile<C>(path, filesize, false), perm(perm) {
|
||||
this->buf = (u8 *)mmap(NULL, filesize, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
if (this->buf == MAP_FAILED)
|
||||
Fatal(ctx) << "mmap failed: " << errno_string();
|
||||
}
|
||||
|
||||
void close(C &ctx) override {
|
||||
Timer t(ctx, "close_file");
|
||||
|
||||
if (this->path == "-") {
|
||||
fwrite(this->buf, this->filesize, 1, stdout);
|
||||
fclose(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
i64 fd = ::open(this->path.c_str(), O_RDWR | O_CREAT, perm);
|
||||
if (fd == -1)
|
||||
Fatal(ctx) << "cannot open " << this->path << ": " << errno_string();
|
||||
|
||||
FILE *fp = fdopen(fd, "w");
|
||||
fwrite(this->buf, this->filesize, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
private:
|
||||
i64 perm;
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
std::unique_ptr<OutputFile<C>>
|
||||
OutputFile<C>::open(C &ctx, std::string path, i64 filesize, i64 perm) {
|
||||
Timer t(ctx, "open_file");
|
||||
|
||||
if (path.starts_with('/') && !ctx.arg.chroot.empty())
|
||||
path = ctx.arg.chroot + "/" + path_clean(path);
|
||||
|
||||
bool is_special = false;
|
||||
if (path == "-") {
|
||||
is_special = true;
|
||||
} else {
|
||||
struct stat st;
|
||||
if (stat(path.c_str(), &st) == 0 && (st.st_mode & S_IFMT) != S_IFREG)
|
||||
is_special = true;
|
||||
}
|
||||
|
||||
OutputFile<C> *file;
|
||||
if (is_special)
|
||||
file = new MallocOutputFile<C>(ctx, path, filesize, perm);
|
||||
else
|
||||
file = new MemoryMappedOutputFile<C>(ctx, path, filesize, perm);
|
||||
|
||||
if (ctx.arg.filler != -1)
|
||||
memset(file->buf, ctx.arg.filler, filesize);
|
||||
return std::unique_ptr<OutputFile<C>>(file);
|
||||
}
|
||||
|
||||
} // namespace mold
|
||||
|
Loading…
Reference in New Issue
Block a user