forked from OSchip/llvm-project
Revert "llvm-mt: implement simple merging of manifests, not factoring namespaces."
This reverts commit 813308e240792ca70ed2f998f21df24a5061ada0. llvm-svn: 309050
This commit is contained in:
parent
8dc8394d5f
commit
455210e18f
|
@ -57,8 +57,6 @@ private:
|
|||
|
||||
class WindowsManifestMerger {
|
||||
public:
|
||||
~WindowsManifestMerger();
|
||||
|
||||
Error merge(const MemoryBuffer &Manifest);
|
||||
|
||||
// Returns vector containing merged xml manifest, or uninitialized vector for
|
||||
|
@ -70,8 +68,7 @@ private:
|
|||
Error getParseError();
|
||||
|
||||
#if LLVM_LIBXML2_ENABLED
|
||||
XMLDocumentImpl CombinedDoc = nullptr;
|
||||
std::vector<XMLDocumentImpl> MergedDocs;
|
||||
XMLNodeImpl CombinedRoot = nullptr;
|
||||
#endif
|
||||
bool ParseErrorOccurred = false;
|
||||
};
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define TO_XML_CHAR(X) reinterpret_cast<const unsigned char *>(X)
|
||||
#define FROM_XML_CHAR(X) reinterpret_cast<const char *>(X)
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
|
||||
char WindowsManifestError::ID = 0;
|
||||
|
@ -29,148 +24,16 @@ WindowsManifestError::WindowsManifestError(const Twine &Msg) : Msg(Msg.str()) {}
|
|||
|
||||
void WindowsManifestError::log(raw_ostream &OS) const { OS << Msg; }
|
||||
|
||||
static bool xmlStringsEqual(const unsigned char *A, const unsigned char *B) {
|
||||
return strcmp(FROM_XML_CHAR(A), FROM_XML_CHAR(B)) == 0;
|
||||
}
|
||||
|
||||
bool isMergeableElement(const unsigned char *ElementName) {
|
||||
for (StringRef S : {"application", "assembly", "assemblyIdentity",
|
||||
"compatibility", "noInherit", "requestedExecutionLevel",
|
||||
"requestedPrivileges", "security", "trustInfo"}) {
|
||||
if (S == FROM_XML_CHAR(ElementName))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
XMLNodeImpl getChildWithName(XMLNodeImpl Parent,
|
||||
const unsigned char *ElementName) {
|
||||
#if LLVM_LIBXML2_ENABLED
|
||||
for (XMLNodeImpl Child = Parent->children; Child; Child = Child->next)
|
||||
if (xmlStringsEqual(Child->name, ElementName)) {
|
||||
return Child;
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const unsigned char *getAttribute(XMLNodeImpl Node,
|
||||
const unsigned char *AttributeName) {
|
||||
#if LLVM_LIBXML2_ENABLED
|
||||
for (xmlAttrPtr Attribute = Node->properties; Attribute != nullptr;
|
||||
Attribute = Attribute->next) {
|
||||
if (xmlStringsEqual(Attribute->name, AttributeName))
|
||||
return Attribute->children->content;
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Error mergeAttributes(XMLNodeImpl OriginalNode, XMLNodeImpl AdditionalNode) {
|
||||
#if LLVM_LIBXML2_ENABLED
|
||||
for (xmlAttrPtr Attribute = AdditionalNode->properties; Attribute != nullptr;
|
||||
Attribute = Attribute->next) {
|
||||
if (const unsigned char *OriginalValue =
|
||||
getAttribute(OriginalNode, Attribute->name)) {
|
||||
// Attributes of the same name must also have the same value. Otherwise
|
||||
// an error is thrown.
|
||||
if (!xmlStringsEqual(OriginalValue, Attribute->children->content))
|
||||
return make_error<WindowsManifestError>(
|
||||
Twine("conflicting attributes for ") +
|
||||
FROM_XML_CHAR(OriginalNode->name));
|
||||
} else {
|
||||
char *NameCopy = strdup(FROM_XML_CHAR(Attribute->name));
|
||||
char *ContentCopy = strdup(FROM_XML_CHAR(Attribute->children->content));
|
||||
xmlNewProp(OriginalNode, TO_XML_CHAR(NameCopy), TO_XML_CHAR(ContentCopy));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error treeMerge(XMLNodeImpl OriginalRoot, XMLNodeImpl AdditionalRoot) {
|
||||
#if LLVM_LIBXML2_ENABLED
|
||||
XMLNodeImpl AdditionalFirstChild = AdditionalRoot->children;
|
||||
for (XMLNodeImpl Child = AdditionalFirstChild; Child; Child = Child->next) {
|
||||
XMLNodeImpl OriginalChildWithName;
|
||||
if (!isMergeableElement(Child->name) ||
|
||||
!(OriginalChildWithName =
|
||||
getChildWithName(OriginalRoot, Child->name))) {
|
||||
XMLNodeImpl NewChild = xmlCopyNode(Child, 1);
|
||||
if (!NewChild)
|
||||
return make_error<WindowsManifestError>(Twine("error when copying ") +
|
||||
FROM_XML_CHAR(Child->name));
|
||||
if (NewChild->ns)
|
||||
xmlFreeNs(NewChild->ns); // xmlCopyNode explicitly defines default
|
||||
// namespace, undo this here.
|
||||
if (!xmlAddChild(OriginalRoot, NewChild))
|
||||
return make_error<WindowsManifestError>(Twine("could not merge ") +
|
||||
FROM_XML_CHAR(NewChild->name));
|
||||
} else if (auto E = treeMerge(OriginalChildWithName, Child)) {
|
||||
return E;
|
||||
}
|
||||
}
|
||||
if (auto E = mergeAttributes(OriginalRoot, AdditionalRoot))
|
||||
return E;
|
||||
#endif
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
void stripCommentsAndText(XMLNodeImpl Root) {
|
||||
xmlNode StoreNext;
|
||||
for (XMLNodeImpl Child = Root->children; Child; Child = Child->next) {
|
||||
if (!xmlStringsEqual(Child->name, TO_XML_CHAR("text")) &&
|
||||
!xmlStringsEqual(Child->name, TO_XML_CHAR("comment"))) {
|
||||
stripCommentsAndText(Child);
|
||||
} else {
|
||||
StoreNext.next = Child->next;
|
||||
XMLNodeImpl Remove = Child;
|
||||
Child = &StoreNext;
|
||||
xmlUnlinkNode(Remove);
|
||||
xmlFreeNode(Remove);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WindowsManifestMerger::~WindowsManifestMerger() {
|
||||
#if LLVM_LIBXML2_ENABLED
|
||||
for (auto &Doc : MergedDocs)
|
||||
xmlFreeDoc(Doc);
|
||||
#endif
|
||||
}
|
||||
|
||||
Error WindowsManifestMerger::merge(const MemoryBuffer &Manifest) {
|
||||
#if LLVM_LIBXML2_ENABLED
|
||||
if (Manifest.getBufferSize() == 0)
|
||||
return make_error<WindowsManifestError>(
|
||||
"attempted to merge empty manifest");
|
||||
xmlSetGenericErrorFunc((void *)this, WindowsManifestMerger::errorCallback);
|
||||
XMLDocumentImpl ManifestXML =
|
||||
xmlReadMemory(Manifest.getBufferStart(), Manifest.getBufferSize(),
|
||||
"manifest.xml", nullptr, XML_PARSE_NOBLANKS);
|
||||
"manifest.xml", nullptr, 0);
|
||||
xmlSetGenericErrorFunc(nullptr, nullptr);
|
||||
if (auto E = getParseError())
|
||||
return E;
|
||||
XMLNodeImpl AdditionalRoot = xmlDocGetRootElement(ManifestXML);
|
||||
stripCommentsAndText(AdditionalRoot);
|
||||
if (CombinedDoc == nullptr) {
|
||||
CombinedDoc = ManifestXML;
|
||||
} else {
|
||||
XMLNodeImpl CombinedRoot = xmlDocGetRootElement(CombinedDoc);
|
||||
if (xmlStringsEqual(CombinedRoot->name, AdditionalRoot->name) &&
|
||||
isMergeableElement(AdditionalRoot->name)) {
|
||||
if (auto E = treeMerge(CombinedRoot, AdditionalRoot)) {
|
||||
return E;
|
||||
}
|
||||
} else {
|
||||
XMLNodeImpl NewChild = xmlCopyNode(AdditionalRoot, 1);
|
||||
if (!NewChild)
|
||||
return make_error<WindowsManifestError>("could not copy manifest");
|
||||
if (!xmlAddChild(CombinedRoot, NewChild))
|
||||
return make_error<WindowsManifestError>("could not append manifest");
|
||||
}
|
||||
}
|
||||
MergedDocs.push_back(ManifestXML);
|
||||
CombinedRoot = xmlDocGetRootElement(ManifestXML);
|
||||
#endif
|
||||
return Error::success();
|
||||
}
|
||||
|
@ -179,16 +42,15 @@ std::unique_ptr<MemoryBuffer> WindowsManifestMerger::getMergedManifest() {
|
|||
#if LLVM_LIBXML2_ENABLED
|
||||
unsigned char *XmlBuff;
|
||||
int BufferSize = 0;
|
||||
if (CombinedDoc) {
|
||||
if (CombinedRoot) {
|
||||
std::unique_ptr<xmlDoc> OutputDoc(xmlNewDoc((const unsigned char *)"1.0"));
|
||||
xmlDocSetRootElement(OutputDoc.get(), xmlDocGetRootElement(CombinedDoc));
|
||||
xmlKeepBlanksDefault(0);
|
||||
xmlDocDumpFormatMemory(OutputDoc.get(), &XmlBuff, &BufferSize, 1);
|
||||
xmlDocSetRootElement(OutputDoc.get(), CombinedRoot);
|
||||
xmlDocDumpMemory(OutputDoc.get(), &XmlBuff, &BufferSize);
|
||||
}
|
||||
if (BufferSize == 0)
|
||||
return nullptr;
|
||||
return MemoryBuffer::getMemBuffer(
|
||||
StringRef(FROM_XML_CHAR(XmlBuff), (size_t)BufferSize));
|
||||
StringRef(reinterpret_cast<const char *>(XmlBuff), (size_t)BufferSize));
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<trustInfo>
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<!--Comment will be removed-->
|
||||
<requestedExecutionLevel level="3" admin="false"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity program="logDisplay"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<compatibility>
|
||||
<dependency>
|
||||
<assemblyIdentity program="compatibilityCheck2"/>
|
||||
</dependency>
|
||||
<application>
|
||||
<supportedOS Id="BarOS"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<trustInfo>
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="2" uiAccess="1"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</assembly>
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<trustInfo>
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
|
@ -12,12 +12,4 @@
|
|||
<assemblyIdentity program="displayDriver"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<compatibility>
|
||||
<dependency>
|
||||
<assemblyIdentity program="compatibilityCheck1"/>
|
||||
</dependency>
|
||||
<application>
|
||||
<supportedOS Id="FooOS"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
REQUIRES: libxml2
|
||||
UNSUPPORTED: windows
|
||||
|
||||
RUN: not llvm-mt /manifest %p/Inputs/test_manifest.manifest /manifest \
|
||||
RUN: %p/Inputs/conflicting.manifest /out:%t 2>&1 >/dev/null | FileCheck %s
|
||||
|
||||
CHECK: llvm-mt error: conflicting attributes for requestedExecutionLevel
|
|
@ -1,39 +0,0 @@
|
|||
REQUIRES: libxml2
|
||||
UNSUPPORTED: windows
|
||||
|
||||
RUN: llvm-mt /manifest %p/Inputs/test_manifest.manifest /manifest \
|
||||
RUN: %p/Inputs/additional.manifest /out:%t
|
||||
RUN: FileCheck %s -input-file=%t
|
||||
|
||||
CHECK: <?xml version="1.0"?>
|
||||
CHECK-NEXT: <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
CHECK-NEXT: <trustInfo>
|
||||
CHECK-NEXT: <security>
|
||||
CHECK-NEXT: <requestedPrivileges>
|
||||
CHECK-NEXT: <requestedExecutionLevel level="3" uiAccess="1" admin="false"/>
|
||||
CHECK-NEXT: </requestedPrivileges>
|
||||
CHECK-NEXT: </security>
|
||||
CHECK-NEXT: </trustInfo>
|
||||
CHECK-NEXT: <dependency>
|
||||
CHECK-NEXT: <dependentAssembly>
|
||||
CHECK-NEXT: <assemblyIdentity program="displayDriver"/>
|
||||
CHECK-NEXT: </dependentAssembly>
|
||||
CHECK-NEXT: </dependency>
|
||||
CHECK-NEXT: <compatibility>
|
||||
CHECK-NEXT: <dependency>
|
||||
CHECK-NEXT: <assemblyIdentity program="compatibilityCheck1"/>
|
||||
CHECK-NEXT: </dependency>
|
||||
CHECK-NEXT: <application>
|
||||
CHECK-NEXT: <supportedOS Id="FooOS"/>
|
||||
CHECK-NEXT: <supportedOS Id="BarOS"/>
|
||||
CHECK-NEXT: </application>
|
||||
CHECK-NEXT: <dependency>
|
||||
CHECK-NEXT: <assemblyIdentity program="compatibilityCheck2"/>
|
||||
CHECK-NEXT: </dependency>
|
||||
CHECK-NEXT: </compatibility>
|
||||
CHECK-NEXT: <dependency>
|
||||
CHECK-NEXT: <dependentAssembly>
|
||||
CHECK-NEXT: <assemblyIdentity program="logDisplay"/>
|
||||
CHECK-NEXT: </dependentAssembly>
|
||||
CHECK-NEXT: </dependency>
|
||||
CHECK-NEXT: </assembly>
|
|
@ -95,6 +95,7 @@ int main(int argc, const char **argv) {
|
|||
SpecificBumpPtrAllocator<char> ArgAllocator;
|
||||
ExitOnErr(errorCodeToError(sys::Process::GetArgumentVector(
|
||||
argv_buf, makeArrayRef(argv, argc), ArgAllocator)));
|
||||
|
||||
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
|
||||
|
||||
CvtResOptTable T;
|
||||
|
|
Loading…
Reference in New Issue