mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[llvm-size][libobject] Add explicit "inTextSegment" methods similar to "isText" section methods to calculate size correctly.
Summary: llvm-size uses "isText()" etc. which seem to indicate whether the section contains code-like things, not whether or not it will actually go in the text segment when in a fully linked executable. The unit test added (elf-sizes.test) shows some types of sections that cause discrepencies versus the GNU size tool. llvm-size is not correctly reporting sizes of things mapping to text/data segments, at least for ELF files. This fixes pr38723. Reviewers: echristo, Bigcheese, MaskRay Reviewed By: MaskRay Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D54369 llvm-svn: 349074
This commit is contained in:
parent
fc983d8fa5
commit
b88c3ef139
@ -260,6 +260,8 @@ protected:
|
||||
bool isSectionData(DataRefImpl Sec) const override;
|
||||
bool isSectionBSS(DataRefImpl Sec) const override;
|
||||
bool isSectionVirtual(DataRefImpl Sec) const override;
|
||||
bool isBerkeleyText(DataRefImpl Sec) const override;
|
||||
bool isBerkeleyData(DataRefImpl Sec) const override;
|
||||
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
|
||||
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
|
||||
std::vector<SectionRef> dynamic_relocation_sections() const override;
|
||||
@ -759,6 +761,20 @@ bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
|
||||
return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
bool ELFObjectFile<ELFT>::isBerkeleyText(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 <class ELFT>
|
||||
bool ELFObjectFile<ELFT>::isBerkeleyData(DataRefImpl Sec) const {
|
||||
const Elf_Shdr *EShdr = getSection(Sec);
|
||||
return !isBerkeleyText(Sec) && EShdr->sh_type != ELF::SHT_NOBITS &&
|
||||
EShdr->sh_flags & ELF::SHF_ALLOC;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
relocation_iterator
|
||||
ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
|
||||
|
@ -104,13 +104,25 @@ public:
|
||||
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 uninitialized data.
|
||||
bool isBSS() const;
|
||||
bool isVirtual() const;
|
||||
bool isBitcode() const;
|
||||
bool isStripped() const;
|
||||
|
||||
/// Whether this section will be placed in the text segment, according to the
|
||||
/// Berkeley size format. This is true if the section is allocatable, and
|
||||
/// contains either code or readonly data.
|
||||
bool isBerkeleyText() const;
|
||||
/// Whether this section will be placed in the data segment, according to the
|
||||
/// Berkeley size format. This is true if the section is allocatable and
|
||||
/// contains data (e.g. PROGBITS), but is not text.
|
||||
bool isBerkeleyData() const;
|
||||
|
||||
bool containsSymbol(SymbolRef S) const;
|
||||
|
||||
relocation_iterator relocation_begin() const;
|
||||
@ -238,6 +250,8 @@ protected:
|
||||
virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
|
||||
virtual bool isSectionBitcode(DataRefImpl Sec) const;
|
||||
virtual bool isSectionStripped(DataRefImpl Sec) const;
|
||||
virtual bool isBerkeleyText(DataRefImpl Sec) const;
|
||||
virtual bool isBerkeleyData(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 +463,14 @@ inline bool SectionRef::isStripped() const {
|
||||
return OwningObject->isSectionStripped(SectionPimpl);
|
||||
}
|
||||
|
||||
inline bool SectionRef::isBerkeleyText() const {
|
||||
return OwningObject->isBerkeleyText(SectionPimpl);
|
||||
}
|
||||
|
||||
inline bool SectionRef::isBerkeleyData() const {
|
||||
return OwningObject->isBerkeleyData(SectionPimpl);
|
||||
}
|
||||
|
||||
inline relocation_iterator SectionRef::relocation_begin() const {
|
||||
return OwningObject->section_rel_begin(SectionPimpl);
|
||||
}
|
||||
|
@ -77,6 +77,14 @@ bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const {
|
||||
|
||||
bool ObjectFile::isSectionStripped(DataRefImpl Sec) const { return false; }
|
||||
|
||||
bool ObjectFile::isBerkeleyText(DataRefImpl Sec) const {
|
||||
return isSectionText(Sec);
|
||||
}
|
||||
|
||||
bool ObjectFile::isBerkeleyData(DataRefImpl Sec) const {
|
||||
return isSectionData(Sec);
|
||||
}
|
||||
|
||||
section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
|
||||
return section_iterator(SectionRef(Sec, this));
|
||||
}
|
||||
|
55
test/tools/llvm-size/X86/elf-sizes.test
Normal file
55
test/tools/llvm-size/X86/elf-sizes.test
Normal file
@ -0,0 +1,55 @@
|
||||
# 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: .unusual_name_for_code
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Size: 64
|
||||
- Name: .eh_frame
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC ]
|
||||
Size: 4
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_WRITE ]
|
||||
Size: 8
|
||||
- Name: .moar_stuff
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_WRITE ]
|
||||
Size: 128
|
||||
- Name: .text.but_not_really
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ ]
|
||||
Size: 256
|
||||
- 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, .unusual_name_for_code: 2 + 4 + 64 = 70
|
||||
# data is .data, .init_array, .moar_stuff: 8 + 32 + 128 = 168
|
||||
# bss is .bss: 1
|
||||
# total: 239
|
||||
# unaccounted for (not affecting total) is .debug_info, .text.but_not_really
|
||||
|
||||
# CHECK: text data bss dec
|
||||
# CHECK: 70 168 1 239
|
@ -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)
|
||||
|
@ -457,8 +457,8 @@ static void printObjectSectionSizes(ObjectFile *Obj) {
|
||||
// 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 isText = Section.isBerkeleyText();
|
||||
bool isData = Section.isBerkeleyData();
|
||||
bool isBSS = Section.isBSS();
|
||||
if (isText)
|
||||
total_text += size;
|
||||
|
Loading…
Reference in New Issue
Block a user