forked from OSchip/llvm-project
COFF: Switch to new archive writer interface (D21721).
Differential Revision: http://reviews.llvm.org/D21722 llvm-svn: 274184
This commit is contained in:
parent
8ec68fad33
commit
eadba86c3e
|
@ -621,15 +621,16 @@ static std::unique_ptr<MemoryBuffer> createEmptyImportLibrary() {
|
|||
return MemoryBuffer::getMemBufferCopy((*BufOrErr)->getBuffer());
|
||||
}
|
||||
|
||||
static std::vector<NewArchiveIterator>
|
||||
static std::vector<NewArchiveMember>
|
||||
readMembers(const object::Archive &Archive) {
|
||||
std::vector<NewArchiveIterator> V;
|
||||
std::vector<NewArchiveMember> V;
|
||||
for (const auto &ChildOrErr : Archive.children()) {
|
||||
error(ChildOrErr, "Archive::Child::getName failed");
|
||||
const object::Archive::Child C(*ChildOrErr);
|
||||
ErrorOr<StringRef> NameOrErr = C.getName();
|
||||
error(NameOrErr, "Archive::Child::getName failed");
|
||||
V.emplace_back(C, *NameOrErr);
|
||||
NewArchiveMember M =
|
||||
check(NewArchiveMember::getOldMember(C, /*Deterministic=*/true),
|
||||
"NewArchiveMember::getOldMember failed");
|
||||
V.emplace_back(std::move(M));
|
||||
}
|
||||
return V;
|
||||
}
|
||||
|
@ -638,27 +639,16 @@ readMembers(const object::Archive &Archive) {
|
|||
// PE/COFF spec 7. Import Library Format.
|
||||
class ShortImportCreator {
|
||||
public:
|
||||
ShortImportCreator(object::Archive *A, StringRef S) : Parent(A), DLLName(S) {}
|
||||
ShortImportCreator(StringRef S) : DLLName(S) {}
|
||||
|
||||
NewArchiveIterator create(StringRef Sym, uint16_t Ordinal,
|
||||
ImportNameType NameType, bool isData) {
|
||||
NewArchiveMember create(StringRef Sym, uint16_t Ordinal,
|
||||
ImportNameType NameType, bool isData) {
|
||||
size_t ImpSize = DLLName.size() + Sym.size() + 2; // +2 for NULs
|
||||
size_t Size = sizeof(object::ArchiveMemberHeader) +
|
||||
sizeof(coff_import_header) + ImpSize;
|
||||
size_t Size = sizeof(coff_import_header) + ImpSize;
|
||||
char *Buf = Alloc.Allocate<char>(Size);
|
||||
memset(Buf, 0, Size);
|
||||
char *P = Buf;
|
||||
|
||||
// Write archive member header
|
||||
auto *Hdr = reinterpret_cast<object::ArchiveMemberHeader *>(P);
|
||||
P += sizeof(*Hdr);
|
||||
sprintf(Hdr->Name, "%-12s", "dummy");
|
||||
sprintf(Hdr->LastModified, "%-12d", 0);
|
||||
sprintf(Hdr->UID, "%-6d", 0);
|
||||
sprintf(Hdr->GID, "%-6d", 0);
|
||||
sprintf(Hdr->AccessMode, "%-8d", 0644);
|
||||
sprintf(Hdr->Size, "%-10d", int(sizeof(coff_import_header) + ImpSize));
|
||||
|
||||
// Write short import library.
|
||||
auto *Imp = reinterpret_cast<coff_import_header *>(P);
|
||||
P += sizeof(*Imp);
|
||||
|
@ -675,15 +665,11 @@ public:
|
|||
P += Sym.size() + 1;
|
||||
memcpy(P, DLLName.data(), DLLName.size());
|
||||
|
||||
std::error_code EC;
|
||||
object::Archive::Child C(Parent, Buf, &EC);
|
||||
assert(!EC && "We created an invalid buffer");
|
||||
return NewArchiveIterator(C, DLLName);
|
||||
return NewArchiveMember(MemoryBufferRef(StringRef(Buf, Size), DLLName));
|
||||
}
|
||||
|
||||
private:
|
||||
BumpPtrAllocator Alloc;
|
||||
object::Archive *Parent;
|
||||
StringRef DLLName;
|
||||
};
|
||||
|
||||
|
@ -708,11 +694,11 @@ void writeImportLibrary() {
|
|||
std::unique_ptr<MemoryBuffer> Buf = createEmptyImportLibrary();
|
||||
llvm::Error Err;
|
||||
object::Archive Archive(Buf->getMemBufferRef(), Err);
|
||||
error(errorToErrorCode(std::move(Err)), "Error reading an empty import file");
|
||||
std::vector<NewArchiveIterator> Members = readMembers(Archive);
|
||||
error(std::move(Err), "Error reading an empty import file");
|
||||
std::vector<NewArchiveMember> Members = readMembers(Archive);
|
||||
|
||||
std::string DLLName = llvm::sys::path::filename(Config->OutputFile);
|
||||
ShortImportCreator ShortImport(&Archive, DLLName);
|
||||
ShortImportCreator ShortImport(DLLName);
|
||||
for (Export &E : Config->Exports) {
|
||||
if (E.Private)
|
||||
continue;
|
||||
|
|
|
@ -26,5 +26,13 @@ void error(std::error_code EC, const Twine &Prefix) {
|
|||
error(Prefix + ": " + EC.message());
|
||||
}
|
||||
|
||||
void error(llvm::Error E, const Twine &Prefix) {
|
||||
if (!E)
|
||||
return;
|
||||
handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
|
||||
error(Prefix + ": " + EIB.message());
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace coff
|
||||
} // namespace lld
|
||||
|
|
|
@ -11,17 +11,26 @@
|
|||
#define LLD_COFF_ERROR_H
|
||||
|
||||
#include "lld/Core/LLVM.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace lld {
|
||||
namespace coff {
|
||||
|
||||
LLVM_ATTRIBUTE_NORETURN void error(const Twine &Msg);
|
||||
void error(std::error_code EC, const Twine &Prefix);
|
||||
void error(llvm::Error E, const Twine &Prefix);
|
||||
|
||||
template <typename T> void error(const ErrorOr<T> &V, const Twine &Prefix) {
|
||||
error(V.getError(), Prefix);
|
||||
}
|
||||
|
||||
template <class T> T check(Expected<T> E, const Twine &Prefix) {
|
||||
if (!E)
|
||||
return std::move(*E);
|
||||
error(E.takeError(), Prefix);
|
||||
return T();
|
||||
}
|
||||
|
||||
} // namespace coff
|
||||
} // namespace lld
|
||||
|
||||
|
|
Loading…
Reference in New Issue