Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Introduce Mold into third_party #853

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ include third_party/zip/zip.mk
include third_party/xxhash/xxhash.mk
include third_party/unzip/unzip.mk
include tool/build/lib/buildlib.mk
include third_party/mold/mold.mk
include third_party/chibicc/chibicc.mk
include third_party/chibicc/test/test.mk
include third_party/python/python.mk
Expand Down
2 changes: 1 addition & 1 deletion libc/sysv/consts/sig.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ COSMOPOLITAN_C_END_
#define SIGWINCH 28
#define SIGXCPU 24
#define SIGXFSZ 25
#define SIGBUS 7

#define SIGBUS SIGBUS
#define SIGTHR SIGTHR
#define SIGCHLD SIGCHLD
#define SIGCONT SIGCONT
Expand Down
14 changes: 7 additions & 7 deletions third_party/libcxx/atomic
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ bool __cxx_atomic_compare_exchange_strong(
}

template <typename _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY inline
bool __cxx_atomic_compare_exchange_strong(
__cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
memory_order __failure) {
Expand All @@ -803,7 +803,7 @@ bool __cxx_atomic_compare_exchange_weak(
}

template <typename _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY inline
bool __cxx_atomic_compare_exchange_weak(
__cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
memory_order __failure) {
Expand Down Expand Up @@ -835,7 +835,7 @@ _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
}

template <typename _Tp, typename _Td>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY inline
_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
memory_order __order) {
return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Expand All @@ -851,7 +851,7 @@ _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
}

template <typename _Tp, typename _Td>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY inline
_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
memory_order __order) {
return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Expand All @@ -867,23 +867,23 @@ _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
}

template <typename _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY inline
_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
_Tp __pattern, memory_order __order) {
return __atomic_fetch_and(&__a->__a_value, __pattern,
__to_gcc_order(__order));
}

template <typename _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY inline
_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
_Tp __pattern, memory_order __order) {
return __atomic_fetch_or(&__a->__a_value, __pattern,
__to_gcc_order(__order));
}

