Skip to content

Commit 270b6c4

Browse files
authored
Merge pull request #13964 from ziglang/issue-11737
Misc MachO linker improvements and link-tests refactor
2 parents 68d2f68 + b20a610 commit 270b6c4

13 files changed

+897
-1010
lines changed

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -585,10 +585,13 @@ set(ZIG_STAGE2_SOURCES
585585
"${CMAKE_SOURCE_DIR}/src/link/MachO/DwarfInfo.zig"
586586
"${CMAKE_SOURCE_DIR}/src/link/MachO/Dylib.zig"
587587
"${CMAKE_SOURCE_DIR}/src/link/MachO/Object.zig"
588+
"${CMAKE_SOURCE_DIR}/src/link/MachO/Relocation.zig"
588589
"${CMAKE_SOURCE_DIR}/src/link/MachO/Trie.zig"
589590
"${CMAKE_SOURCE_DIR}/src/link/MachO/ZldAtom.zig"
590591
"${CMAKE_SOURCE_DIR}/src/link/MachO/bind.zig"
591592
"${CMAKE_SOURCE_DIR}/src/link/MachO/dead_strip.zig"
593+
"${CMAKE_SOURCE_DIR}/src/link/MachO/fat.zig"
594+
"${CMAKE_SOURCE_DIR}/src/link/MachO/load_commands.zig"
592595
"${CMAKE_SOURCE_DIR}/src/link/MachO/thunks.zig"
593596
"${CMAKE_SOURCE_DIR}/src/link/MachO/zld.zig"
594597
"${CMAKE_SOURCE_DIR}/src/link/Plan9.zig"

ci/aarch64-macos.sh

+16
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,19 @@ stage3-release/bin/zig build test docs \
5252

5353
# Produce the experimental std lib documentation.
5454
stage3-release/bin/zig test ../lib/std/std.zig -femit-docs -fno-emit-bin --zig-lib-dir ../lib
55+
56+
# Ensure that stage3 and stage4 are byte-for-byte identical.
57+
stage3-release/bin/zig build \
58+
--prefix stage4-release \
59+
-Denable-llvm \
60+
-Dno-lib \
61+
-Drelease \
62+
-Dstrip \
63+
-Dtarget=$TARGET \
64+
-Duse-zig-libcxx \
65+
-Dversion-string="$(stage3-release/bin/zig version)"
66+
67+
# diff returns an error code if the files differ.
68+
echo "If the following command fails, it means nondeterminism has been"
69+
echo "introduced, making stage3 and stage4 no longer byte-for-byte identical."
70+
diff stage3-release/bin/zig stage4-release/bin/zig

ci/x86_64-macos.sh

+16
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,19 @@ stage3-release/bin/zig build test docs \
6060

6161
# Produce the experimental std lib documentation.
6262
stage3-release/bin/zig test ../lib/std/std.zig -femit-docs -fno-emit-bin --zig-lib-dir ../lib
63+
64+
# Ensure that stage3 and stage4 are byte-for-byte identical.
65+
stage3-release/bin/zig build \
66+
--prefix stage4-release \
67+
-Denable-llvm \
68+
-Dno-lib \
69+
-Drelease \
70+
-Dstrip \
71+
-Dtarget=$TARGET \
72+
-Duse-zig-libcxx \
73+
-Dversion-string="$(stage3-release/bin/zig version)"
74+
75+
# diff returns an error code if the files differ.
76+
echo "If the following command fails, it means nondeterminism has been"
77+
echo "introduced, making stage3 and stage4 no longer byte-for-byte identical."
78+
diff stage3-release/bin/zig stage4-release/bin/zig

lib/std/build/CheckObjectStep.zig

+6
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,12 @@ const MachODumper = struct {
571571
});
572572
},
573573

574+
.UUID => {
575+
const uuid = lc.cast(macho.uuid_command).?;
576+
try writer.writeByte('\n');
577+
try writer.print("uuid {x}", .{std.fmt.fmtSliceHexLower(&uuid.uuid)});
578+
},
579+
574580
else => {},
575581
}
576582
}

lib/std/macho.zig

+46-46
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ pub const uuid_command = extern struct {
5858
cmd: LC = .UUID,
5959

6060
/// sizeof(struct uuid_command)
61-
cmdsize: u32,
61+
cmdsize: u32 = @sizeOf(uuid_command),
6262

6363
/// the 128-bit uuid
64-
uuid: [16]u8,
64+
uuid: [16]u8 = undefined,
6565
};
6666

