Compare commits

...

7 Commits

Author SHA1 Message Date
Jarred Sumner
1bcd168dad does not segfault 2023-05-13 07:35:32 -07:00
Jarred Sumner
0349749a6c Move some code around 2023-05-13 07:34:02 -07:00
Jarred Sumner
ad4d7e6866 Add zstd 2023-05-13 05:20:26 -07:00
Jarred Sumner
ee6d745341 proof of concept 2023-05-12 23:00:32 -07:00
Jarred Sumner
8951972bab Implement support for embedding files on macOS 2023-05-12 22:58:57 -07:00
Jarred Sumner
01de6575df Compile LIEF 2023-05-12 22:58:34 -07:00
Jarred Sumner
73fc26c799 Add LIEF 2023-05-12 22:54:08 -07:00
12 changed files with 691 additions and 13 deletions

1
.gitattributes vendored
View File

@@ -8,3 +8,4 @@ src/bun.js/bindings/sqlite/sqlite3_local.h linguist-vendored
*.zig text eol=lf
src/bun.js/bindings/simdutf.cpp linguist-vendored
src/bun.js/bindings/simdutf.h linguist-vendored
src/deps/LIEF linguist-vendored

4
.gitmodules vendored
View File

@@ -65,3 +65,7 @@ fetchRecurseSubmodules = false
[submodule "src/deps/c-ares"]
path = src/deps/c-ares
url = https://github.com/c-ares/c-ares.git
[submodule "src/deps/LIEF"]
path = src/deps/LIEF
url = git@github.com:lief-project/LIEF.git
ignore = dirty

View File

@@ -19,6 +19,7 @@
"${workspaceFolder}/src/bun.js/builtins/cpp",
"${workspaceFolder}/src/deps/boringssl/include/",
"${workspaceFolder}/src/deps",
"${workspaceFolder}/src/deps/LIEF/include",
"${workspaceFolder}/src/deps/uws/uSockets/src"
],
"browse": {
@@ -36,6 +37,7 @@
"${workspaceFolder}/src/bun.js/builtins/*",
"${workspaceFolder}/src/bun.js/builtins/cpp/*",
"${workspaceFolder}/src/bun.js/modules/*",
"${workspaceFolder}/src/deps/LIEF/include/*/*",
"${workspaceFolder}/src/deps",
"${workspaceFolder}/src/deps/boringssl/include/",
"${workspaceFolder}/src/deps/uws/uSockets/src"

18
.vscode/settings.json vendored
View File

@@ -77,6 +77,7 @@
"src/deps/lol-html": true,
"src/deps/c-ares": true,
"src/deps/tinycc": true,
"src/deps/LIEF": true,
"test/snippets/package-json-exports/_node_modules_copy": true
},
"C_Cpp.files.exclude": {
@@ -95,7 +96,9 @@
"src/bun.js/WebKit/WebCore": true,
"src/bun.js/WebKit/WebDriver": true,
"src/bun.js/WebKit/WebKitBuild": true,
"src/bun.js/WebKit/WebInspectorUI": true
"src/bun.js/WebKit/WebInspectorUI": true,
"src/deps/LIEF/src": true,
"src/deps/LIEF/test": true
},
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format"
@@ -204,7 +207,18 @@
"compare": "cpp",
"concepts": "cpp",
"typeindex": "cpp",
"__verbose_abort": "cpp"
"__verbose_abort": "cpp",
"__std_stream": "cpp",
"any": "cpp",
"charconv": "cpp",
"csignal": "cpp",
"format": "cpp",
"forward_list": "cpp",
"future": "cpp",
"regex": "cpp",
"span": "cpp",
"valarray": "cpp",
"codecvt": "cpp"
},
"cmake.configureOnOpen": false,
"C_Cpp.errorSquiggles": "enabled",

View File

