From 317e951b0c9b9d6c3eab826267ae48650734b5b1 Mon Sep 17 00:00:00 2001 From: ericwa Date: Mon, 8 Jul 2013 09:07:37 +0000 Subject: [PATCH] libobjc2: some changes needed to build on OS X. CDECL macro to prefix symbol names in assembly code with an underscore, macros to omit the .type and .section derictives which are unsupported on OS X, and also a linker flag to make weak symbols work --- CMakeLists.txt | 13 ++++++++ block_trampolines.S | 76 +++++++++++++++++++++++-------------------- common.S | 12 +++++++ objc_msgSend.S | 3 ++ objc_msgSend.arm.S | 20 ++++++------ objc_msgSend.mips.S | 24 +++++++------- objc_msgSend.x86-32.S | 18 +++++----- objc_msgSend.x86-64.S | 22 ++++++------- 8 files changed, 110 insertions(+), 78 deletions(-) create mode 100644 common.S diff --git a/CMakeLists.txt b/CMakeLists.txt index 719a017..faa8520 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -275,6 +275,19 @@ if (LIBDISPATCH) target_link_libraries(objc ${LIBDISPATCH}) endif () +# Enable .type and .section assembly directives on platforms other than OS X +if (NOT APPLE) + add_definitions(-DHAS_SECTION_DIRECTIVE=1 -DHAS_TYPE_DIRECTIVE=1) +endif () + +# Make weak symbols work on OS X +if (APPLE) + set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS + "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} -undefined dynamic_lookup") + set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-undefined,dynamic_lookup") + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-undefined,dynamic_lookup") +endif () + # # Installation # diff --git a/block_trampolines.S b/block_trampolines.S index 879e9a7..2955787 100644 --- a/block_trampolines.S +++ b/block_trampolines.S @@ -1,3 +1,5 @@ +#include "common.S" + # # This file defines some trampolines for calling blocks. A block function # looks like this: @@ -15,33 +17,33 @@ .file "block_trampolines.S" #if __arm__ .syntax unified -.globl __objc_block_trampoline_sret - .type __objc_block_trampoline_sret, %function -.globl __objc_block_trampoline_end_sret -.globl __objc_block_trampoline - .type __objc_block_trampoline, %function -.globl __objc_block_trampoline_end +.globl CDECL(__objc_block_trampoline_sret) +TYPE_DIRECTIVE(CDECL(__objc_block_trampoline_sret), %function) +.globl CDECL(__objc_block_trampoline_end_sret) +.globl CDECL(__objc_block_trampoline) +TYPE_DIRECTIVE(CDECL(__objc_block_trampoline), %function) +.globl CDECL(__objc_block_trampoline_end) #else -.globl __objc_block_trampoline_sret - .type __objc_block_trampoline_sret, @function -.globl __objc_block_trampoline_end_sret -.globl __objc_block_trampoline - .type __objc_block_trampoline, @function -.globl __objc_block_trampoline_end +.globl CDECL(__objc_block_trampoline_sret) +TYPE_DIRECTIVE(CDECL(__objc_block_trampoline_sret), @function) +.globl CDECL(__objc_block_trampoline_end_sret) +.globl CDECL(__objc_block_trampoline) +TYPE_DIRECTIVE(CDECL(__objc_block_trampoline), @function) +.globl CDECL(__objc_block_trampoline_end) #endif #if __x86_64 -__objc_block_trampoline: +CDECL(__objc_block_trampoline): mov -15(%rip), %rsi # Load the block pointer into the second argument xchg %rdi, %rsi # Swap the first and second arguments jmp *-32(%rip) # Call the block function -__objc_block_trampoline_end: -__objc_block_trampoline_sret: +CDECL(__objc_block_trampoline_end): +CDECL(__objc_block_trampoline_sret): mov -15(%rip), %rdx # Load the block pointer into the second argument xchg %rdx, %rsi # Swap the first and second arguments jmp *-32(%rip) # Call the block function -__objc_block_trampoline_end_sret: +CDECL(__objc_block_trampoline_end_sret): #elif __i386 -__objc_block_trampoline: +CDECL(__objc_block_trampoline): call next_line # Store the instruction pointer on the stack next_line: pop %eax # Load the old instruction pointer @@ -50,8 +52,8 @@ next_line: mov -9(%eax), %ebx # Load the block pointer to %ebx mov %ebx, 4(%esp) # Store the block pointer in the first argument jmp *-13(%eax) # Call the block function -__objc_block_trampoline_end: -__objc_block_trampoline_sret: +CDECL(__objc_block_trampoline_end): +CDECL(__objc_block_trampoline_sret): call next_line2 # Store the instruction pointer on the stack next_line2: pop %eax # Load the old instruction pointer @@ -60,51 +62,53 @@ next_line2: mov -9(%eax), %ebx # Load the block pointer to %ebx mov %ebx, 8(%esp) # Store the block pointer in the first argument jmp *-13(%eax) # Call the block function -__objc_block_trampoline_end_sret: +CDECL(__objc_block_trampoline_end_sret): #elif __mips__ # ifdef _ABI64 -__objc_block_trampoline: +CDECL(__objc_block_trampoline): move $a1, $a0 ld $a0, -16($25) ld $25, -8($25) jr $25 -__objc_block_trampoline_end: -__objc_block_trampoline_sret: +CDECL(__objc_block_trampoline_end): +CDECL(__objc_block_trampoline_sret): move $a2, $a1 ld $a1, -16($25) ld $25, -8($25) jr $25 -__objc_block_trampoline_end_sret: +CDECL(__objc_block_trampoline_end_sret): # else -__objc_block_trampoline: +CDECL(__objc_block_trampoline): move $a1, $a0 lw $a0, -8($25) lw $25, -4($25) jr $25 -__objc_block_trampoline_end: -__objc_block_trampoline_sret: +CDECL(__objc_block_trampoline_end): +CDECL(__objc_block_trampoline_sret): move $a2, $a1 lw $a1, -8($25) lw $25, -4($25) jr $25 -__objc_block_trampoline_end_sret: +CDECL(__objc_block_trampoline_end_sret): # endif #elif __arm__ -__objc_block_trampoline: +CDECL(__objc_block_trampoline): mov r1, r0 // Move self over _cmd ldr r0, [pc, #-16] // Load the block pointer over self ldr pc, [pc, #-24] // Jump to the block function -__objc_block_trampoline_end: -__objc_block_trampoline_sret: +CDECL(__objc_block_trampoline_end): +CDECL(__objc_block_trampoline_sret): mov r2, r1 // Move self over _cmd ldr r1, [pc, #-16] // Load the block pointer over self ldr pc, [pc, #-24] // Jump to the block function -__objc_block_trampoline_end_sret: +CDECL(__objc_block_trampoline_end_sret): #else #warning imp_implementationWithBlock() not implemented for your architecture -__objc_block_trampoline: -__objc_block_trampoline_end: -__objc_block_trampoline_sret: -__objc_block_trampoline_end_sret: +CDECL(__objc_block_trampoline): +CDECL(__objc_block_trampoline_end): +CDECL(__objc_block_trampoline_sret): +CDECL(__objc_block_trampoline_end_sret): #endif +#if HAS_SECTION_DIRECTIVE .section .note.GNU-stack,"",%progbits +#endif diff --git a/common.S b/common.S new file mode 100644 index 0000000..521e65d --- /dev/null +++ b/common.S @@ -0,0 +1,12 @@ +#if defined(__WIN32__) || defined(__APPLE__) +#define CDECL(symbol) _##symbol +#else +#define CDECL(symbol) symbol +#endif + +#if HAS_TYPE_DIRECTIVE +#define TYPE_DIRECTIVE(symbol, symboltype) .type symbol, symboltype +#else +#define TYPE_DIRECTIVE(symbol, symboltype) +#endif + diff --git a/objc_msgSend.S b/objc_msgSend.S index 8f3a004..3cdf15f 100644 --- a/objc_msgSend.S +++ b/objc_msgSend.S @@ -1,3 +1,4 @@ +#include "common.S" #if __x86_64 #include "objc_msgSend.x86-64.S" #elif __i386 @@ -9,4 +10,6 @@ #else #warning objc_msgSend() not implemented for your architecture #endif +#if HAS_SECTION_DIRECTIVE .section .note.GNU-stack,"",%progbits +#endif diff --git a/objc_msgSend.arm.S b/objc_msgSend.arm.S index 9ec7f4b..d0cd25d 100644 --- a/objc_msgSend.arm.S +++ b/objc_msgSend.arm.S @@ -77,7 +77,7 @@ .save {\receiver} mov r1, \sel - bl slowMsgLookup(PLT) // This is the only place where the CFI directives have to be accurate... + bl CDECL(slowMsgLookup)(PLT) // This is the only place where the CFI directives have to be accurate... mov ip, r0 // IMP -> ip pop {r5} // restore (modified) self to r5 @@ -87,16 +87,16 @@ .fnend .endm -.globl objc_msgSend_fpret - .type objc_msgSend_fpret, %function -.globl objc_msgSend - .type objc_msgSend, %function -objc_msgSend: -objc_msgSend_fpret: +.globl CDECL(objc_msgSend_fpret) +TYPE_DIRECTIVE(CDECL(objc_msgSend_fpret), %function) +.globl CDECL(objc_msgSend) +TYPE_DIRECTIVE(CDECL(objc_msgSend), %function) +CDECL(objc_msgSend): +CDECL(objc_msgSend_fpret): MSGSEND r0, r1 -.globl objc_msgSend_stret - .type objc_msgSend_stret, %function -objc_msgSend_stret: +.globl CDECL(objc_msgSend_stret) +TYPE_DIRECTIVE(CDECL(objc_msgSend_stret), %function) +CDECL(objc_msgSend_stret): MSGSEND r1, r2 LSmallIntClass: diff --git a/objc_msgSend.mips.S b/objc_msgSend.mips.S index 1aafc12..c33baaa 100644 --- a/objc_msgSend.mips.S +++ b/objc_msgSend.mips.S @@ -127,7 +127,7 @@ lw $zero, ($zero) # MIPS implementations. # Note: A better linker ought to be able to turn this into a single # jump-immediate, so revisit this decision later... - LP $25, %got_disp(slowMsgLookup)($t8) + LP $25, %got_disp(CDECL(slowMsgLookup))($t8) daddiu $sp, $sp, -SAVE_SIZE # We need to preserve all registers that may contain arguments: @@ -193,24 +193,24 @@ lw $zero, ($zero) 6: # smallObject: #if _ABI64 dsll $t4, $t4, 3 # Convert tag to pointer offset - LP $t6, %got_disp(SmallObjectClasses)($t8) # Load small object classes array address + LP $t6, %got_disp(CDECL(SmallObjectClasses))($t8) # Load small object classes array address daddu $t4, $t4, $t6 # Add the base address to the offset b 1b # Return to the normal path LP $t4, ($t4) # Load the class (in delay slot) #else b 1b - LP $t4, %got_disp(SmallIntClass)($t8) + LP $t4, %got_disp(CDECL(SmallIntClass))($t8) #endif .cfi_endproc .endm -.globl objc_msgSend - .type objc_msgSend, @function -.globl objc_msgSend_fpret - .type objc_msgSend_fpret, @function -objc_msgSend_fpret: -objc_msgSend: +.globl CDECL(objc_msgSend) +TYPE_DIRECTIVE(CDECL(objc_msgSend), @function) +.globl CDECL(objc_msgSend_fpret) +TYPE_DIRECTIVE(CDECL(objc_msgSend_fpret), @function) +CDECL(objc_msgSend_fpret): +CDECL(objc_msgSend): MSGSEND $a0, $a1 -.globl objc_msgSend_stret - .type objc_msgSend_stret, @function -objc_msgSend_stret: +.globl CDECL(objc_msgSend_stret) +TYPE_DIRECTIVE(CDECL(objc_msgSend_stret), @function) +CDECL(objc_msgSend_stret): MSGSEND $a1, $a2 diff --git a/objc_msgSend.x86-32.S b/objc_msgSend.x86-32.S index 8e9f8f6..2b5406f 100644 --- a/objc_msgSend.x86-32.S +++ b/objc_msgSend.x86-32.S @@ -87,15 +87,15 @@ jmp 1b .cfi_endproc .endm -.globl objc_msgSend_fpret - .type objc_msgSend_fpret, @function -objc_msgSend_fpret: +.globl CDECL(objc_msgSend_fpret) +TYPE_DIRECTIVE(CDECL(objc_msgSend_fpret), @function) +CDECL(objc_msgSend_fpret): MSGSEND 4, 8, 1 -.globl objc_msgSend - .type objc_msgSend, @function -objc_msgSend: +.globl CDECL(objc_msgSend) +TYPE_DIRECTIVE(CDECL(objc_msgSend), @function) +CDECL(objc_msgSend): MSGSEND 4, 8, 0 -.globl objc_msgSend_stret - .type objc_msgSend_stret, @function -objc_msgSend_stret: +.globl CDECL(objc_msgSend_stret) +TYPE_DIRECTIVE(CDECL(objc_msgSend_stret), @function) +CDECL(objc_msgSend_stret): MSGSEND 8, 12, 0 diff --git a/objc_msgSend.x86-64.S b/objc_msgSend.x86-64.S index f519bf3..4be831b 100644 --- a/objc_msgSend.x86-64.S +++ b/objc_msgSend.x86-64.S @@ -234,7 +234,7 @@ .endif .cfi_adjust_cfa_offset 0xD8 - call slowMsgLookup # Call the slow lookup function + call CDECL(slowMsgLookup) # Call the slow lookup function mov %rax, %r10 # Load the returned IMP pop %rdx @@ -260,20 +260,20 @@ 6: # smallObject: and \receiver, %r10 # Find the small int type shll $3, %r10d - lea SmallObjectClasses(%rip), %r11 + lea CDECL(SmallObjectClasses)(%rip), %r11 add %r11, %r10 mov (%r10), %r10 jmp 1b .cfi_endproc .endm -.globl objc_msgSend - .type objc_msgSend, @function -.globl objc_msgSend_fpret - .type objc_msgSend_fpret, @function -objc_msgSend_fpret: -objc_msgSend: +.globl CDECL(objc_msgSend) +TYPE_DIRECTIVE(CDECL(objc_msgSend), @function) +.globl CDECL(objc_msgSend_fpret) +TYPE_DIRECTIVE(CDECL(objc_msgSend_fpret), @function) +CDECL(objc_msgSend_fpret): +CDECL(objc_msgSend): MSGSEND %rdi, %rsi -.globl objc_msgSend_stret - .type objc_msgSend_stret, @function -objc_msgSend_stret: +.globl CDECL(objc_msgSend_stret) +TYPE_DIRECTIVE(CDECL(objc_msgSend_stret), @function) +CDECL(objc_msgSend_stret): MSGSEND %rsi, %rdx