Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Opting out of libc on Apple Silicon #5

Open
saagarjha opened this issue Jul 5, 2020 · 7 comments
Open

Opting out of libc on Apple Silicon #5

saagarjha opened this issue Jul 5, 2020 · 7 comments

Comments

@saagarjha
Copy link

saagarjha commented Jul 5, 2020

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

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

@below
Copy link
Owner

below commented Jul 5, 2020

That's cool to know! Although now that I have solved the issue of in the makefile, I will continue to work on that!

@saagarjha
Copy link
Author

I lied, that code is likely outdated/not complete. I know of at least one statically linked binary running.

@below
Copy link
Owner

below commented Jul 6, 2020

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 ;)

@saagarjha
Copy link
Author

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!

@below
Copy link
Owner

below commented Jul 6, 2020

Most interesting! Any idea why the documentation would claim such a thing?

@saagarjha
Copy link
Author

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 ;)

@DarkDust
Copy link

DarkDust commented Feb 3, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants