Index: include/llvm/Object/ELFObjectFile.h =================================================================== --- include/llvm/Object/ELFObjectFile.h +++ include/llvm/Object/ELFObjectFile.h @@ -260,6 +260,8 @@ bool isSectionData(DataRefImpl Sec) const override; bool isSectionBSS(DataRefImpl Sec) const override; bool isSectionVirtual(DataRefImpl Sec) const override; + bool inTextSegment(DataRefImpl Sec) const override; + bool inDataSegment(DataRefImpl Sec) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; std::vector dynamic_relocation_sections() const override; @@ -758,6 +760,20 @@ return getSection(Sec)->sh_type == ELF::SHT_NOBITS; } +template +bool ELFObjectFile::inTextSegment(DataRefImpl Sec) const { + return getSection(Sec)->sh_flags & ELF::SHF_ALLOC && + (getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR || + (!(getSection(Sec)->sh_flags & ELF::SHF_WRITE))); +} + +template +bool ELFObjectFile::inDataSegment(DataRefImpl Sec) const { + const Elf_Shdr *EShdr = getSection(Sec); + return !inTextSegment(Sec) && EShdr->sh_type != ELF::SHT_NOBITS && + EShdr->sh_flags & ELF::SHF_ALLOC; +} + template relocation_iterator ELFObjectFile::section_rel_begin(DataRefImpl Sec) const { Index: include/llvm/Object/ObjectFile.h =================================================================== --- include/llvm/Object/ObjectFile.h +++ include/llvm/Object/ObjectFile.h @@ -104,13 +104,23 @@ uint64_t getAlignment() const; bool isCompressed() const; + /// Whether this section contains instructions. bool isText() const; + /// Whether this section contains data, not instructions. bool isData() const; + /// Whether this section contains BSS initialized data. bool isBSS() const; bool isVirtual() const; bool isBitcode() const; bool isStripped() const; + /// Whether this section will be placed in the text segment. + bool inTextSegment() const; + /// Whether this section will be placed in the data segment (and is not BSS). + bool inDataSegment() const; + /// Whether this is a BSS section that will be placed in the data segment. + bool inBSSSegment() const; + bool containsSymbol(SymbolRef S) const; relocation_iterator relocation_begin() const; @@ -238,6 +248,9 @@ virtual bool isSectionVirtual(DataRefImpl Sec) const = 0; virtual bool isSectionBitcode(DataRefImpl Sec) const; virtual bool isSectionStripped(DataRefImpl Sec) const; + virtual bool inTextSegment(DataRefImpl Sec) const; + virtual bool inDataSegment(DataRefImpl Sec) const; + virtual bool inBSSSegment(DataRefImpl Sec) const; virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0; virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0; virtual section_iterator getRelocatedSection(DataRefImpl Sec) const; @@ -449,6 +462,18 @@ return OwningObject->isSectionStripped(SectionPimpl); } +inline bool SectionRef::inTextSegment() const { + return OwningObject->inTextSegment(SectionPimpl); +} + +inline bool SectionRef::inDataSegment() const { + return OwningObject->inDataSegment(SectionPimpl); +} + +inline bool SectionRef::inBSSSegment() const { + return OwningObject->inBSSSegment(SectionPimpl); +} + inline relocation_iterator SectionRef::relocation_begin() const { return OwningObject->section_rel_begin(SectionPimpl); } Index: lib/Object/ObjectFile.cpp =================================================================== --- lib/Object/ObjectFile.cpp +++ lib/Object/ObjectFile.cpp @@ -77,6 +77,18 @@ bool ObjectFile::isSectionStripped(DataRefImpl Sec) const { return false; } +bool ObjectFile::inTextSegment(DataRefImpl Sec) const { + return isSectionText(Sec); +} + +bool ObjectFile::inDataSegment(DataRefImpl Sec) const { + return isSectionData(Sec); +} + +bool ObjectFile::inBSSSegment(DataRefImpl Sec) const { + return isSectionBSS(Sec); +} + section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const { return section_iterator(SectionRef(Sec, this)); } Index: test/tools/llvm-size/X86/elf-sizes.test =================================================================== --- /dev/null +++ test/tools/llvm-size/X86/elf-sizes.test @@ -0,0 +1,43 @@ +# RUN: yaml2obj %s > %t.o +# RUN: llvm-size -B %t.o | FileCheck %s + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_ALLOC, SHF_WRITE ] + Size: 1 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Size: 2 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Size: 4 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_WRITE ] + Size: 8 + - Name: .debug_info + Type: SHT_PROGBITS + Flags: [ ] + Size: 16 + - Name: .init_array + Type: SHT_INIT_ARRAY + Flags: [ SHF_ALLOC, SHF_WRITE ] + Size: 32 + +# text is .text, .eh_frame: 2 + 4 = 6 +# data is .data, .init_array: 8 + 32 = 40 +# bss is .bss: 1 +# total: 47 +# unaccounted for (not affecting total) is .debug_info + +# CHECK: text data bss dec +# CHECK: 6 40 1 47 Index: test/tools/llvm-size/X86/ignore-sections.s =================================================================== --- test/tools/llvm-size/X86/ignore-sections.s +++ test/tools/llvm-size/X86/ignore-sections.s @@ -25,5 +25,5 @@ // SYSV-NEXT: Total 69 // BSD: text data bss dec hex filename -// BSD-NEXT: 4 4 4 12 c {{[ -\(\)_A-Za-z0-9.\\/:]+}} -// BSD-NEXT: 4 4 4 12 c (TOTALS) +// BSD-NEXT: 52 4 4 60 3c {{[ -\(\)_A-Za-z0-9.\\/:]+}} +// BSD-NEXT: 52 4 4 60 3c (TOTALS) Index: tools/llvm-size/llvm-size.cpp =================================================================== --- tools/llvm-size/llvm-size.cpp +++ tools/llvm-size/llvm-size.cpp @@ -457,9 +457,9 @@ // Make one pass over the section table to calculate sizes. for (const SectionRef &Section : Obj->sections()) { uint64_t size = Section.getSize(); - bool isText = Section.isText(); - bool isData = Section.isData(); - bool isBSS = Section.isBSS(); + bool isText = Section.inTextSegment(); + bool isData = Section.inDataSegment(); + bool isBSS = Section.inBSSSegment(); if (isText) total_text += size; else if (isData)