aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/WindowsResource.cpp
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2019-04-24 11:42:59 +0000
committerNico Weber <nicolasweber@gmx.de>2019-04-24 11:42:59 +0000
commitccf096463a86b4b8f49bf4141c17bf155dcbfe60 (patch)
treee438673312bf3fa57aef17782366aee45eec322a /llvm/lib/Object/WindowsResource.cpp
parent039a563e6a29d7baae54dd58460ca091081ab981 (diff)
downloadllvm-ccf096463a86b4b8f49bf4141c17bf155dcbfe60.zip
llvm-ccf096463a86b4b8f49bf4141c17bf155dcbfe60.tar.gz
llvm-ccf096463a86b4b8f49bf4141c17bf155dcbfe60.tar.bz2
Let llvm-cvtres (and lld-link) report duplicate resources
If two .res files contain the same resource, cvtres.exe (and hence link.exe) reject the input with this message: CVTRES : fatal error CVT1100: duplicate resource. type:STRING, name:101, language:0x0409 LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt llvm-cvtres (and lld-link) used to silently pick one of the duplicate resources instead. This patch makes them report an error as well. We slightly improve on cvtres by printing the name of two .res files containing duplicate entries as well. Differential Revision: https://reviews.llvm.org/D61049 llvm-svn: 359083
Diffstat (limited to 'llvm/lib/Object/WindowsResource.cpp')
-rw-r--r--llvm/lib/Object/WindowsResource.cpp86
1 files changed, 63 insertions, 23 deletions
diff --git a/llvm/lib/Object/WindowsResource.cpp b/llvm/lib/Object/WindowsResource.cpp
index 2195a61..813b4b6 100644
--- a/llvm/lib/Object/WindowsResource.cpp
+++ b/llvm/lib/Object/WindowsResource.cpp
@@ -127,6 +127,39 @@ Error ResourceEntryRef::loadNext() {
WindowsResourceParser::WindowsResourceParser() : Root(false) {}
+static Error duplicateResourceError(const ResourceEntryRef& Entry,
+ StringRef File1, StringRef File2) {
+ std::string Ret;
+ raw_string_ostream OS(Ret);
+
+ OS << "duplicate resource:";
+
+ OS << " type ";
+ if (Entry.checkTypeString()) {
+ std::string UTF8;
+ if (!convertUTF16ToUTF8String(Entry.getTypeString(), UTF8))
+ UTF8 = "(failed conversion from UTF16)";
+ OS << '\"' << UTF8 << '\"';
+ } else {
+ OS << "ID " << Entry.getTypeID();
+ }
+
+ OS << "/name ";
+ if (Entry.checkNameString()) {
+ std::string UTF8;
+ if (!convertUTF16ToUTF8String(Entry.getNameString(), UTF8))
+ UTF8 = "(failed conversion from UTF16)";
+ OS << '\"' << UTF8 << '\"';
+ } else {
+ OS << "ID " << Entry.getNameID();
+ }
+
+ OS << "/language " << Entry.getLanguage() << ", in " << File1 << " and in "
+ << File2;
+
+ return make_error<GenericBinaryError>(OS.str(), object_error::parse_failed);
+}
+
Error WindowsResourceParser::parse(WindowsResource *WR) {
auto EntryOrErr = WR->getHeadEntry();
if (!EntryOrErr) {
@@ -152,7 +185,13 @@ Error WindowsResourceParser::parse(WindowsResource *WR) {
bool IsNewTypeString = false;
bool IsNewNameString = false;
- Root.addEntry(Entry, IsNewTypeString, IsNewNameString);
+ TreeNode* Node;
+ bool IsNewNode = Root.addEntry(Entry, InputFilenames.size(),
+ IsNewTypeString, IsNewNameString, Node);
+ InputFilenames.push_back(WR->getFileName());
+ if (!IsNewNode)
+ return duplicateResourceError(Entry, InputFilenames[Node->Origin],
+ WR->getFileName());
if (IsNewTypeString)
StringTable.push_back(Entry.getTypeString());
@@ -171,12 +210,14 @@ void WindowsResourceParser::printTree(raw_ostream &OS) const {
Root.print(Writer, "Resource Tree");
}
-void WindowsResourceParser::TreeNode::addEntry(const ResourceEntryRef &Entry,
+bool WindowsResourceParser::TreeNode::addEntry(const ResourceEntryRef &Entry,
+ uint32_t Origin,
bool &IsNewTypeString,
- bool &IsNewNameString) {
+ bool &IsNewNameString,
+ TreeNode *&Result) {
TreeNode &TypeNode = addTypeNode(Entry, IsNewTypeString);
TreeNode &NameNode = TypeNode.addNameNode(Entry, IsNewNameString);
- NameNode.addLanguageNode(Entry);
+ return NameNode.addLanguageNode(Entry, Origin, Result);
}
WindowsResourceParser::TreeNode::TreeNode(bool IsStringNode) {
@@ -186,10 +227,11 @@ WindowsResourceParser::TreeNode::TreeNode(bool IsStringNode) {
WindowsResourceParser::TreeNode::TreeNode(uint16_t MajorVersion,
uint16_t MinorVersion,
- uint32_t Characteristics)
+ uint32_t Characteristics,
+ uint32_t Origin)
: IsDataNode(true), MajorVersion(MajorVersion), MinorVersion(MinorVersion),
- Characteristics(Characteristics) {
- DataIndex = DataCount++;
+ Characteristics(Characteristics), Origin(Origin) {
+ DataIndex = DataCount++;
}
std::unique_ptr<WindowsResourceParser::TreeNode>
@@ -205,9 +247,10 @@ WindowsResourceParser::TreeNode::createIDNode() {
std::unique_ptr<WindowsResourceParser::TreeNode>
WindowsResourceParser::TreeNode::createDataNode(uint16_t MajorVersion,
uint16_t MinorVersion,
- uint32_t Characteristics) {
+ uint32_t Characteristics,
+ uint32_t Origin) {
return std::unique_ptr<TreeNode>(
- new TreeNode(MajorVersion, MinorVersion, Characteristics));
+ new TreeNode(MajorVersion, MinorVersion, Characteristics, Origin));
}
WindowsResourceParser::TreeNode &
@@ -228,24 +271,21 @@ WindowsResourceParser::TreeNode::addNameNode(const ResourceEntryRef &Entry,
return addIDChild(Entry.getNameID());
}
-WindowsResourceParser::TreeNode &
-WindowsResourceParser::TreeNode::addLanguageNode(
- const ResourceEntryRef &Entry) {
+bool WindowsResourceParser::TreeNode::addLanguageNode(
+ const ResourceEntryRef &Entry, uint32_t Origin, TreeNode *&Result) {
return addDataChild(Entry.getLanguage(), Entry.getMajorVersion(),
- Entry.getMinorVersion(), Entry.getCharacteristics());
+ Entry.getMinorVersion(), Entry.getCharacteristics(),
+ Origin, Result);
}
-WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addDataChild(
+bool WindowsResourceParser::TreeNode::addDataChild(
uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion,
- uint32_t Characteristics) {
- auto Child = IDChildren.find(ID);
- if (Child == IDChildren.end()) {
- auto NewChild = createDataNode(MajorVersion, MinorVersion, Characteristics);
- WindowsResourceParser::TreeNode &Node = *NewChild;
- IDChildren.emplace(ID, std::move(NewChild));
- return Node;
- } else
- return *(Child->second);
+ uint32_t Characteristics, uint32_t Origin, TreeNode *&Result) {
+ auto NewChild =
+ createDataNode(MajorVersion, MinorVersion, Characteristics, Origin);
+ auto ElementInserted = IDChildren.emplace(ID, std::move(NewChild));
+ Result = ElementInserted.first->second.get();
+ return ElementInserted.second;
}
WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addIDChild(