forked from OSchip/llvm-project
[MachO] Begin to add some MachO specific File/Atoms, and add the start of
normalizedToAtoms. llvm-svn: 198459
This commit is contained in:
parent
0724bf6767
commit
ceb16dedef
|
|
@ -0,0 +1,41 @@
|
|||
//===- lib/ReaderWriter/MachO/Atoms.h -------------------------------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLD_READER_WRITER_MACHO_ATOMS_H
|
||||
#define LLD_READER_WRITER_MACHO_ATOMS_H
|
||||
|
||||
#include "lld/ReaderWriter/Simple.h"
|
||||
|
||||
namespace lld {
|
||||
namespace mach_o {
|
||||
class MachODefinedAtom : public SimpleDefinedAtom {
|
||||
public:
|
||||
// FIXME: This constructor should also take the ContentType.
|
||||
MachODefinedAtom(const File &f, const StringRef name,
|
||||
const ArrayRef<uint8_t> content)
|
||||
: SimpleDefinedAtom(f), _name(name), _content(content) {}
|
||||
|
||||
virtual uint64_t size() const { return rawContent().size(); }
|
||||
|
||||
virtual ContentType contentType() const { return DefinedAtom::typeCode; }
|
||||
|
||||
virtual StringRef name() const { return _name; }
|
||||
|
||||
virtual Scope scope() const { return scopeGlobal; }
|
||||
|
||||
virtual ArrayRef<uint8_t> rawContent() const { return _content; }
|
||||
|
||||
private:
|
||||
const StringRef _name;
|
||||
const ArrayRef<uint8_t> _content;
|
||||
};
|
||||
} // mach_o
|
||||
} // lld
|
||||
|
||||
#endif
|
||||
|
|
@ -3,6 +3,7 @@ add_lld_library(lldMachO
|
|||
MachONormalizedFileBinaryReader.cpp
|
||||
MachONormalizedFileBinaryWriter.cpp
|
||||
MachONormalizedFileFromAtoms.cpp
|
||||
MachONormalizedFileToAtoms.cpp
|
||||
MachONormalizedFileYAML.cpp
|
||||
ReferenceKinds.cpp
|
||||
WriterMachO.cpp
|
||||
|
|
@ -12,3 +13,5 @@ target_link_libraries(lldMachO
|
|||
lldReaderWriter
|
||||
lldPasses
|
||||
)
|
||||
|
||||
include_directories(.)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
//===- lib/ReaderWriter/MachO/File.h --------------------------------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLD_READER_WRITER_MACHO_FILE_H
|
||||
#define LLD_READER_WRITER_MACHO_FILE_H
|
||||
|
||||
#include "Atoms.h"
|
||||
|
||||
#include "lld/ReaderWriter/Simple.h"
|
||||
|
||||
namespace lld {
|
||||
namespace mach_o {
|
||||
|
||||
class MachOFile : public SimpleFile {
|
||||
public:
|
||||
MachOFile(StringRef path) : SimpleFile(path) {}
|
||||
|
||||
void addDefinedAtom(StringRef name, ArrayRef<uint8_t> content) {
|
||||
MachODefinedAtom *atom =
|
||||
new (_allocator) MachODefinedAtom(*this, name, content);
|
||||
addAtom(*atom);
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::BumpPtrAllocator _allocator;
|
||||
};
|
||||
|
||||
} // end namespace mach_o
|
||||
} // end namespace lld
|
||||
|
||||
#endif
|
||||
|
|
@ -113,7 +113,7 @@ struct Section {
|
|||
SectionAttr attributes;
|
||||
uint32_t alignment;
|
||||
Hex64 address;
|
||||
ContentBytes content;
|
||||
std::vector<uint8_t> content;
|
||||
Relocations relocations;
|
||||
IndirectSymbols indirectSymbols;
|
||||
};
|
||||
|
|
@ -273,7 +273,3 @@ normalizedFromAtoms(const lld::File &atomFile, const MachOLinkingContext &ctxt);
|
|||
} // namespace lld
|
||||
|
||||
#endif // LLD_READER_WRITER_MACHO_NORMALIZE_FILE_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ void Util::appendSection(SectionInfo *si, NormalizedFile &file) {
|
|||
// Copy content from atoms to content buffer for section.
|
||||
// FIXME: zerofill atoms/sections should not take up content space.
|
||||
normSect->content.resize(si->size);
|
||||
Hex8 *sectionContent = normSect->content.data();
|
||||
uint8_t *sectionContent = normSect->content.data();
|
||||
for (AtomInfo &ai : si->atomsAndOffsets) {
|
||||
// Copy raw bytes.
|
||||
uint8_t *atomContent = reinterpret_cast<uint8_t*>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
//===- lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp --------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
///
|
||||
/// \file Converts from in-memory normalized mach-o to in-memory Atoms.
|
||||
///
|
||||
/// +------------+
|
||||
/// | normalized |
|
||||
/// +------------+
|
||||
/// |
|
||||
/// |
|
||||
/// v
|
||||
/// +-------+
|
||||
/// | Atoms |
|
||||
/// +-------+
|
||||
|
||||
#include "MachONormalizedFile.h"
|
||||
#include "File.h"
|
||||
#include "Atoms.h"
|
||||
|
||||
#include "lld/Core/LLVM.h"
|
||||
|
||||
#include "llvm/Support/MachO.h"
|
||||
|
||||
using namespace llvm::MachO;
|
||||
|
||||
namespace lld {
|
||||
namespace mach_o {
|
||||
namespace normalized {
|
||||
|
||||
static ErrorOr<std::unique_ptr<lld::File>>
|
||||
normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path) {
|
||||
std::unique_ptr<MachOFile> file(new MachOFile(path));
|
||||
|
||||
for (auto &sym : normalizedFile.globalSymbols) {
|
||||
file->addDefinedAtom(sym.name,
|
||||
normalizedFile.sections[sym.sect - 1].content);
|
||||
}
|
||||
|
||||
assert(normalizedFile.localSymbols.empty() &&
|
||||
"local symbols not supported yet!");
|
||||
assert(normalizedFile.undefinedSymbols.empty() &&
|
||||
"undefined symbols not supported yet!");
|
||||
|
||||
return std::unique_ptr<File>(std::move(file));
|
||||
}
|
||||
|
||||
ErrorOr<std::unique_ptr<lld::File>>
|
||||
normalizedToAtoms(const NormalizedFile &normalizedFile, StringRef path) {
|
||||
switch (normalizedFile.fileType) {
|
||||
case MH_OBJECT:
|
||||
return normalizedObjectToAtoms(normalizedFile, path);
|
||||
default:
|
||||
llvm_unreachable("unhandled MachO file type!");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace normalized
|
||||
} // namespace mach_o
|
||||
} // namespace lld
|
||||
|
|
@ -269,6 +269,7 @@ struct ScalarBitSetTraits<SymbolDesc> {
|
|||
|
||||
template <>
|
||||
struct MappingTraits<Section> {
|
||||
struct NormalizedContentBytes;
|
||||
static void mapping(IO &io, Section §) {
|
||||
io.mapRequired("segment", sect.segmentName);
|
||||
io.mapRequired("section", sect.sectionName);
|
||||
|
|
@ -276,10 +277,31 @@ struct MappingTraits<Section> {
|
|||
io.mapOptional("attributes", sect.attributes);
|
||||
io.mapOptional("alignment", sect.alignment, 0U);
|
||||
io.mapRequired("address", sect.address);
|
||||
io.mapOptional("content", sect.content);
|
||||
MappingNormalization<NormalizedContent, std::vector<uint8_t>> content(
|
||||
io, sect.content);
|
||||
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) {
|
||||
for (auto &c : content) {
|
||||
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;
|
||||
}
|
||||
ContentBytes normalizedContent;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
add_lld_unittest(lldMachOTests
|
||||
MachONormalizedFileBinaryReaderTests.cpp
|
||||
MachONormalizedFileBinaryWriterTests.cpp
|
||||
MachONormalizedFileToAtomsTests.cpp
|
||||
MachONormalizedFileYAMLTests.cpp
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
//===- lld/unittest/MachOTests/MachONormalizedFileToAtomsTests.cpp --------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <llvm/Support/MachO.h>
|
||||
#include "../../lib/ReaderWriter/MachO/MachONormalizedFile.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
|
||||
using llvm::ErrorOr;
|
||||
|
||||
using namespace lld::mach_o::normalized;
|
||||
using namespace llvm::MachO;
|
||||
|
||||
unsigned countDefinedAtoms(const lld::File &file) {
|
||||
unsigned count = 0;
|
||||
for (const auto &d : file.defined()) {
|
||||
(void)d;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
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, "");
|
||||
EXPECT_FALSE(!atom_f);
|
||||
EXPECT_EQ(0U, countDefinedAtoms(**atom_f));
|
||||
}
|
||||
|
||||
TEST(ToAtomsTest, basic_obj_x86_64) {
|
||||
NormalizedFile f;
|
||||
f.arch = lld::MachOLinkingContext::arch_x86_64;
|
||||
Section textSection;
|
||||
static const uint8_t contentBytes[] = { 0x55, 0x48, 0x89, 0xE5,
|
||||
0x31, 0xC0, 0x5D, 0xC3 };
|
||||
const unsigned contentSize = sizeof(contentBytes) / sizeof(contentBytes[0]);
|
||||
textSection.content.insert(textSection.content.begin(), contentBytes,
|
||||
&contentBytes[contentSize]);
|
||||
f.sections.push_back(textSection);
|
||||
Symbol mainSymbol;
|
||||
mainSymbol.name = "_main";
|
||||
mainSymbol.type = N_SECT;
|
||||
mainSymbol.sect = 1;
|
||||
f.globalSymbols.push_back(mainSymbol);
|
||||
ErrorOr<std::unique_ptr<const lld::File>> atom_f = normalizedToAtoms(f, "");
|
||||
EXPECT_FALSE(!atom_f);
|
||||
EXPECT_EQ(1U, countDefinedAtoms(**atom_f));
|
||||
const lld::DefinedAtom *singleAtom = *(*atom_f)->defined().begin();
|
||||
llvm::ArrayRef<uint8_t> atomContent(singleAtom->rawContent());
|
||||
EXPECT_EQ(0, memcmp(atomContent.data(), contentBytes, contentSize));
|
||||
}
|
||||
Loading…
Reference in New Issue