Skip to content

Commit dd60195

Browse files
committedJun 11, 2019
Let writeWindowsResourceCOFF() take a TimeStamp parameter
For lld, pass in Config->Timestamp (which is set based on lld's /timestamp: and /Brepro flags). Since the writeWindowsResourceCOFF() data is only used in-memory by LLD and the obj's timestamp isn't used for anything in the output, this doesn't change behavior. For llvm-cvtres, add an optional /timestamp: parameter, and use the current behavior of calling time() if the parameter is not passed in. This doesn't really change observable behavior (unless someone passes /timestamp: to llvm-cvtres, which wasn't possible before), but it removes the last unqualified call to time() from llvm/lib, which seems like a good thing. Differential Revision: https://reviews.llvm.org/D63116 llvm-svn: 363050
1 parent bc888f0 commit dd60195

File tree

7 files changed

+50
-18
lines changed

7 files changed

+50
-18
lines changed
 

‎lld/COFF/DriverUtils.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,8 @@ MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs) {
718718
}
719719

720720
Expected<std::unique_ptr<MemoryBuffer>> E =
721-
llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser);
721+
llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser,
722+
Config->Timestamp);
722723
if (!E)
723724
fatal("failed to write .res to COFF: " + toString(E.takeError()));
724725

‎llvm/include/llvm/Object/WindowsResource.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ class WindowsResourceParser {
232232

233233
Expected<std::unique_ptr<MemoryBuffer>>
234234
writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
235-
const WindowsResourceParser &Parser);
235+
const WindowsResourceParser &Parser,
236+
uint32_t TimeDateStamp);
236237

237238
void printResourceTypeName(uint16_t TypeID, raw_ostream &OS);
238239
} // namespace object

‎llvm/lib/Object/WindowsResource.cpp

