HelloSilicon
HelloSilicon copied to clipboard
Opting out of libc on Apple Silicon
Embedded platforms don't do static. However, if you're still curious here's how you can convince Xcode to make those files:
diff --git a/AsMain/main.s b/AsMain/main.s
index 953236a..61760cd 100644
--- a/AsMain/main.s
+++ b/AsMain/main.s
@@ -6,12 +6,11 @@
// X16 - Mach function number
//
-.global _main // Provide program starting address to linker
+.global start // Provide program starting address to linker
.align 2
-
// Setup the parameters to print hello world
// and then call Linux to do it.
-_main: mov X0, #1 // 1 = StdOut
+start: mov X0, #1 // 1 = StdOut
adr X1, helloworld // string to print
mov X2, #13 // length of our string
mov X16, #4 // linux write system call
diff --git a/MacAs.xcodeproj/project.pbxproj b/MacAs.xcodeproj/project.pbxproj
index 11b501e..f95d6bd 100644
--- a/MacAs.xcodeproj/project.pbxproj
+++ b/MacAs.xcodeproj/project.pbxproj
@@ -318,6 +318,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
+ LINK_WITH_STANDARD_LIBRARIES = NO;
+ OTHER_LDFLAGS = "-static";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@@ -326,6 +328,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
+ LINK_WITH_STANDARD_LIBRARIES = NO;
+ OTHER_LDFLAGS = "-static";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
![Screen Shot 2020-07-04 at 19 50 03](https://user-images.githubusercontent.com/13786931/86524433-8f970180-be2f-11ea-82ac-c48171c4975a.png)
If you put an underscore in front of main
in both places and give up on static linking:
![Screen Shot 2020-07-04 at 19 51 31](https://user-images.githubusercontent.com/13786931/86524457-c3722700-be2f-11ea-97cc-39cf527a1286.png)
That's cool to know! Although now that I have solved the issue of in the makefile, I will continue to work on that!
I lied, that code is likely outdated/not complete. I know of at least one statically linked binary running.
I lied, that code is likely outdated/not complete. I know of at least one statically linked binary running.
Most interesting, the documentation I could find is also that Mach-O doesn't do static binaries.
That said, currently I am happy as long as I can easily build and deploy assembler source from the command line, and I might come back to the issue of building a Mach-O binary later ;)
Oh, no, Mach-O totally does static binaries. In fact, here's how to make one you can run on your Intel machine:
$ clang -x assembler-with-cpp -static -nostdlib -
.intel_syntax noprefix
#include <sys/syscall.h>
#define UNIX_SYSCALL 0x2000000
.globl start
start:
mov rax, UNIX_SYSCALL | SYS_write
mov rdi, 1
lea rsi, text[rip]
lea rdx, length
syscall
mov rax, UNIX_SYSCALL | SYS_exit
xor rdi, rdi
syscall
text:
.asciz "Hello, world!\n"
.equ length, . - text
$ ./a.out
Hello, world!
Most interesting! Any idea why the documentation would claim such a thing?
System call numbers on macOS are not stable, so Apple would like you to go through libc. Go used to create static binaries on macOS but they would constantly break whenever an update came out, so they've starting linking against the system libraries. The only reason you should be making system calls yourself is curiosity or if you have an extremely good reason that you cannot link against libSystem ;)
Oh, no, Mach-O totally does static binaries. In fact, here's how to make one you can run on your Intel machine:
…
While you can create static binaries, the macOS kernel (XNU) allows the execution of static binaries on x86_64 only (or with debug kernels, which probably nobody outside Apple is using). On all other platforms (ARM64), the kernel enforces that an executable must use the dynamic linker (this was already linked to in the issue above). It's a restriction that cannot be bypassed. However, you can create a dynamically linked executable and simply not link to any library/framework.