diff options
author | Joey Gouly <joey.gouly@gmail.com> | 2014-01-03 23:12:02 +0000 |
---|---|---|
committer | Joey Gouly <joey.gouly@gmail.com> | 2014-01-03 23:12:02 +0000 |
commit | ceb16dedefc7833b3f3b7305e751ad9ba748d99b (patch) | |
tree | 7158a67f016d6a8bece0f3cf0b35fd8d62f6ce46 | |
parent | 0724bf67672c754aa61ce2659939450ff22c30fa (diff) | |
download | bcm5719-llvm-ceb16dedefc7833b3f3b7305e751ad9ba748d99b.tar.gz bcm5719-llvm-ceb16dedefc7833b3f3b7305e751ad9ba748d99b.zip |
[MachO] Begin to add some MachO specific File/Atoms, and add the start of
normalizedToAtoms.
llvm-svn: 198459
-rw-r--r-- | lld/lib/ReaderWriter/MachO/Atoms.h | 41 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/File.h | 37 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFile.h | 6 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp | 2 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp | 66 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp | 24 | ||||
-rw-r--r-- | lld/unittests/MachOTests/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lld/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp | 61 |
9 files changed, 234 insertions, 7 deletions
diff --git a/lld/lib/ReaderWriter/MachO/Atoms.h b/lld/lib/ReaderWriter/MachO/Atoms.h new file mode 100644 index 00000000000..7733b2a9546 --- /dev/null +++ b/lld/lib/ReaderWriter/MachO/Atoms.h @@ -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 diff --git a/lld/lib/ReaderWriter/MachO/CMakeLists.txt b/lld/lib/ReaderWriter/MachO/CMakeLists.txt index d63b4d454d7..0b9b13545e0 100644 --- a/lld/lib/ReaderWriter/MachO/CMakeLists.txt +++ b/lld/lib/ReaderWriter/MachO/CMakeLists.txt @@ -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(.) diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h new file mode 100644 index 00000000000..e002a93e4b4 --- /dev/null +++ b/lld/lib/ReaderWriter/MachO/File.h @@ -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 diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h index f2f6cf86184..15fd4c3686d 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h @@ -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 - - - - diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index 0d73ec81180..1479ac20da2 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -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*> diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp new file mode 100644 index 00000000000..2032e0cea05 --- /dev/null +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -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 diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp index 2a888d5d3eb..78efae6adb8 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp @@ -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; + }; }; diff --git a/lld/unittests/MachOTests/CMakeLists.txt b/lld/unittests/MachOTests/CMakeLists.txt index e95d261ff7c..23052d366c6 100644 --- a/lld/unittests/MachOTests/CMakeLists.txt +++ b/lld/unittests/MachOTests/CMakeLists.txt @@ -2,6 +2,7 @@ add_lld_unittest(lldMachOTests MachONormalizedFileBinaryReaderTests.cpp MachONormalizedFileBinaryWriterTests.cpp + MachONormalizedFileToAtomsTests.cpp MachONormalizedFileYAMLTests.cpp ) diff --git a/lld/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp b/lld/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp new file mode 100644 index 00000000000..9b2859a5961 --- /dev/null +++ b/lld/unittests/MachOTests/MachONormalizedFileToAtomsTests.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)); +} |