Commit 592210a173
Changed files (4)
src/link.cpp
@@ -80,14 +80,68 @@ static const char *get_exe_file_extension(CodeGen *g) {
}
}
+static const char *getLDMOption(const ZigTarget *t) {
+ switch (t->arch.arch) {
+ case ZigLLVM_x86:
+ return "elf_i386";
+ case ZigLLVM_aarch64:
+ return "aarch64linux";
+ case ZigLLVM_aarch64_be:
+ return "aarch64_be_linux";
+ case ZigLLVM_arm:
+ case ZigLLVM_thumb:
+ return "armelf_linux_eabi";
+ case ZigLLVM_armeb:
+ case ZigLLVM_thumbeb:
+ return "armebelf_linux_eabi";
+ case ZigLLVM_ppc:
+ return "elf32ppclinux";
+ case ZigLLVM_ppc64:
+ return "elf64ppc";
+ case ZigLLVM_ppc64le:
+ return "elf64lppc";
+ case ZigLLVM_sparc:
+ case ZigLLVM_sparcel:
+ return "elf32_sparc";
+ case ZigLLVM_sparcv9:
+ return "elf64_sparc";
+ case ZigLLVM_mips:
+ return "elf32btsmip";
+ case ZigLLVM_mipsel:
+ return "elf32ltsmip";
+ return "elf64btsmip";
+ case ZigLLVM_mips64el:
+ return "elf64ltsmip";
+ case ZigLLVM_systemz:
+ return "elf64_s390";
+ case ZigLLVM_x86_64:
+ if (t->environ == ZigLLVM_GNUX32) {
+ return "elf32_x86_64";
+ }
+ return "elf_x86_64";
+ default:
+ zig_unreachable();
+ }
+}
+
static void construct_linker_job_linux(LinkJob *lj) {
CodeGen *g = lj->codegen;
lj->args.append("-m");
- lj->args.append("elf_x86_64");
+ lj->args.append(getLDMOption(&g->zig_target));
+ bool is_lib = g->out_type == OutTypeLib;
+ bool shared = !g->is_static && is_lib;
if (g->is_static) {
- lj->args.append("-static");
+ if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb ||
+ g->zig_target.arch.arch == ZigLLVM_thumb || g->zig_target.arch.arch == ZigLLVM_thumbeb)
+ {
+ lj->args.append("-Bstatic");
+ } else {
+ lj->args.append("-static");
+ }
+ } else if (shared) {
+ lj->args.append("-shared");
}
lj->args.append("-o");
@@ -135,7 +189,6 @@ static void construct_linker_job_linux(LinkJob *lj) {
buf_appendf(&lj->out_file, "lib%s.so.%d.%d.%d",
buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch);
Buf *soname = buf_sprintf("lib%s.so.%d", buf_ptr(g->root_out_name), g->version_major);
- lj->args.append("-shared");
lj->args.append("-soname");
lj->args.append(buf_ptr(soname));
}
std/bootstrap.zig
@@ -9,9 +9,19 @@ var env: &&u8 = undefined;
#attribute("naked")
export fn _start() -> unreachable {
- argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> isize));
- argv = asm("lea 0x8(%%rsp), %[argv]": [argv] "=r" (-> &&u8));
- env = asm("lea 0x10(%%rsp,%%rdi,8), %[env]": [env] "=r" (-> &&u8));
+ switch (@compile_var("arch")) {
+ x86_64 => {
+ argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> isize));
+ argv = asm("lea 0x8(%%rsp), %[argv]": [argv] "=r" (-> &&u8));
+ env = asm("lea 0x10(%%rsp,[argc],8), %[env]": [env] "=r" (-> &&u8): [argc] "r" (argc));
+ },
+ i386 => {
+ argc = asm("mov (%%esp), %[argc]": [argc] "=r" (-> isize));
+ argv = asm("lea 0x4(%%esp), %[argv]": [argv] "=r" (-> &&u8));
+ env = asm("lea 0x8(%%esp,%[argc],4), %[env]": [env] "=r" (-> &&u8): [argc] "r" (argc));
+ },
+ else => unreachable{},
+ }
call_main()
}
std/syscall.zig
@@ -1,17 +1,63 @@
-// this file is specific to x86_64
-
-const SYS_read = 0;
-const SYS_write = 1;
-const SYS_mmap = 9;
-const SYS_munmap = 11;
-const SYS_rt_sigprocmask = 14;
-const SYS_exit = 60;
-const SYS_kill = 62;
-const SYS_getgid = 104;
-const SYS_gettid = 186;
-const SYS_tkill = 200;
-const SYS_tgkill = 234;
-const SYS_getrandom = 318;
+const SYS_read = switch (@compile_var("arch")) {
+ x86_64 => 0,
+ i386 => 3,
+ else => unreachable{},
+};
+const SYS_write = switch (@compile_var("arch")) {
+ x86_64 => 1,
+ i386 => 4,
+ else => unreachable{},
+};
+const SYS_mmap = switch (@compile_var("arch")) {
+ x86_64 => 9,
+ i386 => 90,
+ else => unreachable{},
+};
+const SYS_munmap = switch (@compile_var("arch")) {
+ x86_64 => 11,
+ i386 => 91,
+ else => unreachable{},
+};
+const SYS_rt_sigprocmask = switch (@compile_var("arch")) {
+ x86_64 => 14,
+ i386 => 175,
+ else => unreachable{},
+};
+const SYS_exit = switch (@compile_var("arch")) {
+ x86_64 => 60,
+ i386 => 1,
+ else => unreachable{},
+};
+const SYS_kill = switch (@compile_var("arch")) {
+ x86_64 => 62,
+ i386 => 37,
+ else => unreachable{},
+};
+const SYS_getgid = switch (@compile_var("arch")) {
+ x86_64 => 104,
+ i386 => 47,
+ else => unreachable{},
+};
+const SYS_gettid = switch (@compile_var("arch")) {
+ x86_64 => 186,
+ i386 => 224,
+ else => unreachable{},
+};
+const SYS_tkill = switch (@compile_var("arch")) {
+ x86_64 => 200,
+ i386 => 238,
+ else => unreachable{},
+};
+const SYS_tgkill = switch (@compile_var("arch")) {
+ x86_64 => 234,
+ i386 => 270,
+ else => unreachable{},
+};
+const SYS_getrandom = switch (@compile_var("arch")) {
+ x86_64 => 318,
+ i386 => 355,
+ else => unreachable{},
+};
pub const MMAP_PROT_NONE = 0;
pub const MMAP_PROT_READ = 1;
@@ -63,14 +109,45 @@ const SIG_BLOCK = 0;
const SIG_UNBLOCK = 1;
const SIG_SETMASK = 2;
-fn syscall0(number: isize) -> isize {
+const syscall0 = switch (@compile_var("arch")) {
+ x86_64 => x86_64_syscall0,
+ i386 => i386_syscall0,
+ else => unreachable{},
+};
+const syscall1 = switch (@compile_var("arch")) {
+ x86_64 => x86_64_syscall1,
+ i386 => i386_syscall1,
+ else => unreachable{},
+};
+const syscall2 = switch (@compile_var("arch")) {
+ x86_64 => x86_64_syscall2,
+ i386 => i386_syscall2,
+ else => unreachable{},
+};
+const syscall3 = switch (@compile_var("arch")) {
+ x86_64 => x86_64_syscall3,
+ i386 => i386_syscall3,
+ else => unreachable{},
+};
+const syscall4 = switch (@compile_var("arch")) {
+ x86_64 => x86_64_syscall4,
+ i386 => i386_syscall4,
+ else => unreachable{},
+};
+const syscall6 = switch (@compile_var("arch")) {
+ x86_64 => x86_64_syscall6,
+ i386 => i386_syscall6,
+ else => unreachable{},
+};
+
+fn x86_64_syscall0(number: isize) -> isize {
asm volatile ("syscall"
: [ret] "={rax}" (-> isize)
: [number] "{rax}" (number)
: "rcx", "r11")
}
-fn syscall1(number: isize, arg1: isize) -> isize {
+fn x86_64_syscall1(number: isize, arg1: isize) -> isize {
asm volatile ("syscall"
: [ret] "={rax}" (-> isize)
: [number] "{rax}" (number),
@@ -78,7 +155,7 @@ fn syscall1(number: isize, arg1: isize) -> isize {
: "rcx", "r11")
}
-fn syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
+fn x86_64_syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
asm volatile ("syscall"
: [ret] "={rax}" (-> isize)
: [number] "{rax}" (number),
@@ -87,7 +164,7 @@ fn syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
: "rcx", "r11")
}
-fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
+fn x86_64_syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
asm volatile ("syscall"
: [ret] "={rax}" (-> isize)
: [number] "{rax}" (number),
@@ -97,7 +174,7 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
: "rcx", "r11")
}
-fn syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
+fn x86_64_syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
asm volatile ("syscall"
: [ret] "={rax}" (-> isize)
: [number] "{rax}" (number),
@@ -108,7 +185,7 @@ fn syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -
: "rcx", "r11")
}
-fn syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
+fn x86_64_syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
asm volatile ("syscall"
: [ret] "={rax}" (-> isize)
: [number] "{rax}" (number),
@@ -121,6 +198,58 @@ fn syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, a
: "rcx", "r11")
}
+fn i386_syscall0(number: isize) -> isize {
+ asm volatile ("int $0x80"
+ : [ret] "={eax}" (-> isize)
+ : [number] "{eax}" (number))
+}
+
+fn i386_syscall1(number: isize, arg1: isize) -> isize {
+ asm volatile ("int $0x80"
+ : [ret] "={eax}" (-> isize)
+ : [number] "{eax}" (number),
+ [arg1] "{ebx}" (arg1))
+}
+
+fn i386_syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
+ asm volatile ("int $0x80"
+ : [ret] "={eax}" (-> isize)
+ : [number] "{eax}" (number),
+ [arg1] "{ebx}" (arg1),
+ [arg2] "{ecx}" (arg2))
+}
+
+fn i386_syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
+ asm volatile ("int $0x80"
+ : [ret] "={eax}" (-> isize)
+ : [number] "{eax}" (number),
+ [arg1] "{ebx}" (arg1),
+ [arg2] "{ecx}" (arg2),
+ [arg3] "{edx}" (arg3))
+}
+
+fn i386_syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
+ asm volatile ("int $0x80"
+ : [ret] "={eax}" (-> isize)
+ : [number] "{eax}" (number),
+ [arg1] "{ebx}" (arg1),
+ [arg2] "{ecx}" (arg2),
+ [arg3] "{edx}" (arg3),
+ [arg4] "{esi}" (arg4))
+}
+
+fn i386_syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
+ asm volatile ("int $0x80"
+ : [ret] "={eax}" (-> isize)
+ : [number] "{eax}" (number),
+ [arg1] "{ebx}" (arg1),
+ [arg2] "{ecx}" (arg2),
+ [arg3] "{edx}" (arg3),
+ [arg4] "{esi}" (arg4),
+ [arg5] "{edi}" (arg5),
+ [arg6] "{ebp}" (arg6))
+}
+
pub fn mmap(address: isize, length: isize, prot: isize, flags: isize, fd: isize, offset: isize) -> isize {
syscall6(SYS_mmap, address, length, prot, flags, fd, offset)
}
test/self_hosted.zig
@@ -164,7 +164,12 @@ fn enum_type() {
assert(bar == EnumTypeBar.B);
assert(@member_count(EnumTypeFoo) == 3);
assert(@member_count(EnumTypeBar) == 4);
- assert(@sizeof(EnumTypeFoo) == 24);
+ const expected_foo_size = switch (@compile_var("arch")) {
+ i386 => 20,
+ x86_64 => 24,
+ else => unreachable{},
+ };
+ assert(@sizeof(EnumTypeFoo) == expected_foo_size);
assert(@sizeof(EnumTypeBar) == 1);
}
struct EnumType {