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
cmd/go: dlopen of c-shared binary on MacOS fails with "segment filesize exceeds vmsize" #50506
Comments
How is your shared library built? Could you try writing a C program that dlopen it and see if it works? Thanks. |
With
I forgot a few important details about my system. I will add it to the description. |
Some more data points:
|
On MacOS Catalina (10.15.7) with
same result. |
Ok, with a minimal C program there was no problem. So I had the gut feeling it has something to do with MacOS containers and security restrictions. I copied the ssh executable into my home directory and started it from there. And, lo and behold, it works! So, I have to find out how to increase the vmsize for system tools on MacOS. Nothing wrong with Go. Sorry for the noise. Closing. |
Thanks for following up. |
I still think there might be something wrong, which only is checked in certain situations. Look here:
In the last segment (__DWARF), the vmsize is 0, which is indeed smaller than the filesize of 2570152. Here the full output$ otool -l ./pkcs11.so ./pkcs11.so: Load command 0 cmd LC_SEGMENT_64 cmdsize 632 segname __TEXT vmaddr 0x0000000000000000 vmsize 0x0000000000374000 fileoff 0 filesize 3620864 maxprot 0x00000005 initprot 0x00000005 nsects 7 flags 0x0 Section sectname __text segname __TEXT addr 0x00000000000029c0 size 0x00000000002f1796 offset 10688 align 2^5 (32) reloff 0 nreloc 0 flags 0x80000400 reserved1 0 reserved2 0 Section sectname __stubs segname __TEXT addr 0x00000000002f4156 size 0x00000000000001f8 offset 3096918 align 2^1 (2) reloff 0 nreloc 0 flags 0x80000408 reserved1 0 (index into indirect symbol table) reserved2 6 (size of stubs) Section sectname __stub_helper segname __TEXT addr 0x00000000002f4350 size 0x0000000000000358 offset 3097424 align 2^2 (4) reloff 0 nreloc 0 flags 0x80000400 reserved1 0 reserved2 0 Section sectname __rodata segname __TEXT addr 0x00000000002f46c0 size 0x000000000007c914 offset 3098304 align 2^5 (32) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __const segname __TEXT addr 0x0000000000370fe0 size 0x0000000000000b78 offset 3608544 align 2^5 (32) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __cstring segname __TEXT addr 0x0000000000371b58 size 0x0000000000000074 offset 3611480 align 2^3 (8) reloff 0 nreloc 0 flags 0x00000002 reserved1 0 reserved2 0 Section sectname __eh_frame segname __TEXT addr 0x0000000000371bd0 size 0x0000000000002430 offset 3611600 align 2^3 (8) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Load command 1 cmd LC_SEGMENT_64 cmdsize 632 segname __DATA_CONST vmaddr 0x0000000000374000 vmsize 0x0000000000250000 fileoff 3620864 filesize 2424832 maxprot 0x00000003 initprot 0x00000003 nsects 7 flags 0x10 Section sectname __got segname __DATA_CONST addr 0x0000000000374000 size 0x0000000000000010 offset 3620864 align 2^3 (8) reloff 0 nreloc 0 flags 0x00000006 reserved1 84 (index into indirect symbol table) reserved2 0 Section sectname __mod_init_func segname __DATA_CONST addr 0x0000000000374010 size 0x0000000000000008 offset 3620880 align 2^3 (8) reloff 0 nreloc 0 flags 0x00000009 reserved1 0 reserved2 0 Section sectname __rodata segname __DATA_CONST addr 0x0000000000374020 size 0x00000000000a39a8 offset 3620896 align 2^5 (32) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __typelink segname __DATA_CONST addr 0x00000000004179e0 size 0x0000000000001be0 offset 4291040 align 2^5 (32) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __itablink segname __DATA_CONST addr 0x00000000004195c0 size 0x0000000000000a50 offset 4298176 align 2^5 (32) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __gosymtab segname __DATA_CONST addr 0x000000000041a010 size 0x0000000000000000 offset 4300816 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __gopclntab segname __DATA_CONST addr 0x000000000041a020 size 0x00000000001a9a60 offset 4300832 align 2^5 (32) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Load command 2 cmd LC_SEGMENT_64 cmdsize 552 segname __DATA vmaddr 0x00000000005c4000 vmsize 0x0000000000098000 fileoff 6045696 filesize 376832 maxprot 0x00000003 initprot 0x00000003 nsects 6 flags 0x0 Section sectname __la_symbol_ptr segname __DATA addr 0x00000000005c4000 size 0x00000000000002a0 offset 6045696 align 2^3 (8) reloff 0 nreloc 0 flags 0x00000007 reserved1 86 (index into indirect symbol table) reserved2 0 Section sectname __go_buildinfo segname __DATA addr 0x00000000005c42a0 size 0x0000000000000020 offset 6046368 align 2^4 (16) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __noptrdata segname __DATA addr 0x00000000005c42c0 size 0x000000000004a3a0 offset 6046400 align 2^5 (32) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __data segname __DATA addr 0x000000000060e660 size 0x000000000000fc10 offset 6350432 align 2^5 (32) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __bss segname __DATA addr 0x000000000061e280 size 0x000000000003261c offset 0 align 2^5 (32) reloff 0 nreloc 0 flags 0x00000001 reserved1 0 reserved2 0 Section sectname __noptrbss segname __DATA addr 0x00000000006508a0 size 0x0000000000007cc0 offset 0 align 2^5 (32) reloff 0 nreloc 0 flags 0x00000001 reserved1 0 reserved2 0 Load command 3 cmd LC_SEGMENT_64 cmdsize 72 segname __LINKEDIT vmaddr 0x000000000065c000 vmsize 0x00000000000908c8 fileoff 8994816 filesize 592072 maxprot 0x00000001 initprot 0x00000001 nsects 0 flags 0x0 Load command 4 cmd LC_ID_DYLIB cmdsize 40 name pkcs11.so (offset 24) time stamp 1 Thu Jan 1 01:00:01 1970 current version 0.0.0 compatibility version 0.0.0 Load command 5 cmd LC_DYLD_INFO_ONLY cmdsize 48 rebase_off 8994816 rebase_size 50640 bind_off 9045456 bind_size 40 weak_bind_off 0 weak_bind_size 0 lazy_bind_off 9045496 lazy_bind_size 1720 export_off 9047216 export_size 2016 Load command 6 cmd LC_SYMTAB cmdsize 24 symoff 9059968 nsyms 10937 stroff 9235640 strsize 351248 Load command 7 cmd LC_DYSYMTAB cmdsize 80 ilocalsym 0 nlocalsym 10757 iextdefsym 10757 nextdefsym 94 iundefsym 10851 nundefsym 86 tocoff 0 ntoc 0 modtaboff 0 nmodtab 0 extrefsymoff 0 nextrefsyms 0 indirectsymoff 9234960 nindirectsyms 170 extreloff 0 nextrel 0 locreloff 0 nlocrel 0 Load command 8 cmd LC_UUID cmdsize 24 uuid EE3F98D2-BF6A-367B-BDA2-7F9741034BBA Load command 9 cmd LC_BUILD_VERSION cmdsize 32 platform 1 minos 11.5 sdk 11.0 ntools 1 tool 3 version 711.0 Load command 10 cmd LC_SOURCE_VERSION cmdsize 16 version 0.0 Load command 11 cmd LC_LOAD_DYLIB cmdsize 104 name /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (offset 24) time stamp 2 Thu Jan 1 01:00:02 1970 current version 1775.118.101 compatibility version 150.0.0 Load command 12 cmd LC_LOAD_DYLIB cmdsize 96 name /System/Library/Frameworks/Security.framework/Versions/A/Security (offset 24) time stamp 2 Thu Jan 1 01:00:02 1970 current version 59754.100.106 compatibility version 1.0.0 Load command 13 cmd LC_LOAD_DYLIB cmdsize 56 name /usr/lib/libSystem.B.dylib (offset 24) time stamp 2 Thu Jan 1 01:00:02 1970 current version 1292.100.5 compatibility version 1.0.0 Load command 14 cmd LC_LOAD_DYLIB cmdsize 72 name /usr/local/opt/gcc/lib/gcc/11/libgcc_s.1.dylib (offset 24) time stamp 2 Thu Jan 1 01:00:02 1970 current version 1.0.0 compatibility version 1.0.0 Load command 15 cmd LC_FUNCTION_STARTS cmdsize 16 dataoff 9049232 datasize 10736 Load command 16 cmd LC_DATA_IN_CODE cmdsize 16 dataoff 9059968 datasize 0 Load command 17 cmd LC_SEGMENT_64 cmdsize 1192 segname __DWARF vmaddr 0x0000000000000000 vmsize 0x0000000000000000 fileoff 6422528 filesize 2570152 maxprot 0x00000007 initprot 0x00000000 nsects 14 flags 0x0 Section sectname __zdebug_line segname __DWARF addr 0x00000000006dc000 size 0x0000000000071c26 offset 6422528 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zdebug_pubname segname __DWARF addr 0x000000000074dc26 size 0x000000000001e52e offset 6888486 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zdebug_loc segname __DWARF addr 0x000000000076c154 size 0x000000000007b5f7 offset 7012692 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zdebug_ranges segname __DWARF addr 0x00000000007e774b size 0x0000000000028bac offset 7518027 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zdebug_pubtype segname __DWARF addr 0x00000000008102f7 size 0x0000000000009ba5 offset 7684855 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zdebug_aranges segname __DWARF addr 0x0000000000819e9c size 0x000000000000714b offset 7724700 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zdebug_info segname __DWARF addr 0x0000000000820fe7 size 0x0000000000098a14 offset 7753703 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zdebug_frame segname __DWARF addr 0x00000000008b99fb size 0x0000000000015268 offset 8378875 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zdebug_abbrev segname __DWARF addr 0x00000000008cec63 size 0x00000000000001ff offset 8465507 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zdebug_str segname __DWARF addr 0x00000000008cee62 size 0x0000000000023e8b offset 8466018 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zapple_names segname __DWARF addr 0x00000000008f2ced size 0x0000000000046b21 offset 8613101 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __apple_namespac segname __DWARF addr 0x000000000093980e size 0x0000000000000024 offset 8902670 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __zapple_types segname __DWARF addr 0x0000000000939832 size 0x0000000000015f52 offset 8902706 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 Section sectname __apple_objc segname __DWARF addr 0x000000000094f784 size 0x0000000000000024 offset 8992644 align 2^0 (1) reloff 0 nreloc 0 flags 0x00000000 reserved1 0 reserved2 0 |
The DWARF segment has always been weird with the darwin dynamic linker. The DWARF segment is not a loadable segment, meaning that it is not loaded into memory as part of the program's address space, therefore "vmsize" is 0. I vaguely recall that the darwin dynamic linker permits vmsize 0 for such segments. As your C program shows, dlopen does work, so I'm leaning to think this is probably not a problem. There is probably still something weird about your ssh program. As a workaround, you can try building the shared library without DWARF, by using |
The darwin dynamic linker has the following code
which allows vmsize 0. |
Change https://golang.org/cl/377854 mentions this issue: |
Does it help if you build the Go toolchain with CL https://go-review.googlesource.com/c/go/+/377854 ? Thanks. |
My error seems to come from MachOAnalyzer: else if ( (seg->filesize > seg->vmsize) && ((seg->vmsize != 0) || ((seg->flags & SG_NORELOC) == 0)) ) {
// <rdar://problem/19986776> dyld should support non-allocatable __LLVM segment
diag.error("in '%s' segment filesize exceeds vmsize", path);
badSegmentLoadCommand = true;
stop = true;
} (https://opensource.apple.com/source/dyld/dyld-852.2/dyld3/MachOAnalyzer.cpp.auto.html) Maybe the analyzer is only used for secured code (like system tools) or something like that.
The failing ssh is the original
Will try. |
Oh, that is a hot lead. I will try, thanks! |
@cherrymui Oh, wow, that reduced the size of the library by 28%! I can't seem to be able to remove the DWARF debugging info with the strip tool on MacOS. So I'm wondering, if it is actually a good idea to include them by default. 🤔 But the important info is: it works! So it not only works but also makes the lib a lot smaller (2.5 MB in my case). Thanks! |
@cherrymui It unfortunately doesn't work but brings a new error:
Seems like __DWARF must come before __DATA_CONST? |
The down side is that this flag makes the debugging experience much worse (if you ever need it). Go generally includes debug information by default in almost all configurations, so I don't think we'll change the default to this particular case. You can always use this flag if you don't want debug info. You can also set environment variable |
MachOAnalyzer again: // check for out of order segments
if ( (seg1Index < seg2Index) && !stop1 ) {
if ( (seg1vmAddr > seg2vmAddr) || ((seg1FileOffset > seg2FileOffset) && (seg1FileOffset != 0) && (seg2FileOffset != 0)) ){
diag.warning("segment load commands out of order with respect to layout for %s and %s", seg1Name, seg2Name);
badSegments = true;
stop1 = true;
stop2 = true;
}
} |
@cherrymui So, you also don't know a way how to remove it from the binary afterwards? |
Could you try the updated version of the CL, which also sets vmaddr? In the past it's been difficult to please the dynamic linker about the unmapped segment, and we've fiddled the condition a few times (see #32673). I'm not sure what will work for all configurations. I'm also unclear why dyld3 is involved in your case but not other cases (I've almost never seen it gets involved). |
I've never used any tools that removes the DWARF segment from a binary. Googling "mach-o remove segment" found https://github.com/Tyilo/macho_edit . llvm-objcopy might also do. (I've never tried any of them.) It is probably also possible to write a Go program that does so, using the debug/macho package. |
Well, that CL doesn't work. It causes flaky SIGBUS failures on macOS ARM64. Given that dlopen works in general, and there is a workaround in the particular case (the -w flag), I'm going to stop fiddling the conditions and give up. Feel free to reopen if you think there is anyway forward. Thanks. |
Sure, it's quite a corner case. Now hopefully other people will find the workaround with this issue. Thanks for your efforts, @cherrymui! |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Build any binary with
-buildmode=c-shared
and try to load as it PKCS#11 module with OpenSSH likessh -I ./c-shared.so ...
What did you expect to see?
For arbitrary c-shared binaries it should fail with
and in case of a proper PKCS11 module it should not fail at all.
What did you see instead?
However, loading the same library with pkcs11-tool (installed with brew) works. So it might be a bug in OpenSSH, but since it can load other pkcs11 modules, I guess that is unlikely.
Environment
MacOS 11.6.2
The text was updated successfully, but these errors were encountered: