llvm.org GIT mirror llvm / 39def88
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363050 91177308-0d34-0410-b5e6-96231b3b80d8 Nico Weber 2 months ago
6 changed file(s) with 48 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
231231
232232 Expected>
233233 writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
234 const WindowsResourceParser &Parser);
234 const WindowsResourceParser &Parser,
235 uint32_t TimeDateStamp);
235236
236237 void printResourceTypeName(uint16_t TypeID, raw_ostream &OS);
237238 } // namespace object
399399 public:
400400 WindowsResourceCOFFWriter(COFF::MachineTypes MachineType,
401401 const WindowsResourceParser &Parser, Error &E);
402 std::unique_ptr write();
402 std::unique_ptr write(uint32_t TimeDateStamp);
403403
404404 private:
405405 void performFileLayout();
406406 void performSectionOneLayout();
407407 void performSectionTwoLayout();
408 void writeCOFFHeader();
408 void writeCOFFHeader(uint32_t TimeDateStamp);
409409 void writeFirstSectionHeader();
410410 void writeSecondSectionHeader();
411411 void writeFirstSection();
498498 FileSize = alignTo(FileSize, SECTION_ALIGNMENT);
499499 }
500500
501 static std::time_t getTime() {
502 std::time_t Now = time(nullptr);
503 if (Now < 0 || !isUInt<32>(Now))
504 return UINT32_MAX;
505 return Now;
506 }
507
508 std::unique_ptr WindowsResourceCOFFWriter::write() {
501 std::unique_ptr
502 WindowsResourceCOFFWriter::write(uint32_t TimeDateStamp) {
509503 BufferStart = OutputBuffer->getBufferStart();
510504
511 writeCOFFHeader();
505 writeCOFFHeader(TimeDateStamp);
512506 writeFirstSectionHeader();
513507 writeSecondSectionHeader();
514508 writeFirstSection();
519513 return std::move(OutputBuffer);
520514 }
521515
522 void WindowsResourceCOFFWriter::writeCOFFHeader() {
516 void WindowsResourceCOFFWriter::writeCOFFHeader(uint32_t TimeDateStamp) {
523517 // Write the COFF header.
524518 auto *Header = reinterpret_cast(BufferStart);
525519 Header->Machine = MachineType;
526520 Header->NumberOfSections = 2;
527 Header->TimeDateStamp = getTime();
521 Header->TimeDateStamp = TimeDateStamp;
528522 Header->PointerToSymbolTable = SymbolTableOffset;
529523 // One symbol for every resource plus 2 for each section and @feat.00
530524 Header->NumberOfSymbols = Data.size() + 5;
531525 Header->SizeOfOptionalHeader = 0;
526 // cvtres.exe sets 32BIT_MACHINE even for 64-bit machine types. Match it.
532527 Header->Characteristics = COFF::IMAGE_FILE_32BIT_MACHINE;
533528 }
534529
793788
794789 Expected>
795790 writeWindowsResourceCOFF(COFF::MachineTypes MachineType,
796 const WindowsResourceParser &Parser) {
791 const WindowsResourceParser &Parser,
792 uint32_t TimeDateStamp) {
797793 Error E = Error::success();
798794 WindowsResourceCOFFWriter Writer(MachineType, Parser, E);
799795 if (E)
800796 return std::move(E);
801 return Writer.write();
797 return Writer.write(TimeDateStamp);
802798 }
803799
804800 } // namespace object
99 ; HELP_TEST-DAG: /NOLOGO
1010 ; HELP_TEST-NEXT: /OUT:filename
1111 ; HELP_TEST-NEXT: /READONLY
12 ; HELP_TEST-NEXT: /TIMESTAMP: Timestamp for coff header, defaults to current time
1213 ; HELP_TEST-NEXT: /VERBOSE
0 RUN: llvm-cvtres /timestamp:0x12345678 /out:%t %p/Inputs/test_resource.res
1 RUN: llvm-readobj -h %t | FileCheck %s --check-prefix=1TO8
2
3 1TO8: TimeDateStamp: 1979-09-05 22:51:36 (0x12345678)
4
5
6 RUN: not llvm-cvtres /timestamp:0x123456789 /out:%t \
7 RUN: %p/Inputs/test_resource.res 2>&1 | FileCheck %s --check-prefix=ERR
8
9 ERR: invalid timestamp: 0x123456789. Expected 32-bit integer
1111 def HELP : Flag<["/", "-"], "HELP">;
1212 def H : Flag<["/", "-"], "H">, Alias;
1313 def HELP_Q : Flag<["/?", "-?"], "">, Alias;
14
15 // Extensions.
16
17 def TIMESTAMP : Joined<["/", "-"], "TIMESTAMP:">,
18 HelpText<"Timestamp for coff header, defaults to current time">;
8787 [&](const ErrorInfoBase &EI) { reportError(EI.message()); });
8888 }
8989
90 static uint32_t getTime() {
91 std::time_t Now = time(nullptr);
92 if (Now < 0 || !isUInt<32>(Now))
93 return UINT32_MAX;
94 return static_cast(Now);
95 }
96
9097 template T error(Expected EC) {
9198 if (!EC)
9299 error(EC.takeError());
139146 } else {
140147 OutputFile = sys::path::filename(StringRef(InputFiles[0]));
141148 sys::path::replace_extension(OutputFile, ".obj");
149 }
150
151 uint32_t DateTimeStamp;
152 if (llvm::opt::Arg *Arg = InputArgs.getLastArg(OPT_TIMESTAMP)) {
153 StringRef Value(Arg->getValue());
154 if (Value.getAsInteger(0, DateTimeStamp))
155 reportError(Twine("invalid timestamp: ") + Value +
156 ". Expected 32-bit integer\n");
157 } else {
158 DateTimeStamp = getTime();
142159 }
143160
144161 if (Verbose) {
193210 }
194211
195212 std::unique_ptr OutputBuffer =
196 error(llvm::object::writeWindowsResourceCOFF(MachineType, Parser));
213 error(llvm::object::writeWindowsResourceCOFF(MachineType, Parser,
214 DateTimeStamp));
197215 auto FileOrErr =
198216 FileOutputBuffer::create(OutputFile, OutputBuffer->getBufferSize());
199217 if (!FileOrErr)