+11-15
Original file line numberDiff line numberDiff line change
@@ -400,13 +400,13 @@ class WindowsResourceCOFFWriter {
400400
public:
401401
WindowsResourceCOFFWriter(COFF::MachineTypes MachineType,
402402
const WindowsResourceParser &Parser, Error &E);
403-
std::unique_ptr<MemoryBuffer> write();
403+
std::unique_ptr<MemoryBuffer> write(uint32_t TimeDateStamp);
404404

405405
private:
406406
void performFileLayout();
407407
void performSectionOneLayout();
408408
void performSectionTwoLayout();
409-
void writeCOFFHeader();
409+
void writeCOFFHeader(uint32_t TimeDateStamp);
410410
void writeFirstSectionHeader();
411411
void writeSecondSectionHeader();
412412
void writeFirstSection();
@@ -499,17 +499,11 @@ void WindowsResourceCOFFWriter::performSectionTwoLayout() {
499499
FileSize = alignTo(FileSize, SECTION_ALIGNMENT);
500500
}
501501

502-
static std::time_t getTime() {
503-
std::time_t Now = time(nullptr);
504-
if (Now < 0 || !isUInt<32>(Now))
505-
return UINT32_MAX;
506-
return Now;
507-
}
508-
509-
std::unique_ptr<MemoryBuffer> WindowsResourceCOFFWriter::write() {
502+
std::unique_ptr<MemoryBuffer>
503+
WindowsResourceCOFFWriter::write(uint32_t TimeDateStamp) {
510504
BufferStart = OutputBuffer->getBufferStart();
511505

512-
writeCOFFHeader();
506+
writeCOFFHeader(TimeDateStamp);
513507
writeFirstSectionHeader();
514508
writeSecondSectionHeader();
515509
writeFirstSection();
@@ -520,16 +514,17 @@ std::unique_ptr<MemoryBuffer> WindowsResourceCOFFWriter::write() {
520514
return std::move(OutputBuffer);
521515
}
522516

523-
void WindowsResourceCOFFWriter::writeCOFFHeader() {
517+
void WindowsResourceCOFFWriter::writeCOFFHeader(uint32_t TimeDateStamp) {
524518
// Write the COFF header.
525519
auto *Header = reinterpret_cast<coff_file_header *>(BufferStart);
526520
Header->Machine = MachineType;
527521
Header->NumberOfSections = 2;
528-
Header->TimeDateStamp = getTime();
522+
Header->TimeDateStamp = TimeDateStamp;
529523
Header->PointerToSymbolTable = SymbolTableOffset;
530524
// One symbol for every resource plus 2 for each section and @feat.00
531525
Header->NumberOfSymbols = Data.size() + 5;
532526
Header->SizeOfOptionalHeader = 0;
527+
// cvtres.exe sets 32BIT_MACHINE even for 64-bit machine types. Match it.
533528
Header->Characteristics = COFF::IMAGE_FILE_32BIT_MACHINE;
534529
}
535530

@@ -794,12 +789,13 @@ void WindowsResourceCOFFWriter::writeFirstSectionRelocations() {
794789

795790
Expected<std::unique_ptr<MemoryBuffer>>
796791
writeWindowsResourceCOFF(COFF::MachineTypes MachineType,
797-
const WindowsResourceParser &Parser) {
792+
const WindowsResourceParser &Parser,
793+
uint32_t TimeDateStamp) {
798794
Error E = Error::success();
799795
WindowsResourceCOFFWriter Writer(MachineType, Parser, E);
800796
if (E)
801797
return std::move(E);
802-
return Writer.write();
798+
return Writer.write(TimeDateStamp);
803799
}
804800

805801
} // namespace object

‎llvm/test/tools/llvm-cvtres/help.test

+1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@
1010
; HELP_TEST-DAG: /NOLOGO
1111
; HELP_TEST-NEXT: /OUT:filename
1212
; HELP_TEST-NEXT: /READONLY
13+
; HELP_TEST-NEXT: /TIMESTAMP:<value> Timestamp for coff header, defaults to current time
1314
; HELP_TEST-NEXT: /VERBOSE
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
RUN: llvm-cvtres /timestamp:0x12345678 /out:%t %p/Inputs/test_resource.res
2+
RUN: llvm-readobj -h %t | FileCheck %s --check-prefix=1TO8
3+
4+
1TO8: TimeDateStamp: 1979-09-05 22:51:36 (0x12345678)
5+
6+
7+
RUN: not llvm-cvtres /timestamp:0x123456789 /out:%t \
8+
RUN: %p/Inputs/test_resource.res 2>&1 | FileCheck %s --check-prefix=ERR
9+
10+
ERR: invalid timestamp: 0x123456789. Expected 32-bit integer

‎llvm/tools/llvm-cvtres/Opts.td

+5
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,8 @@ def VERBOSE : Flag<["/", "-"], "VERBOSE">, HelpText<"">;
1212
def HELP : Flag<["/", "-"], "HELP">;
1313
def H : Flag<["/", "-"], "H">, Alias<HELP>;
1414
def HELP_Q : Flag<["/?", "-?"], "">, Alias<HELP>;
15+
16+
// Extensions.
17+
18+
def TIMESTAMP : Joined<["/", "-"], "TIMESTAMP:">,
19+
HelpText<"Timestamp for coff header, defaults to current time">;

‎llvm/tools/llvm-cvtres/llvm-cvtres.cpp

+19-1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ void error(Error EC) {
8888
[&](const ErrorInfoBase &EI) { reportError(EI.message()); });
8989
}
9090

91+
static uint32_t getTime() {
92+
std::time_t Now = time(nullptr);
93+
if (Now < 0 || !isUInt<32>(Now))
94+
return UINT32_MAX;
95+
return static_cast<uint32_t>(Now);
96+
}
97+
9198
template <typename T> T error(Expected<T> EC) {
9299
if (!EC)
93100
error(EC.takeError());
@@ -142,6 +149,16 @@ int main(int Argc, const char **Argv) {
142149
sys::path::replace_extension(OutputFile, ".obj");
143150
}
144151

152+
uint32_t DateTimeStamp;
153+
if (llvm::opt::Arg *Arg = InputArgs.getLastArg(OPT_TIMESTAMP)) {
154+
StringRef Value(Arg->getValue());
155+
if (Value.getAsInteger(0, DateTimeStamp))
156+
reportError(Twine("invalid timestamp: ") + Value +
157+
". Expected 32-bit integer\n");
158+
} else {
159+
DateTimeStamp = getTime();
160+
}
161+
145162
if (Verbose) {
146163
outs() << "Machine: ";
147164
switch (MachineType) {
@@ -194,7 +211,8 @@ int main(int Argc, const char **Argv) {
194211
}
195212

196213
std::unique_ptr<MemoryBuffer> OutputBuffer =
197-
error(llvm::object::writeWindowsResourceCOFF(MachineType, Parser));
214+
error(llvm::object::writeWindowsResourceCOFF(MachineType, Parser,
215+
DateTimeStamp));
198216
auto FileOrErr =
199217
FileOutputBuffer::create(OutputFile, OutputBuffer->getBufferSize());
200218
if (!FileOrErr)

0 commit comments

Comments
 (0)
Please sign in to comment.