Я написал этот код.
// a.swift
struct Stone {
var weight: Int = 3
}
Я выпустил сборку этой командой и получил следующие строки.
$ swiftc -emit-assembly a.swift
_$s1a5StoneVMn:
.long 81
.long (_$s1aMXM-_$s1a5StoneVMn)-4
.long (l___unnamed_2-_$s1a5StoneVMn)-8
.long (_$s1a5StoneVMa-_$s1a5StoneVMn)-12
.long (_$s1a5StoneVMF-_$s1a5StoneVMn)-16
.long 1
.long 2
.section __DATA,__const
.p2align 3
_$s1a5StoneVMf:
.quad _$sBi64_WV
.quad 512
.quad _$s1a5StoneVMn
.long 0
.space 4
Это дескриптор номинального типа и метаданные полного типа.
Я выпустил объектный файл этой командой.
$ swiftc -emit-object a.swift
По этой команде я просматривал содержимое объектного файла.
$ objdump -x -s a.o
Я получил эти выводы.
SYMBOL TABLE:
0000000000000100 l O __DATA,__const _$s1a5StoneVMf
00000000000000e0 g O __TEXT,__const _$s1a5StoneVMn
Contents of section __const:
00c8 61000000 00000000 00000000 f8ffffff a...............
00d8 53746f6e 65000000 51000000 fcffffff Stone...Q.......
00e8 f8ffffff f4ffffff f0ffffff 01000000 ................
00f8 02000000 0300 ......
Contents of section __const:
0100 00000000 00000000 00020000 00000000 ................
0110 00000000 00000000 00000000 00000000 ................
RELOCATION RECORDS FOR [__const]:
0000000000000028 X86_64_RELOC_SUBTRACTOR _$s1a5StoneVMF-_$s1a5StoneVMn
0000000000000028 X86_64_RELOC_UNSIGNED _$s1a5StoneVMF
0000000000000024 X86_64_RELOC_SUBTRACTOR _$s1a5StoneVMa-_$s1a5StoneVMn
0000000000000024 X86_64_RELOC_UNSIGNED _$s1a5StoneVMa
0000000000000020 X86_64_RELOC_SUBTRACTOR l___unnamed_2-_$s1a5StoneVMn
0000000000000020 X86_64_RELOC_UNSIGNED l___unnamed_2
000000000000001c X86_64_RELOC_SUBTRACTOR _$s1aMXM-_$s1a5StoneVMn
000000000000001c X86_64_RELOC_UNSIGNED _$s1aMXM
RELOCATION RECORDS FOR [__const]:
0000000000000000 X86_64_RELOC_UNSIGNED _$sBi64_WV
Для относительного указателя в дескрипторе номинального типа представлены записи о перемещении и значения.
Например, .long (_$s1aMXM-_$s1a5StoneVMn)-4
в сборке представлен записью перемещения X86_64_RELOC_SUBTRACTOR _$s1aMXM-_$s1a5StoneVMn
со смещением 0x1C. Начальный адрес секции - 0xC8. Таким образом, эта запись указывает 0xE4 и значение fcffffff(= -4)
там.
Один абсолютный указатель в метаданных полного типа находится в записи перемещения X86_64_RELOC_UNSIGNED _$sBi64_WV
. Следующее литеральное значение 512 также существует в 0x0180 как 00020000 00000000
. Это 512.
Почему не существует записи перемещения для дескриптора именного типа в метаданных полного типа (.quad _$s1a5StoneVMn
)?
Значение в этом поле равно 0.
Как компилятор и компоновщик обрабатывают этот указатель?
Мое окружение:
macOS Catalina 10.15 Beta(19A501i)
Xcode Version 11.0 beta 3 (11M362v)
Apple Swift version 5.1 (swiftlang-1100.0.212.5 clang-1100.0.28.2)
Target: x86_64-apple-darwin19.0.0