2

I'm on MacOS (Apple Silicon M4 processor, so, ARM64), and when trying to use puts from the standard C library:

 .global main // 1 main: // 2 stp x21, x30, [sp, -16]! // push onto stack // 3 mov x21, x1 // argc -> x0, argv -> x1 // 4 // 5 top: // 6 ldr x0, [x21], 8 // argv++, old value in x0 // 7 cbz x0, bottom // if *argv == NULL goto bottom // 8 bl puts // puts(*argv) // 9 b top // goto top // 10 // 11 bottom: // 12 ldp x21, x30, [sp], 16 // pop from stack // 13 mov x0, xzr // return 0 // 14 ret // 15 // 16 .end 

It fails, and returns:

~/ clang -lc -arch arm64 test2.s -e main Undefined symbols for architecture arm64: "puts", referenced from: main in test2-8965bb.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) 

I have tried with the addition of the -lSystem flag, doesn't work, instead just returns a ld: warning: ignoring duplicate libraries: '-lSystem' warning.

Not sure what I did wrong, making it that I can't use libc (just in case, I have tried this:

#include <stdio.h> int main(){ puts("Hello, World!"); return 0; } 

Whos assembly equivalent is:

 .section __TEXT,__text,regular,pure_instructions .build_version macos, 15, 0 sdk_version 15, 2 .globl _main ; -- Begin function main .p2align 2 _main: ; @main .cfi_startproc ; %bb.0: sub sp, sp, #32 stp x29, x30, [sp, #16] ; 16-byte Folded Spill add x29, sp, #16 .cfi_def_cfa w29, 16 .cfi_offset w30, -8 .cfi_offset w29, -16 mov w8, #0 ; =0x0 str w8, [sp, #8] ; 4-byte Folded Spill stur wzr, [x29, #-4] adrp x0, l_.str@PAGE add x0, x0, l_.str@PAGEOFF bl _puts ldr w0, [sp, #8] ; 4-byte Folded Reload ldp x29, x30, [sp, #16] ; 16-byte Folded Reload add sp, sp, #32 ret .cfi_endproc ; -- End function .section __TEXT,__cstring,cstring_literals l_.str: ; @.str .asciz "Hello, World!" .subsections_via_symbols 

Which works just fine!)

Some help would be appreciated!

8
  • 2
    I have vague memories that Mac OS prefixes symbols with an underscore, so _puts. What does the assembly output of the C program use? Commented Jan 17 at 22:08
  • @Shawn it worked, just, does every function in libc have to be prefixed with an underscore? Commented Jan 17 at 22:18
  • 1
    @Silicon Every C language identifier is decorated with a leading underscore. Commented Jan 17 at 22:36
  • 1
    @Silicon This applies to all C code built for the macOS ABI, which is what mandates this decoration. If you build programs for ELF targets following the SysV ABI (such as Linux), there is no decoration. Commented Jan 17 at 22:48
  • 1
    See also __USER_LABEL_PREFIX__ in gcc and clang. Commented Jan 17 at 22:51

1 Answer 1

1

As @Shawn and @fuz mentioned, adding a prefixing _ is required for all C code built for the macOS ABI.

Therefore, the corrected code would become:

 .global main // 1 main: // 2 stp x21, x30, [sp, -16]! // push onto stack // 3 mov x21, x1 // argc -> x0, argv -> x1 // 4 // 5 top: // 6 ldr x0, [x21], 8 // argv++, old value in x0 // 7 cbz x0, bottom // if *argv == NULL goto bottom // 8 bl _puts // note that there is a `_` // 9 b top // goto top // 10 // 11 bottom: // 12 ldp x21, x30, [sp], 16 // pop from stack // 13 mov x0, xzr // return 0 // 14 ret // 15 // 16 .end 

Fixed part:

bl _puts // with the addition of the leading `_` 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.