[swift-dev] [SR-40] Port Swift to Arm progress / question

William Dillon william at housedillon.com
Mon Dec 14 19:57:22 CST 2015


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:

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}")

      if("${arch}" STREQUAL "arm")
        configure_file(
            "swift_32.ld" "${SWIFTLIB_DIR}/${arch_subdir}/swift.ld" COPYONLY)
      else()
        configure_file(
            "swift_64.ld" "${SWIFTLIB_DIR}/${arch_subdir}/swift.ld" COPYONLY)
      endif()

      swift_install_in_component(compiler
          FILES "swift.ld"
          DESTINATION "lib/swift/${arch_subdir}")

    endforeach()
  endif()
endforeach()


But, I don’t know exactly what would need to change for the 32-bit ld script.  

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.

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

Are there any other paths that I should be following that you can think of?
Thanks!
- Will

> On Dec 10, 2015, at 9:31 AM, Joe Groff <jgroff at apple.com> wrote:
> 
> 
>> On Dec 10, 2015, at 9:29 AM, William Dillon <william at housedillon.com> wrote:
>> 
>> Yep.  I see that are a few of those in there (1700 and change).  When it comes to linking and ELF, I am fumbling in the dark a bit.  With the hope of getting some context, I decided to see whether R_ARM_REL32 is used in any other shared libraries in the system; it is not.  It seems as though R_ARM_REL32 is not appropriate for use in dynamic libraries, but the generated swift executables are trying to use it that way.  I thought I remembered that swift binaries are only capable of static liking for the time being, is that true?  Could the problem be as simple as the compiler that I built on ARM is trying to emit executables expecting dynamic linking when that’s not supported yet?
> 
> We use relative references to symbols in the conformance table to avoid the need for the dynamic linker to eagerly resolve relocations. These should be wholly internal to the image, though, and resolvable by the static linker. I'm not sure why they'd persist to dynamic linking time like this.
> 
> -Joe
> 
>> I’m building the debug variant (I’ve been using release due to the memory requirements of linking debug) now to see if it does the same thing.  I don’t understand why the arch. change would cause differences here.
>> 
>> By the way, that pull request for module.map looks perfect.  I’ll have to wait for it to merge in before I can prepare any kind of pull request of my own.  I think that is the only thing that breaks other builds that I don’t know how to fix on my own.
>> 
>> Thanks,
>> - Will
>> 
>>> On Dec 9, 2015, at 8:23 PM, Dmitri Gribenko <gribozavr at gmail.com> wrote:
>>> 
>>> Here's a relevant line (there are lots, this is just one instance):
>>> 
>>> 003a91cc  0015d403 R_ARM_REL32       003af914   _TMps13GeneratorType
>>> 
>>> _TMps13GeneratorType ---> protocol descriptor for Swift.GeneratorType
>>> 
>>> Dmitri
>>> 
>>> On Wed, Dec 9, 2015 at 7:25 PM, William Dillon <william at housedillon.com> wrote:
>>>> I’m looking at that pull request currently, thanks for the link.
>>>> 
>>>> Here is the output of readelf -r for libswiftcore, test.swift (as compiled)
>>>> and test.swift.
>>>> 
>>>> Thanks for looking into this!
>>>> - Will
>>>> 
>>>> 
>>>> 
>>>> On Dec 9, 2015, at 7:14 PM, Dmitri Gribenko <gribozavr at gmail.com> wrote:
>>>> 
>>>> On Wed, Dec 9, 2015 at 7:05 PM, Dmitri Gribenko <gribozavr at gmail.com> wrote:
>>>> 
>>>> On Wed, Dec 9, 2015 at 3:05 PM, William Dillon via swift-dev
>>>> <swift-dev at swift.org> wrote:
>>>> 
>>>> Nick was correct in noting that __muloti4 wasn’t needed on 32-bit platforms.
>>>> I added another case to the preprocessor conditional for __muloti4, and
>>>> specified __arm__ and __linux__ for mulodi4.  The __multi3 and __divti3
>>>> references went away.
>>>> 
>>>> Then, I went on to the module.map file for bringing in the Glibc headers.
>>>> I’m trying to think of a way to either remove the architecture specific
>>>> paths to many of those libraries (they’re now x86_64-linux-gnu, but need to
>>>> be arm-linux-gnueabihf for arm).  I read the modules documentation at
>>>> http://clang.llvm.org/docs/Modules.html and it doesn’t look like it’s
>>>> possible to have conditionals in there.  I’m considering whether it’s a good
>>>> idea to preprocess that file in some way to fill them out with the correct
>>>> paths in the build scripts.  I went ahead and changed them all (breaking
>>>> x86_64 for the time being).
>>>> 
>>>> 
>>>> Did you try https://github.com/apple/swift/pull/282 ?
>>>> 
>>>> At this point, the compiler and standard library are all built, and I think
>>>> I have one final issue.  In the testing suite, the binaries generated by the
>>>> swift compiler don’t run.  They’re emitting unexpected reloc type errors.
>>>> It appears that reolc type 0x03 is R_ARM_REL32 which is not permitted for
>>>> use with shared libraries:
>>>> 
>>>> CollectionOfOne.swift.tmp/a.out: error while loading shared libraries:
>>>> /home/wdillon/build/Ninja-ReleaseAssert/swift-linux-armv7/lib/swift/linux/libswiftCore.so:
>>>> unexpected reloc type 0x03
>>>> 
>>>> This also happens with small example swift programs that I’ve written for
>>>> testing.
>>>> 
>>>> 
>>>> +John for this error.
>>>> 
>>>> 
>>>> It would be also helpful if you could find which code contains these
>>>> relocations.  Try 'objdump -R libswiftCore.so' or 'readelf -r'.
>>>> 
>>>> 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 <gribozavr at gmail.com>*/
>>>> 
>>>> 
>>>> 
>>> 
>>> 
>>> 
>>> -- 
>>> 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 <gribozavr at gmail.com>*/
>> 
> 



More information about the swift-dev mailing list