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 | |
| 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
| -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 | ||||
| -rw-r--r-- | lld/test/mach-o/parse-data.yaml | 81 | ||||
| -rw-r--r-- | lld/test/mach-o/parse-tentative-defs.yaml | 88 |
8 files changed, 245 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); } }; diff --git a/lld/test/mach-o/parse-data.yaml b/lld/test/mach-o/parse-data.yaml new file mode 100644 index 00000000000..c09162798d2 --- /dev/null +++ b/lld/test/mach-o/parse-data.yaml @@ -0,0 +1,81 @@ +# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s +# +# Test parsing of mach-o data symbols. +# +# long a = 0x0807060504030201; +# int b = 0x14131211; +# int c = 0x24232221; +# static int s1; +# static int s2 = 0x34333231; +# +# + + +--- !mach-o +arch: x86_64 +file-type: MH_OBJECT +flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ] +has-UUID: false +OS: unknown +sections: + - segment: __DATA + section: __data + type: S_REGULAR + attributes: [ ] + alignment: 3 + address: 0x0000000000000000 + content: [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, + 0x31, 0x32, 0x33, 0x34 ] + - segment: __DATA + section: __bss + type: S_ZEROFILL + attributes: [ ] + alignment: 2 + address: 0x0000000000000014 + content: [ 0x00, 0x00, 0x00, 0x00 ] +local-symbols: + - name: _s1 + type: N_SECT + sect: 2 + value: 0x0000000000000014 + - name: _s2 + type: N_SECT + sect: 1 + value: 0x0000000000000010 +global-symbols: + - name: _a + type: N_SECT + scope: [ N_EXT ] + sect: 1 + value: 0x0000000000000000 + - name: _b + type: N_SECT + scope: [ N_EXT ] + sect: 1 + value: 0x0000000000000008 + - name: _c + type: N_SECT + scope: [ N_EXT ] + sect: 1 + value: 0x000000000000000C +... + +# CHECK: defined-atoms: +# CHECK: - name: _a +# CHECK: scope: global +# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ] + +# CHECK: - name: _b +# CHECK: scope: global +# CHECK: content: [ 11, 12, 13, 14 ] + +# CHECK: - name: _c +# CHECK: scope: global +# CHECK: content: [ 21, 22, 23, 24 ] + +# CHECK: - name: _s1 +# CHECK: content: [ 00, 00, 00, 00 ] + +# CHECK: - name: _s2 +# CHECK: content: [ 31, 32, 33, 34 ] diff --git a/lld/test/mach-o/parse-tentative-defs.yaml b/lld/test/mach-o/parse-tentative-defs.yaml new file mode 100644 index 00000000000..fc75167bd89 --- /dev/null +++ b/lld/test/mach-o/parse-tentative-defs.yaml @@ -0,0 +1,88 @@ +# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s +# +# Test parsing of tentative definitions, including size, scope, and alignment. +# +# +# int tent4; +# long tent8; +# __attribute__((visibility("hidden"))) int tentHidden; +# __attribute__((aligned(16))) int tent4_16; +# __attribute__((aligned(32))) long tent64_32[8]; +# + +--- !mach-o +arch: x86_64 +file-type: MH_OBJECT +flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ] +has-UUID: false +OS: unknown +sections: + - segment: __TEXT + section: __tex + type: S_REGULAR + attributes: [ S_ATTR_PURE_INSTRUCTIONS ] + address: 0x0000000000000000 +undefined-symbols: + - name: _tent4 + type: N_UNDF + scope: [ N_EXT ] + desc: 0x0200 + value: 0x0000000000000004 + - name: _tent4_16 + type: N_UNDF + scope: [ N_EXT ] + desc: 0x0400 + value: 0x0000000000000004 + - name: _tent64_32 + type: N_UNDF + scope: [ N_EXT ] + desc: 0x0500 + value: 0x0000000000000040 + - name: _tent8 + type: N_UNDF + scope: [ N_EXT ] + desc: 0x0300 + value: 0x0000000000000008 + - name: _tentHidden + type: N_UNDF + scope: [ N_EXT, N_PEXT ] + desc: 0x0200 + value: 0x0000000000000004 +... + + +# CHECK: defined-atoms: +# CHECK: name: _tent4 +# CHECK: scope: global +# CHECK: type: zero-fill +# CHECK: size: 4 +# CHECK: merge: as-tentative +# CHECK: alignment: 2^2 + +# CHECK: name: _tent4_16 +# CHECK: scope: global +# CHECK: type: zero-fill +# CHECK: size: 4 +# CHECK: merge: as-tentative +# CHECK: alignment: 2^4 + +# CHECK: name: _tent64_32 +# CHECK: scope: global +# CHECK: type: zero-fill +# CHECK: size: 64 +# CHECK: merge: as-tentative +# CHECK: alignment: 2^5 + +# CHECK: name: _tent8 +# CHECK: scope: global +# CHECK: type: zero-fill +# CHECK: size: 8 +# CHECK: merge: as-tentative +# CHECK: alignment: 2^3 + +# CHECK: name: _tentHidden +# CHECK: scope: hidden +# CHECK: type: zero-fill +# CHECK: size: 4 +# CHECK: merge: as-tentative +# CHECK: alignment: 2^2 |

