Skip to content

Commit ed80584

Browse files
committed
Initial
1 parent 6656cd9 commit ed80584

File tree

4 files changed

+136
-17
lines changed

4 files changed

+136
-17
lines changed

compiler/src/dmd/backend/mscoffobj.d

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import dmd.backend.mscoff;
3636

3737
import dmd.common.outbuffer;
3838

39+
import dmd.root.hash : calcHash;
40+
3941
nothrow:
4042
@safe:
4143

@@ -649,8 +651,29 @@ void MsCoffObj_term(const(char)[] objfilename)
649651
BIGOBJ_HEADER header = void;
650652
IMAGE_FILE_HEADER header_old = void;
651653

652-
time_t f_timedat = 0;
653-
time(&f_timedat);
654+
// Calculate a deterministic hash instead of using the current time
655+
// Use a hash of all section data to ensure deterministic builds
656+
uint f_timedat = 0;
657+
// Hash sections and their contents for deterministic timestamp
658+
import dmd.root.hash : calcHash;
659+
// Collect all section data to hash
660+
OutBuffer hashBuf;
661+
for (segidx_t seg = 1; seg < SegData.length; seg++)
662+
{
663+
seg_data* pseg = SegData[seg];
664+
if (pseg.SDbuf && pseg.SDbuf.length())
665+
{
666+
// Add segment contents to the buffer
667+
hashBuf.write(pseg.SDbuf.buf[0 .. pseg.SDbuf.length()]);
668+
}
669+
}
670+
671+
// Calculate the hash based on all sections
672+
if (hashBuf.length > 0)
673+
f_timedat = calcHash(hashBuf.buf[0 .. hashBuf.length]);
674+
675+
// Add fixed value to make the hash recognizable (timestamp starts from 1970)
676+
f_timedat = (f_timedat & 0x7FFFFFFF) | 0x40000000; // Make sure it's a reasonable timestamp
654677
uint symtable_offset;
655678

656679
if (bigobj)
@@ -660,7 +683,7 @@ void MsCoffObj_term(const(char)[] objfilename)
660683
header.Version = 2;
661684
header.Machine = I64 ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386;
662685
header.NumberOfSections = scnhdr_cnt;
663-
header.TimeDateStamp = cast(uint)f_timedat;
686+
header.TimeDateStamp = f_timedat;
664687
static immutable ubyte[16] uuid =
665688
[ '\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b',
666689
'\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8' ];
@@ -677,7 +700,7 @@ void MsCoffObj_term(const(char)[] objfilename)
677700
{
678701
header_old.Machine = I64 ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386;
679702
header_old.NumberOfSections = cast(ushort)scnhdr_cnt;
680-
header_old.TimeDateStamp = cast(uint)f_timedat;
703+
header_old.TimeDateStamp = f_timedat;
681704
header_old.SizeOfOptionalHeader = 0;
682705
header_old.Characteristics = 0;
683706
foffset = (header_old).sizeof; // start after header

compiler/src/dmd/lib/elf.d

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,16 @@ final class LibElf : Library
305305
static assert(0, "unsupported operating system");
306306

307307
time_t file_time = 0;
308-
time(&file_time);
308+
309+
// Use deterministic timestamp instead of current time
310+
import dmd.root.hash : calcHash;
311+
// Create a hash from the object module content
312+
if (om.base && om.length > 0)
313+
file_time = calcHash(om.base[0 .. om.length]);
314+
315+
// Add fixed value to make the hash recognizable (start from 1970s)
316+
file_time = (file_time & 0x7FFFFFFF) | 0x40000000;
317+
309318
om.file_time = cast(long)file_time;
310319
om.file_mode = (1 << 15) | (6 << 6) | (4 << 3) | (4 << 0); // 0100644
311320
}
@@ -434,20 +443,44 @@ private:
434443
om.length = cast(uint)(hoffset - (8 + ElfLibHeader.sizeof));
435444
om.offset = 8;
436445
om.name = "";
437-
.time(&om.file_time);
446+
447+
// Use deterministic timestamp instead of current time
448+
// Calculate a hash based on library contents
449+
import dmd.root.hash : calcHash;
450+
451+
// Collect all symbol and module data in a buffer
452+
OutBuffer hashBuf;
453+
foreach (os; objsymbols)
454+
{
455+
// Add symbol names to the buffer
456+
hashBuf.writestring(os.name);
457+
458+
// Add module content to the buffer if available
459+
if (os.om && os.om.base && os.om.length > 0)
460+
hashBuf.write(os.om.base[0 .. os.om.length]);
461+
}
462+
463+
// Calculate the hash from the buffer
464+
om.file_time = 0;
465+
if (hashBuf.length > 0)
466+
om.file_time = calcHash(hashBuf.buf[0 .. hashBuf.length]);
467+
468+
// Add fixed value to make the hash recognizable (start from 1970s)
469+
om.file_time = (om.file_time & 0x7FFFFFFF) | 0x40000000;
470+
438471
om.user_id = 0;
439472
om.group_id = 0;
440473
om.file_mode = 0;
441474
ElfLibHeader h;
442475
ElfOmToHeader(&h, &om);
443476
libbuf.write((&h)[0 .. 1]);
444-
char[4] buf;
445-
Port.writelongBE(cast(uint)objsymbols.length, buf.ptr);
446-
libbuf.write(buf[0 .. 4]);
477+
char[4] buf2;
478+
Port.writelongBE(cast(uint)objsymbols.length, buf2.ptr);
479+
libbuf.write(buf2[0 .. 4]);
447480
foreach (os; objsymbols)
448481
{
449-
Port.writelongBE(os.om.offset, buf.ptr);
450-
libbuf.write(buf[0 .. 4]);
482+
Port.writelongBE(os.om.offset, buf2.ptr);
483+
libbuf.write(buf2[0 .. 4]);
451484
}
452485
foreach (os; objsymbols)
453486
{

compiler/src/dmd/lib/mach.d

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,17 @@ final class LibMach : Library
259259
else
260260
static assert(0, "unsupported operating system");
261261

262-
time(&om.file_time);
262+
// Use deterministic timestamp instead of current time
263+
import dmd.root.hash : calcHash;
264+
// Create a hash from the object module content
265+
time_t file_time = 0;
266+
if (om.base && om.length > 0)
267+
file_time = calcHash(om.base[0 .. om.length]);
268+
269+
// Add fixed value to make the hash recognizable (start from 1970s)
270+
file_time = (file_time & 0x7FFFFFFF) | 0x40000000;
271+
272+
om.file_time = file_time;
263273
om.file_mode = (1 << 15) | (6 << 6) | (4 << 3) | (4 << 0); // 0100644
264274
}
265275
objmodules.push(om);
@@ -395,7 +405,30 @@ private:
395405
om.length = cast(uint)(hoffset - (8 + MachLibHeader.sizeof));
396406
om.offset = 8;
397407
om.name = "";
398-
.time(&om.file_time);
408+
409+
// Use deterministic timestamp instead of current time
410+
// Calculate a hash based on library contents
411+
import dmd.root.hash : calcHash;
412+
413+
// Collect all symbol and module data in a buffer
414+
OutBuffer hashBuf;
415+
foreach (os; objsymbols)
416+
{
417+
// Add symbol names to the buffer
418+
hashBuf.writestring(os.name);
419+
420+
// Add module content to the buffer if available
421+
if (os.om && os.om.base && os.om.length > 0)
422+
hashBuf.write(os.om.base[0 .. os.om.length]);
423+
}
424+
425+
// Calculate the hash from the buffer
426+
om.file_time = 0;
427+
if (hashBuf.length > 0)
428+
om.file_time = calcHash(hashBuf.buf[0 .. hashBuf.length]);
429+
430+
// Add fixed value to make the hash recognizable (start from 1970s)
431+
om.file_time = (om.file_time & 0x7FFFFFFF) | 0x40000000;
399432

