How to emit metadata for builtins

Hi all,

Bit of a funny question (as usual for me!)

I’m building and compiling my own standard library, not using ninja to do it.

I do ninja swift To build the compiler then use it to build my stdlib. It’s mostly working (now the avr back end is more stable).

My missing piece is the metadata for builtins.

In docs/Runtime.rst there’s a section about “Standard metadata” that says

“The Swift runtime exports standard metadata objects for Builtin types as well as standard value witness tables that can be freely adopted by types with common layout attributes.”

Unless I’m being dumb, there’s no code in stdlib/public/runtime to create these metadata structures. So I’m assuming that during some point in the standard build process, while the standard library module and binaries are being constructed, somehow swift is “told” to emit metadata for builtin types?

Can someone please tell me how this is done? Is there a command line something like:

swiftc —emit-metadata “Builtin.Object”?

I couldn’t see how it’s being done. And I can’t decide the intricacies of the cmake files driving it or grep through to find the commands used.

Thanks for any advice you can give as ever!

Carl

The Builtin metadata are automatically emitted in IRGen when the following options are present:
-parse-stdlib -module-name Swift. There's some code around here: swift/GenReflection.cpp at main · apple/swift · GitHub that can help guide you. Edit: There's also the following file that declares builtin metadata in the runtime: swift/KnownMetadata.cpp at main · apple/swift · GitHub .

2 Likes

Great answer, thanks @Alejandro! I am building my stdlib with those exact command line switches. So it should have worked. Looking at swift/GenReflection.cpp at main · apple/swift · GitHub, it looks like it emits "reflection metadata". I'm not 100% sure what that is!

I did an objdump -t on my libSwift.a and looked for things like Bi1_. After a bit of hunting, found these:

00000000  w    O swift5_builtin	00000014 .hidden $sBi1_MB
00000034  w    O swift5_typeref	00000003 .hidden symbolic Bo
00000000  w    O swift5_builtin	00000014 .hidden $sBoMB
00000038  w    O swift5_typeref	00000003 .hidden symbolic BO
00000000  w    O swift5_builtin	00000014 .hidden $sBOMB
0000003c  w    O swift5_typeref	00000003 .hidden symbolic Bb
00000000  w    O swift5_builtin	00000014 .hidden $sBbMB
00000040  w    O swift5_typeref	00000003 .hidden symbolic Bp
00000000  w    O swift5_builtin	00000014 .hidden $sBpMB
00000044  w    O swift5_typeref	00000003 .hidden symbolic BB
00000000  w    O swift5_builtin	00000014 .hidden $sBBMB
00000048  w    O swift5_typeref	00000005 .hidden symbolic yyXf
00000000  w    O swift5_builtin	00000014 .hidden $syyXfMB
0000004e  w    O swift5_typeref	00000005 .hidden symbolic ypXp
00000000  w    O swift5_builtin	00000014 .hidden $sypXpMB
00000004 g     O .rodata.$sSbMf	00000010 .protected $sSbN

...so that's part of the story. Currently my ELF file is failing link with...

ld.lld: error: undefined symbol: $sBoWV
>>> referenced by main.bc
>>>               main.o:

A quick demangle...

Carls-MacBook-Pro:AVR carlpeto$ sd sBoMB
$sBoMB ---> reflection metadata builtin descriptor Builtin.NativeObject
Carls-MacBook-Pro:AVR carlpeto$ sd sBoWV
$sBoWV ---> value witness table for Builtin.NativeObject
Carls-MacBook-Pro:AVR carlpeto$

So I'm guessing that the automatic emission you were talking about is only for the "reflection metadata"? And the value witness tables are created "by hand" in C++ in stdlib/public/runtime/KnownMetadata.cpp, is that right?

So to get my program to link, I probably just need to compile and link stdlib/public/runtime/KnownMetadata.cpp into my runtime, right?

Carl