[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.  

llvm-svn: 198986
This commit is contained in:
Nick Kledzik 2014-01-11 01:07:43 +00:00
parent 976d94b834
commit 6edd722a2c
17 changed files with 255 additions and 81 deletions

View File

@ -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:

View File

@ -39,6 +39,7 @@ struct YamlContext {
const Registry *_registry;
File *_file;
NormalizedFile *_normalizeMachOFile;
StringRef _path;
};
} // end namespace lld

View File

@ -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);

View File

@ -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, raw_ostream &out);
/// 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

View File

@ -175,12 +175,12 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb) {
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> &mb) {
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(StringRef archName) {
default:
llvm_unreachable("mach-o arch not supported");
}
add(std::unique_ptr<YamlIOTaggedDocumentHandler>(
new mach_o::MachOYamlIOTaggedDocumentHandler()));
}
} // namespace lld

View File

@ -422,8 +422,8 @@ void Util::appendSection(SectionInfo *si, NormalizedFile &file) {
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*>

View File

@ -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 NormalizedFile &normalizedFile,
}
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 &section = 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(&section.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 NormalizedFile &normalizedFile, StringRef path) {
}
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!");
}

View File

@ -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> &mb) {
/// 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);

View File

@ -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[]) {

View File

@ -664,24 +664,15 @@ template <> struct MappingTraits<const lld::File *> {
};
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 &registry) : _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) {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -4,7 +4,7 @@
# Test that hello-world can be linked into a mach-o executable
#
--- !atoms
--- !native
defined-atoms:
- name: _main
type: code

View File

@ -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

View File

@ -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,

View File

@ -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());