[swift-dev] Porting swift to FreeBSD

Davide Italiano dccitaliano at gmail.com
Sun Dec 13 04:52:19 CST 2015


On Sun, Dec 13, 2015 at 12:35 AM, Davide Italiano <dccitaliano at gmail.com> wrote:
> On Sun, Dec 13, 2015 at 12:30 AM, Dmitri Gribenko <gribozavr at gmail.com> wrote:
>> On Sat, Dec 12, 2015 at 9:26 PM, Davide Italiano <dccitaliano at gmail.com> wrote:
>>> On Sun, Dec 13, 2015 at 12:22 AM, Dmitri Gribenko <gribozavr at gmail.com> wrote:
>>>> On Sat, Dec 12, 2015 at 9:09 PM, Davide Italiano <dccitaliano at gmail.com> wrote:
>>>>> On Sat, Dec 12, 2015 at 11:45 PM, Dmitri Gribenko <gribozavr at gmail.com> wrote:
>>>>>> On Sat, Dec 12, 2015 at 8:29 PM, Davide Italiano via swift-dev
>>>>>> <swift-dev at swift.org> wrote:
>>>>>>> Hi,
>>>>>>> I'm a FreeBSD developer who has been working on porting swift to FreeBSD.
>>>>>>> I'm at a point where with a local patch (
>>>>>>> https://people.freebsd.org/~davide/swift/build_freebsd.diff ) to fix
>>>>>>> build errors I'm able to build the compiler itself on FreeBSD 11
>>>>>>> (-CURRENT).
>>>>>>
>>>>>> +Doug for this patch.
>>>>>>
>>>>>>> The compiler itself seems to work fine (at least semantic analysis is
>>>>>>> able to produce the correct result for toy examples).
>>>>>>> Example:
>>>>>>>
>>>>>>> % cat hello.swift
>>>>>>> let number = 4
>>>>>>> println(number)
>>>>>>>
>>>>>>> % ./swiftc hello.swift -o hello
>>>>>>> hello.swift:2:1: error: 'println' has been renamed to 'print'
>>>>>>> println(number)
>>>>>>> ^~~~~~~
>>>>>>> [...]
>>>>>>>
>>>>>>> The executables generated seem to have some problems, though.
>>>>>>> This is what I see:
>>>>>>>
>>>>>>> % cat hello2.swift
>>>>>>> let number = 4
>>>>>>> print(number)
>>>>>>> % ./swiftc hello2.swift -o hello2
>>>>>>>  % ./hello2
>>>>>>> Int(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(String(Stri
>>>>>>
>>>>>> The reason is that the program can't find the protocol conformance
>>>>>> tables.  On Linux, we are using a linker script to collect all
>>>>>> conformances into one section, and insert symbols at the beginning and
>>>>>> at the end, see stdlib/public/runtime/swift.ld.  The code that reads
>>>>>> these sections is in stdlib/public/runtime/Casting.cpp.
>>>>>>
>>>>>
>>>>> Thanks Dmitri.
>>>>> The linker script is actually executed on FreeBSD as well (with a
>>>>> recent version of GNU ld, with the old ld shipped with FreeBSD or gold
>>>>> the parsing of the linker script fails)
>>>>>
>>>>> and the section is created (as objdump -h witnesses):
>>>>>
>>>>>  20 .dtors        00000010  0000000000603218  0000000000603218  00003218  2**3
>>>>>                   CONTENTS, ALLOC, LOAD, DATA
>>>>>  21 .swift2_protocol_conformances 00000008  0000000000603228
>>>>> 0000000000603228  00003228  2**0
>>>>>                   CONTENTS, ALLOC, LOAD, DATA
>>>>>  22 .jcr          00000008  0000000000603230  0000000000603230  00003230  2**3
>>>>>                   CONTENTS, ALLOC, LOAD, DATA
>>>>>
>>>>> % objdump -t ./hello | grep conformances
>>>>> 0000000000603228 l    d  .swift2_protocol_conformances
>>>>> 0000000000000000              .swift2_protocol_conformances
>>>>> 0000000000603228 g       .swift2_protocol_conformances
>>>>> 0000000000000000              .swift2_protocol_conformances_start
>>>>>
>>>>> Although the section seems to be empty/corrupted:
>>>>
>>>> It should be empty in the binary (since this simple program does not
>>>> define any new conformances to protocols).  Could you try checking the
>>>> standard library, libswiftCore.so:
>>>>
>>>
>>>  % objdump -t ./lib/swift/freebsd/x86_64/libswiftCore.so | grep conformances
>>> 0000000000833710 l    d  .swift2_protocol_conformances
>>> 0000000000000000              .swift2_protocol_conformances
>>> 0000000000833710 l     O .swift2_protocol_conformances
>>> 0000000000002eb0              l_protocol_conformances
>>> 00000000008365c0 g       .swift2_protocol_conformances
>>> 0000000000000000              _edata
>>>
>>>  % objdump -s -j .swift2_protocol_conformances
>>> ./lib/swift/freebsd/libswiftCore.so |head -n 10
>>>
>>> ./lib/swift/freebsd/libswiftCore.so:     file format elf64-x86-64-freebsd
>>>
>>> Contents of section .swift2_protocol_conformances:
>>>  833710 00000000 00000000 00000000 04000000  ................
>>>  833720 00000000 00000000 00000000 04000000  ................
>>
>> The section should start with an 8-byte size of the conformances
>> section, seems to be missing here (compare to my output, which has
>> "b02e0000 00000000").
>>
>> The linker script adds this size using:
>>
>> QUAD(SIZEOF(.swift2_protocol_conformances) - 8) ;
>>
>> Could you verify you have that line?
>>
>
> hmm, apparently we replied almost at the same time.
> Anyway, yes, my linker script has the QUAD line.
>
> SECTIONS
> {
>   .swift2_protocol_conformances :
>   {
>     .swift2_protocol_conformances_start = . ;
>     QUAD(SIZEOF(.swift2_protocol_conformances) - 8) ;
>     *(.swift2_protocol_conformances) ;
>   }
> }
> INSERT AFTER .dtors

I found the problem. For the standard library the section weren't
coalesced because the correct flags weren't passed to the linker in
FreeBSD.
The following patch, which I'm going to submit soon, fixes the problem for me.

diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 48288b7..37cb2ba 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -1099,10 +1099,11 @@ function(_add_swift_library_single target name)
     set(PLIST_INFO_BUILD_VERSION)
   endif()

-  # On Linux add the linker script that coalesces protocol conformance
-  # sections. This wouldn't be necessary if the link was done by the swift
-  # binary: rdar://problem/19007002
-  if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+  # On Linux and FreeBSD add the linker script that coalesces protocol
+  # conformance sections. This wouldn't be necessary if the link was done by
+  # the swift binary: rdar://problem/19007002
+  if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" OR
+    "${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
     list(APPEND link_flags
         "-Xlinker" "-T"
         "-Xlinker" "${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}/swift.ld")

And now, swift compiled programs run correctly on FreeBSD!

% ./swiftc hello.swift -o hello
davide at rabbit1:/exps/swift/build/Ninja-ReleaseAssert/swift-freebsd-x86_64/bin
% ./hello
hello
% cat hello.swift
print ("hello")

Thank you for your assistance Dmitri.

--
Davide


More information about the swift-dev mailing list