6767
/// The version_min_command contains the min OS version on which this
@@ -71,7 +71,7 @@ pub const version_min_command = extern struct {
7171
cmd: LC,
7272

7373
/// sizeof(struct version_min_command)
74-
cmdsize: u32,
74+
cmdsize: u32 = @sizeOf(version_min_command),
7575

7676
/// X.Y.Z is encoded in nibbles xxxx.yy.zz
7777
version: u32,
@@ -87,7 +87,7 @@ pub const source_version_command = extern struct {
8787
cmd: LC = .SOURCE_VERSION,
8888

8989
/// sizeof(source_version_command)
90-
cmdsize: u32,
90+
cmdsize: u32 = @sizeOf(source_version_command),
9191

9292
/// A.B.C.D.E packed as a24.b10.c10.d10.e10
9393
version: u64,
@@ -155,13 +155,13 @@ pub const entry_point_command = extern struct {
155155
cmd: LC = .MAIN,
156156

157157
/// sizeof(struct entry_point_command)
158-
cmdsize: u32,
158+
cmdsize: u32 = @sizeOf(entry_point_command),
159159

160160
/// file (__TEXT) offset of main()
161-
entryoff: u64,
161+
entryoff: u64 = 0,
162162

163163
/// if not zero, initial stack size
164-
stacksize: u64,
164+
stacksize: u64 = 0,
165165
};
166166

167167
/// The symtab_command contains the offsets and sizes of the link-edit 4.3BSD
@@ -172,19 +172,19 @@ pub const symtab_command = extern struct {
172172
cmd: LC = .SYMTAB,
173173

174174
/// sizeof(struct symtab_command)
175-
cmdsize: u32,
175+
cmdsize: u32 = @sizeOf(symtab_command),
176176

177177
/// symbol table offset
178-
symoff: u32,
178+
symoff: u32 = 0,
179179

180180
/// number of symbol table entries
181-
nsyms: u32,
181+
nsyms: u32 = 0,
182182

183183
/// string table offset
184-
stroff: u32,
184+
stroff: u32 = 0,
185185

186186
/// string table size in bytes
187-
strsize: u32,
187+
strsize: u32 = 0,
188188
};
189189

190190
/// This is the second set of the symbolic information which is used to support
@@ -230,7 +230,7 @@ pub const dysymtab_command = extern struct {
230230
cmd: LC = .DYSYMTAB,
231231

232232
/// sizeof(struct dysymtab_command)
233-
cmdsize: u32,
233+
cmdsize: u32 = @sizeOf(dysymtab_command),
234234

235235
// The symbols indicated by symoff and nsyms of the LC_SYMTAB load command
236236
// are grouped into the following three groups:
@@ -247,22 +247,22 @@ pub const dysymtab_command = extern struct {
247247
// table when this is a dynamically linked shared library file).
248248

249249
/// index of local symbols
250-
ilocalsym: u32,
250+
ilocalsym: u32 = 0,
251251

252252
/// number of local symbols
253-
nlocalsym: u32,
253+
nlocalsym: u32 = 0,
254254

255255
/// index to externally defined symbols
256-
iextdefsym: u32,
256+
iextdefsym: u32 = 0,
257257

258258
/// number of externally defined symbols
259-
nextdefsym: u32,
259+
nextdefsym: u32 = 0,
260260

261261
/// index to undefined symbols
262-
iundefsym: u32,
262+
iundefsym: u32 = 0,
263263

264264
/// number of undefined symbols
265-
nundefsym: u32,
265+
nundefsym: u32 = 0,
266266

267267
// For the for the dynamic binding process to find which module a symbol
268268
// is defined in the table of contents is used (analogous to the ranlib
@@ -272,10 +272,10 @@ pub const dysymtab_command = extern struct {
272272
// symbols are sorted by name and is use as the table of contents.
273273

274274
/// file offset to table of contents
275-
tocoff: u32,
275+
tocoff: u32 = 0,
276276

277277
/// number of entries in table of contents
278-
ntoc: u32,
278+
ntoc: u32 = 0,
279279

280280
// To support dynamic binding of "modules" (whole object files) the symbol
281281
// table must reflect the modules that the file was created from. This is
@@ -286,10 +286,10 @@ pub const dysymtab_command = extern struct {
286286
// contains one module so everything in the file belongs to the module.
287287

288288
/// file offset to module table
289-
modtaboff: u32,
289+
modtaboff: u32 = 0,
290290

291291
/// number of module table entries
292-
nmodtab: u32,
292+
nmodtab: u32 = 0,
293293

294294
// To support dynamic module binding the module structure for each module
295295
// indicates the external references (defined and undefined) each module
@@ -300,10 +300,10 @@ pub const dysymtab_command = extern struct {
300300
// undefined external symbols indicates the external references.
301301

302302
/// offset to referenced symbol table
303-
extrefsymoff: u32,
303+
extrefsymoff: u32 = 0,
304304

305305
/// number of referenced symbol table entries
306-
nextrefsyms: u32,
306+
nextrefsyms: u32 = 0,
307307

308308
// The sections that contain "symbol pointers" and "routine stubs" have
309309
// indexes and (implied counts based on the size of the section and fixed
@@ -315,10 +315,10 @@ pub const dysymtab_command = extern struct {
315315
// The indirect symbol table is ordered to match the entries in the section.
316316

317317
/// file offset to the indirect symbol table
318-
indirectsymoff: u32,
318+
indirectsymoff: u32 = 0,
319319

320320
/// number of indirect symbol table entries
321-
nindirectsyms: u32,
321+
nindirectsyms: u32 = 0,
322322

323323
// To support relocating an individual module in a library file quickly the
324324
// external relocation entries for each module in the library need to be
@@ -347,20 +347,20 @@ pub const dysymtab_command = extern struct {
347347
// remaining relocation entries must be local).
348348

349349
/// offset to external relocation entries
350-
extreloff: u32,
350+
extreloff: u32 = 0,
351351

352352
/// number of external relocation entries
353-
nextrel: u32,
353+
nextrel: u32 = 0,
354354

355355
// All the local relocation entries are grouped together (they are not
356356
// grouped by their module since they are only used if the object is moved
357357
// from it staticly link edited address).
358358

359359
/// offset to local relocation entries
360-
locreloff: u32,
360+
locreloff: u32 = 0,
361361

362362
/// number of local relocation entries
363-
nlocrel: u32,
363+
nlocrel: u32 = 0,
364364
};
365365

366366
/// The linkedit_data_command contains the offsets and sizes of a blob
@@ -370,13 +370,13 @@ pub const linkedit_data_command = extern struct {
370370
cmd: LC,
371371

372372
/// sizeof(struct linkedit_data_command)
373-
cmdsize: u32,
373+
cmdsize: u32 = @sizeOf(linkedit_data_command),
374374

375375
/// file offset of data in __LINKEDIT segment
376-
dataoff: u32,
376+
dataoff: u32 = 0,
377377

378378
/// file size of data in __LINKEDIT segment
379-
datasize: u32,
379+
datasize: u32 = 0,
380380
};
381381

382382
/// The dyld_info_command contains the file offsets and sizes of
@@ -387,10 +387,10 @@ pub const linkedit_data_command = extern struct {
387387
/// to interpret it.
388388
pub const dyld_info_command = extern struct {
389389
/// LC_DYLD_INFO or LC_DYLD_INFO_ONLY
390-
cmd: LC,
390+
cmd: LC = .DYLD_INFO_ONLY,
391391

392392
/// sizeof(struct dyld_info_command)
393-
cmdsize: u32,
393+
cmdsize: u32 = @sizeOf(dyld_info_command),
394394

395395
// Dyld rebases an image whenever dyld loads it at an address different
396396
// from its preferred address. The rebase information is a stream
@@ -403,10 +403,10 @@ pub const dyld_info_command = extern struct {
403403
// bytes.
404404

405405
/// file offset to rebase info
406-
rebase_off: u32,
406+
rebase_off: u32 = 0,
407407

408408
/// size of rebase info
409-
rebase_size: u32,
409+
rebase_size: u32 = 0,
410410

411411
// Dyld binds an image during the loading process, if the image
412412
// requires any pointers to be initialized to symbols in other images.
@@ -420,10 +420,10 @@ pub const dyld_info_command = extern struct {
420420
// encoded in a few bytes.
421421

422422
/// file offset to binding info
423-
bind_off: u32,
423+
bind_off: u32 = 0,
424424

425425
/// size of binding info
426-
bind_size: u32,
426+
bind_size: u32 = 0,
427427

428428
// Some C++ programs require dyld to unique symbols so that all
429429
// images in the process use the same copy of some code/data.
@@ -440,10 +440,10 @@ pub const dyld_info_command = extern struct {
440440
// and the call to operator new is then rebound.
441441

442442
/// file offset to weak binding info
443-
weak_bind_off: u32,
443+
weak_bind_off: u32 = 0,
444444

445445
/// size of weak binding info
446-
weak_bind_size: u32,
446+
weak_bind_size: u32 = 0,
447447

448448
// Some uses of external symbols do not need to be bound immediately.
449449
// Instead they can be lazily bound on first use. The lazy_bind
@@ -457,10 +457,10 @@ pub const dyld_info_command = extern struct {
457457
// to bind.
458458

459459
/// file offset to lazy binding info
460-
lazy_bind_off: u32,
460+
lazy_bind_off: u32 = 0,
461461

462462
/// size of lazy binding info
463-
lazy_bind_size: u32,
463+
lazy_bind_size: u32 = 0,
464464

465465
// The symbols exported by a dylib are encoded in a trie. This
466466
// is a compact representation that factors out common prefixes.
@@ -494,10 +494,10 @@ pub const dyld_info_command = extern struct {
494494
// edge points to.
495495

496496
/// file offset to lazy binding info
497-
export_off: u32,
497+
export_off: u32 = 0,
498498

499499
/// size of lazy binding info
500-
export_size: u32,
500+
export_size: u32 = 0,
501501
};
502502

503503
/// A program that uses a dynamic linker contains a dylinker_command to identify

0 commit comments

Comments
 (0)