@@ -503,6 +503,60 @@ ENV LIB_ICU_PATH=${WEBKIT_DIR}/lib
RUN --mount=type=cache,target=/ccache cd $BUN_DIR && make sqlite
FROM bun-base as zstd
ARG DEBIAN_FRONTEND
ARG GITHUB_WORKSPACE
ARG ZIG_PATH
# Directory extracts to "bun-webkit"
ARG WEBKIT_DIR
ARG BUN_RELEASE_DIR
ARG BUN_DEPS_OUT_DIR
ARG BUN_DIR
ARG CPU_TARGET
ENV CPU_TARGET=${CPU_TARGET}
ENV CCACHE_DIR=/ccache
COPY Makefile ${BUN_DIR}/Makefile
COPY src/deps/zstd ${BUN_DIR}/src/deps/zstd
COPY .prettierrc.cjs ${BUN_DIR}/.prettierrc.cjs
WORKDIR $BUN_DIR
ENV JSC_BASE_DIR=${WEBKIT_DIR}
ENV LIB_ICU_PATH=${WEBKIT_DIR}/lib
RUN --mount=type=cache,target=/ccache cd $BUN_DIR && make zstd
FROM bun-base as lief
ARG DEBIAN_FRONTEND
ARG GITHUB_WORKSPACE
ARG ZIG_PATH
# Directory extracts to "bun-webkit"
ARG WEBKIT_DIR
ARG BUN_RELEASE_DIR
ARG BUN_DEPS_OUT_DIR
ARG BUN_DIR
ARG CPU_TARGET
ENV CPU_TARGET=${CPU_TARGET}
ENV CCACHE_DIR=/ccache
COPY Makefile ${BUN_DIR}/Makefile
COPY src/deps/LIEF ${BUN_DIR}/src/deps/LIEF
COPY .prettierrc.cjs ${BUN_DIR}/.prettierrc.cjs
WORKDIR $BUN_DIR
ENV JSC_BASE_DIR=${WEBKIT_DIR}
ENV LIB_ICU_PATH=${WEBKIT_DIR}/lib
RUN --mount=type=cache,target=/ccache cd $BUN_DIR && make lief
FROM scratch as build_release_cpp
COPY --from=compile_cpp /tmp/*.o /
@@ -535,6 +589,8 @@ COPY --from=lolhtml ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
COPY --from=mimalloc ${BUN_DEPS_OUT_DIR}/*.o ${BUN_DEPS_OUT_DIR}/
COPY --from=picohttp ${BUN_DEPS_OUT_DIR}/*.o ${BUN_DEPS_OUT_DIR}/
COPY --from=sqlite ${BUN_DEPS_OUT_DIR}/*.o ${BUN_DEPS_OUT_DIR}/
COPY --from=zstd ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
COPY --from=lief ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
COPY --from=tinycc ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
COPY --from=uws ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
COPY --from=uws ${BUN_DEPS_OUT_DIR}/*.o ${BUN_DEPS_OUT_DIR}/

View File

@@ -344,7 +344,7 @@ LINUX_INCLUDE_DIRS := $(ALL_JSC_INCLUDE_DIRS) \
UWS_INCLUDE_DIR := -I$(BUN_DEPS_DIR)/uws/uSockets/src -I$(BUN_DEPS_DIR)/uws/src -I$(BUN_DEPS_DIR)
INCLUDE_DIRS := $(UWS_INCLUDE_DIR) -I$(BUN_DEPS_DIR)/mimalloc/include -Isrc/napi -I$(BUN_DEPS_DIR)/boringssl/include -I$(BUN_DEPS_DIR)/c-ares/include
INCLUDE_DIRS := $(UWS_INCLUDE_DIR) -I$(BUN_DEPS_DIR)/mimalloc/include -I$(BUN_DEPS_DIR)/zstd/include -I$(BUN_DEPS_DIR)/LIEF/include -Isrc/napi -I$(BUN_DEPS_DIR)/boringssl/include -I$(BUN_DEPS_DIR)/c-ares/include
ifeq ($(OS_NAME),linux)
@@ -452,6 +452,8 @@ ARCHIVE_FILES_WITHOUT_LIBCRYPTO = $(MINIMUM_ARCHIVE_FILES) \
-ltcc \
-lusockets \
-lcares \
-lLIEF \
-lzstd \
$(BUN_DEPS_OUT_DIR)/libuwsockets.o
ARCHIVE_FILES = $(ARCHIVE_FILES_WITHOUT_LIBCRYPTO)
@@ -636,6 +638,9 @@ compile-ffi-test:
sqlite:
.PHONY: zstd
zstd:
cd $(BUN_DEPS_DIR)/zstd && rm -rf build-cmake-debug && cmake $(CMAKE_FLAGS) -DZSTD_BUILD_STATIC=ON -B build-cmake-debug -S build/cmake -G Ninja && ninja -C build-cmake-debug && cp build-cmake-debug/lib/libzstd.a $(BUN_DEPS_OUT_DIR)/libzstd.a
.PHONY: libarchive
libarchive:
@@ -908,7 +913,41 @@ bun-codesign-release-local:
bun-codesign-release-local-debug:
LIEF_MACHO = OFF
LIEF_ELF = OFF
LIEF_PE = OFF
ifeq ($(OS_NAME),darwin)
LIEF_MACHO = ON
endif
ifeq ($(OS_NAME),linux)
LIEF_ELF = ON
endif
.PHONY: lief
lief:
cd $(BUN_DEPS_DIR)/LIEF && (make clean || echo "") && \
CXX=$(CXX) CC=$(CC) cmake \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_CXX_COMPILER=$(REAL_CXX) \
-DCMAKE_AR=$(AR) \
-DLIEF_USE_CCACHE=OFF \
-DLIEF_MACHO=$(LIEF_MACHO) \
-DLIEF_ELF=$(LIEF_ELF) \
-DLIEF_PE=$(LIEF_PE) \
-DLIEF_OAT=OFF \
-DLIEF_DEX=OFF \
-DLIEF_VDEX=OFF \
-DLIEF_ART=OFF \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DLIEF_ENABLE_JSON=OFF \
-DLIEF_EXAMPLES=OFF \
-DLIEF_TESTS=OFF \
-DLIEF_DOC=OFF \
-DLIEF_INSTALL=$(BUN_DEPS_OUT_DIR) \
-DCMAKE_RANLIB=$(which llvm-15-ranlib 2>/dev/null || which llvm-ranlib 2>/dev/null) && \
CXX=$(CXX) CC=$(CC) make -j$(CPUS) && cp libLIEF.a $(BUN_DEPS_OUT_DIR)/libLIEF.a
.PHONY: jsc
jsc: jsc-build jsc-copy-headers jsc-bindings
.PHONY: jsc-build
@@ -1857,7 +1896,7 @@ cold-jsc-start:
misctools/cold-jsc-start.cpp -o cold-jsc-start
.PHONY: vendor-without-npm
vendor-without-npm: node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib boringssl libarchive lolhtml sqlite usockets uws tinycc c-ares
vendor-without-npm: node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib boringssl libarchive lolhtml sqlite usockets uws tinycc c-ares lief zstd
.PHONY: vendor-without-check
vendor-without-check: npm-install vendor-without-npm

View File

@@ -0,0 +1,284 @@
// This code is based on https://github.com/nodejs/postject/
// Thank you RaisinTen and the rest of the Node.js team who worked on postject.
#include "root.h"
#include <unistd.h>
#include <algorithm>
#include <codecvt>
#include <locale>
#include <memory>
#include <vector>
#include <LIEF/LIEF.hpp>
#ifdef __APPLE__
#include <mach-o/dyld.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
static const char* segment_name = "__BUNBUILD";
extern "C" int inject_into_macho(
uint8_t* bytes,
size_t bytes_length,
const char* section_name)
{
// Step 1. Copy the executable to a temporary location
char templocation[PATH_MAX];
memcpy(templocation, "/tmp/bun.XXXXXX", 15);
templocation[15] = '\0';
auto* templocationName = mkdtemp(templocation);
if (!templocationName) {
return -1;
}
templocationName = strcat(templocationName, "/bun");
char processLocationBuf[PATH_MAX];
uint32_t processLocationLen = PATH_MAX;
{
if (_NSGetExecutablePath(processLocationBuf, &processLocationLen) != 0) {
return -1;
}
}
// Step 3. Inject the data into the executable
auto config = LIEF::MachO::ParserConfig::deep();
auto fat_binary = LIEF::MachO::Parser::parse(std::string(processLocationBuf, processLocationLen));
if (!fat_binary) {
return -1;
}
// Inject into all Mach-O binaries if there's more than one in a fat binary
for (LIEF::MachO::Binary& binary : *fat_binary) {
LIEF::MachO::Section* existing_section = binary.get_section(segment_name, section_name);
if (existing_section) {
binary.remove_section(segment_name, section_name, true);
}
LIEF::MachO::SegmentCommand* segment = binary.get_segment(segment_name);
std::vector<uint8_t> bytesVec(bytes, bytes + bytes_length);
LIEF::MachO::Section section(std::string(section_name, strlen(section_name)), WTFMove(bytesVec));
if (!segment) {
// Create the segment and mark it read-only
LIEF::MachO::SegmentCommand new_segment(segment_name);
new_segment.max_protection(
static_cast<uint32_t>(LIEF::MachO::VM_PROTECTIONS::VM_PROT_READ));
new_segment.init_protection(
static_cast<uint32_t>(LIEF::MachO::VM_PROTECTIONS::VM_PROT_READ));
new_segment.add_section(section);
binary.add(new_segment);
} else {
binary.add_section(*segment, section);
}
// It will need to be signed again anyway, so remove the signature
if (binary.has_code_signature()) {
binary.remove_signature();
}
}
int fd = open(templocationName, O_RDWR | O_CREAT | O_TRUNC, 0777);
// Construct a new Uint8Array in JS
std::vector<uint8_t> output = fat_binary->raw();
size_t remain = output.size();
size_t offset = 0;
while (remain > 0) {
ssize_t written = write(fd, output.data() + offset, remain);
if (written == -1) {
close(fd);
return -1;
}
remain -= written;
offset += written;
}
output.clear();
fchmod(fd, 0777);
return fd;
}
#endif
#if defined(__APPLE__) && defined(__MACH__)
#include <mach-o/dyld.h>
#include <mach-o/getsect.h>
#elif defined(__linux__)
#include <elf.h>
#include <link.h>
#include <sys/param.h>
#elif defined(_WIN32)
#include <windows.h>
#endif
#ifndef POSTJECT_SENTINEL_FUSE
#define POSTJECT_SENTINEL_FUSE \
"POSTJECT_SENTINEL_fce680ab2cc467b6e072b8b5df1996b2"
#endif
struct postject_options {
const char* elf_section_name;
const char* macho_framework_name;
const char* macho_section_name;
const char* macho_segment_name;
const char* pe_resource_name;
};
inline void postject_options_init(struct postject_options* options)
{
options->elf_section_name = NULL;
options->macho_framework_name = NULL;
options->macho_section_name = NULL;
options->macho_segment_name = NULL;
options->pe_resource_name = NULL;
}
static inline bool postject_has_resource()
{
static const volatile char* sentinel = POSTJECT_SENTINEL_FUSE ":0";
return sentinel[sizeof(POSTJECT_SENTINEL_FUSE)] == '1';
}
#if defined(__linux__)
static int postject__dl_iterate_phdr_callback(struct dl_phdr_info* info,
size_t size,
void* data)
{
// Snag the dl_phdr_info struct for the main program, then stop iterating
*((struct dl_phdr_info*)data) = *info;
return 1;
}
#endif
extern "C" const void* postject_find_resource(
const char* name,
size_t* size)
{
// Always zero out the size pointer to start
if (size != NULL) {
*size = 0;
}
#if defined(__APPLE__) && defined(__MACH__)
unsigned long section_size;
char* ptr = NULL;
ptr = getsectdata(segment_name, name,
&section_size);
#ifdef __clang__
#pragma clang diagnostic pop
#endif
if (ptr != NULL) {
// Add the "virtual memory address slide" amount to ensure a valid pointer
// in cases where the virtual memory address have been adjusted by the OS.
//
// NOTE - `getsectdataFromFramework` already handles this adjustment for
// us, which is why we only do it for `getsectdata`, see:
// https://web.archive.org/web/20220613234007/https://opensource.apple.com/source/cctools/cctools-590/libmacho/getsecbyname.c.auto.html
ptr += _dyld_get_image_vmaddr_slide(0);
}
if (size != NULL) {
*size = (size_t)section_size;
}
return ptr;
#elif defined(__linux__)
if (options != NULL && options->elf_section_name != NULL) {
name = options->elf_section_name;
}
struct dl_phdr_info main_program_info;
dl_iterate_phdr(postject__dl_iterate_phdr_callback, &main_program_info);
uintptr_t p = (uintptr_t)main_program_info.dlpi_phdr;
size_t n = main_program_info.dlpi_phnum;
uintptr_t base_addr = main_program_info.dlpi_addr;
// iterate program header
for (; n > 0; n--, p += sizeof(ElfW(Phdr))) {
ElfW(Phdr)* phdr = (ElfW(Phdr)*)p;
// skip everything but notes
if (phdr->p_type != PT_NOTE) {
continue;
}
// note segment starts at base address + segment virtual address
uintptr_t pos = (base_addr + phdr->p_vaddr);
uintptr_t end = (pos + phdr->p_memsz);
// iterate through segment until we reach the end
while (pos < end) {
if (pos + sizeof(ElfW(Nhdr)) > end) {
break; // invalid
}
ElfW(Nhdr)* note = (ElfW(Nhdr)*)(uintptr_t)pos;
if (note->n_namesz != 0 && note->n_descsz != 0 && strncmp((char*)(pos + sizeof(ElfW(Nhdr))), (char*)name, sizeof(name)) == 0) {
*size = note->n_descsz;
// advance past note header and aligned name
// to get to description data
return (void*)((uintptr_t)note + sizeof(ElfW(Nhdr)) + roundup(note->n_namesz, 4));
}
pos += (sizeof(ElfW(Nhdr)) + roundup(note->n_namesz, 4) + roundup(note->n_descsz, 4));
}
}
return NULL;
#elif defined(_WIN32)
void* ptr = NULL;
char* resource_name = NULL;
if (options != NULL && options->pe_resource_name != NULL) {
name = options->pe_resource_name;
} else {
// Automatically uppercase the resource name or it won't be found
resource_name = (char*)malloc(strlen(name) + 1);
if (resource_name == NULL) {
return NULL;
}
strcpy_s(resource_name, strlen(name) + 1, name);
CharUpperA(resource_name); // Uppercases inplace
}
HRSRC resource_handle = FindResourceA(NULL, resource_name != NULL ? resource_name : name,
MAKEINTRESOURCEA(10) /* RT_RCDATA */);
if (resource_handle) {
HGLOBAL global_resource_handle = LoadResource(NULL, resource_handle);
if (global_resource_handle) {
if (size != NULL) {
*size = SizeofResource(NULL, resource_handle);
}
ptr = LockResource(global_resource_handle);
}
}
free(resource_name);
return ptr;
#else
return NULL;
#endif
}

