summaryrefslogtreecommitdiffstats
path: root/src/binutils-1-fixes.patch
blob: 58a6e2a37e9468a4d7749e4d65fd8815acb7fa21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
This file is part of MXE. See LICENSE.md for licensing information.

Contains ad hoc patches for cross building.

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Stephen Kitt <skitt@debian.org>
Date: Sat, 15 Jul 2017 00:09:40 +1000
Subject: [PATCH] Allow the PE timestamp to be specified with SOURCE_DATE_EPOCH

Taken from:
https://sources.debian.net/patches/binutils-mingw-w64/7.4/specify-timestamp.patch/

diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 1111111..2222222 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -70,6 +70,9 @@
 #include <wctype.h>
 #endif
 
+#include <errno.h>
+#include <limits.h>
+
 /* NOTE: it's strange to be including an architecture specific header
    in what's supposed to be general (to PE/PEI) code.  However, that's
    where the definitions are, and they don't vary per architecture
@@ -878,10 +881,38 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
   H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
 
   /* Only use a real timestamp if the option was chosen.  */
-  if ((pe_data (abfd)->insert_timestamp))
-    H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
-  else
+  if (pe_data (abfd)->insert_timestamp) {
+    time_t now;
+    char *source_date_epoch;
+    unsigned long long epoch;
+    char *endptr;
+
+    now = time(NULL);
+    source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+    if (source_date_epoch) {
+      errno = 0;
+      epoch = strtoull(source_date_epoch, &endptr, 10);
+      if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0))
+          || (errno != 0 && epoch == 0)) {
+        _bfd_error_handler("Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n",
+                           strerror(errno));
+      } else if (endptr == source_date_epoch) {
+        _bfd_error_handler("Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n",
+                           endptr);
+      } else if (*endptr != '\0') {
+        _bfd_error_handler("Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n",
+                           endptr);
+      } else if (epoch > ULONG_MAX) {
+        _bfd_error_handler("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to: %lu but was found to be: %llu\n",
+                           ULONG_MAX, epoch);
+      } else {
+        now = epoch;
+      }
+    }
+    H_PUT_32 (abfd, now, filehdr_out->f_timdat);
+  } else {
     H_PUT_32 (abfd, 0, filehdr_out->f_timdat);
+  }
 
   PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
 		      filehdr_out->f_symptr);
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 1111111..2222222 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -305,7 +305,7 @@ gld${EMULATION_NAME}_add_options
      OPTION_USE_NUL_PREFIXED_IMPORT_TABLES},
     {"no-leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE},
     {"leading-underscore", no_argument, NULL, OPTION_LEADING_UNDERSCORE},
-    {"insert-timestamp", no_argument, NULL, OPTION_INSERT_TIMESTAMP},
+    {"insert-timestamp", optional_argument, NULL, OPTION_INSERT_TIMESTAMP},
     {"no-insert-timestamp", no_argument, NULL, OPTION_NO_INSERT_TIMESTAMP},
 #ifdef DLL_SUPPORT
     /* getopt allows abbreviations, so we do this to stop it
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 1111111..2222222 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -321,7 +321,7 @@ gld${EMULATION_NAME}_add_options
     {"no-bind", no_argument, NULL, OPTION_NO_BIND},
     {"wdmdriver", no_argument, NULL, OPTION_WDM_DRIVER},
     {"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},
-    {"insert-timestamp", no_argument, NULL, OPTION_INSERT_TIMESTAMP},
+    {"insert-timestamp", optional_argument, NULL, OPTION_INSERT_TIMESTAMP},
     {"no-insert-timestamp", no_argument, NULL, OPTION_NO_INSERT_TIMESTAMP},
     {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
     {NULL, no_argument, NULL, 0}
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index 1111111..2222222 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -26,6 +26,8 @@
 #include "filenames.h"
 #include "safe-ctype.h"
 
+#include <errno.h>
+#include <limits.h>
 #include <time.h>
 
 #include "ld.h"
@@ -1192,8 +1194,36 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
 
   memset (edata_d, 0, edata_sz);
 
-  if (pe_data (abfd)->insert_timestamp)
-    H_PUT_32 (abfd, time (0), edata_d + 4);
+  if (pe_data (abfd)->insert_timestamp) {
+    time_t now;
+    char *source_date_epoch;
+    unsigned long long epoch;
+    char *endptr;
+
+    now = time(NULL);
+    source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+    if (source_date_epoch) {
+      errno = 0;
+      epoch = strtoull(source_date_epoch, &endptr, 10);
+      if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0))
+	  || (errno != 0 && epoch == 0)) {
+	einfo("Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n",
+	      strerror(errno));
+      } else if (endptr == source_date_epoch) {
+	einfo("Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n",
+	      endptr);
+      } else if (*endptr != '\0') {
+	einfo("Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n",
+	      endptr);
+      } else if (epoch > ULONG_MAX) {
+	einfo("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to: %lu but was found to be: %llu\n",
+	      ULONG_MAX, epoch);
+      } else {
+	now = epoch;
+      }
+    }
+    H_PUT_32 (abfd, now, edata_d + 4);
+  }
 
   if (pe_def_file->version_major != -1)
     {