llvm.org GIT mirror llvm / f74bed2
Move manifest utils into separate lib, to reduce libxml2 deps. Summary: Previously were in support. Since many many things depend on support, were all forced to also depend on libxml2, which we only want in a few cases. This puts all the libxml2 deps in a separate lib to be used only in a few places. Reviewers: ruiu, thakis, rnk Subscribers: mgorny, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D35819 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309070 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Beckmann 2 years ago
13 changed file(s) with 343 addition(s) and 298 deletion(s). Raw diff Collapse all Expand all
+0
-80
include/llvm/Support/WindowsManifestMerger.h less more
None //===-- WindowsManifestMerger.h ---------------------------------*- C++-*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===---------------------------------------------------------------------===//
8 //
9 // This file provides a utility for merging Microsoft .manifest files. These
10 // files are xml documents which contain meta-information about applications,
11 // such as whether or not admin access is required, system compatibility,
12 // versions, etc. Part of the linking process of an executable may require
13 // merging several of these .manifest files using a tree-merge following
14 // specific rules. Unfortunately, these rules are not documented well
15 // anywhere. However, a careful investigation of the behavior of the original
16 // Microsoft Manifest Tool (mt.exe) revealed the rules of this merge. As the
17 // saying goes, code is the best documentation, so please look below if you are
18 // interested in the exact merging requirements.
19 //
20 // Ref:
21 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa374191(v=vs.85).aspx
22 //
23 //===---------------------------------------------------------------------===//
24
25 #ifndef LLVM_INCLUDE_LLVM_SUPPORT_WINDOWS_MANIFEST_MERGER_H
26 #define LLVM_INCLUDE_LLVM_SUPPORT_WINDOWS_MANIFEST_MERGER_H
27
28 #include "llvm/Config/config.h"
29 #include "llvm/Support/Error.h"
30
31 #if LLVM_LIBXML2_ENABLED
32 #include
33 #endif
34
35 namespace llvm {
36
37 class MemoryBuffer;
38
39 #if LLVM_LIBXML2_ENABLED
40 typedef xmlDocPtr XMLDocumentImpl;
41 typedef xmlNodePtr XMLNodeImpl;
42 #else
43 typedef void *XMLDocumentImpl;
44 typedef void *XMLNodeImpl;
45 #endif
46
47 class WindowsManifestError : public ErrorInfo {
48 public:
49 static char ID;
50 WindowsManifestError(const Twine &Msg);
51 void log(raw_ostream &OS) const override;
52
53 private:
54 std::string Msg;
55 };
56
57 class WindowsManifestMerger {
58 public:
59 ~WindowsManifestMerger();
60
61 Error merge(const MemoryBuffer &Manifest);
62
63 // Returns vector containing merged xml manifest, or uninitialized vector for
64 // empty manifest.
65 std::unique_ptr getMergedManifest();
66
67 private:
68 static void errorCallback(void *Ctx, const char *Format, ...);
69 Error getParseError();
70
71 #if LLVM_LIBXML2_ENABLED
72 XMLDocumentImpl CombinedDoc = nullptr;
73 std::vector MergedDocs;
74 #endif
75 bool ParseErrorOccurred = false;
76 };
77
78 } // namespace llvm
79 #endif
0 //===-- WindowsManifestMerger.h ---------------------------------*- C++-*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===---------------------------------------------------------------------===//
8 //
9 // This file provides a utility for merging Microsoft .manifest files. These
10 // files are xml documents which contain meta-information about applications,
11 // such as whether or not admin access is required, system compatibility,
12 // versions, etc. Part of the linking process of an executable may require
13 // merging several of these .manifest files using a tree-merge following
14 // specific rules. Unfortunately, these rules are not documented well
15 // anywhere. However, a careful investigation of the behavior of the original
16 // Microsoft Manifest Tool (mt.exe) revealed the rules of this merge. As the
17 // saying goes, code is the best documentation, so please look below if you are
18 // interested in the exact merging requirements.
19 //
20 // Ref:
21 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa374191(v=vs.85).aspx
22 //
23 //===---------------------------------------------------------------------===//
24
25 #ifndef LLVM_INCLUDE_LLVM_SUPPORT_WINDOWS_MANIFEST_MERGER_H
26 #define LLVM_INCLUDE_LLVM_SUPPORT_WINDOWS_MANIFEST_MERGER_H
27
28 #include "llvm/Config/config.h"
29 #include "llvm/Support/Error.h"
30
31 #if LLVM_LIBXML2_ENABLED
32 #include
33 #endif
34
35 namespace llvm {
36
37 class MemoryBuffer;
38
39 #if LLVM_LIBXML2_ENABLED
40 typedef xmlDocPtr XMLDocumentImpl;
41 typedef xmlNodePtr XMLNodeImpl;
42 #else
43 typedef void *XMLDocumentImpl;
44 typedef void *XMLNodeImpl;
45 #endif
46
47 class WindowsManifestError : public ErrorInfo {
48 public:
49 static char ID;
50 WindowsManifestError(const Twine &Msg);
51 void log(raw_ostream &OS) const override;
52
53 private:
54 std::string Msg;
55 };
56
57 class WindowsManifestMerger {
58 public:
59 ~WindowsManifestMerger();
60
61 Error merge(const MemoryBuffer &Manifest);
62
63 // Returns vector containing merged xml manifest, or uninitialized vector for
64 // empty manifest.
65 std::unique_ptr getMergedManifest();
66
67 private:
68 static void errorCallback(void *Ctx, const char *Format, ...);
69 Error getParseError();
70
71 #if LLVM_LIBXML2_ENABLED
72 XMLDocumentImpl CombinedDoc = nullptr;
73 std::vector MergedDocs;
74 #endif
75 bool ParseErrorOccurred = false;
76 };
77
78 } // namespace llvm
79 #endif
305305 header "llvm/Support/DataTypes.h"
306306 export *
307307 }
308
309 module LLVM_WindowsManifest {
310 requires cplusplus
311 umbrella "WindowsManifest"
312 module * { export * }
313 }
2424 add_subdirectory(ToolDrivers)
2525 add_subdirectory(XRay)
2626 add_subdirectory(Testing)
27 add_subdirectory(WindowsManifest)
4141 Testing
4242 ToolDrivers
4343 Transforms
44 WindowsManifest
4445
4546 [component_0]
4647 type = Group
2525 endif()
2626 if( UNIX AND NOT (BEOS OR HAIKU) )
2727 set(system_libs ${system_libs} m)
28 endif()
29 if( LLVM_LIBXML2_ENABLED )
30 set(system_libs ${system_libs} ${LIBXML2_LIBS})
3128 endif()
3229 endif( MSVC OR MINGW )
3330
112109 Triple.cpp
113110 Twine.cpp
114111 Unicode.cpp
115 WindowsManifestMerger.cpp
116112 YAMLParser.cpp
117113 YAMLTraits.cpp
118114 raw_os_ostream.cpp
+0
-212
lib/Support/WindowsManifestMerger.cpp less more
None //===-- WindowsManifestMerger.cpp ------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===---------------------------------------------------------------------===//
8 //
9 // This file implements the .manifest merger class.
10 //
11 //===---------------------------------------------------------------------===//
12
13 #include "llvm/Support/WindowsManifestMerger.h"
14 #include "llvm/Support/MemoryBuffer.h"
15
16 #include
17
18 #define TO_XML_CHAR(X) reinterpret_cast(X)
19 #define FROM_XML_CHAR(X) reinterpret_cast(X)
20
21 using namespace llvm;
22
23 namespace llvm {
24
25 char WindowsManifestError::ID = 0;
26
27 WindowsManifestError::WindowsManifestError(const Twine &Msg) : Msg(Msg.str()) {}
28
29 void WindowsManifestError::log(raw_ostream &OS) const { OS << Msg; }
30
31 #if LLVM_LIBXML2_ENABLED
32 static bool xmlStringsEqual(const unsigned char *A, const unsigned char *B) {
33 return strcmp(FROM_XML_CHAR(A), FROM_XML_CHAR(B)) == 0;
34 }
35 #endif
36
37 bool isMergeableElement(const unsigned char *ElementName) {
38 for (StringRef S : {"application", "assembly", "assemblyIdentity",
39 "compatibility", "noInherit", "requestedExecutionLevel",
40 "requestedPrivileges", "security", "trustInfo"}) {
41 if (S == FROM_XML_CHAR(ElementName))
42 return true;
43 }
44 return false;
45 }
46
47 XMLNodeImpl getChildWithName(XMLNodeImpl Parent,
48 const unsigned char *ElementName) {
49 #if LLVM_LIBXML2_ENABLED
50 for (XMLNodeImpl Child = Parent->children; Child; Child = Child->next)
51 if (xmlStringsEqual(Child->name, ElementName)) {
52 return Child;
53 }
54 #endif
55 return nullptr;
56 }
57
58 const unsigned char *getAttribute(XMLNodeImpl Node,
59 const unsigned char *AttributeName) {
60 #if LLVM_LIBXML2_ENABLED
61 for (xmlAttrPtr Attribute = Node->properties; Attribute != nullptr;
62 Attribute = Attribute->next) {
63 if (xmlStringsEqual(Attribute->name, AttributeName))
64 return Attribute->children->content;
65 }
66 #endif
67 return nullptr;
68 }
69
70 Error mergeAttributes(XMLNodeImpl OriginalNode, XMLNodeImpl AdditionalNode) {
71 #if LLVM_LIBXML2_ENABLED
72 for (xmlAttrPtr Attribute = AdditionalNode->properties; Attribute != nullptr;
73 Attribute = Attribute->next) {
74 if (const unsigned char *OriginalValue =
75 getAttribute(OriginalNode, Attribute->name)) {
76 // Attributes of the same name must also have the same value. Otherwise
77 // an error is thrown.
78 if (!xmlStringsEqual(OriginalValue, Attribute->children->content))
79 return make_error(
80 Twine("conflicting attributes for ") +
81 FROM_XML_CHAR(OriginalNode->name));
82 } else {
83 char *NameCopy = strdup(FROM_XML_CHAR(Attribute->name));
84 char *ContentCopy = strdup(FROM_XML_CHAR(Attribute->children->content));
85 xmlNewProp(OriginalNode, TO_XML_CHAR(NameCopy), TO_XML_CHAR(ContentCopy));
86 }
87 }
88 #endif
89 return Error::success();
90 }
91
92 Error treeMerge(XMLNodeImpl OriginalRoot, XMLNodeImpl AdditionalRoot) {
93 #if LLVM_LIBXML2_ENABLED
94 XMLNodeImpl AdditionalFirstChild = AdditionalRoot->children;
95 for (XMLNodeImpl Child = AdditionalFirstChild; Child; Child = Child->next) {
96 XMLNodeImpl OriginalChildWithName;
97 if (!isMergeableElement(Child->name) ||
98 !(OriginalChildWithName =
99 getChildWithName(OriginalRoot, Child->name))) {
100 XMLNodeImpl NewChild = xmlCopyNode(Child, 1);
101 if (!NewChild)
102 return make_error(Twine("error when copying ") +
103 FROM_XML_CHAR(Child->name));
104 if (NewChild->ns)
105 xmlFreeNs(NewChild->ns); // xmlCopyNode explicitly defines default
106 // namespace, undo this here.
107 if (!xmlAddChild(OriginalRoot, NewChild))
108 return make_error(Twine("could not merge ") +
109 FROM_XML_CHAR(NewChild->name));
110 } else if (auto E = treeMerge(OriginalChildWithName, Child)) {
111 return E;
112 }
113 }
114 if (auto E = mergeAttributes(OriginalRoot, AdditionalRoot))
115 return E;
116 #endif
117 return Error::success();
118 }
119
120 void stripCommentsAndText(XMLNodeImpl Root) {
121 #if LLVM_LIBXML2_ENABLED
122 xmlNode StoreNext;
123 for (XMLNodeImpl Child = Root->children; Child; Child = Child->next) {
124 if (!xmlStringsEqual(Child->name, TO_XML_CHAR("text")) &&
125 !xmlStringsEqual(Child->name, TO_XML_CHAR("comment"))) {
126 stripCommentsAndText(Child);
127 } else {
128 StoreNext.next = Child->next;
129 XMLNodeImpl Remove = Child;
130 Child = &StoreNext;
131 xmlUnlinkNode(Remove);
132 xmlFreeNode(Remove);
133 }
134 }
135 #endif
136 }
137
138 WindowsManifestMerger::~WindowsManifestMerger() {
139 #if LLVM_LIBXML2_ENABLED
140 for (auto &Doc : MergedDocs)
141 xmlFreeDoc(Doc);
142 #endif
143 }
144
145 Error WindowsManifestMerger::merge(const MemoryBuffer &Manifest) {
146 #if LLVM_LIBXML2_ENABLED
147 if (Manifest.getBufferSize() == 0)
148 return make_error(
149 "attempted to merge empty manifest");
150 xmlSetGenericErrorFunc((void *)this, WindowsManifestMerger::errorCallback);
151 XMLDocumentImpl ManifestXML =
152 xmlReadMemory(Manifest.getBufferStart(), Manifest.getBufferSize(),
153 "manifest.xml", nullptr, XML_PARSE_NOBLANKS);
154 xmlSetGenericErrorFunc(nullptr, nullptr);
155 if (auto E = getParseError())
156 return E;
157 XMLNodeImpl AdditionalRoot = xmlDocGetRootElement(ManifestXML);
158 stripCommentsAndText(AdditionalRoot);
159 if (CombinedDoc == nullptr) {
160 CombinedDoc = ManifestXML;
161 } else {
162 XMLNodeImpl CombinedRoot = xmlDocGetRootElement(CombinedDoc);
163 if (xmlStringsEqual(CombinedRoot->name, AdditionalRoot->name) &&
164 isMergeableElement(AdditionalRoot->name)) {
165 if (auto E = treeMerge(CombinedRoot, AdditionalRoot)) {
166 return E;
167 }
168 } else {
169 XMLNodeImpl NewChild = xmlCopyNode(AdditionalRoot, 1);
170 if (!NewChild)
171 return make_error("could not copy manifest");
172 if (!xmlAddChild(CombinedRoot, NewChild))
173 return make_error("could not append manifest");
174 }
175 }
176 MergedDocs.push_back(ManifestXML);
177 #endif
178 return Error::success();
179 }
180
181 std::unique_ptr WindowsManifestMerger::getMergedManifest() {
182 #if LLVM_LIBXML2_ENABLED
183 unsigned char *XmlBuff;
184 int BufferSize = 0;
185 if (CombinedDoc) {
186 std::unique_ptr OutputDoc(xmlNewDoc((const unsigned char *)"1.0"));
187 xmlDocSetRootElement(OutputDoc.get(), xmlDocGetRootElement(CombinedDoc));
188 xmlKeepBlanksDefault(0);
189 xmlDocDumpFormatMemory(OutputDoc.get(), &XmlBuff, &BufferSize, 1);
190 }
191 if (BufferSize == 0)
192 return nullptr;
193 return MemoryBuffer::getMemBuffer(
194 StringRef(FROM_XML_CHAR(XmlBuff), (size_t)BufferSize));
195 #else
196 return nullptr;
197 #endif
198 }
199
200 void WindowsManifestMerger::errorCallback(void *Ctx, const char *Format, ...) {
201 auto *Merger = (WindowsManifestMerger *)Ctx;
202 Merger->ParseErrorOccurred = true;
203 }
204
205 Error WindowsManifestMerger::getParseError() {
206 if (!ParseErrorOccurred)
207 return Error::success();
208 return make_error("invalid xml document");
209 }
210
211 } // namespace llvm
0 set(system_libs)
1 if( CMAKE_HOST_UNIX )
2 if( LLVM_LIBXML2_ENABLED )
3 set(system_libs ${system_libs} ${LIBXML2_LIBS})
4 endif()
5 endif()
6
7 add_llvm_library(LLVMWindowsManifest
8 WindowsManifestMerger.cpp
9
10 ADDITIONAL_HEADER_DIRS
11 ${LLVM_MAIN_INCLUDE_DIR}/llvm/WindowsManifest
12 ${Backtrace_INCLUDE_DIRS}
13
14 LINK_LIBS ${system_libs}
15 )
16
17 set_property(TARGET LLVMWindowsManifest PROPERTY LLVM_SYSTEM_LIBS "${system_libs}")
0 ;===- ./lib/WindowsManifest/LLVMBuild.txt ----------------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Library
19 name = WindowsManifest
20 parent = Libraries
21 required_libraries = Support
0 //===-- WindowsManifestMerger.cpp ------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===---------------------------------------------------------------------===//
8 //
9 // This file implements the .manifest merger class.
10 //
11 //===---------------------------------------------------------------------===//
12
13 #include "llvm/WindowsManifest/WindowsManifestMerger.h"
14 #include "llvm/Support/MemoryBuffer.h"
15
16 #include
17
18 #define TO_XML_CHAR(X) reinterpret_cast(X)
19 #define FROM_XML_CHAR(X) reinterpret_cast(X)
20
21 using namespace llvm;
22
23 namespace llvm {
24
25 char WindowsManifestError::ID = 0;
26
27 WindowsManifestError::WindowsManifestError(const Twine &Msg) : Msg(Msg.str()) {}
28
29 void WindowsManifestError::log(raw_ostream &OS) const { OS << Msg; }
30
31 #if LLVM_LIBXML2_ENABLED
32 static bool xmlStringsEqual(const unsigned char *A, const unsigned char *B) {
33 return strcmp(FROM_XML_CHAR(A), FROM_XML_CHAR(B)) == 0;
34 }
35 #endif
36
37 bool isMergeableElement(const unsigned char *ElementName) {
38 for (StringRef S : {"application", "assembly", "assemblyIdentity",
39 "compatibility", "noInherit", "requestedExecutionLevel",
40 "requestedPrivileges", "security", "trustInfo"}) {
41 if (S == FROM_XML_CHAR(ElementName))
42 return true;
43 }
44 return false;
45 }
46
47 XMLNodeImpl getChildWithName(XMLNodeImpl Parent,
48 const unsigned char *ElementName) {
49 #if LLVM_LIBXML2_ENABLED
50 for (XMLNodeImpl Child = Parent->children; Child; Child = Child->next)
51 if (xmlStringsEqual(Child->name, ElementName)) {
52 return Child;
53 }
54 #endif
55 return nullptr;
56 }
57
58 const unsigned char *getAttribute(XMLNodeImpl Node,
59 const unsigned char *AttributeName) {
60 #if LLVM_LIBXML2_ENABLED
61 for (xmlAttrPtr Attribute = Node->properties; Attribute != nullptr;
62 Attribute = Attribute->next) {
63 if (xmlStringsEqual(Attribute->name, AttributeName))
64 return Attribute->children->content;
65 }
66 #endif
67 return nullptr;
68 }
69
70 Error mergeAttributes(XMLNodeImpl OriginalNode, XMLNodeImpl AdditionalNode) {
71 #if LLVM_LIBXML2_ENABLED
72 for (xmlAttrPtr Attribute = AdditionalNode->properties; Attribute != nullptr;
73 Attribute = Attribute->next) {
74 if (const unsigned char *OriginalValue =
75 getAttribute(OriginalNode, Attribute->name)) {
76 // Attributes of the same name must also have the same value. Otherwise
77 // an error is thrown.
78 if (!xmlStringsEqual(OriginalValue, Attribute->children->content))
79 return make_error(
80 Twine("conflicting attributes for ") +
81 FROM_XML_CHAR(OriginalNode->name));
82 } else {
83 char *NameCopy = strdup(FROM_XML_CHAR(Attribute->name));
84 char *ContentCopy = strdup(FROM_XML_CHAR(Attribute->children->content));
85 xmlNewProp(OriginalNode, TO_XML_CHAR(NameCopy), TO_XML_CHAR(ContentCopy));
86 }
87 }
88 #endif
89 return Error::success();
90 }
91
92 Error treeMerge(XMLNodeImpl OriginalRoot, XMLNodeImpl AdditionalRoot) {
93 #if LLVM_LIBXML2_ENABLED
94 XMLNodeImpl AdditionalFirstChild = AdditionalRoot->children;
95 for (XMLNodeImpl Child = AdditionalFirstChild; Child; Child = Child->next) {
96 XMLNodeImpl OriginalChildWithName;
97 if (!isMergeableElement(Child->name) ||
98 !(OriginalChildWithName =
99 getChildWithName(OriginalRoot, Child->name))) {
100 XMLNodeImpl NewChild = xmlCopyNode(Child, 1);
101 if (!NewChild)
102 return make_error(Twine("error when copying ") +
103 FROM_XML_CHAR(Child->name));
104 if (NewChild->ns)
105 xmlFreeNs(NewChild->ns); // xmlCopyNode explicitly defines default
106 // namespace, undo this here.
107 if (!xmlAddChild(OriginalRoot, NewChild))
108 return make_error(Twine("could not merge ") +
109 FROM_XML_CHAR(NewChild->name));
110 } else if (auto E = treeMerge(OriginalChildWithName, Child)) {
111 return E;
112 }
113 }
114 if (auto E = mergeAttributes(OriginalRoot, AdditionalRoot))
115 return E;
116 #endif
117 return Error::success();
118 }
119
120 void stripCommentsAndText(XMLNodeImpl Root) {
121 #if LLVM_LIBXML2_ENABLED
122 xmlNode StoreNext;
123 for (XMLNodeImpl Child = Root->children; Child; Child = Child->next) {
124 if (!xmlStringsEqual(Child->name, TO_XML_CHAR("text")) &&
125 !xmlStringsEqual(Child->name, TO_XML_CHAR("comment"))) {
126 stripCommentsAndText(Child);
127 } else {
128 StoreNext.next = Child->next;
129 XMLNodeImpl Remove = Child;
130 Child = &StoreNext;
131 xmlUnlinkNode(Remove);
132 xmlFreeNode(Remove);
133 }
134 }
135 #endif
136 }
137
138 WindowsManifestMerger::~WindowsManifestMerger() {
139 #if LLVM_LIBXML2_ENABLED
140 for (auto &Doc : MergedDocs)
141 xmlFreeDoc(Doc);
142 #endif
143 }
144
145 Error WindowsManifestMerger::merge(const MemoryBuffer &Manifest) {
146 #if LLVM_LIBXML2_ENABLED
147 if (Manifest.getBufferSize() == 0)
148 return make_error(
149 "attempted to merge empty manifest");
150 xmlSetGenericErrorFunc((void *)this, WindowsManifestMerger::errorCallback);
151 XMLDocumentImpl ManifestXML =
152 xmlReadMemory(Manifest.getBufferStart(), Manifest.getBufferSize(),
153 "manifest.xml", nullptr, XML_PARSE_NOBLANKS);
154 xmlSetGenericErrorFunc(nullptr, nullptr);
155 if (auto E = getParseError())
156 return E;
157 XMLNodeImpl AdditionalRoot = xmlDocGetRootElement(ManifestXML);
158 stripCommentsAndText(AdditionalRoot);
159 if (CombinedDoc == nullptr) {
160 CombinedDoc = ManifestXML;
161 } else {
162 XMLNodeImpl CombinedRoot = xmlDocGetRootElement(CombinedDoc);
163 if (xmlStringsEqual(CombinedRoot->name, AdditionalRoot->name) &&
164 isMergeableElement(AdditionalRoot->name)) {
165 if (auto E = treeMerge(CombinedRoot, AdditionalRoot)) {
166 return E;
167 }
168 } else {
169 XMLNodeImpl NewChild = xmlCopyNode(AdditionalRoot, 1);
170 if (!NewChild)
171 return make_error("could not copy manifest");
172 if (!xmlAddChild(CombinedRoot, NewChild))
173 return make_error("could not append manifest");
174 }
175 }
176 MergedDocs.push_back(ManifestXML);
177 #endif
178 return Error::success();
179 }
180
181 std::unique_ptr WindowsManifestMerger::getMergedManifest() {
182 #if LLVM_LIBXML2_ENABLED
183 unsigned char *XmlBuff;
184 int BufferSize = 0;
185 if (CombinedDoc) {
186 std::unique_ptr OutputDoc(xmlNewDoc((const unsigned char *)"1.0"));
187 xmlDocSetRootElement(OutputDoc.get(), xmlDocGetRootElement(CombinedDoc));
188 xmlKeepBlanksDefault(0);
189 xmlDocDumpFormatMemory(OutputDoc.get(), &XmlBuff, &BufferSize, 1);
190 }
191 if (BufferSize == 0)
192 return nullptr;
193 return MemoryBuffer::getMemBuffer(
194 StringRef(FROM_XML_CHAR(XmlBuff), (size_t)BufferSize));
195 #else
196 return nullptr;
197 #endif
198 }
199
200 void WindowsManifestMerger::errorCallback(void *Ctx, const char *Format, ...) {
201 auto *Merger = (WindowsManifestMerger *)Ctx;
202 Merger->ParseErrorOccurred = true;
203 }
204
205 Error WindowsManifestMerger::getParseError() {
206 if (!ParseErrorOccurred)
207 return Error::success();
208 return make_error("invalid xml document");
209 }
210
211 } // namespace llvm
0 set(LLVM_LINK_COMPONENTS
11 Option
22 Support
3 WindowsManifest
34 )
45
56 set(LLVM_TARGET_DEFINITIONS Opts.td)
1818 type = Tool
1919 name = llvm-mt
2020 parent = Tools
21 required_libraries = Option Support
21 required_libraries = Option Support WindowsManifest
2121 #include "llvm/Support/PrettyStackTrace.h"
2222 #include "llvm/Support/Process.h"
2323 #include "llvm/Support/Signals.h"
24 #include "llvm/Support/WindowsManifestMerger.h"
2524 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/WindowsManifest/WindowsManifestMerger.h"
2626
2727 #include
2828