[lld] r198986 - [mach-o] enable mach-o and native yaml to be intermixed
Nick Kledzik
kledzik at apple.com
Fri Jan 10 17:07:44 PST 2014
Author: kledzik
Date: Fri Jan 10 19:07:43 2014
New Revision: 198986
URL: http://llvm.org/viewvc/llvm-project?rev=198986&view=rev
Log:
[mach-o] enable mach-o and native yaml to be intermixed
The main goal of this patch is to allow "mach-o encoded as yaml" and "native
encoded as yaml" documents to be intermixed. They are distinguished via
yaml tags at the start of the document. This will enable all mach-o test cases
to be written using yaml instead of checking in object files.
The Registry was extend to allow yaml tag handlers to be registered. The
mach-o Reader adds a yaml tag handler for the tag "!mach-o".
Additionally, this patch fixes some buffer ownership issues. When parsing
mach-o binaries, the mach-o atoms can have pointers back into the memory
mapped .o file. But with yaml encoded mach-o, name and content are ephemeral,
so a copyRefs parameter was added to cause the mach-o atoms to make their
own copy.
Added:
lld/trunk/test/darwin/native-and-mach-o.objtxt
Modified:
lld/trunk/include/lld/ReaderWriter/Reader.h
lld/trunk/include/lld/ReaderWriter/YamlContext.h
lld/trunk/lib/ReaderWriter/MachO/File.h
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
lld/trunk/lib/ReaderWriter/Reader.cpp
lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
lld/trunk/test/core/archive-basic.objtxt
lld/trunk/test/core/archive-chain.objtxt
lld/trunk/test/core/archive-tentdef-search.objtxt
lld/trunk/test/darwin/hello-world.objtxt
lld/trunk/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp
lld/trunk/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp
Modified: lld/trunk/include/lld/ReaderWriter/Reader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/Reader.h?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/Reader.h (original)
+++ lld/trunk/include/lld/ReaderWriter/Reader.h Fri Jan 10 19:07:43 2014
@@ -21,6 +21,12 @@
using llvm::sys::fs::file_magic;
+namespace llvm {
+ namespace yaml {
+ class IO;
+ }
+}
+
namespace lld {
class ELFLinkingContext;
class File;
@@ -54,6 +60,29 @@ public:
std::vector<std::unique_ptr<File>> &result) const = 0;
};
+
+/// \brief An abstract class for handling alternate yaml representations
+/// of object files.
+///
+/// The YAML syntax allows "tags" which are used to specify the type of
+/// the YAML node. In lld, top level YAML documents can be in many YAML
+/// representations (e.g mach-o encoded as yaml, etc). A tag is used to
+/// specify which representation is used in the following YAML document.
+/// To work, there must be a YamlIOTaggedDocumentHandler registered that
+/// handles each tag type.
+class YamlIOTaggedDocumentHandler {
+public:
+ virtual ~YamlIOTaggedDocumentHandler();
+
+ /// This method is called on each registered YamlIOTaggedDocumentHandler
+ /// until one returns true. If the subclass handles tag type !xyz, then
+ /// this method should call io.mapTag("!xzy") to see if that is the current
+ /// document type, and if so, process the rest of the document using
+ /// YAML I/O, then convert the result into an lld::File* and return it.
+ virtual bool handledDocTag(llvm::yaml::IO &io, const lld::File *&f) const = 0;
+};
+
+
/// A registry to hold the list of currently registered Readers and
/// tables which map Reference kind values to strings.
/// The linker does not directly invoke Readers. Instead, it registers
@@ -79,6 +108,10 @@ public:
bool referenceKindToString(Reference::KindNamespace ns, Reference::KindArch a,
Reference::KindValue value, StringRef &) const;
+ /// Walk the list of registered tag handlers and have the one that handles
+ /// the current document type process the yaml into an lld::File*.
+ bool handleTaggedDoc(llvm::yaml::IO &io, const lld::File *&file) const;
+
// These methods are called to dynamically add support for various file
// formats. The methods are also implemented in the appropriate lib*.a
// library, so that the code for handling a format is only linked in, if this
@@ -108,6 +141,7 @@ public:
void addKindTable(Reference::KindNamespace ns, Reference::KindArch arch,
const KindStrings array[]);
+
private:
struct KindEntry {
Reference::KindNamespace ns;
@@ -116,9 +150,11 @@ private:
};
void add(std::unique_ptr<Reader>);
+ void add(std::unique_ptr<YamlIOTaggedDocumentHandler>);
- std::vector<std::unique_ptr<Reader>> _readers;
- std::vector<KindEntry> _kindEntries;
+ std::vector<std::unique_ptr<Reader>> _readers;
+ std::vector<std::unique_ptr<YamlIOTaggedDocumentHandler>> _yamlHandlers;
+ std::vector<KindEntry> _kindEntries;
};
// Utilities for building a KindString table. For instance:
Modified: lld/trunk/include/lld/ReaderWriter/YamlContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/YamlContext.h?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/YamlContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/YamlContext.h Fri Jan 10 19:07:43 2014
@@ -39,6 +39,7 @@ struct YamlContext {
const Registry *_registry;
File *_file;
NormalizedFile *_normalizeMachOFile;
+ StringRef _path;
};
} // end namespace lld
Modified: lld/trunk/lib/ReaderWriter/MachO/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/File.h?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/File.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/File.h Fri Jan 10 19:07:43 2014
@@ -21,7 +21,16 @@ class MachOFile : public SimpleFile {
public:
MachOFile(StringRef path) : SimpleFile(path) {}
- void addDefinedAtom(StringRef name, ArrayRef<uint8_t> content) {
+ void addDefinedAtom(StringRef name, ArrayRef<uint8_t> content, bool cpyRefs) {
+ if (cpyRefs) {
+ // Make a copy of the atom's name and content that is owned by this file.
+ char *s = _allocator.Allocate<char>(name.size());
+ memcpy(s, name.data(), name.size());
+ name = StringRef(s, name.size());
+ uint8_t *bytes = _allocator.Allocate<uint8_t>(content.size());
+ memcpy(bytes, content.data(), content.size());
+ content = llvm::makeArrayRef(bytes, content.size());
+ }
MachODefinedAtom *atom =
new (_allocator) MachODefinedAtom(*this, name, content);
addAtom(*atom);
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h Fri Jan 10 19:07:43 2014
@@ -45,6 +45,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MachO.h"
#include "llvm/Support/YAMLTraits.h"
@@ -52,6 +53,7 @@
#ifndef LLD_READER_WRITER_MACHO_NORMALIZE_FILE_H
#define LLD_READER_WRITER_MACHO_NORMALIZE_FILE_H
+using llvm::BumpPtrAllocator;
using llvm::yaml::Hex64;
using llvm::yaml::Hex32;
using llvm::yaml::Hex8;
@@ -113,7 +115,7 @@ struct Section {
SectionAttr attributes;
uint32_t alignment;
Hex64 address;
- std::vector<uint8_t> content;
+ ArrayRef<uint8_t> content;
Relocations relocations;
IndirectSymbols indirectSymbols;
};
@@ -235,6 +237,9 @@ struct NormalizedFile {
// split-seg-info
// function-starts
// data-in-code
+
+ // For any allocations in this struct which need to be owned by this struct.
+ BumpPtrAllocator ownedAllocations;
};
@@ -260,15 +265,22 @@ writeYaml(const NormalizedFile &file, ra
/// Takes in-memory normalized dylib or object and parses it into lld::File
ErrorOr<std::unique_ptr<lld::File>>
-normalizedToAtoms(const NormalizedFile &normalizedFile, StringRef path);
+normalizedToAtoms(const NormalizedFile &normalizedFile, StringRef path,
+ bool copyRefs);
/// Takes atoms and generates a normalized macho-o view.
ErrorOr<std::unique_ptr<NormalizedFile>>
normalizedFromAtoms(const lld::File &atomFile, const MachOLinkingContext &ctxt);
-
} // namespace normalized
+
+/// Class for interfacing mach-o yaml files into generic yaml parsing
+class MachOYamlIOTaggedDocumentHandler : public YamlIOTaggedDocumentHandler {
+ bool handledDocTag(llvm::yaml::IO &io, const lld::File *&file) const;
+};
+
+
} // namespace mach_o
} // namespace lld
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp Fri Jan 10 19:07:43 2014
@@ -175,12 +175,12 @@ readBinary(std::unique_ptr<MemoryBuffer>
section.attributes = read32(swap, sect->flags) & SECTION_ATTRIBUTES;
section.alignment = read32(swap, sect->align);
section.address = read64(swap, sect->addr);
- const char *content = mb->getBufferStart()
+ const uint8_t *content = (uint8_t *)mb->getBufferStart()
+ read32(swap, sect->offset);
size_t contentSize = read64(swap, sect->size);
// Note: this assign() is copying the content bytes. Ideally,
// we can use a custom allocator for vector to avoid the copy.
- section.content.assign(content, content+contentSize);
+ section.content = llvm::makeArrayRef(content, contentSize);
appendRelocations(section.relocations, mb->getBuffer(),
swap, isBigEndianArch, read32(swap, sect->reloff),
read32(swap, sect->nreloc));
@@ -210,12 +210,12 @@ readBinary(std::unique_ptr<MemoryBuffer>
section.attributes = read32(swap, sect->flags) & SECTION_ATTRIBUTES;
section.alignment = read32(swap, sect->align);
section.address = read32(swap, sect->addr);
- const char *content = mb->getBufferStart()
+ const uint8_t *content = (uint8_t *)mb->getBufferStart()
+ read32(swap, sect->offset);
size_t contentSize = read32(swap, sect->size);
// Note: this assign() is copying the content bytes. Ideally,
// we can use a custom allocator for vector to avoid the copy.
- section.content.assign(content, content+contentSize);
+ section.content = llvm::makeArrayRef(content, contentSize);
appendRelocations(section.relocations, mb->getBuffer(),
swap, isBigEndianArch, read32(swap, sect->reloff),
read32(swap, sect->nreloc));
@@ -328,6 +328,8 @@ void Registry::addSupportMachOObjects(St
default:
llvm_unreachable("mach-o arch not supported");
}
+ add(std::unique_ptr<YamlIOTaggedDocumentHandler>(
+ new mach_o::MachOYamlIOTaggedDocumentHandler()));
}
} // namespace lld
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Fri Jan 10 19:07:43 2014
@@ -422,8 +422,8 @@ void Util::appendSection(SectionInfo *si
si->normalizedSectionIndex = file.sections.size()-1;
// Copy content from atoms to content buffer for section.
// FIXME: zerofill atoms/sections should not take up content space.
- normSect->content.resize(si->size);
- uint8_t *sectionContent = normSect->content.data();
+ uint8_t *sectionContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
+ normSect->content = llvm::makeArrayRef(sectionContent, si->size);
for (AtomInfo &ai : si->atomsAndOffsets) {
// Copy raw bytes.
uint8_t *atomContent = reinterpret_cast<uint8_t*>
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Fri Jan 10 19:07:43 2014
@@ -34,7 +34,7 @@ namespace lld {
namespace mach_o {
namespace normalized {
-static uint64_t nextSymbolAddress(const NormalizedFile &normalizedFile,
+static uint64_t nextSymbolAddress(const NormalizedFile &normalizedFile,
const Symbol &symbol) {
uint64_t symbolAddr = symbol.value;
uint8_t symbolSectionIndex = symbol.sect;
@@ -54,18 +54,18 @@ static uint64_t nextSymbolAddress(const
}
static ErrorOr<std::unique_ptr<lld::File>>
-normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path) {
+normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path,
+ bool copyRefs) {
std::unique_ptr<MachOFile> file(new MachOFile(path));
- for (const Symbol &sym : normalizedFile.globalSymbols) {
+ for (const Symbol &sym : normalizedFile.globalSymbols) {
// Mach-O symbol table does have size in it, so need to scan ahead
// to find symbol with next highest address.
const Section §ion = normalizedFile.sections[sym.sect - 1];
uint64_t offset = sym.value - section.address;
uint64_t size = nextSymbolAddress(normalizedFile, sym) - sym.value;
- ArrayRef<uint8_t> atomContent = llvm::makeArrayRef(§ion.content[offset],
- size);
- file->addDefinedAtom(sym.name, atomContent);
+ ArrayRef<uint8_t> atomContent = section.content.slice(offset, size);
+ file->addDefinedAtom(sym.name, atomContent, copyRefs);
}
assert(normalizedFile.localSymbols.empty() &&
@@ -77,10 +77,11 @@ normalizedObjectToAtoms(const Normalized
}
ErrorOr<std::unique_ptr<lld::File>>
-normalizedToAtoms(const NormalizedFile &normalizedFile, StringRef path) {
+normalizedToAtoms(const NormalizedFile &normalizedFile, StringRef path,
+ bool copyRefs) {
switch (normalizedFile.fileType) {
case MH_OBJECT:
- return normalizedObjectToAtoms(normalizedFile, path);
+ return normalizedObjectToAtoms(normalizedFile, path, copyRefs);
default:
llvm_unreachable("unhandled MachO file type!");
}
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp Fri Jan 10 19:07:43 2014
@@ -107,7 +107,7 @@ struct SequenceTraits< ContentBytes > {
static const bool flow = true;
};
-// The indirect symbols for a section is represented as a flow sequence
+// The indirect symbols for a section is represented as a flow sequence
// of numbers (symbol table indexes).
template<>
struct SequenceTraits< IndirectSymbols > {
@@ -279,30 +279,36 @@ struct MappingTraits<Section> {
io.mapOptional("attributes", sect.attributes);
io.mapOptional("alignment", sect.alignment, 0U);
io.mapRequired("address", sect.address);
- MappingNormalization<NormalizedContent, std::vector<uint8_t>> content(
+ MappingNormalization<NormalizedContent, ArrayRef<uint8_t>> content(
io, sect.content);
- io.mapOptional("content", content->normalizedContent);
+ io.mapOptional("content", content->_normalizedContent);
io.mapOptional("relocations", sect.relocations);
io.mapOptional("indirect-syms", sect.indirectSymbols);
}
- // FIXME: It would be good if we could remove this, so we don't need to copy
- // the content data.
struct NormalizedContent {
- NormalizedContent(IO &) {}
- NormalizedContent(IO &, std::vector<uint8_t> content) {
+ NormalizedContent(IO &io) : _io(io) {}
+ NormalizedContent(IO &io, ArrayRef<uint8_t> content) : _io(io) {
+ // When writing yaml, copy content byte array to Hex8 vector.
for (auto &c : content) {
- normalizedContent.push_back(c);
+ _normalizedContent.push_back(c);
}
}
- std::vector<uint8_t> denormalize(IO &) {
- std::vector<uint8_t> content;
- for (auto &c : normalizedContent) {
- content.push_back(c);
- }
- return content;
+ ArrayRef<uint8_t> denormalize(IO &io) {
+ // When reading yaml, allocate byte array owned by NormalizedFile and
+ // copy Hex8 vector to byte array.
+ YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
+ assert(info != nullptr);
+ NormalizedFile *file = info->_normalizeMachOFile;
+ assert(file != nullptr);
+ size_t size = _normalizedContent.size();
+ uint8_t *bytes = file->ownedAllocations.Allocate<uint8_t>(size);
+ std::copy(_normalizedContent.begin(), _normalizedContent.end(), bytes);
+ return makeArrayRef(bytes, size);
}
- ContentBytes normalizedContent;
+
+ IO &_io;
+ ContentBytes _normalizedContent;
};
};
@@ -612,10 +618,37 @@ struct MappingTraits<NormalizedFile> {
namespace lld {
namespace mach_o {
+
+/// Handles !mach-o tagged yaml documents.
+bool MachOYamlIOTaggedDocumentHandler::handledDocTag(llvm::yaml::IO &io,
+ const lld::File *&file) const {
+ if (!io.mapTag("!mach-o"))
+ return false;
+ // Step 1: parse yaml into normalized mach-o struct.
+ NormalizedFile nf;
+ YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
+ assert(info != nullptr);
+ assert(info->_normalizeMachOFile == nullptr);
+ info->_normalizeMachOFile = &nf;
+ MappingTraits<NormalizedFile>::mapping(io, nf);
+ // Step 2: parse normalized mach-o struct into atoms.
+ ErrorOr<std::unique_ptr<lld::File>> foe = normalizedToAtoms(nf, info->_path,
+ true);
+ if (foe) {
+ // Transfer ownership to "out" File parameter.
+ std::unique_ptr<lld::File> f = std::move(foe.get());
+ file = f.release();
+ return true;
+ }
+ return false;
+}
+
+
+
namespace normalized {
/// Parses a yaml encoded mach-o file to produce an in-memory normalized view.
-ErrorOr<std::unique_ptr<NormalizedFile>>
+ErrorOr<std::unique_ptr<NormalizedFile>>
readYaml(std::unique_ptr<MemoryBuffer> &mb) {
// Make empty NormalizedFile.
std::unique_ptr<NormalizedFile> f(new NormalizedFile());
@@ -638,7 +671,7 @@ readYaml(std::unique_ptr<MemoryBuffer> &
/// Writes a yaml encoded mach-o files from an in-memory normalized view.
-error_code
+error_code
writeYaml(const NormalizedFile &file, raw_ostream &out) {
// YAML I/O is not const aware, so need to cast away ;-(
NormalizedFile *f = const_cast<NormalizedFile*>(&file);
Modified: lld/trunk/lib/ReaderWriter/Reader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Reader.cpp?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Reader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/Reader.cpp Fri Jan 10 19:07:43 2014
@@ -21,10 +21,18 @@ namespace lld {
Reader::~Reader() {
}
+
+YamlIOTaggedDocumentHandler::~YamlIOTaggedDocumentHandler() { }
+
+
void Registry::add(std::unique_ptr<Reader> reader) {
_readers.push_back(std::move(reader));
}
+void Registry::add(std::unique_ptr<YamlIOTaggedDocumentHandler> handler) {
+ _yamlHandlers.push_back(std::move(handler));
+}
+
error_code
Registry::parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const {
@@ -56,6 +64,16 @@ Registry::Registry() {
kindStrings);
}
+bool Registry::handleTaggedDoc(llvm::yaml::IO &io,
+ const lld::File *&file) const {
+ for (const std::unique_ptr<YamlIOTaggedDocumentHandler> &h : _yamlHandlers) {
+ if (h->handledDocTag(io, file))
+ return true;
+ }
+ return false;
+}
+
+
void Registry::addKindTable(Reference::KindNamespace ns,
Reference::KindArch arch,
const KindStrings array[]) {
Modified: lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp Fri Jan 10 19:07:43 2014
@@ -664,24 +664,15 @@ template <> struct MappingTraits<const l
};
static void mapping(IO &io, const lld::File *&file) {
- // We only support writing atom based YAML
- FileKinds kind = fileKindObjectAtoms;
- // If reading, peek ahead to see what kind of file this is.
- io.mapOptional("kind", kind, fileKindObjectAtoms);
- switch (kind) {
- case fileKindObjectAtoms:
+ YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
+ assert(info != nullptr);
+ // Let any register tag handler process this.
+ if (info->_registry && info->_registry->handleTaggedDoc(io, file))
+ return;
+ // If no registered handler claims this tag and there is no tag,
+ // grandfather in as "!native".
+ if (io.mapTag("!native", true) || io.mapTag("tag:yaml.org,2002:map"))
mappingAtoms(io, file);
- break;
- case fileKindArchive:
- mappingArchive(io, file);
- break;
- case fileKindObjectELF:
- case fileKindObjectMachO:
- // Eventually we will have an external function to call, similar
- // to mappingAtoms() and mappingArchive() but implememented
- // with coresponding file format code.
- llvm_unreachable("section based YAML not supported yet");
- }
}
static void mappingAtoms(IO &io, const lld::File *&file) {
@@ -1236,6 +1227,31 @@ private:
namespace {
+/// Handles !native tagged yaml documents.
+class NativeYamlIOTaggedDocumentHandler : public YamlIOTaggedDocumentHandler {
+ bool handledDocTag(llvm::yaml::IO &io, const lld::File *&file) const {
+ if (io.mapTag("!native")) {
+ MappingTraits<const lld::File *>::mappingAtoms(io, file);
+ return true;
+ }
+ return false;
+ }
+};
+
+
+/// Handles !archive tagged yaml documents.
+class ArchiveYamlIOTaggedDocumentHandler : public YamlIOTaggedDocumentHandler {
+ bool handledDocTag(llvm::yaml::IO &io, const lld::File *&file) const {
+ if (io.mapTag("!archive")) {
+ MappingTraits<const lld::File *>::mappingArchive(io, file);
+ return true;
+ }
+ return false;
+ }
+};
+
+
+
class YAMLReader : public Reader {
public:
YAMLReader(const Registry ®istry) : _registry(registry) {}
@@ -1257,6 +1273,7 @@ public:
// Create YAML Input Reader.
YamlContext yamlContext;
yamlContext._registry = &_registry;
+ yamlContext._path = mb->getBufferIdentifier();
llvm::yaml::Input yin(mb->getBuffer(), &yamlContext);
// Fill vector with File objects created by parsing yaml.
@@ -1283,6 +1300,10 @@ private:
void Registry::addSupportYamlFiles() {
add(std::unique_ptr<Reader>(new YAMLReader(*this)));
+ add(std::unique_ptr<YamlIOTaggedDocumentHandler>(
+ new NativeYamlIOTaggedDocumentHandler()));
+ add(std::unique_ptr<YamlIOTaggedDocumentHandler>(
+ new ArchiveYamlIOTaggedDocumentHandler()));
}
std::unique_ptr<Writer> createWriterYAML(const LinkingContext &context) {
Modified: lld/trunk/test/core/archive-basic.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/core/archive-basic.objtxt?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/test/core/archive-basic.objtxt (original)
+++ lld/trunk/test/core/archive-basic.objtxt Fri Jan 10 19:07:43 2014
@@ -5,7 +5,7 @@
# all atoms in select archive members.
#
----
+--- !native
defined-atoms:
- name: foo
type: code
@@ -13,11 +13,10 @@ defined-atoms:
undefined-atoms:
- name: bar
----
-kind: archive
+--- !archive
members:
- name: bar.o
- content:
+ content: !native
defined-atoms:
- name: bar
scope: global
@@ -27,7 +26,7 @@ members:
type: code
- name: baz.o
- content:
+ content: !native
defined-atoms:
- name: baz
scope: global
Modified: lld/trunk/test/core/archive-chain.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/core/archive-chain.objtxt?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/test/core/archive-chain.objtxt (original)
+++ lld/trunk/test/core/archive-chain.objtxt Fri Jan 10 19:07:43 2014
@@ -4,7 +4,7 @@
# Tests that an undefine in one archive can force a load from another archive.
#
----
+--- !native
defined-atoms:
- name: foo
type: code
@@ -12,11 +12,10 @@ defined-atoms:
undefined-atoms:
- name: bar1
----
-kind: archive
+--- !archive
members:
- name: bar1.o
- content:
+ content: !native
defined-atoms:
- name: bar1
scope: global
@@ -29,7 +28,7 @@ members:
- name: baz1
- name: bar2.o
- content:
+ content: !native
defined-atoms:
- name: bar2
scope: global
@@ -38,11 +37,10 @@ members:
- name: bar2b
type: code
----
-kind: archive
+--- !archive
members:
- name: baz1.o
- content:
+ content: !native
defined-atoms:
- name: baz1
scope: global
@@ -52,7 +50,7 @@ members:
type: code
- name: baz2.o
- content:
+ content: !native
defined-atoms:
- name: baz2
scope: global
Modified: lld/trunk/test/core/archive-tentdef-search.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/core/archive-tentdef-search.objtxt?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/test/core/archive-tentdef-search.objtxt (original)
+++ lld/trunk/test/core/archive-tentdef-search.objtxt Fri Jan 10 19:07:43 2014
@@ -7,7 +7,7 @@
# does not search.
#
----
+--- !native
defined-atoms:
- name: foo
type: code
@@ -17,11 +17,10 @@ defined-atoms:
type: zero-fill
merge: as-tentative
----
-kind: archive
+--- !archive
members:
- name: bar.o
- content:
+ content: !native
defined-atoms:
- name: bar
scope: global
Modified: lld/trunk/test/darwin/hello-world.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/darwin/hello-world.objtxt?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/test/darwin/hello-world.objtxt (original)
+++ lld/trunk/test/darwin/hello-world.objtxt Fri Jan 10 19:07:43 2014
@@ -4,7 +4,7 @@
# Test that hello-world can be linked into a mach-o executable
#
---- !atoms
+--- !native
defined-atoms:
- name: _main
type: code
Added: lld/trunk/test/darwin/native-and-mach-o.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/darwin/native-and-mach-o.objtxt?rev=198986&view=auto
==============================================================================
--- lld/trunk/test/darwin/native-and-mach-o.objtxt (added)
+++ lld/trunk/test/darwin/native-and-mach-o.objtxt Fri Jan 10 19:07:43 2014
@@ -0,0 +1,44 @@
+# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t && \
+# RUN: llvm-nm %t | FileCheck %s
+#
+# Test a mix of atoms and mach-o both encoded in yaml
+#
+
+--- !native
+defined-atoms:
+ - name: _main
+ type: code
+ scope: global
+ content: [ 55, 48, 89, E5, 30, C0, E8, 00,
+ 00, 00, 00, 31, C0, 5D, C3 ]
+ references:
+ - offset: 7
+ kind: X86_64_RELOC_BRANCH
+ target: _foo
+
+undefined-atoms:
+ - name: _foo
+
+
+--- !mach-o
+arch: x86_64
+file-type: MH_OBJECT
+sections:
+ - segment: __TEXT
+ section: __text
+ type: S_REGULAR
+ attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
+ address: 0
+ content: [ 0xC3 ]
+global-symbols:
+ - name: _foo
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ desc: [ ]
+ value: 0
+
+...
+
+# CHECK: {{[0-9a-f]+}} T _foo
+# CHECK: {{[0-9a-f]+}} T _main
Modified: lld/trunk/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp (original)
+++ lld/trunk/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp Fri Jan 10 19:07:43 2014
@@ -139,7 +139,7 @@ TEST(BinaryWriterTest, obj_relocs_x86_64
0x05, 0xfc, 0xff, 0xff, 0xff, 0x78, 0x56, 0x34,
0x12, 0x48, 0x8b, 0x3d, 0x00, 0x00, 0x00, 0x00 };
- text.content.assign(textBytes, textBytes+sizeof(textBytes));
+ text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
text.relocations.push_back(makeReloc(0x01, false, true, X86_64_RELOC_BRANCH, 1));
text.relocations.push_back(makeReloc(0x08, false, true, X86_64_RELOC_GOT_LOAD, 1));
text.relocations.push_back(makeReloc(0x0E, false, true, X86_64_RELOC_GOT, 1));
@@ -252,7 +252,7 @@ TEST(BinaryWriterTest, obj_relocs_x86) {
0x00, 0x00, 0x8b, 0xb0, 0xfb, 0xff, 0xff, 0xff,
0x8b, 0x80, 0x11, 0x00, 0x00, 0x00 };
- text.content.assign(textBytes, textBytes+sizeof(textBytes));
+ text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
text.relocations.push_back(makeReloc(0x01, true, true, GENERIC_RELOC_VANILLA, 0));
text.relocations.push_back(makeReloc(0x06, false, true, GENERIC_RELOC_VANILLA, 0));
text.relocations.push_back(makeScatReloc(0x0c, GENERIC_RELOC_LOCAL_SECTDIFF, 0));
@@ -361,7 +361,7 @@ TEST(BinaryWriterTest, obj_relocs_armv7)
0xc0, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0xbf };
- text.content.assign(textBytes, textBytes+sizeof(textBytes));
+ text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
text.relocations.push_back(makeReloc(0x00, true, true,
ARM_THUMB_RELOC_BR22, 2));
text.relocations.push_back(makeScatReloc(0x04,
@@ -492,7 +492,7 @@ TEST(BinaryWriterTest, obj_relocs_ppc) {
0x80, 0x42, 0x00, 0x28, 0x80, 0x63, 0x00, 0x28,
0x60, 0x00, 0x00, 0x00 };
- text.content.assign(textBytes, textBytes+sizeof(textBytes));
+ text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
text.relocations.push_back(makeReloc(0x00, true, true,
PPC_RELOC_BR24, 2));
text.relocations.push_back(makeReloc(0x04, true, true,
Modified: lld/trunk/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp?rev=198986&r1=198985&r2=198986&view=diff
==============================================================================
--- lld/trunk/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp (original)
+++ lld/trunk/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp Fri Jan 10 19:07:43 2014
@@ -23,7 +23,8 @@ using namespace llvm::MachO;
TEST(ToAtomsTest, empty_obj_x86_64) {
NormalizedFile f;
f.arch = lld::MachOLinkingContext::arch_x86_64;
- ErrorOr<std::unique_ptr<const lld::File>> atom_f = normalizedToAtoms(f, "");
+ ErrorOr<std::unique_ptr<const lld::File>> atom_f = normalizedToAtoms(f, "",
+ false);
EXPECT_FALSE(!atom_f);
EXPECT_EQ(0U, (*atom_f)->defined().size());
}
@@ -34,8 +35,7 @@ TEST(ToAtomsTest, basic_obj_x86_64) {
Section textSection;
static const uint8_t contentBytes[] = { 0x90, 0xC3, 0xC3 };
const unsigned contentSize = sizeof(contentBytes) / sizeof(contentBytes[0]);
- textSection.content.insert(textSection.content.begin(), contentBytes,
- &contentBytes[contentSize]);
+ textSection.content = llvm::makeArrayRef(contentBytes, contentSize);
f.sections.push_back(textSection);
Symbol fooSymbol;
fooSymbol.name = "_foo";
@@ -50,7 +50,8 @@ TEST(ToAtomsTest, basic_obj_x86_64) {
barSymbol.value = 2;
f.globalSymbols.push_back(barSymbol);
- ErrorOr<std::unique_ptr<const lld::File>> atom_f = normalizedToAtoms(f, "");
+ ErrorOr<std::unique_ptr<const lld::File>> atom_f = normalizedToAtoms(f, "",
+ false);
EXPECT_FALSE(!atom_f);
const lld::File &file = **atom_f;
EXPECT_EQ(2U, file.defined().size());
More information about the llvm-commits
mailing list