From 7b0a1306b4e9b2908e5e17979e05e4179a0099a4 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Mon, 30 Jun 2014 09:49:33 +0000 Subject: [PATCH] MachO: align segment virtual addresses to page size. Segments must occupy a multiple of the page size in memory (4096 currently). We check for this when emitting files, but the placement algorithm broke down for the second non-__TEXT segment encountered: the offset wasn't aligned up to 4096 before starting its layout. llvm-svn: 212031 --- .../MachO/MachONormalizedFileFromAtoms.cpp | 7 ++- lld/test/mach-o/exe-segment-overlap.yaml | 44 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 lld/test/mach-o/exe-segment-overlap.yaml diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index f187df9d674d..ad45bacefce0 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -278,11 +278,12 @@ SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) { // Not found, so need to create a new custom section. size_t seperatorIndex = customName.find('/'); assert(seperatorIndex != StringRef::npos); - StringRef segName = customName.slice(0, seperatorIndex-1); - StringRef sectName = customName.drop_front(seperatorIndex); + StringRef segName = customName.slice(0, seperatorIndex); + StringRef sectName = customName.drop_front(seperatorIndex + 1); SectionInfo *sect = new (_allocator) SectionInfo(segName, sectName, S_REGULAR); _customSections.push_back(sect); + _sectionInfos.push_back(sect); return sect; } } @@ -452,6 +453,8 @@ void Util::assignAddressesToSections() { layoutSectionsInTextSegment(seg, address); else layoutSectionsInSegment(seg, address); + + address = llvm::RoundUpToAlignment(address, _context.pageSize()); } DEBUG_WITH_TYPE("WriterMachO-norm", llvm::dbgs() << "assignAddressesToSections()\n"; diff --git a/lld/test/mach-o/exe-segment-overlap.yaml b/lld/test/mach-o/exe-segment-overlap.yaml new file mode 100644 index 000000000000..b0ed7624e608 --- /dev/null +++ b/lld/test/mach-o/exe-segment-overlap.yaml @@ -0,0 +1,44 @@ +# RUN: lld -flavor darwin -arch x86_64 %s -o %t +# RUN: llvm-readobj -sections -section-data %t | FileCheck %s + +--- !native +defined-atoms: + - name: start + scope: global + content: [ 90 ] + + - name: _s2 + type: data + content: [ 31, 32, 33, 34 ] + + - name: _kustom + scope: global + type: unknown + content: [ 01, 02, 03, 04, 05, 06, 07, 08 ] + section-choice: custom-required + section-name: __CUST/__custom + + +# CHECK-LABEL: Section { +# CHECK: Name: __text +# CHECK: Segment: __TEXT +# CHECK: Size: 0x1 +# CHECK: Offset: 4095 + +# CHECK-LABEL: Section { +# CHECK: Name: __data +# CHECK: Segment: __DATA +# CHECK: Size: 0x4 +# CHECK: Offset: 4096 +# CHECK: SectionData ( +# CHECK-NEXT: 0000: 31323334 +# CHECK-NEXT: ) + +# CHECK-LABEL: Section { +# CHECK: Name: __custom{{ }} +# CHECK: Segment: __CUST{{ }} +# CHECK: Size: 0x8 +# CHECK: Offset: 8192 +# CHECK: SectionData ( +# CHECK-NEXT: 0000: 01020304 05060708 +# CHECK-NEXT: )