View File

@@ -89,6 +89,8 @@ fn invalidTarget(diag: *clap.Diagnostic, _target: []const u8) noreturn {
diag.report(Output.errorWriter(), error.InvalidTarget) catch {};
std.process.exit(1);
}
extern "C" fn postject_find_resource(name: [*:0]const u8, size: *usize) ?[*:0]const u8;
pub const Arguments = struct {
pub fn loader_resolver(in: string) !Api.Loader {
const option_loader = options.Loader.fromString(in) orelse return error.InvalidLoader;
@@ -206,6 +208,7 @@ pub const Arguments = struct {
clap.parseParam("--asset-naming <STR> Customize asset filenames. Defaults to \"[name]-[hash].[ext]\"") catch unreachable,
clap.parseParam("--server-components Enable React Server Components (experimental)") catch unreachable,
clap.parseParam("--transpile Transpile file only, do not bundle") catch unreachable,
clap.parseParam("--compile Generate a standalone Bun executable containing your bundled code") catch unreachable,
};
// TODO: update test completions
@@ -663,6 +666,9 @@ pub const Arguments = struct {
switch (comptime cmd) {
.BuildCommand => {
if (args.flag("--compile")) {
ctx.bundler_options.compile = true;
}
// if (args.option("--resolve")) |_resolve| {
// switch (ResolveMatcher.match(_resolve)) {
// ResolveMatcher.case("disable") => {
@@ -953,6 +959,8 @@ pub const Command = struct {
minify_syntax: bool = false,
minify_whitespace: bool = false,
minify_identifiers: bool = false,
compile: bool = false,
};
const _ctx = Command.Context{

View File

@@ -53,6 +53,8 @@ pub const BuildCommand = struct {
Global.exit(1);
return;
}
var outfile = ctx.bundler_options.outfile;
this_bundler.options.entry_naming = ctx.bundler_options.entry_naming;
this_bundler.options.chunk_naming = ctx.bundler_options.chunk_naming;
this_bundler.options.asset_naming = ctx.bundler_options.asset_naming;
@@ -75,7 +77,38 @@ pub const BuildCommand = struct {
this_bundler.options.minify_identifiers = ctx.bundler_options.minify_identifiers;
this_bundler.resolver.opts.minify_identifiers = ctx.bundler_options.minify_identifiers;
if (this_bundler.options.entry_points.len > 1 and ctx.bundler_options.outdir.len == 0) {
if (ctx.bundler_options.compile) {
if (ctx.bundler_options.code_splitting) {
Output.prettyErrorln("<r><red>error<r><d>:<r> cannot use --compile with --code-splitting", .{});
Global.exit(1);
return;
}
if (this_bundler.options.entry_points.len > 1) {
Output.prettyErrorln("<r><red>error<r><d>:<r> multiple entry points are not supported with --compile", .{});
Global.exit(1);
return;
}
if (ctx.bundler_options.outdir.len > 0) {
Output.prettyErrorln("<r><red>error<r><d>:<r> cannot use --compile with --outdir", .{});
Global.exit(1);
return;
}
if (outfile.len == 0) {
outfile = std.fs.path.basename(this_bundler.options.entry_points[0]);
while (strings.eqlComptime(outfile, "index")) {
outfile = std.fs.path.basename(std.fs.path.dirname(this_bundler.options.entry_points[0]) orelse break);
}
}
if (ctx.bundler_options.transform_only) {
Output.prettyErrorln("<r><red>error<r><d>:<r> --compile does not support --transform", .{});
Global.exit(1);
return;
}
} else if (this_bundler.options.entry_points.len > 1 and ctx.bundler_options.outdir.len == 0) {
Output.prettyErrorln("error: to use multiple entry points, specify --outdir", .{});
Global.exit(1);
return;
@@ -201,16 +234,18 @@ pub const BuildCommand = struct {
defer Output.flush();
var writer = Output.writer();
var output_dir = this_bundler.options.output_dir;
if (ctx.bundler_options.outfile.len > 0 and output_files.len == 1 and output_files[0].value == .buffer) {
output_dir = std.fs.path.dirname(ctx.bundler_options.outfile) orelse ".";
output_files[0].path = std.fs.path.basename(ctx.bundler_options.outfile);
if (outfile.len > 0 and output_files.len == 1 and output_files[0].value == .buffer) {
output_dir = std.fs.path.dirname(outfile) orelse ".";
output_files[0].path = std.fs.path.basename(outfile);
}
if (ctx.bundler_options.outfile.len == 0 and output_files.len == 1 and ctx.bundler_options.outdir.len == 0) {
// if --transpile is passed, it won't have an output dir
if (output_files[0].value == .buffer)
try writer.writeAll(output_files[0].value.buffer.bytes);
break :dump;
if (!ctx.bundler_options.compile) {
if (outfile.len == 0 and output_files.len == 1 and ctx.bundler_options.outdir.len == 0) {
// if --transpile is passed, it won't have an output dir
if (output_files[0].value == .buffer)
try writer.writeAll(output_files[0].value.buffer.bytes);
break :dump;
}
}
var root_path = output_dir;
@@ -237,6 +272,11 @@ pub const BuildCommand = struct {
);
}
if (ctx.bundler_options.compile) {
// try bun.StandaloneModuleGraph.toExecutable(allocator, output_files, root_dir, ctx.bundler_options.outfile);
break :dump;
}
// On posix, file handles automatically close on process exit by the OS
// Closing files shows up in profiling.
// So don't do that unless we actually need to.
@@ -268,6 +308,7 @@ pub const BuildCommand = struct {
}
}
}
try root_dir.dir.writeFile(rel_path, value.bytes);
},
.move => |value| {

1
src/deps/LIEF vendored Submodule

Submodule src/deps/LIEF added at 23223aaefa

1
src/deps/zstd Submodule

Submodule src/deps/zstd added at 63779c7982

227
src/deps/zstd.zig Normal file
View File

@@ -0,0 +1,227 @@
pub extern fn ZSTD_versionNumber() c_uint;
pub extern fn ZSTD_versionString() [*c]const u8;
pub extern fn ZSTD_compress(dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, srcSize: usize, compressionLevel: c_int) usize;
pub extern fn ZSTD_decompress(dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, compressedSize: usize) usize;
pub extern fn ZSTD_getFrameContentSize(src: ?*const anyopaque, srcSize: usize) c_ulonglong;
pub extern fn ZSTD_getDecompressedSize(src: ?*const anyopaque, srcSize: usize) c_ulonglong;
pub extern fn ZSTD_findFrameCompressedSize(src: ?*const anyopaque, srcSize: usize) usize;
pub extern fn ZSTD_compressBound(srcSize: usize) usize;
pub extern fn ZSTD_isError(code: usize) c_uint;
pub extern fn ZSTD_getErrorName(code: usize) [*:0]const u8;
pub extern fn ZSTD_minCLevel() c_int;
pub extern fn ZSTD_maxCLevel() c_int;
pub extern fn ZSTD_defaultCLevel() c_int;
pub const struct_ZSTD_CCtx_s = opaque {};
pub const ZSTD_CCtx = struct_ZSTD_CCtx_s;
pub extern fn ZSTD_createCCtx() ?*ZSTD_CCtx;
pub extern fn ZSTD_freeCCtx(cctx: ?*ZSTD_CCtx) usize;
pub extern fn ZSTD_compressCCtx(cctx: ?*ZSTD_CCtx, dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, srcSize: usize, compressionLevel: c_int) usize;
pub const struct_ZSTD_DCtx_s = opaque {};
pub const ZSTD_DCtx = struct_ZSTD_DCtx_s;
pub extern fn ZSTD_createDCtx() ?*ZSTD_DCtx;
pub extern fn ZSTD_freeDCtx(dctx: ?*ZSTD_DCtx) usize;
pub extern fn ZSTD_decompressDCtx(dctx: ?*ZSTD_DCtx, dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, srcSize: usize) usize;
pub const ZSTD_fast: c_int = 1;
pub const ZSTD_dfast: c_int = 2;
pub const ZSTD_greedy: c_int = 3;
pub const ZSTD_lazy: c_int = 4;
pub const ZSTD_lazy2: c_int = 5;
pub const ZSTD_btlazy2: c_int = 6;
pub const ZSTD_btopt: c_int = 7;
pub const ZSTD_btultra: c_int = 8;
pub const ZSTD_btultra2: c_int = 9;
pub const ZSTD_strategy = c_uint;
pub const ZSTD_c_compressionLevel: c_int = 100;
pub const ZSTD_c_windowLog: c_int = 101;
pub const ZSTD_c_hashLog: c_int = 102;
pub const ZSTD_c_chainLog: c_int = 103;
pub const ZSTD_c_searchLog: c_int = 104;
pub const ZSTD_c_minMatch: c_int = 105;
pub const ZSTD_c_targetLength: c_int = 106;
pub const ZSTD_c_strategy: c_int = 107;
pub const ZSTD_c_enableLongDistanceMatching: c_int = 160;
pub const ZSTD_c_ldmHashLog: c_int = 161;
pub const ZSTD_c_ldmMinMatch: c_int = 162;
pub const ZSTD_c_ldmBucketSizeLog: c_int = 163;
pub const ZSTD_c_ldmHashRateLog: c_int = 164;
pub const ZSTD_c_contentSizeFlag: c_int = 200;
pub const ZSTD_c_checksumFlag: c_int = 201;
pub const ZSTD_c_dictIDFlag: c_int = 202;
pub const ZSTD_c_nbWorkers: c_int = 400;
pub const ZSTD_c_jobSize: c_int = 401;
pub const ZSTD_c_overlapLog: c_int = 402;
pub const ZSTD_c_experimentalParam1: c_int = 500;
pub const ZSTD_c_experimentalParam2: c_int = 10;
pub const ZSTD_c_experimentalParam3: c_int = 1000;
pub const ZSTD_c_experimentalParam4: c_int = 1001;
pub const ZSTD_c_experimentalParam5: c_int = 1002;
pub const ZSTD_c_experimentalParam6: c_int = 1003;
pub const ZSTD_c_experimentalParam7: c_int = 1004;
pub const ZSTD_c_experimentalParam8: c_int = 1005;
pub const ZSTD_c_experimentalParam9: c_int = 1006;
pub const ZSTD_c_experimentalParam10: c_int = 1007;
pub const ZSTD_c_experimentalParam11: c_int = 1008;
pub const ZSTD_c_experimentalParam12: c_int = 1009;
pub const ZSTD_c_experimentalParam13: c_int = 1010;
pub const ZSTD_c_experimentalParam14: c_int = 1011;
pub const ZSTD_c_experimentalParam15: c_int = 1012;
pub const ZSTD_c_experimentalParam16: c_int = 1013;
pub const ZSTD_c_experimentalParam17: c_int = 1014;
pub const ZSTD_c_experimentalParam18: c_int = 1015;
pub const ZSTD_c_experimentalParam19: c_int = 1016;
pub const ZSTD_cParameter = c_uint;
pub const ZSTD_bounds = extern struct {
@"error": usize,
lowerBound: c_int,
upperBound: c_int,
};
pub extern fn ZSTD_cParam_getBounds(cParam: ZSTD_cParameter) ZSTD_bounds;
pub extern fn ZSTD_CCtx_setParameter(cctx: ?*ZSTD_CCtx, param: ZSTD_cParameter, value: c_int) usize;
pub extern fn ZSTD_CCtx_setPledgedSrcSize(cctx: ?*ZSTD_CCtx, pledgedSrcSize: c_ulonglong) usize;
pub const ZSTD_reset_session_only: c_int = 1;
pub const ZSTD_reset_parameters: c_int = 2;
pub const ZSTD_reset_session_and_parameters: c_int = 3;
pub const ZSTD_ResetDirective = c_uint;
pub extern fn ZSTD_CCtx_reset(cctx: ?*ZSTD_CCtx, reset: ZSTD_ResetDirective) usize;
pub extern fn ZSTD_compress2(cctx: ?*ZSTD_CCtx, dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, srcSize: usize) usize;
pub const ZSTD_d_windowLogMax: c_int = 100;
pub const ZSTD_d_experimentalParam1: c_int = 1000;
pub const ZSTD_d_experimentalParam2: c_int = 1001;
pub const ZSTD_d_experimentalParam3: c_int = 1002;
pub const ZSTD_d_experimentalParam4: c_int = 1003;
pub const ZSTD_d_experimentalParam5: c_int = 1004;
pub const ZSTD_dParameter = c_uint;
pub extern fn ZSTD_dParam_getBounds(dParam: ZSTD_dParameter) ZSTD_bounds;
pub extern fn ZSTD_DCtx_setParameter(dctx: ?*ZSTD_DCtx, param: ZSTD_dParameter, value: c_int) usize;
pub extern fn ZSTD_DCtx_reset(dctx: ?*ZSTD_DCtx, reset: ZSTD_ResetDirective) usize;
pub const struct_ZSTD_inBuffer_s = extern struct {
src: ?*const anyopaque,
size: usize,
pos: usize,
};
pub const ZSTD_inBuffer = struct_ZSTD_inBuffer_s;
pub const struct_ZSTD_outBuffer_s = extern struct {
dst: ?*anyopaque,
size: usize,
pos: usize,
};
pub const ZSTD_outBuffer = struct_ZSTD_outBuffer_s;
pub const ZSTD_CStream = ZSTD_CCtx;
pub extern fn ZSTD_createCStream() ?*ZSTD_CStream;
pub extern fn ZSTD_freeCStream(zcs: ?*ZSTD_CStream) usize;
pub const ZSTD_e_continue: c_int = 0;
pub const ZSTD_e_flush: c_int = 1;
pub const ZSTD_e_end: c_int = 2;
pub const ZSTD_EndDirective = c_uint;
pub extern fn ZSTD_compressStream2(cctx: ?*ZSTD_CCtx, output: [*c]ZSTD_outBuffer, input: [*c]ZSTD_inBuffer, endOp: ZSTD_EndDirective) usize;
pub extern fn ZSTD_CStreamInSize() usize;
pub extern fn ZSTD_CStreamOutSize() usize;
pub extern fn ZSTD_initCStream(zcs: ?*ZSTD_CStream, compressionLevel: c_int) usize;
pub extern fn ZSTD_compressStream(zcs: ?*ZSTD_CStream, output: [*c]ZSTD_outBuffer, input: [*c]ZSTD_inBuffer) usize;
pub extern fn ZSTD_flushStream(zcs: ?*ZSTD_CStream, output: [*c]ZSTD_outBuffer) usize;
pub extern fn ZSTD_endStream(zcs: ?*ZSTD_CStream, output: [*c]ZSTD_outBuffer) usize;
pub const ZSTD_DStream = ZSTD_DCtx;
pub extern fn ZSTD_createDStream() ?*ZSTD_DStream;
pub extern fn ZSTD_freeDStream(zds: ?*ZSTD_DStream) usize;
pub extern fn ZSTD_initDStream(zds: ?*ZSTD_DStream) usize;
pub extern fn ZSTD_decompressStream(zds: ?*ZSTD_DStream, output: [*c]ZSTD_outBuffer, input: [*c]ZSTD_inBuffer) usize;
pub extern fn ZSTD_DStreamInSize() usize;
pub extern fn ZSTD_DStreamOutSize() usize;
pub extern fn ZSTD_compress_usingDict(ctx: ?*ZSTD_CCtx, dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, srcSize: usize, dict: ?*const anyopaque, dictSize: usize, compressionLevel: c_int) usize;
pub extern fn ZSTD_decompress_usingDict(dctx: ?*ZSTD_DCtx, dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, srcSize: usize, dict: ?*const anyopaque, dictSize: usize) usize;
pub const struct_ZSTD_CDict_s = opaque {};
pub const ZSTD_CDict = struct_ZSTD_CDict_s;
pub extern fn ZSTD_createCDict(dictBuffer: ?*const anyopaque, dictSize: usize, compressionLevel: c_int) ?*ZSTD_CDict;
pub extern fn ZSTD_freeCDict(CDict: ?*ZSTD_CDict) usize;
pub extern fn ZSTD_compress_usingCDict(cctx: ?*ZSTD_CCtx, dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, srcSize: usize, cdict: ?*const ZSTD_CDict) usize;
pub const struct_ZSTD_DDict_s = opaque {};
pub const ZSTD_DDict = struct_ZSTD_DDict_s;
pub extern fn ZSTD_createDDict(dictBuffer: ?*const anyopaque, dictSize: usize) ?*ZSTD_DDict;
pub extern fn ZSTD_freeDDict(ddict: ?*ZSTD_DDict) usize;
pub extern fn ZSTD_decompress_usingDDict(dctx: ?*ZSTD_DCtx, dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, srcSize: usize, ddict: ?*const ZSTD_DDict) usize;
pub extern fn ZSTD_getDictID_fromDict(dict: ?*const anyopaque, dictSize: usize) c_uint;
pub extern fn ZSTD_getDictID_fromCDict(cdict: ?*const ZSTD_CDict) c_uint;
pub extern fn ZSTD_getDictID_fromDDict(ddict: ?*const ZSTD_DDict) c_uint;
pub extern fn ZSTD_getDictID_fromFrame(src: ?*const anyopaque, srcSize: usize) c_uint;
pub extern fn ZSTD_CCtx_loadDictionary(cctx: ?*ZSTD_CCtx, dict: ?*const anyopaque, dictSize: usize) usize;
pub extern fn ZSTD_CCtx_refCDict(cctx: ?*ZSTD_CCtx, cdict: ?*const ZSTD_CDict) usize;
pub extern fn ZSTD_CCtx_refPrefix(cctx: ?*ZSTD_CCtx, prefix: ?*const anyopaque, prefixSize: usize) usize;
pub extern fn ZSTD_DCtx_loadDictionary(dctx: ?*ZSTD_DCtx, dict: ?*const anyopaque, dictSize: usize) usize;
pub extern fn ZSTD_DCtx_refDDict(dctx: ?*ZSTD_DCtx, ddict: ?*const ZSTD_DDict) usize;
pub extern fn ZSTD_DCtx_refPrefix(dctx: ?*ZSTD_DCtx, prefix: ?*const anyopaque, prefixSize: usize) usize;
pub extern fn ZSTD_sizeof_CCtx(cctx: ?*const ZSTD_CCtx) usize;
pub extern fn ZSTD_sizeof_DCtx(dctx: ?*const ZSTD_DCtx) usize;
pub extern fn ZSTD_sizeof_CStream(zcs: ?*const ZSTD_CStream) usize;
pub extern fn ZSTD_sizeof_DStream(zds: ?*const ZSTD_DStream) usize;
pub extern fn ZSTD_sizeof_CDict(cdict: ?*const ZSTD_CDict) usize;
pub extern fn ZSTD_sizeof_DDict(ddict: ?*const ZSTD_DDict) usize;
pub const ZSTD_VERSION_MAJOR = @as(c_int, 1);
pub const ZSTD_VERSION_MINOR = @as(c_int, 5);
pub const ZSTD_VERSION_RELEASE = @as(c_int, 5);
pub const ZSTD_VERSION_NUMBER = (((ZSTD_VERSION_MAJOR * @as(c_int, 100)) * @as(c_int, 100)) + (ZSTD_VERSION_MINOR * @as(c_int, 100))) + ZSTD_VERSION_RELEASE;
pub const ZSTD_LIB_VERSION = ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE;
pub const ZSTD_CLEVEL_DEFAULT = @as(c_int, 3);
pub const ZSTD_MAGICNUMBER = @import("std").zig.c_translation.promoteIntLiteral(c_int, 0xFD2FB528, .hexadecimal);
pub const ZSTD_MAGIC_DICTIONARY = @import("std").zig.c_translation.promoteIntLiteral(c_int, 0xEC30A437, .hexadecimal);
pub const ZSTD_MAGIC_SKIPPABLE_START = @import("std").zig.c_translation.promoteIntLiteral(c_int, 0x184D2A50, .hexadecimal);
pub const ZSTD_MAGIC_SKIPPABLE_MASK = @import("std").zig.c_translation.promoteIntLiteral(c_int, 0xFFFFFFF0, .hexadecimal);
pub const ZSTD_BLOCKSIZELOG_MAX = @as(c_int, 17);
pub const ZSTD_BLOCKSIZE_MAX = @as(c_int, 1) << ZSTD_BLOCKSIZELOG_MAX;
pub const ZSTD_CONTENTSIZE_UNKNOWN = @as(c_ulonglong, 0) - @as(c_int, 1);
pub const ZSTD_CONTENTSIZE_ERROR = @as(c_ulonglong, 0) - @as(c_int, 2);
pub const ZSTD_MAX_INPUT_SIZE = if (@import("std").zig.c_translation.sizeof(usize) == @as(c_int, 8)) @as(c_ulonglong, 0xFF00FF00FF00FF00) else @import("std").zig.c_translation.promoteIntLiteral(c_uint, 0xFF00FF00, .hexadecimal);
pub inline fn ZSTD_COMPRESSBOUND(srcSize: anytype) @TypeOf(if (@import("std").zig.c_translation.cast(usize, srcSize) >= ZSTD_MAX_INPUT_SIZE) @as(c_int, 0) else (srcSize + (srcSize >> @as(c_int, 8))) + (if (srcSize < (@as(c_int, 128) << @as(c_int, 10))) ((@as(c_int, 128) << @as(c_int, 10)) - srcSize) >> @as(c_int, 11) else @as(c_int, 0))) {
return if (@import("std").zig.c_translation.cast(usize, srcSize) >= ZSTD_MAX_INPUT_SIZE) @as(c_int, 0) else (srcSize + (srcSize >> @as(c_int, 8))) + (if (srcSize < (@as(c_int, 128) << @as(c_int, 10))) ((@as(c_int, 128) << @as(c_int, 10)) - srcSize) >> @as(c_int, 11) else @as(c_int, 0));
}
pub const ZSTD_CCtx_s = struct_ZSTD_CCtx_s;
pub const ZSTD_DCtx_s = struct_ZSTD_DCtx_s;
pub const ZSTD_inBuffer_s = struct_ZSTD_inBuffer_s;
pub const ZSTD_outBuffer_s = struct_ZSTD_outBuffer_s;
pub const ZSTD_CDict_s = struct_ZSTD_CDict_s;
pub const ZSTD_DDict_s = struct_ZSTD_DDict_s;
// -----------------------------------
/// ZSTD_compress() :
/// Compresses `src` content as a single zstd compressed frame into already allocated `dst`.
/// NOTE: Providing `dstCapacity >= ZSTD_compressBound(srcSize)` guarantees that zstd will have
/// enough space to successfully compress the data.
/// @return : compressed size written into `dst` (<= `dstCapacity),
/// or an error code if it fails (which can be tested using ZSTD_isError()). */
// ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,
// const void* src, size_t srcSize,
// int compressionLevel);
pub fn compress(dest: []u8, src: []const u8, level: ?i32) Result {
const result = ZSTD_compress(dest.ptr, dest.len, src.ptr, src.len, level orelse ZSTD_defaultCLevel());
if (ZSTD_isError(result)) return .{ .err = bun.sliceTo(ZSTD_getErrorName(result), 0) };
return .{ .success = result };
}
pub fn compressBound(srcSize: usize) usize {
return ZSTD_compressBound(srcSize);
}
/// ZSTD_decompress() :
/// `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames.
/// `dstCapacity` is an upper bound of originalSize to regenerate.
/// If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data.
/// @return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
/// or an errorCode if it fails (which can be tested using ZSTD_isError()). */
// ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
// const void* src, size_t compressedSize);
pub fn decompress(dest: []u8, src: []const u8) Result {
const result = ZSTD_decompress(dest.ptr, dest.len, src.ptr, src.len);
if (ZSTD_isError(result)) return .{ .err = bun.sliceTo(ZSTD_getErrorName(result), 0) };
return .{ .success = result };
}
pub fn getDecompressedSize(src: []const u8) usize {
return ZSTD_getDecompressedSize(src.ptr, src.len);
}
pub const Result = union(enum) {
success: usize,
err: [:0]const u8,
};
const bun = @import("root").bun;