Index: llvm/lib/Object/WindowsResource.cpp =================================================================== --- llvm/lib/Object/WindowsResource.cpp +++ llvm/lib/Object/WindowsResource.cpp @@ -515,6 +515,17 @@ return std::move(OutputBuffer); } +// According to COFF specification, if the Src has a size equal to Dest, +// it's okay to *not* copy the trailing zero. +template +static void coffnamecpy(char (&Dest)[DestSize], StringRef Src) { + static_assert(DestSize <= COFF::NameSize, "Dest is large enough"); + assert(Src.size() <= DestSize && "Dest is larger than Src"); + assert(Src.size() <= COFF::NameSize && + "Src is not larger than COFF::NameSize"); + strncpy(Dest, Src.data(), (size_t)COFF::NameSize); +} + void WindowsResourceCOFFWriter::writeCOFFHeader(uint32_t TimeDateStamp) { // Write the COFF header. auto *Header = reinterpret_cast(BufferStart); @@ -534,7 +545,7 @@ CurrentOffset += sizeof(coff_file_header); auto *SectionOneHeader = reinterpret_cast(BufferStart + CurrentOffset); - strncpy(SectionOneHeader->Name, ".rsrc$01", (size_t)COFF::NameSize); + coffnamecpy(SectionOneHeader->Name, ".rsrc$01"); SectionOneHeader->VirtualSize = 0; SectionOneHeader->VirtualAddress = 0; SectionOneHeader->SizeOfRawData = SectionOneSize; @@ -552,7 +563,7 @@ CurrentOffset += sizeof(coff_section); auto *SectionTwoHeader = reinterpret_cast(BufferStart + CurrentOffset); - strncpy(SectionTwoHeader->Name, ".rsrc$02", (size_t)COFF::NameSize); + coffnamecpy(SectionTwoHeader->Name, ".rsrc$02"); SectionTwoHeader->VirtualSize = 0; SectionTwoHeader->VirtualAddress = 0; SectionTwoHeader->SizeOfRawData = SectionTwoSize; @@ -590,7 +601,7 @@ // Now write the symbol table. // First, the feat symbol. auto *Symbol = reinterpret_cast(BufferStart + CurrentOffset); - strncpy(Symbol->Name.ShortName, "@feat.00", (size_t)COFF::NameSize); + coffnamecpy(Symbol->Name.ShortName, "@feat.00"); Symbol->Value = 0x11; Symbol->SectionNumber = 0xffff; Symbol->Type = COFF::IMAGE_SYM_DTYPE_NULL; @@ -600,7 +611,7 @@ // Now write the .rsrc1 symbol + aux. Symbol = reinterpret_cast(BufferStart + CurrentOffset); - strncpy(Symbol->Name.ShortName, ".rsrc$01", (size_t)COFF::NameSize); + coffnamecpy(Symbol->Name.ShortName, ".rsrc$01"); Symbol->Value = 0; Symbol->SectionNumber = 1; Symbol->Type = COFF::IMAGE_SYM_DTYPE_NULL; @@ -619,7 +630,7 @@ // Now write the .rsrc2 symbol + aux. Symbol = reinterpret_cast(BufferStart + CurrentOffset); - strncpy(Symbol->Name.ShortName, ".rsrc$02", (size_t)COFF::NameSize); + coffnamecpy(Symbol->Name.ShortName, ".rsrc$02"); Symbol->Value = 0; Symbol->SectionNumber = 2; Symbol->Type = COFF::IMAGE_SYM_DTYPE_NULL; @@ -640,7 +651,7 @@ for (unsigned i = 0; i < Data.size(); i++) { auto RelocationName = formatv("$R{0:X-6}", i & 0xffffff).sstr(); Symbol = reinterpret_cast(BufferStart + CurrentOffset); - memcpy(Symbol->Name.ShortName, RelocationName.data(), (size_t) COFF::NameSize); + coffnamecpy(Symbol->Name.ShortName, RelocationName); Symbol->Value = DataOffsets[i]; Symbol->SectionNumber = 2; Symbol->Type = COFF::IMAGE_SYM_DTYPE_NULL;