template <typename _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY inline
_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
memory_order __order) {
return __atomic_fetch_or(&__a->__a_value, __pattern,
Expand Down
1 change: 1 addition & 0 deletions third_party/libcxx/libcxx.mk
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ THIRD_PARTY_LIBCXX_A_HDRS = \
third_party/libcxx/refstring.hh \
third_party/libcxx/regex \
third_party/libcxx/scoped_allocator \
third_party/libcxx/span \
third_party/libcxx/set \
third_party/libcxx/span \
third_party/libcxx/sstream \
Expand Down
24 changes: 24 additions & 0 deletions third_party/mold/README.cosmo
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
DESCRIPTION

Mold: A Modern Linker 🦠

mold is a faster drop-in replacement for existing Unix linkers.
It is several times quicker than the LLVM lld linker, the second-fastest open-source linker,
which I initially developed a few years ago. mold aims to enhance developer productivity by minimizing build time,
particularly in rapid debug-edit-rebuild cycles.

SOURCE

https://github.com/rui314/mold

commit d4d93d7fb72dd19c44aafa4dd5397e35787d33ad
Author: Rui Ueyama <[email protected]>
Date: Mon Jun 19 12:35:20 2023 +0900

Format

CHANGES
* removed tbb by including a fake implementation
* made the parallel_for effectively single-threaded
* changed tbb:enumerable_thread_specific to thread_local
* removed rust demangle support
178 changes: 178 additions & 0 deletions third_party/mold/archive-file.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// clang-format off
// This file contains functions to read an archive file (.a file).
// An archive file is just a bundle of object files. It's similar to
// tar or zip, but the contents are not compressed.
//
// An archive file is either "regular" or "thin". A regular archive
// contains object files directly, while a thin archive contains only
// pathnames. In the latter case, actual file contents have to be read
// from given pathnames. A regular archive is sometimes called "fat"
// archive as opposed to "thin".
//
// If an archive file is given to the linker, the linker pulls out
// object files that are needed to resolve undefined symbols. So,
// bunding object files as an archive and giving that archive to the
// linker has a different meaning than directly giving the same set of
// object files to the linker. The former links only needed object
// files, while the latter links all the given object files.
//
// Therefore, if you link libc.a for example, not all the libc
// functions are linked to your binary. Instead, only object files
// that provides functions and variables used in your program get
// linked. To make this efficient, static library functions are
// usually separated to each object file in an archive file. You can
// see the contents of libc.a by running `ar t
// /usr/lib/x86_64-linux-gnu/libc.a`.

#pragma once

#include "third_party/mold/common.h"
#include "third_party/mold/filetype.h"

namespace mold {

struct ArHdr {
char ar_name[16];
char ar_date[12];
char ar_uid[6];
char ar_gid[6];
char ar_mode[8];
char ar_size[10];
char ar_fmag[2];

bool starts_with(std::string_view s) const {
return std::string_view(ar_name, s.size()) == s;
}

bool is_strtab() const {
return starts_with("// ");
}

bool is_symtab() const {
return starts_with("/ ") || starts_with("/SYM64/ ");
}

std::string read_name(std::string_view strtab, u8 *&ptr) const {
// BSD-style long filename
if (starts_with("#1/")) {
int namelen = atoi(ar_name + 3);
std::string name{(char *)ptr, (size_t)namelen};
ptr += namelen;

if (size_t pos = name.find('\0'))
name = name.substr(0, pos);
return name;
}

// SysV-style long filename
if (starts_with("/")) {
const char *start = strtab.data() + atoi(ar_name + 1);
return {start, (const char *)strstr(start, "/\n")};
}

// Short fileanme
if (const char *end = (char *)memchr(ar_name, '/', sizeof(ar_name)))
return {ar_name, end};
return {ar_name, sizeof(ar_name)};
}
};

template <typename Context, typename MappedFile>
std::vector<MappedFile *>
read_thin_archive_members(Context &ctx, MappedFile *mf) {
u8 *begin = mf->data;
u8 *data = begin + 8;
std::vector<MappedFile *> vec;
std::string_view strtab;

while (data < begin + mf->size) {
// Each header is aligned to a 2 byte boundary.
if ((begin - data) % 2)
data++;

ArHdr &hdr = *(ArHdr *)data;
u8 *body = data + sizeof(hdr);
u64 size = atol(hdr.ar_size);

// Read a string table.
if (hdr.is_strtab()) {
strtab = {(char *)body, (size_t)size};
data = body + size;
continue;
}

// Skip a symbol table.
if (hdr.is_symtab()) {
data = body + size;
continue;
}

if (!hdr.starts_with("#1/") && !hdr.starts_with("/"))
Fatal(ctx) << mf->name << ": filename is not stored as a long filename";

std::string name = hdr.read_name(strtab, body);

// Skip if symbol table
if (name == "__.SYMDEF" || name == "__.SYMDEF SORTED")
continue;

std::string path = name.starts_with('/') ?
name : (filepath(mf->name).parent_path() / name).string();
vec.push_back(MappedFile::must_open(ctx, path));
vec.back()->thin_parent = mf;
data = body;
}
return vec;
}

template <typename Context, typename MappedFile>
std::vector<MappedFile *> read_fat_archive_members(Context &ctx, MappedFile *mf) {
u8 *begin = mf->data;
u8 *data = begin + 8;
std::vector<MappedFile *> vec;
std::string_view strtab;

while (begin + mf->size - data >= 2) {
if ((begin - data) % 2)
data++;

ArHdr &hdr = *(ArHdr *)data;
u8 *body = data + sizeof(hdr);
u64 size = atol(hdr.ar_size);
data = body + size;

// Read if string table
if (hdr.is_strtab()) {
strtab = {(char *)body, (size_t)size};
continue;
}

// Skip if symbol table
if (hdr.is_symtab())
continue;

// Read the name field
std::string name = hdr.read_name(strtab, body);

// Skip if symbol table
if (name == "__.SYMDEF" || name == "__.SYMDEF SORTED")
continue;

vec.push_back(mf->slice(ctx, name, body - begin, data - body));
}
return vec;
}

template <typename Context, typename MappedFile>
std::vector<MappedFile *> read_archive_members(Context &ctx, MappedFile *mf) {
switch (get_file_type(ctx, mf)) {
case FileType::AR:
return read_fat_archive_members(ctx, mf);
case FileType::THIN_AR:
return read_thin_archive_members(ctx, mf);
default:
unreachable();
}
}

} // namespace mold
91 changes: 91 additions & 0 deletions third_party/mold/cmdline.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// clang-format off
#pragma once

#include "third_party/mold/common.h"

namespace mold {

template <typename Context>
std::vector<std::string_view>
read_response_file(Context &ctx, std::string_view path) {
std::vector<std::string_view> vec;
MappedFile<Context> *mf = MappedFile<Context>::must_open(ctx, std::string(path));
u8 *data = mf->data;

auto read_quoted = [&](i64 i, char quote) {
std::string buf;
while (i < mf->size && data[i] != quote) {
if (data[i] == '\\') {
buf.append(1, data[i + 1]);
i += 2;
} else {
buf.append(1, data[i++]);
}
}
if (i >= mf->size)
Fatal(ctx) << path << ": premature end of input";
vec.push_back(save_string(ctx, buf));
return i + 1;
};

auto read_unquoted = [&](i64 i) {
std::string buf;

while (i < mf->size) {
if (data[i] == '\\' && i + 1 < mf->size) {
buf.append(1, data[i + 1]);
i += 2;
continue;
}

if (!isspace(data[i])) {
buf.append(1, data[i++]);
continue;
}

break;
}

vec.push_back(save_string(ctx, buf));
return i;
};

for (i64 i = 0; i < mf->size;) {
if (isspace(data[i]))
i++;
else if (data[i] == '\'')
i = read_quoted(i + 1, '\'');
else if (data[i] == '\"')
i = read_quoted(i + 1, '\"');
else
i = read_unquoted(i);
}
return vec;
}

// Replace "@path/to/some/text/file" with its file contents.
template <typename Context>
std::vector<std::string_view> expand_response_files(Context &ctx, char **argv) {
std::vector<std::string_view> vec;
for (i64 i = 0; argv[i]; i++) {
if (argv[i][0] == '@')
append(vec, read_response_file(ctx, argv[i] + 1));
else
vec.push_back(argv[i]);
}
return vec;
}

static inline std::string_view string_trim(std::string_view str) {
size_t pos = str.find_first_not_of(" \t");
if (pos == str.npos)
return "";
str = str.substr(pos);

pos = str.find_last_not_of(" \t");
if (pos == str.npos)
return str;
return str.substr(0, pos + 1);
}

} // namespace mold
Loading