diff --git a/lld/MachO/OutputSection.h b/lld/MachO/OutputSection.h index 90f8a841a7f292..08dc41228dcd7d 100644 --- a/lld/MachO/OutputSection.h +++ b/lld/MachO/OutputSection.h @@ -36,8 +36,8 @@ class OutputSection { // as-is so their file size is the same as their address space size. virtual uint64_t getFileSize() const { return getSize(); } - // Hidden sections omit header content, but body content is still present. - virtual bool isHidden() const { return !this->isNeeded(); } + // Hidden sections omit header content, but body content may still be present. + virtual bool isHidden() const { return false; } // Unneeded sections are omitted entirely (header and body). virtual bool isNeeded() const { return true; } diff --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp index 1512e3f302f8f1..484d0b9da3ec8d 100644 --- a/lld/MachO/OutputSegment.cpp +++ b/lld/MachO/OutputSegment.cpp @@ -40,7 +40,7 @@ size_t OutputSegment::numNonHiddenSections() const { size_t count = 0; for (const OutputSegment::SectionMapEntry &i : sections) { OutputSection *os = i.second; - count += (os->isHidden() ? 0 : 1); + count += (!os->isHidden() ? 1 : 0); } return count; } @@ -70,6 +70,12 @@ void OutputSegment::sortOutputSections(OutputSegmentComparator *comparator) { llvm::stable_sort(sections, *comparator->sectionComparator(this)); } +void OutputSegment::removeUnneededSections() { + sections.remove_if([](const std::pair &p) { + return !p.second->isNeeded(); + }); +} + OutputSegmentComparator::OutputSegmentComparator() { // This defines the order of segments and the sections within each segment. // Segments that are not mentioned here will end up at defaultPosition; @@ -138,9 +144,8 @@ void macho::sortOutputSegmentsAndSections() { seg->sortOutputSections(&comparator); for (auto &p : seg->getSections()) { OutputSection *section = p.second; - if (!section->isHidden()) { + if (!section->isHidden()) section->index = ++sectionIndex; - } } } } diff --git a/lld/MachO/OutputSegment.h b/lld/MachO/OutputSegment.h index 3a801430245c0c..332f38d2c2596d 100644 --- a/lld/MachO/OutputSegment.h +++ b/lld/MachO/OutputSegment.h @@ -51,6 +51,7 @@ class OutputSegment { OutputSection *getOrCreateOutputSection(StringRef name); void addOutputSection(OutputSection *os); void sortOutputSections(OutputSegmentComparator *comparator); + void removeUnneededSections(); const SectionMap &getSections() const { return sections; } size_t numNonHiddenSections() const; diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp index 80915528e11d29..19a69c3bb7340d 100644 --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -114,7 +114,7 @@ class LCSegment : public LoadCommand { c->maxprot = seg->maxProt; c->initprot = seg->initProt; - if (!seg->isNeeded()) + if (seg->getSections().empty()) return; c->vmaddr = seg->firstSection()->addr; @@ -126,6 +126,7 @@ class LCSegment : public LoadCommand { StringRef s = p.first; OutputSection *section = p.second; c->filesize += section->getFileSize(); + if (section->isHidden()) continue; @@ -283,10 +284,8 @@ void Writer::createLoadCommands() { uint8_t segIndex = 0; for (OutputSegment *seg : outputSegments) { - if (seg->isNeeded()) { - headerSection->addLoadCommand(make(seg->name, seg)); - seg->index = segIndex++; - } + headerSection->addLoadCommand(make(seg->name, seg)); + seg->index = segIndex++; } uint64_t dylibOrdinal = 1; @@ -327,6 +326,17 @@ void Writer::createOutputSections() { ->getOrCreateOutputSection(isec->name) ->mergeInput(isec); } + + // Remove unneeded segments and sections. + // TODO: Avoid creating unneeded segments in the first place + for (auto it = outputSegments.begin(); it != outputSegments.end();) { + OutputSegment *seg = *it; + seg->removeUnneededSections(); + if (!seg->isNeeded()) + it = outputSegments.erase(it); + else + ++it; + } } void Writer::assignAddresses(OutputSegment *seg) { diff --git a/lld/test/MachO/section-merge.s b/lld/test/MachO/section-merge.s index bd3563718aa98b..33e1eddd3044ae 100644 --- a/lld/test/MachO/section-merge.s +++ b/lld/test/MachO/section-merge.s @@ -23,9 +23,9 @@ # DATA: {{0*}}[[#%x,BASE:]] <_some_function>: # DATA-NEXT: [[#BASE]]: 48 c7 c0 01 00 00 00 movq $1, %rax # DATA-NEXT: [[#BASE + 0x7]]: c3 retq -# DATA: {{0*}}[[#BASE + 0x8]] <_main>: -# DATA-NEXT: [[#BASE + 0x8]]: 48 c7 c0 00 00 00 00 movq $0, %rax -# DATA-NEXT: [[#BASE + 0xf]]: c3 retq +# DATA: {{0*}}[[#%x,MAIN:]] <_main>: +# DATA-NEXT: [[#MAIN]]: 48 c7 c0 00 00 00 00 movq $0, %rax +# DATA-NEXT: [[#MAIN + 0x7]]: c3 retq .section __TEXT,__text .global _main