diff options
| author | Nick Kledzik <kledzik@apple.com> | 2014-05-15 20:59:23 +0000 |
|---|---|---|
| committer | Nick Kledzik <kledzik@apple.com> | 2014-05-15 20:59:23 +0000 |
| commit | 61fdef6086e72cdb2e148f9c1c2e87e2ed4b589d (patch) | |
| tree | 3c8bc231db5a5c8edff4d4ef30e64d0c0f2c5082 /lld/lib/ReaderWriter/MachO | |
| parent | 130a3b050423c7e2e2631277d705c96d0a721cac (diff) | |
| download | bcm5719-llvm-61fdef6086e72cdb2e148f9c1c2e87e2ed4b589d.tar.gz bcm5719-llvm-61fdef6086e72cdb2e148f9c1c2e87e2ed4b589d.zip | |
[mach-o] Add support and test cases for parsing tentative definitions
llvm-svn: 208919
Diffstat (limited to 'lld/lib/ReaderWriter/MachO')
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/Atoms.h | 31 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/File.h | 12 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp | 2 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp | 6 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp | 15 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp | 14 |
6 files changed, 76 insertions, 4 deletions
diff --git a/lld/lib/ReaderWriter/MachO/Atoms.h b/lld/lib/ReaderWriter/MachO/Atoms.h index e4bffce5a8b..b21a1ac5005 100644 --- a/lld/lib/ReaderWriter/MachO/Atoms.h +++ b/lld/lib/ReaderWriter/MachO/Atoms.h @@ -36,6 +36,37 @@ private: const ArrayRef<uint8_t> _content; const Scope _scope; }; + + +class MachOTentativeDefAtom : public SimpleDefinedAtom { +public: + MachOTentativeDefAtom(const File &f, const StringRef name, Scope scope, + uint64_t size, DefinedAtom::Alignment align) + : SimpleDefinedAtom(f), _name(name), _scope(scope), _size(size), + _align(align) {} + + uint64_t size() const override { return _size; } + + Merge merge() const override { return DefinedAtom::mergeAsTentative; } + + ContentType contentType() const override { return DefinedAtom::typeZeroFill; } + + Alignment alignment() const override { return _align; } + + StringRef name() const override { return _name; } + + Scope scope() const override { return _scope; } + + ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); } + +private: + const StringRef _name; + const Scope _scope; + const uint64_t _size; + const DefinedAtom::Alignment _align; +}; + + } // mach_o } // lld diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h index 68aea4a042c..767d5230cf6 100644 --- a/lld/lib/ReaderWriter/MachO/File.h +++ b/lld/lib/ReaderWriter/MachO/File.h @@ -43,6 +43,18 @@ public: addAtom(*atom); } + void addTentativeDefAtom(StringRef name, Atom::Scope scope, uint64_t size, + DefinedAtom::Alignment align, bool copyRefs) { + if (copyRefs) { + // Make a copy of the atom's name that is owned by this file. + name = name.copy(_allocator); + } + MachOTentativeDefAtom *atom = + new (_allocator) MachOTentativeDefAtom(*this, name, scope, size, align); + addAtom(*atom); + } + + private: llvm::BumpPtrAllocator _allocator; }; diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp index 1ffb4294c92..10123196a57 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp @@ -726,6 +726,8 @@ error_code MachOFileLayout::writeLoadCommands() { void MachOFileLayout::writeSectionContent() { for (const Section &s : _file.sections) { // Copy all section content to output buffer. + if (s.type == llvm::MachO::S_ZEROFILL) + continue; uint32_t offset = _sectInfo[&s].fileOffset; uint8_t *p = &_buffer[offset]; memcpy(p, &s.content[0], s.content.size()); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index b233741e5fb..b5b571898ee 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -176,6 +176,9 @@ SectionInfo *Util::makeSection(DefinedAtom::ContentType type) { case DefinedAtom::typeGOT: return new (_allocator) SectionInfo("__DATA", "__got", S_NON_LAZY_SYMBOL_POINTERS); + case DefinedAtom::typeZeroFill: + return new (_allocator) SectionInfo("__DATA", "__bss", + S_ZEROFILL); default: llvm_unreachable("TO DO: add support for more sections"); break; @@ -420,7 +423,8 @@ void Util::appendSection(SectionInfo *si, NormalizedFile &file) { // Record where normalized section is. 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. + if (si->type == llvm::MachO::S_ZEROFILL) + return; uint8_t *sectionContent = file.ownedAllocations.Allocate<uint8_t>(si->size); normSect->content = llvm::makeArrayRef(sectionContent, si->size); for (AtomInfo &ai : si->atomsAndOffsets) { diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index c84ca77367b..59452fbc3dd 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -85,6 +85,19 @@ static void processSymbol(const NormalizedFile &normalizedFile, MachOFile &file, file.addDefinedAtom(sym.name, atomContent, atomScope(sym.scope), copyRefs); } + +static void processUndefindeSymbol(MachOFile &file, const Symbol &sym, + bool copyRefs) { + // Undefinded symbols with n_value!=0 are actually tentative definitions. + if (sym.value == Hex64(0)) { + file.addUndefinedAtom(sym.name, copyRefs); + } else { + file.addTentativeDefAtom(sym.name, atomScope(sym.scope), sym.value, + DefinedAtom::Alignment(sym.desc >> 8), copyRefs); + } +} + + static ErrorOr<std::unique_ptr<lld::File>> normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path, bool copyRefs) { @@ -99,7 +112,7 @@ normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path, } for (auto &sym : normalizedFile.undefinedSymbols) { - file->addUndefinedAtom(sym.name, copyRefs); + processUndefindeSymbol(*file, sym, copyRefs); } return std::unique_ptr<File>(std::move(file)); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp index d3377399c2e..fb63cac227e 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp @@ -406,8 +406,18 @@ struct MappingTraits<Symbol> { io.mapRequired("type", sym.type); io.mapOptional("scope", sym.scope, SymbolScope(0)); io.mapOptional("sect", sym.sect, (uint8_t)0); - io.mapOptional("desc", sym.desc, SymbolDesc(0)); - io.mapRequired("value", sym.value); + if (sym.type == llvm::MachO::N_UNDF) { + // In undef symbols, desc field contains alignment/ordinal info + // which is better represented as a hex vaule. + uint16_t t1 = sym.desc; + Hex16 t2 = t1; + io.mapOptional("desc", t2, Hex16(0)); + sym.desc = t2; + } else { + // In defined symbols, desc fit is a set of option bits. + io.mapOptional("desc", sym.desc, SymbolDesc(0)); + } + io.mapRequired("value", sym.value); } }; |

