告诉 'ld' dyld_stub_binder 不再在 libSystem.dyld 中,而是在 libSystem.B.dyld 中
Tell 'ld' dyld_stub_binder is no longer in libSystem.dyld but in libSystem.B.dyld
我正在尝试 re-create Launchpad 可执行文件,到目前为止一切似乎都正确,除了我在 运行 ld
:
时收到此警告
Assembling/Linking 与:
as myprogram.s -o myprogram.o
ld myprogram.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -o myprogram
ld: symbol dyld_stub_binder not found (normally in libSystem.dylib). Needed to perform lazy binding to function _CoreDockSendNotification for architecture x86_64
这是我的代码(抱歉 NASM 伙计们,这里是 AT&T 语法):
.section __DATA, __const
.section __TEXT, __text
.globl _start
_start:
pushq %rbp
movq %rbp, %rsp
lea lpToggle_cfstring_(%rip), %rdi
xor %esi, %esi
callq _CoreDockSendNotification
mov %rax, %r14
xor %rdi, %rdi
mov [=15=]x2000001, %rax
syscall
.section __TEXT,__cstring,cstring_literals
lpToggle: .asciz "com.apple.launchpad.toggle"
.section __DATA,__cfstring
lpToggle_cfstring_:
.quad ___CFConstantStringClassReference
.long 1992
.space 4
.quad lpToggle
.quad 26
我已经更新到最新版本的 xcode 和命令行工具,我尝试将 _start
更改为 _main
,我尝试 link libSystem.B.dyld 直接(有和没有 '.dyld' 扩展名):
ld lp.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -L/usr/lib/ -llibSystem.B.dyld -o lp
ld lp.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -llibSystem.B.dyld -o lp
ld lp.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -o lp -l/usr/lib/libSystem.B.dyld
ld lp.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -o lp -libSystem.B.dyld
我得到:
ld: warning: directory not found for option '-L/usr/lib/ -llibSystem.B.dyld'
或
ld: warning: directory not found for option '-l/usr/lib/libSystem.B.dyld'
或
ld: warning: library not found for option '-l/usr/lib/libSystem.B.dyld'
取决于我尝试哪一个。
我什至尝试直接从 /Applications/Xcode.app/Contents/Developer/usr/bin
目录使用 ld
来查看新旧
之间是否存在 symlink 问题
我使用 lldb 转储了 libSystem.dyld 的符号表,果然包含以下行:
`[ 108] 108 X Undefined 0x0000000000000000 0x0000000000000000 0x00010000 dyld_stub_binder`
表示它有一个和108
的index
/user id
,X
表示它是外部定义的(可能是libSystem.B), Undefined
的 type
,'0x0' 的 'File Address/Value' 没有 Load Address
,以及 0x00010000
的标志。
我在 Hopper 中加载了 Launchpad 可执行文件以查看它发生了什么,但没有太大帮助(除了它告诉我 dyld_stub_binder 在 libSystem.B.dyld 中)。
不确定这是否相关,但在实际的 Launchpad header 中包含:
; Load Command 4
;
0000000100000410 struct __macho_dyld_info_command {
LC_DYLD_INFO_ONLY, // LC_DYLD_INFO or LC_DYLD_INFO_ONLY
0x30, // sizeof(struct dyld_info_command)
0x2000, // file offset to rebase info
0x8, // size of rebase info
0x2008, // file offset to binding info
0x40, // size of binding info
0x0, // file offset to weak binding info
0x0, // size of weak binding info
0x2048, // file offset to lazy binding info
0x20, // size of lazy binding infs
0x2068, // file offset to lazy binding info
0x20 // size of lazy binding infs
}
;Load command 7
00000001000004a8 struct __macho_dylinker_command {
LC_LOAD_DYLINKER, // LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT
0x20, // includes pathname string
0xc // dynamic linker's path name (should be 12)
}
00000001000004b4 db "/usr/lib/dyld", 0
00000001000004c2 db 0x00 ; '.'
00000001000004c3 db 0x00 ; '.'
00000001000004c4 db 0x00 ; '.'
00000001000004c5 db 0x00 ; '.'
00000001000004c6 db 0x00 ; '.'
00000001000004c7 db 0x00 ; '.'
在 _stub_helper
部分(看起来像某种 infinite-ish 循环,完全跳过了中间的 4 条指令):
0000000100000f80 lea, qword [dyld_stub_binder_100001000+8]; CODE XREF=0x100000f95
0000000100000f87 push r11
0000000100000f89 jmp qword [dyld_stub_binder_100001000] ; dyld_stub_binder
0000000100000f8f db 0x90
0000000100000f90 push 0x0
0000000100000f95 jmp 0x100000f80
在 __DATA__nl_symbol_ptr
部分:
0000000100001000 dq dyld_stub_binder ; DATA XREF=0x100000f89
0000000100001008 dq 0x0000000000000000 ; DATA XREF=0x100000f80
在 External Symbols
段中:
dyld_stub_binder:
0000000100005010 db 0x00 ; '.' ; in /usr/lib/libSystem.B.dylib, CODE XREF=0x100000f89DATA XREF=dyld_stub_binder_100001000
0000000100005011 db 0x00 ; '.'
0000000100005012 db 0x00 ; '.'
0000000100005013 db 0x00 ; '.'
0000000100005014 db 0x00 ; '.'
0000000100005015 db 0x00 ; '.'
0000000100005016 db 0x00 ; '.'
0000000100005017 db 0x00 ; '.'
更有趣的是如果我用gcc编译:
gcc -arch x86_64 -e _start -framework Foundation -framework ApplicationServices lp.s
它将毫无问题地构建,但在 运行 时间的某个时候会出现段错误。我说在某些时候是因为如果我用 lldb a.out
加载它并执行 run
命令,它会正常执行,没有段错误。所以很难找出到底发生了什么。我的直觉是 lldb
将我的应用程序指向 正确的 dyld_stub_binder
但我可能是错的。
然而,如果我 运行 sudo ./myfile
在 gcc
版本上 运行 完全没问题。 gcc
在做什么而 ld
不是?还是 as
命令中的内容?
我对使用核心 macOS 程序集还是比较陌生,所以任何指示都会有所帮助!
P.S。我也尝试了 -no_weak_imports
但那也不起作用
您的 ld myprogram.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -o myprogram
缺少 -l
libSystem.B
库的搜索选项。
添加以下任一项:
-lsystem.b
-lsystem
-lc
-lm
-ld
所有都是同义词,可以解决缺少的 LC_LOAD_DYLIB(libSystem.B.dylib)
加载命令。顺便说一句,你的程序有效:-)
我正在尝试 re-create Launchpad 可执行文件,到目前为止一切似乎都正确,除了我在 运行 ld
:
Assembling/Linking 与:
as myprogram.s -o myprogram.o
ld myprogram.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -o myprogram
ld: symbol dyld_stub_binder not found (normally in libSystem.dylib). Needed to perform lazy binding to function _CoreDockSendNotification for architecture x86_64
这是我的代码(抱歉 NASM 伙计们,这里是 AT&T 语法):
.section __DATA, __const
.section __TEXT, __text
.globl _start
_start:
pushq %rbp
movq %rbp, %rsp
lea lpToggle_cfstring_(%rip), %rdi
xor %esi, %esi
callq _CoreDockSendNotification
mov %rax, %r14
xor %rdi, %rdi
mov [=15=]x2000001, %rax
syscall
.section __TEXT,__cstring,cstring_literals
lpToggle: .asciz "com.apple.launchpad.toggle"
.section __DATA,__cfstring
lpToggle_cfstring_:
.quad ___CFConstantStringClassReference
.long 1992
.space 4
.quad lpToggle
.quad 26
我已经更新到最新版本的 xcode 和命令行工具,我尝试将 _start
更改为 _main
,我尝试 link libSystem.B.dyld 直接(有和没有 '.dyld' 扩展名):
ld lp.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -L/usr/lib/ -llibSystem.B.dyld -o lp
ld lp.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -llibSystem.B.dyld -o lp
ld lp.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -o lp -l/usr/lib/libSystem.B.dyld
ld lp.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -o lp -libSystem.B.dyld
我得到:
ld: warning: directory not found for option '-L/usr/lib/ -llibSystem.B.dyld'
或
ld: warning: directory not found for option '-l/usr/lib/libSystem.B.dyld'
或
ld: warning: library not found for option '-l/usr/lib/libSystem.B.dyld'
取决于我尝试哪一个。
我什至尝试直接从 /Applications/Xcode.app/Contents/Developer/usr/bin
目录使用 ld
来查看新旧
我使用 lldb 转储了 libSystem.dyld 的符号表,果然包含以下行:
`[ 108] 108 X Undefined 0x0000000000000000 0x0000000000000000 0x00010000 dyld_stub_binder`
表示它有一个和108
的index
/user id
,X
表示它是外部定义的(可能是libSystem.B), Undefined
的 type
,'0x0' 的 'File Address/Value' 没有 Load Address
,以及 0x00010000
的标志。
我在 Hopper 中加载了 Launchpad 可执行文件以查看它发生了什么,但没有太大帮助(除了它告诉我 dyld_stub_binder 在 libSystem.B.dyld 中)。
不确定这是否相关,但在实际的 Launchpad header 中包含:
; Load Command 4
;
0000000100000410 struct __macho_dyld_info_command {
LC_DYLD_INFO_ONLY, // LC_DYLD_INFO or LC_DYLD_INFO_ONLY
0x30, // sizeof(struct dyld_info_command)
0x2000, // file offset to rebase info
0x8, // size of rebase info
0x2008, // file offset to binding info
0x40, // size of binding info
0x0, // file offset to weak binding info
0x0, // size of weak binding info
0x2048, // file offset to lazy binding info
0x20, // size of lazy binding infs
0x2068, // file offset to lazy binding info
0x20 // size of lazy binding infs
}
;Load command 7
00000001000004a8 struct __macho_dylinker_command {
LC_LOAD_DYLINKER, // LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT
0x20, // includes pathname string
0xc // dynamic linker's path name (should be 12)
}
00000001000004b4 db "/usr/lib/dyld", 0
00000001000004c2 db 0x00 ; '.'
00000001000004c3 db 0x00 ; '.'
00000001000004c4 db 0x00 ; '.'
00000001000004c5 db 0x00 ; '.'
00000001000004c6 db 0x00 ; '.'
00000001000004c7 db 0x00 ; '.'
在 _stub_helper
部分(看起来像某种 infinite-ish 循环,完全跳过了中间的 4 条指令):
0000000100000f80 lea, qword [dyld_stub_binder_100001000+8]; CODE XREF=0x100000f95
0000000100000f87 push r11
0000000100000f89 jmp qword [dyld_stub_binder_100001000] ; dyld_stub_binder
0000000100000f8f db 0x90
0000000100000f90 push 0x0
0000000100000f95 jmp 0x100000f80
在 __DATA__nl_symbol_ptr
部分:
0000000100001000 dq dyld_stub_binder ; DATA XREF=0x100000f89
0000000100001008 dq 0x0000000000000000 ; DATA XREF=0x100000f80
在 External Symbols
段中:
dyld_stub_binder:
0000000100005010 db 0x00 ; '.' ; in /usr/lib/libSystem.B.dylib, CODE XREF=0x100000f89DATA XREF=dyld_stub_binder_100001000
0000000100005011 db 0x00 ; '.'
0000000100005012 db 0x00 ; '.'
0000000100005013 db 0x00 ; '.'
0000000100005014 db 0x00 ; '.'
0000000100005015 db 0x00 ; '.'
0000000100005016 db 0x00 ; '.'
0000000100005017 db 0x00 ; '.'
更有趣的是如果我用gcc编译:
gcc -arch x86_64 -e _start -framework Foundation -framework ApplicationServices lp.s
它将毫无问题地构建,但在 运行 时间的某个时候会出现段错误。我说在某些时候是因为如果我用 lldb a.out
加载它并执行 run
命令,它会正常执行,没有段错误。所以很难找出到底发生了什么。我的直觉是 lldb
将我的应用程序指向 正确的 dyld_stub_binder
但我可能是错的。
然而,如果我 运行 sudo ./myfile
在 gcc
版本上 运行 完全没问题。 gcc
在做什么而 ld
不是?还是 as
命令中的内容?
我对使用核心 macOS 程序集还是比较陌生,所以任何指示都会有所帮助!
P.S。我也尝试了 -no_weak_imports
但那也不起作用
您的 ld myprogram.o -arch x86_64 -macosx_version_min 10.12 -e _start -framework Foundation -framework ApplicationServices -o myprogram
缺少 -l
libSystem.B
库的搜索选项。
添加以下任一项:
-lsystem.b
-lsystem
-lc
-lm
-ld
所有都是同义词,可以解决缺少的 LC_LOAD_DYLIB(libSystem.B.dylib)
加载命令。顺便说一句,你的程序有效:-)