Commit 18fabd99cc

Andrew Kelley <andrew@ziglang.org>
2022-01-19 19:43:40
Merge pull request #10475 from lithdew/master
lld: allow for entrypoint symbol name to be set
1 parent afd1f7e
lib/std/build.zig
@@ -1552,6 +1552,8 @@ pub const LibExeObjStep = struct {
 
     subsystem: ?std.Target.SubSystem = null,
 
+    entry_symbol_name: ?[]const u8 = null,
+
     /// Overrides the default stack size
     stack_size: ?u64 = null,
 
@@ -2253,6 +2255,11 @@ pub const LibExeObjStep = struct {
             try zig_args.append(@tagName(builder.color));
         }
 
+        if (self.entry_symbol_name) |entry| {
+            try zig_args.append("--entry");
+            try zig_args.append(entry);
+        }
+
         if (self.stack_size) |stack_size| {
             try zig_args.append("--stack");
             try zig_args.append(try std.fmt.allocPrint(builder.allocator, "{}", .{stack_size}));
src/link/Coff.zig
@@ -925,6 +925,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
             _ = try man.addFile(key.status.success.object_path, null);
         }
         try man.addOptionalFile(module_obj_path);
+        man.hash.addOptionalBytes(self.base.options.entry);
         man.hash.addOptional(self.base.options.stack_size_override);
         man.hash.addOptional(self.base.options.image_base_override);
         man.hash.addListOfBytes(self.base.options.lib_dirs);
@@ -1045,6 +1046,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
             try argv.append("-DLL");
         }
 
+        if (self.base.options.entry) |entry| {
+            try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{entry}));
+        }
+
         if (self.base.options.tsaware) {
             try argv.append("-tsaware");
         }
src/link/Elf.zig
@@ -1316,6 +1316,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
 
         // We can skip hashing libc and libc++ components that we are in charge of building from Zig
         // installation sources because they are always a product of the compiler version + target information.
+        man.hash.addOptionalBytes(self.base.options.entry);
         man.hash.add(stack_size);
         man.hash.addOptional(self.base.options.image_base_override);
         man.hash.add(gc_sections);
@@ -1438,6 +1439,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
             self.base.options.linker_optimization,
         }));
 
+        if (self.base.options.entry) |entry| {
+            try argv.append("--entry");
+            try argv.append(entry);
+        }
+
         if (self.base.options.output_mode == .Exe) {
             try argv.append("-z");
             try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size}));
