Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions compiler/src/dmd/backend/mscoffobj.d
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import dmd.backend.mscoff;

import dmd.common.outbuffer;

import dmd.root.hash : calcHash;

nothrow:
@safe:

Expand Down Expand Up @@ -649,8 +651,29 @@ void MsCoffObj_term(const(char)[] objfilename)
BIGOBJ_HEADER header = void;
IMAGE_FILE_HEADER header_old = void;

time_t f_timedat = 0;
time(&f_timedat);
// Calculate a deterministic hash instead of using the current time
// Use a hash of all section data to ensure deterministic builds
uint f_timedat = 0;
// Hash sections and their contents for deterministic timestamp
import dmd.root.hash : calcHash;
// Collect all section data to hash
OutBuffer hashBuf;
for (segidx_t seg = 1; seg < SegData.length; seg++)
{
seg_data* pseg = SegData[seg];
if (pseg.SDbuf && pseg.SDbuf.length())
{
// Add segment contents to the buffer
hashBuf.write(pseg.SDbuf.buf[0 .. pseg.SDbuf.length()]);
}
}

// Calculate the hash based on all sections
if (hashBuf.length > 0)
f_timedat = calcHash(hashBuf.buf[0 .. hashBuf.length]);

// Add fixed value to make the hash recognizable (timestamp starts from 1970)
f_timedat = (f_timedat & 0x7FFFFFFF) | 0x40000000; // Make sure it's a reasonable timestamp
uint symtable_offset;

if (bigobj)
Expand All @@ -660,7 +683,7 @@ void MsCoffObj_term(const(char)[] objfilename)
header.Version = 2;
header.Machine = I64 ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386;
header.NumberOfSections = scnhdr_cnt;
header.TimeDateStamp = cast(uint)f_timedat;
header.TimeDateStamp = f_timedat;
static immutable ubyte[16] uuid =
[ '\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b',
'\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8' ];
Expand All @@ -677,7 +700,7 @@ void MsCoffObj_term(const(char)[] objfilename)
{
header_old.Machine = I64 ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386;
header_old.NumberOfSections = cast(ushort)scnhdr_cnt;
header_old.TimeDateStamp = cast(uint)f_timedat;
header_old.TimeDateStamp = f_timedat;
header_old.SizeOfOptionalHeader = 0;
header_old.Characteristics = 0;
foffset = (header_old).sizeof; // start after header
Expand Down
47 changes: 40 additions & 7 deletions compiler/src/dmd/lib/elf.d
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,16 @@ final class LibElf : Library
static assert(0, "unsupported operating system");

time_t file_time = 0;
time(&file_time);

// Use deterministic timestamp instead of current time
import dmd.root.hash : calcHash;
// Create a hash from the object module content
if (om.base && om.length > 0)
file_time = calcHash(om.base[0 .. om.length]);

// Add fixed value to make the hash recognizable (start from 1970s)
file_time = (file_time & 0x7FFFFFFF) | 0x40000000;

om.file_time = cast(long)file_time;
om.file_mode = (1 << 15) | (6 << 6) | (4 << 3) | (4 << 0); // 0100644
}
Expand Down Expand Up @@ -434,20 +443,44 @@ private:
om.length = cast(uint)(hoffset - (8 + ElfLibHeader.sizeof));
om.offset = 8;
om.name = "";
.time(&om.file_time);

// Use deterministic timestamp instead of current time
// Calculate a hash based on library contents
import dmd.root.hash : calcHash;

// Collect all symbol and module data in a buffer
OutBuffer hashBuf;
foreach (os; objsymbols)
{
// Add symbol names to the buffer
hashBuf.writestring(os.name);

// Add module content to the buffer if available
if (os.om && os.om.base && os.om.length > 0)
hashBuf.write(os.om.base[0 .. os.om.length]);
}

// Calculate the hash from the buffer
om.file_time = 0;
if (hashBuf.length > 0)
om.file_time = calcHash(hashBuf.buf[0 .. hashBuf.length]);

// Add fixed value to make the hash recognizable (start from 1970s)
om.file_time = (om.file_time & 0x7FFFFFFF) | 0x40000000;

