From 4ddb63e7e2f7bee719aa58befb73be863afd1627 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Fri, 15 Nov 2024 13:02:10 -0800 Subject: [PATCH] Try linker script (#15158) --- cmake/targets/BuildBun.cmake | 20 ++++ cmake/targets/BuildLolHtml.cmake | 12 ++ cmake/tools/SetupLLVM.cmake | 14 ++- src/napi/napi.zig | 187 +++++++++++++++++++++++++------ 4 files changed, 200 insertions(+), 33 deletions(-) diff --git a/cmake/targets/BuildBun.cmake b/cmake/targets/BuildBun.cmake index ec513d84aa..d3e8e5d6b1 100644 --- a/cmake/targets/BuildBun.cmake +++ b/cmake/targets/BuildBun.cmake @@ -850,6 +850,8 @@ elseif(APPLE) target_link_options(${bun} PUBLIC -dead_strip -dead_strip_dylibs + -Wl,-ld_new + -Wl,-no_compact_unwind -Wl,-stack_size,0x1200000 -fno-keep-static-consts -Wl,-map,${bun}.linker-map @@ -947,6 +949,11 @@ else() -Wl,--compress-debug-sections=zlib -Wl,-z,lazy -Wl,-z,norelro + -Wl,-z,combreloc + -Wl,--no-eh-frame-hdr + -Wl,--sort-section=name + -Wl,--hash-style=gnu + -Wl,--build-id=sha1 # Better for debugging than default -Wl,-Map=${bun}.linker-map ) endif() @@ -1087,6 +1094,18 @@ endif() # --- Packaging --- if(NOT BUN_CPP_ONLY) + set(CMAKE_STRIP_FLAGS "") + if (APPLE) + # We do not build with exceptions enabled. These are generated by lolhtml + # and other dependencies. We build lolhtml with abort on panic, so it + # shouldn't be including these in the first place. + set(CMAKE_STRIP_FLAGS --remove-section=__TEXT,__eh_frame --remove-section=__TEXT,__unwind_info --remove-section=__TEXT,__gcc_except_tab) + elseif(LINUX) + # When you use llvm-strip to do this, it doesn't delete it from the binary and instead keeps it as [LOAD #2 [R]] + # So, we must use GNU strip to do this. + set(CMAKE_STRIP_FLAGS -R .eh_frame -R .gcc_except_table) + endif() + if(bunStrip) register_command( TARGET @@ -1098,6 +1117,7 @@ if(NOT BUN_CPP_ONLY) COMMAND ${CMAKE_STRIP} ${bunExe} + ${CMAKE_STRIP_FLAGS} --strip-all --strip-debug --discard-all diff --git a/cmake/targets/BuildLolHtml.cmake b/cmake/targets/BuildLolHtml.cmake index 9a02362723..aeac571321 100644 --- a/cmake/targets/BuildLolHtml.cmake +++ b/cmake/targets/BuildLolHtml.cmake @@ -26,6 +26,13 @@ if(RELEASE) list(APPEND LOLHTML_BUILD_ARGS --release) endif() +# Windows requires unwind tables, apparently. +if (NOT WIN32) + # The encoded escape sequences are intentional. They're how you delimit multiple arguments in a single environment variable. + # Also add rust optimization flag for smaller binary size, but not huge speed penalty. + set(RUSTFLAGS "-Cpanic=abort-Cdebuginfo=0-Cforce-unwind-tables=no-Copt-level=s") +endif() + register_command( TARGET lolhtml @@ -37,6 +44,11 @@ register_command( ${LOLHTML_BUILD_ARGS} ARTIFACTS ${LOLHTML_LIBRARY} + ENVIRONMENT + CARGO_TERM_COLOR=always + CARGO_TERM_VERBOSE=true + CARGO_TERM_DIAGNOSTIC=true + CARGO_ENCODED_RUSTFLAGS=${RUSTFLAGS} ) target_link_libraries(${bun} PRIVATE ${LOLHTML_LIBRARY}) diff --git a/cmake/tools/SetupLLVM.cmake b/cmake/tools/SetupLLVM.cmake index a7046d996f..fb99eff639 100644 --- a/cmake/tools/SetupLLVM.cmake +++ b/cmake/tools/SetupLLVM.cmake @@ -108,7 +108,19 @@ else() find_llvm_command(CMAKE_CXX_COMPILER clang++) find_llvm_command(CMAKE_LINKER llvm-link) find_llvm_command(CMAKE_AR llvm-ar) - find_llvm_command(CMAKE_STRIP llvm-strip) + if (LINUX) + # On Linux, strip ends up being more useful for us. + find_command( + VARIABLE + CMAKE_STRIP + COMMAND + strip + REQUIRED + ON + ) + else() + find_llvm_command(CMAKE_STRIP llvm-strip) + endif() find_llvm_command(CMAKE_RANLIB llvm-ranlib) if(APPLE) find_llvm_command(CMAKE_DSYMUTIL dsymutil) diff --git a/src/napi/napi.zig b/src/napi/napi.zig index dae1a96c69..e2b5dd3e57 100644 --- a/src/napi/napi.zig +++ b/src/napi/napi.zig @@ -128,16 +128,7 @@ pub const napi_value = enum(i64) { } }; -pub const struct_napi_escapable_handle_scope__ = opaque {}; - const char16_t = u16; -pub const napi_default: c_int = 0; -pub const napi_writable: c_int = 1; -pub const napi_enumerable: c_int = 2; -pub const napi_configurable: c_int = 4; -pub const napi_static: c_int = 1024; -pub const napi_default_method: c_int = 5; -pub const napi_default_jsproperty: c_int = 7; pub const napi_property_attributes = c_uint; pub const napi_valuetype = enum(c_uint) { undefined = 0, @@ -245,20 +236,11 @@ pub const napi_extended_error_info = extern struct { engine_error_code: u32, error_code: napi_status, }; -pub const napi_key_include_prototypes: c_int = 0; -pub const napi_key_own_only: c_int = 1; -pub const napi_key_collection_mode = c_uint; -pub const napi_key_all_properties: c_int = 0; -pub const napi_key_writable: c_int = 1; -pub const napi_key_enumerable: c_int = 2; -pub const napi_key_configurable: c_int = 4; -pub const napi_key_skip_strings: c_int = 8; -pub const napi_key_skip_symbols: c_int = 16; -pub const napi_key_filter = c_uint; -pub const napi_key_keep_numbers: c_int = 0; -pub const napi_key_numbers_to_strings: c_int = 1; -pub const napi_key_conversion = c_uint; -pub const napi_type_tag = extern struct { + +const napi_key_collection_mode = c_uint; +const napi_key_filter = c_uint; +const napi_key_conversion = c_uint; +const napi_type_tag = extern struct { lower: u64, upper: u64, }; @@ -1736,11 +1718,9 @@ pub export fn napi_remove_async_cleanup_hook(_: napi_async_cleanup_hook_handle) return .ok; } -pub const NAPI_VERSION_EXPERIMENTAL = @import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const NAPI_VERSION = @as(c_int, 8); -pub const NAPI_AUTO_LENGTH = std.math.maxInt(usize); -pub const SRC_NODE_API_TYPES_H_ = ""; -pub const NAPI_MODULE_VERSION = @as(c_int, 1); +const NAPI_VERSION = @as(c_int, 8); +const NAPI_AUTO_LENGTH = std.math.maxInt(usize); +const NAPI_MODULE_VERSION = @as(c_int, 1); /// v8:: C++ symbols defined in v8.cpp /// @@ -1885,13 +1865,156 @@ const V8API = if (!bun.Environment.isWindows) struct { pub extern fn @"?IsFunction@Value@v8@@QEBA_NXZ"() *anyopaque; }; +// To update this list, use find + multi-cursor in your editor. +// - pub extern fn napi_ +// - pub export fn napi_ +const napi_functions_to_export = .{ + napi_acquire_threadsafe_function, + napi_add_async_cleanup_hook, + napi_add_env_cleanup_hook, + napi_add_finalizer, + napi_adjust_external_memory, + napi_async_destroy, + napi_async_init, + napi_call_function, + napi_call_threadsafe_function, + napi_cancel_async_work, + napi_check_object_type_tag, + napi_close_callback_scope, + napi_close_escapable_handle_scope, + napi_close_handle_scope, + napi_coerce_to_bool, + napi_coerce_to_number, + napi_coerce_to_object, + napi_create_array, + napi_create_array_with_length, + napi_create_arraybuffer, + napi_create_async_work, + napi_create_bigint_int64, + napi_create_bigint_uint64, + napi_create_bigint_words, + napi_create_buffer, + napi_create_buffer_copy, + napi_create_dataview, + napi_create_date, + napi_create_double, + napi_create_error, + napi_create_external, + napi_create_external_arraybuffer, + napi_create_external_buffer, + napi_create_int32, + napi_create_int64, + napi_create_object, + napi_create_promise, + napi_create_range_error, + napi_create_reference, + napi_create_string_latin1, + napi_create_string_utf16, + napi_create_string_utf8, + napi_create_symbol, + napi_create_threadsafe_function, + napi_create_type_error, + napi_create_typedarray, + napi_create_uint32, + napi_define_class, + napi_define_properties, + napi_delete_async_work, + napi_delete_element, + napi_delete_reference, + napi_detach_arraybuffer, + napi_escape_handle, + napi_fatal_error, + napi_fatal_exception, + napi_get_all_property_names, + napi_get_and_clear_last_exception, + napi_get_array_length, + napi_get_arraybuffer_info, + napi_get_boolean, + napi_get_buffer_info, + napi_get_cb_info, + napi_get_dataview_info, + napi_get_date_value, + napi_get_element, + napi_get_global, + napi_get_instance_data, + napi_get_last_error_info, + napi_get_new_target, + napi_get_node_version, + napi_get_null, + napi_get_prototype, + napi_get_reference_value, + napi_get_reference_value_internal, + napi_get_threadsafe_function_context, + napi_get_typedarray_info, + napi_get_undefined, + napi_get_uv_event_loop, + napi_get_value_bigint_int64, + napi_get_value_bigint_uint64, + napi_get_value_bigint_words, + napi_get_value_bool, + napi_get_value_double, + napi_get_value_external, + napi_get_value_int32, + napi_get_value_int64, + napi_get_value_string_latin1, + napi_get_value_string_utf16, + napi_get_value_string_utf8, + napi_get_value_uint32, + napi_get_version, + napi_has_element, + napi_instanceof, + napi_is_array, + napi_is_arraybuffer, + napi_is_buffer, + napi_is_dataview, + napi_is_date, + napi_is_detached_arraybuffer, + napi_is_error, + napi_is_exception_pending, + napi_is_promise, + napi_is_typedarray, + napi_make_callback, + napi_new_instance, + napi_open_callback_scope, + napi_open_escapable_handle_scope, + napi_open_handle_scope, + napi_queue_async_work, + napi_ref_threadsafe_function, + napi_reference_ref, + napi_reference_unref, + napi_reject_deferred, + napi_release_threadsafe_function, + napi_remove_async_cleanup_hook, + napi_remove_env_cleanup_hook, + napi_remove_wrap, + napi_resolve_deferred, + napi_run_script, + napi_set_element, + napi_set_instance_data, + napi_strict_equals, + napi_throw, + napi_throw_error, + napi_throw_range_error, + napi_throw_type_error, + napi_type_tag_object, + napi_typeof, + napi_unref_threadsafe_function, + napi_unwrap, + napi_wrap, + + // -- node-api + node_api_create_syntax_error, + node_api_symbol_for, + node_api_throw_syntax_error, + node_api_create_external_string_latin1, + node_api_create_external_string_utf16, +}; + pub fn fixDeadCodeElimination() void { JSC.markBinding(@src()); - inline for (comptime std.meta.declarations(@This())) |decl| { - if (std.mem.startsWith(u8, decl.name, "node_api_") or std.mem.startsWith(u8, decl.name, "napi_")) { - std.mem.doNotOptimizeAway(&@field(@This(), decl.name)); - } + inline for (napi_functions_to_export) |fn_name| { + std.mem.doNotOptimizeAway(&fn_name); } inline for (comptime std.meta.declarations(V8API)) |decl| {