@@ -2786,7 +2792,8 @@ pub fn updateDeclExports(
         const stb_bits: u8 = switch (exp.options.linkage) {
             .Internal => elf.STB_LOCAL,
             .Strong => blk: {
-                if (mem.eql(u8, exp.options.name, "_start")) {
+                const entry_name = self.base.options.entry orelse "_start";
+                if (mem.eql(u8, exp.options.name, entry_name)) {
                     self.entry_addr = decl_sym.st_value;
                 }
                 break :blk elf.STB_GLOBAL;
src/link/Wasm.zig
@@ -1018,6 +1018,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
         }
         try man.addOptionalFile(module_obj_path);
         try man.addOptionalFile(compiler_rt_path);
+        man.hash.addOptionalBytes(self.base.options.entry);
         man.hash.addOptional(self.base.options.stack_size_override);
         man.hash.add(self.base.options.import_memory);
         man.hash.addOptional(self.base.options.initial_memory);
@@ -1165,6 +1166,11 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
             }
         }
 
+        if (self.base.options.entry) |entry| {
+            try argv.append("--entry");
+            try argv.append(entry);
+        }
+
         if (self.base.options.output_mode == .Exe) {
             // Increase the default stack size to a more reasonable value of 1MB instead of
             // the default of 1 Wasm page being 64KB, unless overridden by the user.
src/clang_options_data.zig
@@ -1655,7 +1655,7 @@ flagpsl("MT"),
 .{
     .name = "entry",
     .syntax = .flag,
-    .zig_equivalent = .other,
+    .zig_equivalent = .entry,
     .pd1 = false,
     .pd2 = true,
     .psl = false,
@@ -6701,7 +6701,14 @@ joinpd1("Z"),
 joinpd1("a"),
 jspd1("b"),
 joinpd1("d"),
-jspd1("e"),
+.{
+    .name = "e",
+    .syntax = .joined_or_separate,
+    .zig_equivalent = .entry,
+    .pd1 = true,
+    .pd2 = false,
+    .psl = false,
+},
 .{
     .name = "l",
     .syntax = .joined_or_separate,
src/Compilation.zig
@@ -765,6 +765,7 @@ pub const InitOptions = struct {
     /// infinite recursion.
     skip_linker_dependencies: bool = false,
     parent_compilation_link_libc: bool = false,
+    entry: ?[]const u8 = null,
     stack_size_override: ?u64 = null,
     image_base_override: ?u64 = null,
     self_exe_path: ?[]const u8 = null,
@@ -1478,6 +1479,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
             .linker_optimization = linker_optimization,
             .major_subsystem_version = options.major_subsystem_version,
             .minor_subsystem_version = options.minor_subsystem_version,
+            .entry = options.entry,
             .stack_size_override = options.stack_size_override,
             .image_base_override = options.image_base_override,
             .include_compiler_rt = include_compiler_rt,
src/link.zig
@@ -68,6 +68,7 @@ pub const Options = struct {
     /// the binary file does not already have such a section.
     program_code_size_hint: u64 = 256 * 1024,
     entry_addr: ?u64 = null,
+    entry: ?[]const u8,
     stack_size_override: ?u64,
     image_base_override: ?u64,
     include_compiler_rt: bool,
src/main.zig
@@ -400,6 +400,7 @@ const usage_build_generic =
     \\  --dynamic-linker [path]        Set the dynamic interpreter path (usually ld.so)
     \\  --sysroot [path]               Set the system root directory (usually /)
     \\  --version [ver]                Dynamic library semver
+    \\  --entry [name]                 Set the entrypoint symbol name
     \\  -fsoname[=name]                Override the default SONAME value
     \\  -fno-soname                    Disable emitting a SONAME
     \\  -fLLD                          Force using LLD as the linker
@@ -643,6 +644,7 @@ fn buildOutputType(
     var linker_optimization: ?u8 = null;
     var test_evented_io = false;
     var test_no_exec = false;
+    var entry: ?[]const u8 = null;
     var stack_size_override: ?u64 = null;
     var image_base_override: ?u64 = null;
     var use_llvm: ?bool = null;
@@ -843,6 +845,10 @@ fn buildOutputType(
                         if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});
                         i += 1;
                         optimize_mode_string = args[i];
+                    } else if (mem.eql(u8, arg, "--entry")) {
+                        if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});
+                        i += 1;
+                        entry = args[i];
                     } else if (mem.eql(u8, arg, "--stack")) {
                         if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});
                         i += 1;
@@ -1471,6 +1477,9 @@ fn buildOutputType(
                     .sysroot => {
                         sysroot = it.only_arg;
                     },
+                    .entry => {
+                        entry = it.only_arg;
+                    },
                 }
             }
             // Parse linker args.
@@ -1612,6 +1621,12 @@ fn buildOutputType(
                         fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
                     };
                     have_version = true;
+                } else if (mem.eql(u8, arg, "-e") or mem.eql(u8, arg, "--entry")) {
+                    i += 1;
+                    if (i >= linker_args.items.len) {
+                        fatal("expected linker arg after '{s}'", .{arg});
+                    }
+                    entry = linker_args.items[i];
                 } else if (mem.eql(u8, arg, "--stack")) {
                     i += 1;
                     if (i >= linker_args.items.len) {
@@ -2477,6 +2492,7 @@ fn buildOutputType(
         .minor_subsystem_version = minor_subsystem_version,
         .link_eh_frame_hdr = link_eh_frame_hdr,
         .link_emit_relocs = link_emit_relocs,
+        .entry = entry,
         .stack_size_override = stack_size_override,
         .image_base_override = image_base_override,
         .strip = strip,
@@ -4119,6 +4135,7 @@ pub const ClangArgIterator = struct {
         exec_model,
         emit_llvm,
         sysroot,
+        entry,
     };
 
     const Args = struct {
tools/update_clang_options.zig
@@ -416,6 +416,14 @@ const known_options = [_]KnownOpt{
         .name = "sysroot",
         .ident = "sysroot",
     },
+    .{
+        .name = "entry",
+        .ident = "entry",
+    },
+    .{
+        .name = "e",
+        .ident = "entry",
+    },
 };
 
 const blacklisted_options = [_][]const u8{};