om.user_id = 0;
om.group_id = 0;
om.file_mode = 0;
ElfLibHeader h;
ElfOmToHeader(&h, &om);
libbuf.write((&h)[0 .. 1]);
char[4] buf;
Port.writelongBE(cast(uint)objsymbols.length, buf.ptr);
libbuf.write(buf[0 .. 4]);
char[4] buf2;
Port.writelongBE(cast(uint)objsymbols.length, buf2.ptr);
libbuf.write(buf2[0 .. 4]);
foreach (os; objsymbols)
{
Port.writelongBE(os.om.offset, buf.ptr);
libbuf.write(buf[0 .. 4]);
Port.writelongBE(os.om.offset, buf2.ptr);
libbuf.write(buf2[0 .. 4]);
}
foreach (os; objsymbols)
{
Expand Down
37 changes: 35 additions & 2 deletions compiler/src/dmd/lib/mach.d
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,17 @@ final class LibMach : Library
else
static assert(0, "unsupported operating system");

time(&om.file_time);
// Use deterministic timestamp instead of current time
import dmd.root.hash : calcHash;
// Create a hash from the object module content
time_t file_time = 0;
if (om.base && om.length > 0)
file_time = calcHash(om.base[0 .. om.length]);

// Add fixed value to make the hash recognizable (start from 1970s)
file_time = (file_time & 0x7FFFFFFF) | 0x40000000;

om.file_time = file_time;
om.file_mode = (1 << 15) | (6 << 6) | (4 << 3) | (4 << 0); // 0100644
}
objmodules.push(om);
Expand Down Expand Up @@ -395,7 +405,30 @@ private:
om.length = cast(uint)(hoffset - (8 + MachLibHeader.sizeof));
om.offset = 8;
om.name = "";
.time(&om.file_time);

// Use deterministic timestamp instead of current time
// Calculate a hash based on library contents
import dmd.root.hash : calcHash;

// Collect all symbol and module data in a buffer
OutBuffer hashBuf;
foreach (os; objsymbols)
{
// Add symbol names to the buffer
hashBuf.writestring(os.name);

// Add module content to the buffer if available
if (os.om && os.om.base && os.om.length > 0)
hashBuf.write(os.om.base[0 .. os.om.length]);
}

// Calculate the hash from the buffer
om.file_time = 0;
if (hashBuf.length > 0)
om.file_time = calcHash(hashBuf.buf[0 .. hashBuf.length]);

// Add fixed value to make the hash recognizable (start from 1970s)
om.file_time = (om.file_time & 0x7FFFFFFF) | 0x40000000;

version (Posix)
{
Expand Down
38 changes: 34 additions & 4 deletions compiler/src/dmd/lib/mscoff.d
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,16 @@ final class LibMSCoff : Library
else
static assert(0, "unsupported operating system");

// Use deterministic timestamp instead of current time
import dmd.root.hash : calcHash;
// Create a hash from the object module content
time_t file_time = 0;
time(&file_time);
if (om.base && om.length > 0)
file_time = calcHash(om.base[0 .. om.length]);

// Add fixed value to make the hash recognizable (start from 1970s)
file_time = (file_time & 0x7FFFFFFF) | 0x40000000;

om.file_time = cast(long)file_time;
om.file_mode = (1 << 15) | (6 << 6) | (4 << 3) | (4 << 0); // 0100644
}
Expand Down Expand Up @@ -494,9 +502,31 @@ private:
om.length = cast(uint)(4 + objsymbols.length * 4 + slength);
om.offset = 8;
om.name = "";
time_t file_time = 0;
.time(&file_time);
om.file_time = cast(long)file_time;

// Use deterministic timestamp instead of current time
// Calculate a hash based on library contents
import dmd.root.hash : calcHash;

// Collect all symbol and module data in a buffer
OutBuffer hashBuf;
foreach (os; objsymbols)
{
// Add symbol names to the buffer
hashBuf.writestring(os.name);

// Add module content to the buffer if available
if (os.om && os.om.base && os.om.length > 0)
hashBuf.write(os.om.base[0 .. os.om.length]);
}

// Calculate the hash from the buffer
om.file_time = 0;
if (hashBuf.length > 0)
om.file_time = calcHash(hashBuf.buf[0 .. hashBuf.length]);

// Add fixed value to make the hash recognizable (start from 1970s)
om.file_time = (om.file_time & 0x7FFFFFFF) | 0x40000000;

om.user_id = 0;
om.group_id = 0;
om.file_mode = 0;
Expand Down
Loading