400433
version (Posix)
401434
{

compiler/src/dmd/lib/mscoff.d

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,16 @@ final class LibMSCoff : Library
361361
else
362362
static assert(0, "unsupported operating system");
363363

364+
// Use deterministic timestamp instead of current time
365+
import dmd.root.hash : calcHash;
366+
// Create a hash from the object module content
364367
time_t file_time = 0;
365-
time(&file_time);
368+
if (om.base && om.length > 0)
369+
file_time = calcHash(om.base[0 .. om.length]);
370+
371+
// Add fixed value to make the hash recognizable (start from 1970s)
372+
file_time = (file_time & 0x7FFFFFFF) | 0x40000000;
373+
366374
om.file_time = cast(long)file_time;
367375
om.file_mode = (1 << 15) | (6 << 6) | (4 << 3) | (4 << 0); // 0100644
368376
}
@@ -494,9 +502,31 @@ private:
494502
om.length = cast(uint)(4 + objsymbols.length * 4 + slength);
495503
om.offset = 8;
496504
om.name = "";
497-
time_t file_time = 0;
498-
.time(&file_time);
499-
om.file_time = cast(long)file_time;
505+
506+
// Use deterministic timestamp instead of current time
507+
// Calculate a hash based on library contents
508+
import dmd.root.hash : calcHash;
509+
510+
// Collect all symbol and module data in a buffer
511+
OutBuffer hashBuf;
512+
foreach (os; objsymbols)
513+
{
514+
// Add symbol names to the buffer
515+
hashBuf.writestring(os.name);
516+
517+
// Add module content to the buffer if available
518+
if (os.om && os.om.base && os.om.length > 0)
519+
hashBuf.write(os.om.base[0 .. os.om.length]);
520+
}
521+
522+
// Calculate the hash from the buffer
523+
om.file_time = 0;
524+
if (hashBuf.length > 0)
525+
om.file_time = calcHash(hashBuf.buf[0 .. hashBuf.length]);
526+
527+
// Add fixed value to make the hash recognizable (start from 1970s)
528+
om.file_time = (om.file_time & 0x7FFFFFFF) | 0x40000000;
529+
500530
om.user_id = 0;
501531
om.group_id = 0;
502532
om.file_mode = 0;

0 commit comments

Comments
 (0)