From 761d6549bc5a5e4223b3f27e3345b7cc1f0dea98 Mon Sep 17 00:00:00 2001 From: Nick Kledzik Date: Fri, 24 Oct 2014 22:19:22 +0000 Subject: [PATCH] [mach-o] Support data-only dylibs In final linked shared images, the __TEXT segment contains both code and the mach-o header/load-commands. In the case of a data-only dylib, there is no code, so we need to force the addition of the __TEXT segment. llvm-svn: 220597 --- lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp | 4 ++++ .../MachO/MachONormalizedFileBinaryWriter.cpp | 3 +++ .../MachO/MachONormalizedFileFromAtoms.cpp | 14 +++++++++-- lld/test/mach-o/data-only-dylib.yaml | 27 ++++++++++++++++++++++ lld/test/mach-o/exe-offsets.yaml | 26 +-------------------- lld/test/mach-o/exe-segment-overlap.yaml | 5 +--- 6 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 lld/test/mach-o/data-only-dylib.yaml diff --git a/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp b/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp index d642a99..ccb1e9c 100644 --- a/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp +++ b/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp @@ -291,6 +291,10 @@ private: collectDwarfFrameEntries(mergedFile, dwarfFrames); + // Skip rest of pass if no unwind info. + if (unwindLocs.empty() && dwarfFrames.empty()) + return; + // FIXME: if there are more than 4 personality functions then we need to // defer to DWARF info for the ones we don't put in the list. They should // also probably be sorted by frequency. diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp index 208ef0b..275060d 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp @@ -500,6 +500,9 @@ void MachOFileLayout::buildFileOffsets() { << ", fileOffset=" << _segInfo[&sg].fileOffset << "\n"); uint32_t segFileSize = 0; + // A segment that is not zero-fill must use a least one page of disk space. + if (sg.access) + segFileSize = _file.pageSize; for (const Section *s : _segInfo[&sg].sections) { uint32_t sectOffset = s->address - sg.address; uint32_t sectFileSize = diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index c420aa6..4a4ba79 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -394,9 +394,19 @@ void Util::organizeSections() { si->finalSectionIndex = sectionIndex++; } } else { - // Main executables, need a zero-page segment - if (_context.outputMachOType() == llvm::MachO::MH_EXECUTE) + switch (_context.outputMachOType()){ + case llvm::MachO::MH_EXECUTE: + // Main executables, need a zero-page segment segmentForName("__PAGEZERO"); + // Fall into next case. + case llvm::MachO::MH_DYLIB: + case llvm::MachO::MH_BUNDLE: + // All dynamic code needs TEXT segment to hold the load commands. + segmentForName("__TEXT"); + break; + default: + break; + } // Group sections into segments. for (SectionInfo *si : _sectionInfos) { SegmentInfo *seg = segmentForName(si->segmentName); diff --git a/lld/test/mach-o/data-only-dylib.yaml b/lld/test/mach-o/data-only-dylib.yaml new file mode 100644 index 0000000..c285066 --- /dev/null +++ b/lld/test/mach-o/data-only-dylib.yaml @@ -0,0 +1,27 @@ +# RUN: lld -flavor darwin -arch x86_64 -dylib %s -o %t %p/Inputs/libSystem.yaml +# RUN: llvm-nm %t | FileCheck %s +# +# Test that a data-only dylib can be built. +# + +--- !mach-o +arch: x86_64 +file-type: MH_OBJECT +flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ] +sections: + - segment: __DATA + section: __data + type: S_REGULAR + attributes: [ ] + alignment: 2 + address: 0x0000000000000000 + content: [ 0x00, 0x00, 0x00, 0x00 ] +global-symbols: + - name: _myData + type: N_SECT + scope: [ N_EXT ] + sect: 1 + value: 0x0000000000000000 +... + +# CHECK: _myData diff --git a/lld/test/mach-o/exe-offsets.yaml b/lld/test/mach-o/exe-offsets.yaml index 5ba8c8c..9fad2f2 100644 --- a/lld/test/mach-o/exe-offsets.yaml +++ b/lld/test/mach-o/exe-offsets.yaml @@ -1,4 +1,4 @@ -# RUN: lld -flavor darwin -arch x86_64 %s -o %t -e start +# RUN: lld -flavor darwin -arch x86_64 %s -o %t -e start %p/Inputs/libSystem.yaml # RUN: llvm-readobj -sections %t | FileCheck %s # Make sure data gets put at offset @@ -25,27 +25,6 @@ defined-atoms: type: data content: [ 01 ] ---- !mach-o -arch: x86_64 -file-type: MH_DYLIB -flags: [ ] -install-name: /usr/lib/libSystem.B.dylib -sections: - - segment: __TEXT - section: __text - type: S_REGULAR - attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ] - address: 0x0000000000000000 - content: [ 0x55 ] - -global-symbols: - - name: dyld_stub_binder - type: N_SECT - scope: [ N_EXT ] - sect: 1 - value: 0x0000000000000000 - - # CHECK-LABEL: Section { # CHECK: Name: __text @@ -54,9 +33,6 @@ global-symbols: # CHECK: Offset: 0 # CHECK-LABEL: Section { -# CHECK: Name: __unwind_info - -# CHECK-LABEL: Section { # CHECK: Name: __data # CHECK: Segment: __DATA # CHECK: Size: 0x5 diff --git a/lld/test/mach-o/exe-segment-overlap.yaml b/lld/test/mach-o/exe-segment-overlap.yaml index 1fbc841..a416ee3 100644 --- a/lld/test/mach-o/exe-segment-overlap.yaml +++ b/lld/test/mach-o/exe-segment-overlap.yaml @@ -23,10 +23,7 @@ defined-atoms: # CHECK: Name: __text # CHECK: Segment: __TEXT # CHECK: Size: 0x1 -# CHECK: Offset: 4027 - -# CHECK-LABEL: Section { -# CHECK: Name: __unwind_info +# CHECK: Offset: 4095 # CHECK-LABEL: Section { # CHECK: Name: __data -- 2.7.4