MachO: re-enable writing of compact-unwind sections.

This isn't really the right place to put them in final object files (that would
be __TEXT,__unwind_info), but the format is different between relocatable and
final objects, which means we really need a pass to handle the translation.

For now, re-emitting in __LD,__compact_unwind is harmless (dyld ignores it and
moves straight on to inspecting __TEXT,__eh_frame), and sidesteps an assertion
failure when processing files containing compact-unwind info.

llvm-svn: 212032
This commit is contained in:
Tim Northover 2014-06-30 09:49:37 +00:00
parent 7b0a1306b4
commit 9ee9935358
2 changed files with 165 additions and 1 deletions

View File

@ -215,7 +215,13 @@ const MachOFinalSectionFromAtomType sectsToAtomType[] = {
typeTerminatorPtr),
ENTRY("__DATA", "___got", S_NON_LAZY_SYMBOL_POINTERS,
typeGOT),
ENTRY("__DATA", "___bss", S_ZEROFILL, typeZeroFill)
ENTRY("__DATA", "___bss", S_ZEROFILL, typeZeroFill),
// FIXME: __compact_unwind actually needs to be processed by a pass and put
// into __TEXT,__unwind_info. For now, forwarding it back to
// __LD,__compact_unwind is harmless (it's ignored by the unwinder, which then
// proceeds to process __TEXT,__eh_frame for its instructions).
ENTRY("__LD", "__compact_unwind", S_REGULAR, typeCompactUnwindInfo),
};
#undef ENTRY

View File

@ -0,0 +1,158 @@
# RUN: lld -flavor darwin -arch x86_64 %s -o %t -e _foo
# RUN: llvm-readobj -sections -section-data %t | FileCheck %s
--- !native
defined-atoms:
# For __TEXT, __text (with typeCode)
- name: _foo
scope: global
content: [ 55 ]
# More for __TEXT, __text (with typeResolver)
- name: _resolver
scope: global
type: resolver
content: [ C3 ]
# CHECK: Name: __text
# CHECK: Segment: __TEXT
# CHECK: SectionData (
# CHECK-NEXT: 0000: 55C3
# CHECK-NEXT: )
# For __TEXT, __const (with typeConstant),
- type: constant
content: [ 01, 00, 00, 00 ]
# From __TEXT, __literal4, (with typeLiteral4)
- scope: hidden
type: const-4-byte
content: [ 02, 00, 00, 00 ]
# From __TEXT, __literal8, (with typeLiteral8)
- scope: hidden
type: const-8-byte
content: [ 03, 00, 00, 00, 00, 00, 00, 00 ]
# From __TEXT, __literal16, (with typeLiteral16)
- scope: hidden
type: const-16-byte
content: [ 04, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 ]
# CHECK: Name: __const
# CHECK: Segment: __TEXT
# CHECK: SectionData (
# CHECK-NEXT: 0000: 01000000 02000000 03000000 00000000
# CHECK-NEXT: 0010: 04000000 00000000 00000000 00000000
# CHECK-NEXT: )
# For __TEXT, __cstring (with typeCString)
- scope: hidden
type: c-string
content: [ 57, 69, 62, 62, 6C, 65, 00 ]
merge: by-content
# CHECK: Name: __cstring
# CHECK: Segment: __TEXT
# CHECK: SectionData (
# CHECK-NEXT: 0000: 57696262 6C6500
# CHECK-NEXT: )
# For __TEXT, __ustring (with typeUTF16String)
- scope: hidden
type: utf16-string
content: [ 05, 00 ]
merge: by-content
# CHECK: Name: __ustring
# CHECK: Segment: __TEXT
# CHECK: SectionData (
# CHECK-NEXT: 0000: 0500
# CHECK-NEXT: )
# For __TEXT, __gcc_except_tab, (with typeLSDA)
- name: GCC_except_table0
type: unwind-lsda
content: [ 06, 00 ]
# CHECK: Name: __gcc_except_tab
# CHECK: Segment: __TEXT
# CHECK: SectionData (
# CHECK-NEXT: 0000: 0600
# CHECK-NEXT: )
# For __TEXT, __eh_frame, (with typeCFI)
- type: unwind-cfi
content: [ 07 ]
# CHECK: Name: __eh_frame
# CHECK: Segment: __TEXT
# CHECK: SectionData (
# CHECK-NEXT: 0000: 07
# CHECK-NEXT: )
# For __DATA, __data, (with typeData)
- name: var
type: data
content: [ 08 ]
# CHECK: Name: __data
# CHECK: Segment: __DATA
# CHECK: SectionData (
# CHECK-NEXT: 0000: 08
# CHECK-NEXT: )
# For __DATA, ___bss (with typeZeroFill)
# FIXME: Attributes & tags of __bss are mostly broken. Should be at end of
# __DATA, should have size, should have S_ZEROFILL flag.
- type: zero-fill
size: 8
# CHECK: Name: ___bss
# CHECK: Segment: __DATA
# For __DATA, __const, (with typeConstData)
- type: const-data
content: [ 09, 00, 00, 00 ]
# CHECK: Name: __const
# CHECK: Segment: __DATA
# CHECK: SectionData (
# CHECK-NEXT: 0000: 09000000
# CHECK-NEXT: )
# For __DATA, __cfstring, (with typeCFString)
- type: cfstring
content: [ 0A, 00 ]
# CHECK: Name: __cfstring
# CHECK: Segment: __DATA
# CHECK: SectionData (
# CHECK-NEXT: 0000: 0A00
# CHECK-NEXT: )
# For __DATA, ___got (with typeGOT)
- type: got
content: [ 0B, 00, 00, 00, 00, 00, 00, 00 ]
# CHECK: Name: ___got
# CHECK: Segment: __DATA
# CHECK: SectionData (
# CHECK-NEXT: 0000: 0B000000 00000000
# CHECK-NEXT: )
# For __DATA, __mod_init_func (with typeInitializerPtr)
- type: initializer-pointer
content: [ 0C, 00, 00, 00, 00, 00, 00, 00 ]
# CHECK: Name: __mod_init_func
# CHECK: Segment: __DATA
# CHECK: SectionData (
# CHECK-NEXT: 0000: 0C000000 00000000
# CHECK-NEXT: )
# For __DATA, __mod_term_func (with typeTerminatorPointer)
- type: terminator-pointer
content: [ 0D, 00, 00, 00, 00, 00, 00, 00 ]
# CHECK: Name: __mod_term_func
# CHECK: Segment: __DATA
# CHECK: SectionData (
# CHECK-NEXT: 0000: 0D000000 00000000
# CHECK-NEXT: )
# FIXME: this should really end up in __TEXT,__unwind_info after being
# processed. Most important fact here is that its presence doesn't trigger an
# assert, but __LD,__compact_unwind is a harmless enough place to stash it.
- type: compact-unwind
content: [ 0E, 00, 00, 00, 00, 00, 00, 00 ]
# CHECK: Name: __compact_unwind
# CHECK: Segment: __LD
# CHECK: SectionData (
# CHECK-NEXT: 0000: 0E000000 00000000
# CHECK-NEXT: )