I built a very simple swift program (minimal hello world) using the arm swiftc and the x86_64 swiftc, and had them emit the sil and llvm ir. The sil it substantially similar between the toolchain tarball on swift.org and my arm swiftc, except that the arm version has a few sil_vtable, NSArray, and ObjectiveC references that are not in the x86_86 version. Is it possible that the arm architecture is triggering assumptions about whether this target is linux or darwin? Fortunately or unfortunately, by the time it gets to LLVM IR it’s effectively identical (other than the odd difference in variable size or alignment).
- Will $ cat hello.swift print("Hello world!") diff hello.sil-arm hello.sil-x86 ... < // Swift._SwiftNativeNSArrayWithContiguousStorage.__deallocating_deinit < sil hidden_external [fragile] @_TFCs40_SwiftNativeNSArrayWithContiguousStorageD : $@convention(method) (@owned _SwiftNativeNSArrayWithContiguousStorage) -> () < < // Swift.NonObjectiveCBase.init () -> Swift.NonObjectiveCBase < sil [fragile] @_TFCs17NonObjectiveCBasecfT_S_ : $@convention(method) (@owned NonObjectiveCBase) -> @owned NonObjectiveCBase < < // Swift.NonObjectiveCBase.__deallocating_deinit < sil [fragile] @_TFCs17NonObjectiveCBaseD : $@convention(method) (@owned NonObjectiveCBase) -> () ... < < sil_vtable _SwiftNativeNSArrayWithContiguousStorage { < #_SwiftNativeNSArrayWithContiguousStorage.deinit!deallocator: _TFCs40_SwiftNativeNSArrayWithContiguousStorageD // Swift._SwiftNativeNSArrayWithContiguousStorage.__deallocating_deinit < } < < sil_vtable NonObjectiveCBase { < #NonObjectiveCBase.init!initializer.1: _TFCs17NonObjectiveCBasecfT_S_ // Swift.NonObjectiveCBase.init () -> Swift.NonObjectiveCBase < #NonObjectiveCBase.deinit!deallocator: _TFCs17NonObjectiveCBaseD // Swift.NonObjectiveCBase.__deallocating_deinit ... wdillon@tegra-ubuntu:~$ grep "sil_vtable" hello* hello.sil-x86:sil_vtable _ContiguousArrayStorage { hello.sil-x86:sil_vtable _HeapBufferStorage { hello.sil-arm:sil_vtable _ContiguousArrayStorage { hello.sil-arm:sil_vtable _HeapBufferStorage { hello.sil-arm:sil_vtable _ContiguousArrayStorage1 { hello.sil-arm:sil_vtable _ContiguousArrayStorageBase { hello.sil-arm:sil_vtable _SwiftNativeNSArrayWithContiguousStorage { hello.sil-arm:sil_vtable NonObjectiveCBase { wdillon@tegra-ubuntu:~$ wdillon@tegra-ubuntu:~$ grep "NonObjectiveC" hello* hello.sil-x86: #NonObjectiveCBase.init!initializer.1: _TFCs18_HeapBufferStoragecfT_GS_xq__ // Swift._HeapBufferStorage.init () -> Swift._HeapBufferStorage<A, B> hello.sil-x86:sil_witness_table NonObjectiveCBase: AnyObject module Swift hello.sil-arm:// Swift.NonObjectiveCBase.init () -> Swift.NonObjectiveCBase hello.sil-arm:sil [fragile] @_TFCs17NonObjectiveCBasecfT_S_ : $@convention(method) (@owned NonObjectiveCBase) -> @owned NonObjectiveCBase hello.sil-arm:// Swift.NonObjectiveCBase.__deallocating_deinit hello.sil-arm:sil [fragile] @_TFCs17NonObjectiveCBaseD : $@convention(method) (@owned NonObjectiveCBase) -> () hello.sil-arm: #NonObjectiveCBase.init!initializer.1: _TFCs18_HeapBufferStoragecfT_GS_xq__ // Swift._HeapBufferStorage.init () -> Swift._HeapBufferStorage<A, B> hello.sil-arm:sil_vtable NonObjectiveCBase { hello.sil-arm: #NonObjectiveCBase.init!initializer.1: _TFCs17NonObjectiveCBasecfT_S_ // Swift.NonObjectiveCBase.init () -> Swift.NonObjectiveCBase hello.sil-arm: #NonObjectiveCBase.deinit!deallocator: _TFCs17NonObjectiveCBaseD // Swift.NonObjectiveCBase.__deallocating_deinit hello.sil-arm:sil_witness_table NonObjectiveCBase: AnyObject module Swift > On Dec 14, 2015, at 6:22 PM, Dmitri Gribenko <griboz...@gmail.com> wrote: > > On Mon, Dec 14, 2015 at 5:57 PM, William Dillon via swift-dev > <swift-dev@swift.org> wrote: >> I’m still stuck on this after a while, but I’ve been paying attention to >> other discussions (specifically the FreeBSD port), as well as reading tons >> of code. One thing I noticed while writing up my observations on my blog >> http://www.housedillon.com/?p=2267 is that in >> stdlib/public/runtime/CMakeLists.txt there is a FIXME that seems relevant: >> >> foreach(sdk ${SWIFT_CONFIGURED_SDKS}) >> if("${sdk}" STREQUAL "LINUX" OR "${sdk}" STREQUAL "FREEBSD") >> foreach(arch ${SWIFT_SDK_${sdk}_ARCHITECTURES}) >> set(arch_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}") >> >> # FIXME: We will need a different linker script for 32-bit builds. >> configure_file( >> "swift.ld" "${SWIFTLIB_DIR}/${arch_subdir}/swift.ld" COPYONLY) >> >> swift_install_in_component(compiler >> FILES "swift.ld" >> DESTINATION "lib/swift/${arch_subdir}") >> >> endforeach() >> endif() >> endforeach() >> >> >> I went ahead and added a conditional for arm, and split swift.ld into >> swift_64.ld and swift_32.ld: > > The reason why I left that comment there is that the linker script > adds a size field to the protocol conformance section, and I thought > that the 32-bit system should have the size be a 32-bit value, so that > would be the difference. > > But the source always loads a 64-bit quantity from the section, so the > FIXME is stale: > > // Extract the size of the conformances block from the head of the section > auto conformancesSize = *reinterpret_cast<const uint64_t*>(conformances); > >> I decided to go ahead and check the same conformances that Dmitri and Davide >> investigated: >> >> $ objdump -t libswiftCore.so | grep conformances >> 003b8ebc l d .swift2_protocol_conformances 00000000 >> .swift2_protocol_conformances >> 003b8ec4 l O .swift2_protocol_conformances 00002f50 >> l_protocol_conformances >> 003b8ebc g .swift2_protocol_conformances 00000000 >> .swift2_protocol_conformances_start >> >> $ objdump -s -j .swift2_protocol_conformances libswiftCore.so |head -n 10 >> >> libswiftCore.so: file format elf32-littlearm >> >> Contents of section .swift2_protocol_conformances: >> 3b8ebc 542f0000 00000000 00000000 00000000 T/.............. >> 3b8ecc 00000000 04000000 00000000 00000000 ................ >> 3b8edc 00000000 04000000 00000000 00000000 ................ >> 3b8eec 00000000 04000000 00000000 00000000 ................ >> 3b8efc 00000000 04000000 00000000 00000000 ................ >> 3b8f0c 00000000 04000000 00000000 00000000 ................ >> >> And that seems OK based on Dmitri’s basic description of how it works. > > Yes, this looks correct to me. > >> >> Paradoxically, I also added a print (and eventually an exit()) to >> _addImageProtocolConformances() to see if it’s ever run. I don’t believe it >> is: >> >> $ swiftc test.swift >> <unknown>:0: error: unable to load standard library for target >> 'armv7l-unknown-linux-gnueabihf' >> $ swiftc -target arm-unknown-linux-gnueabihf test.swift >> $ ./test >> ./test: error while loading shared libraries: >> /mnt/build/build/Ninja-ReleaseAssert/swift-linux-arm/lib/swift/linux/libswiftCore.so: >> unexpected reloc type 0x03 > > The dynamic loader does not finish running, so the code does not even > get a chance to run. > >> Are there any other paths that I should be following that you can think of? > > I think it would make most sense to try to: > > (1) figure out what part of the library code (on the LLVM IR level) > produces this illegal relocation (on the high level, e.g., "this > symbol", "this runtime data structure" etc.), > > (2) provide a minimized LLVM IR example that produces the illegal relocation. > > Dmitri > > -- > main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if > (j){printf("%d\n",i);}}} /*Dmitri Gribenko <griboz...@gmail.com>*/ _______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev