From d4f414583ad3d7f5e599d8060ec6aaf99958a946 Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Tue, 2 Feb 2016 21:37:15 +0000 Subject: [PATCH] Fix handling of mach header and DSO handle symbols. The magic file which contained these symbols inherited from archive which meant that the resolver didn't add the required atoms as archive members only get added when referenced. Instead we now inherit from SimpleFile which always links in the atoms needed. The second issue was in the handling of these symbols when we emit the MachO. The mach header symbol needs to be in the atom list as it gets an offset (0), and being in the atom list makes sure it is emitted to the symbol table. DSO handles are not emitted to the symbol table. rdar://problem/24450654 llvm-svn: 259574 --- lld/include/lld/Core/DefinedAtom.h | 1 + lld/include/lld/Core/File.h | 1 + lld/lib/Core/DefinedAtom.cpp | 1 + lld/lib/Core/Resolver.cpp | 1 + lld/lib/ReaderWriter/MachO/ExecutableAtoms.h | 83 ++++++++++++---------- .../MachO/MachONormalizedFileFromAtoms.cpp | 8 ++- lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp | 1 + lld/test/mach-o/arm-interworking-movw.yaml | 6 +- 8 files changed, 62 insertions(+), 40 deletions(-) diff --git a/lld/include/lld/Core/DefinedAtom.h b/lld/include/lld/Core/DefinedAtom.h index 70fd60d..8406806 100644 --- a/lld/include/lld/Core/DefinedAtom.h +++ b/lld/include/lld/Core/DefinedAtom.h @@ -147,6 +147,7 @@ public: typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin] typeTLVInitializerPtr, // pointer to thread local initializer [Darwin] typeMachHeader, // atom representing mach_header [Darwin] + typeDSOHandle, // atom representing DSO handle [Darwin] typeThreadZeroFill, // Uninitialized thread local data(TBSS) [ELF] typeThreadData, // Initialized thread local data(TDATA) [ELF] typeRONote, // Identifies readonly note sections [ELF] diff --git a/lld/include/lld/Core/File.h b/lld/include/lld/Core/File.h index d902db3..83b2fea 100644 --- a/lld/include/lld/Core/File.h +++ b/lld/include/lld/Core/File.h @@ -50,6 +50,7 @@ public: kindMachObject, ///< a MachO object file (.o) kindELFObject, ///< a ELF object file (.o) kindCEntryObject, ///< a file for CEntries + kindHeaderObject, ///< a file for file headers kindEntryObject, ///< a file for the entry kindUndefinedSymsObject, ///< a file for undefined symbols kindAliasSymsObject, ///< a file for alias symbols diff --git a/lld/lib/Core/DefinedAtom.cpp b/lld/lib/Core/DefinedAtom.cpp index 1e56f66..35596e6 100644 --- a/lld/lib/Core/DefinedAtom.cpp +++ b/lld/lib/Core/DefinedAtom.cpp @@ -79,6 +79,7 @@ DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) { case typeUnknown: case typeTempLTO: case typeSectCreate: + case typeDSOHandle: return permUnknown; } llvm_unreachable("unknown content type"); diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 60e5ace..337f6e4 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -343,6 +343,7 @@ bool Resolver::resolveUndefines() { case File::kindMachObject: case File::kindELFObject: case File::kindCEntryObject: + case File::kindHeaderObject: case File::kindEntryObject: case File::kindUndefinedSymsObject: case File::kindAliasSymsObject: diff --git a/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h b/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h index 620e1875..f1dd799 100644 --- a/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h +++ b/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h @@ -11,10 +11,10 @@ #define LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H #include "Atoms.h" +#include "File.h" #include "llvm/Support/MachO.h" -#include "lld/Core/ArchiveLibraryFile.h" #include "lld/Core/DefinedAtom.h" #include "lld/Core/File.h" #include "lld/Core/LinkingContext.h" @@ -65,45 +65,57 @@ private: // MachHeaderAliasFile lazily instantiates the magic symbols that mark the start // of the mach_header for final linked images. // -class MachHeaderAliasFile : public ArchiveLibraryFile { +class MachHeaderAliasFile : public SimpleFile { public: MachHeaderAliasFile(const MachOLinkingContext &context) - : ArchiveLibraryFile("mach_header symbols") { - switch (context.outputMachOType()) { - case llvm::MachO::MH_EXECUTE: - _machHeaderSymbolName = "__mh_execute_header"; - break; - case llvm::MachO::MH_DYLIB: - _machHeaderSymbolName = "__mh_dylib_header"; - break; - case llvm::MachO::MH_BUNDLE: - _machHeaderSymbolName = "__mh_bundle_header"; - break; - case llvm::MachO::MH_DYLINKER: - _machHeaderSymbolName = "__mh_dylinker_header"; - break; - case llvm::MachO::MH_PRELOAD: - _machHeaderSymbolName = "__mh_preload_header"; - break; - default: - llvm_unreachable("no mach_header symbol for file type"); - } - } - - std::error_code - parseAllMembers(std::vector> &result) override { - return std::error_code(); - } - - File *find(StringRef sym, bool dataSymbolOnly) override { - if (sym.equals("___dso_handle") || sym.equals(_machHeaderSymbolName)) { + : SimpleFile("mach_header symbols", kindHeaderObject) { + StringRef machHeaderSymbolName; + StringRef dsoHandleName; + switch (context.outputMachOType()) { + case llvm::MachO::MH_OBJECT: + machHeaderSymbolName = "__mh_object_header"; + break; + case llvm::MachO::MH_EXECUTE: + machHeaderSymbolName = "__mh_execute_header"; + dsoHandleName = "___dso_handle"; + break; + case llvm::MachO::MH_FVMLIB: + llvm_unreachable("no mach_header symbol for file type"); + case llvm::MachO::MH_CORE: + llvm_unreachable("no mach_header symbol for file type"); + case llvm::MachO::MH_PRELOAD: + llvm_unreachable("no mach_header symbol for file type"); + case llvm::MachO::MH_DYLIB: + machHeaderSymbolName = "__mh_dylib_header"; + dsoHandleName = "___dso_handle"; + break; + case llvm::MachO::MH_DYLINKER: + machHeaderSymbolName = "__mh_dylinker_header"; + dsoHandleName = "___dso_handle"; + break; + case llvm::MachO::MH_BUNDLE: + machHeaderSymbolName = "__mh_bundle_header"; + dsoHandleName = "___dso_handle"; + break; + case llvm::MachO::MH_DYLIB_STUB: + llvm_unreachable("no mach_header symbol for file type"); + case llvm::MachO::MH_DSYM: + llvm_unreachable("no mach_header symbol for file type"); + case llvm::MachO::MH_KEXT_BUNDLE: + dsoHandleName = "___dso_handle"; + break; + } + if (!machHeaderSymbolName.empty()) _definedAtoms.push_back(new (allocator()) MachODefinedAtom( - *this, sym, DefinedAtom::scopeLinkageUnit, + *this, machHeaderSymbolName, DefinedAtom::scopeLinkageUnit, DefinedAtom::typeMachHeader, DefinedAtom::mergeNo, false, false, ArrayRef(), DefinedAtom::Alignment(4096))); - return this; - } - return nullptr; + + if (!dsoHandleName.empty()) + _definedAtoms.push_back(new (allocator()) MachODefinedAtom( + *this, dsoHandleName, DefinedAtom::scopeLinkageUnit, + DefinedAtom::typeDSOHandle, DefinedAtom::mergeNo, false, false, + ArrayRef(), DefinedAtom::Alignment(1))); } const AtomVector &defined() const override { @@ -124,7 +136,6 @@ public: private: mutable AtomVector _definedAtoms; - StringRef _machHeaderSymbolName; }; } // namespace mach_o diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index 22cdede..0d6e188 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -242,6 +242,7 @@ struct MachOFinalSectionFromAtomType { const MachOFinalSectionFromAtomType sectsToAtomType[] = { ENTRY("__TEXT", "__text", S_REGULAR, typeCode), + ENTRY("__TEXT", "__text", S_REGULAR, typeMachHeader), ENTRY("__TEXT", "__cstring", S_CSTRING_LITERALS, typeCString), ENTRY("__TEXT", "__ustring", S_REGULAR, typeUTF16String), ENTRY("__TEXT", "__const", S_REGULAR, typeConstant), @@ -385,7 +386,12 @@ void Util::processAtomAttributes(const DefinedAtom *atom) { } void Util::assignAtomToSection(const DefinedAtom *atom) { - if (atom->contentType() == DefinedAtom::typeMachHeader) + if (atom->contentType() == DefinedAtom::typeMachHeader) { + _machHeaderAliasAtoms.push_back(atom); + // Assign atom to this section with this offset. + AtomInfo ai = {atom, 0}; + sectionForAtom(atom)->atomsAndOffsets.push_back(ai); + } else if (atom->contentType() == DefinedAtom::typeDSOHandle) _machHeaderAliasAtoms.push_back(atom); else appendAtom(sectionForAtom(atom), atom); diff --git a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp index a28237b..3336a3e 100644 --- a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp +++ b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp @@ -435,6 +435,7 @@ template <> struct ScalarEnumerationTraits { io.enumCase(value, "tlv-initializer-ptr", DefinedAtom::typeTLVInitializerPtr); io.enumCase(value, "mach_header", DefinedAtom::typeMachHeader); + io.enumCase(value, "dso_handle", DefinedAtom::typeDSOHandle); io.enumCase(value, "thread-data", DefinedAtom::typeThreadData); io.enumCase(value, "thread-zero-fill",DefinedAtom::typeThreadZeroFill); io.enumCase(value, "ro-note", DefinedAtom::typeRONote); diff --git a/lld/test/mach-o/arm-interworking-movw.yaml b/lld/test/mach-o/arm-interworking-movw.yaml index 7e4a2e0..0423ed6 100644 --- a/lld/test/mach-o/arm-interworking-movw.yaml +++ b/lld/test/mach-o/arm-interworking-movw.yaml @@ -2,7 +2,7 @@ # RUN: lld -flavor darwin -arch armv7 -r -print_atoms %s -o %t | FileCheck %s # RUN: lld -flavor darwin -arch armv7 -dylib -print_atoms %t -o %t2 \ # RUN: %p/Inputs/libSystem.yaml -sectalign __TEXT __text 0x1000 | FileCheck %s -# RUN: llvm-objdump -d -macho %t2 | FileCheck -check-prefix=CODE %s +# RUN: llvm-objdump -d -macho -no-symbolic-operands %t2 | FileCheck -check-prefix=CODE %s # # Test thumb and arm branches round trip through -r. # Test movw/movt pairs have low bit set properly for thumb vs arm. @@ -330,7 +330,7 @@ local-symbols: # CODE-NEXT: movt r0, #0 # CODE-NEXT: movw r1, #1 # CODE-NEXT: movt r1, #0 -# CODE-NEXT: movw r2, _a2 +# CODE-NEXT: movw r2, #4174 # CODE-NEXT: movt r2, #0 # CODE-NEXT: movw r3, #42 # CODE-NEXT: movt r3, #0 @@ -341,7 +341,7 @@ local-symbols: # CODE-NEXT: movt r0, #0 # CODE-NEXT: movw r1, #65495 # CODE-NEXT: movt r1, #65535 -# CODE-NEXT: movw r2, _a2 +# CODE-NEXT: movw r2, #4174 # CODE-NEXT: movt r2, #0 # CODE-NEXT: movw r3, #0 # CODE-NEXT: movt r3, #0 -- 2.7.4