Index: include/llvm/ObjectYAML/ELFYAML.h =================================================================== --- include/llvm/ObjectYAML/ELFYAML.h +++ include/llvm/ObjectYAML/ELFYAML.h @@ -151,8 +151,8 @@ }; struct RawContentSection : Section { - yaml::BinaryRef Content; - llvm::yaml::Hex64 Size; + Optional Content; + Optional Size; llvm::yaml::Hex64 Info; RawContentSection() : Section(SectionKind::RawContent) {} Index: lib/ObjectYAML/ELFYAML.cpp =================================================================== --- lib/ObjectYAML/ELFYAML.cpp +++ lib/ObjectYAML/ELFYAML.cpp @@ -914,7 +914,7 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) { commonSectionMapping(IO, Section); IO.mapOptional("Content", Section.Content); - IO.mapOptional("Size", Section.Size, Hex64(Section.Content.binary_size())); + IO.mapOptional("Size", Section.Size); IO.mapOptional("Info", Section.Info, Hex64(0)); } @@ -1042,9 +1042,12 @@ StringRef MappingTraits>::validate( IO &io, std::unique_ptr &Section) { const auto *RawSection = dyn_cast(Section.get()); - if (!RawSection || RawSection->Size >= RawSection->Content.binary_size()) - return StringRef(); - return "Section size must be greater or equal to the content size"; + if (!RawSection) + return {}; + if (RawSection->Size && RawSection->Content && + (uint64_t)(*RawSection->Size) < RawSection->Content->binary_size()) + return "Section size must be greater or equal to the content size"; + return {}; } namespace { Index: test/Object/obj2yaml.test =================================================================== --- test/Object/obj2yaml.test +++ test/Object/obj2yaml.test @@ -389,7 +389,6 @@ ELF-MIPSEL-NEXT: Type: SHT_PROGBITS ELF-MIPSEL-NEXT: Flags: [ SHF_WRITE, SHF_ALLOC ] ELF-MIPSEL-NEXT: AddressAlign: 0x0000000000000004 -ELF-MIPSEL-NEXT: Content: '' ELF-MIPSEL-NEXT: - Name: .bss ELF-MIPSEL-NEXT: Type: SHT_NOBITS ELF-MIPSEL-NEXT: Flags: [ SHF_WRITE, SHF_ALLOC ] @@ -398,7 +397,6 @@ ELF-MIPSEL-NEXT: - Name: .mdebug.abi32 ELF-MIPSEL-NEXT: Type: SHT_PROGBITS ELF-MIPSEL-NEXT: AddressAlign: 0x0000000000000001 -ELF-MIPSEL-NEXT: Content: '' ELF-MIPSEL-NEXT: - Name: .rodata.str1.1 ELF-MIPSEL-NEXT: Type: SHT_PROGBITS ELF-MIPSEL-NEXT: Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ] @@ -477,7 +475,6 @@ ELF-MIPS64EL-NEXT: Type: SHT_PROGBITS ELF-MIPS64EL-NEXT: Flags: [ SHF_ALLOC, SHF_EXECINSTR ] ELF-MIPS64EL-NEXT: AddressAlign: 0x0000000000000010 -ELF-MIPS64EL-NEXT: Content: '' ELF-MIPS64EL-NEXT: - Name: .data ELF-MIPS64EL-NEXT: Type: SHT_PROGBITS ELF-MIPS64EL-NEXT: Flags: [ SHF_WRITE, SHF_ALLOC ] @@ -506,7 +503,6 @@ ELF-MIPS64EL-NEXT: - Name: .pdr ELF-MIPS64EL-NEXT: Type: SHT_PROGBITS ELF-MIPS64EL-NEXT: AddressAlign: 0x0000000000000004 -ELF-MIPS64EL-NEXT: Content: '' ELF-MIPS64EL-NEXT: Symbols: ELF-MIPS64EL-NEXT: - Name: .text ELF-MIPS64EL-NEXT: Type: STT_SECTION @@ -550,7 +546,6 @@ ELF-X86-64-NEXT: Type: SHT_PROGBITS ELF-X86-64-NEXT: Address: 0x0000000000000033 ELF-X86-64-NEXT: AddressAlign: 0x0000000000000001 -ELF-X86-64-NEXT: Content: '' ELF-X86-64-NEXT: - Name: .rela.text ELF-X86-64-NEXT: Type: SHT_RELA ELF-X86-64-NEXT: Address: 0x0000000000000038 @@ -610,7 +605,6 @@ ELF-AVR-NEXT: Flags: [ SHF_WRITE, SHF_ALLOC ] ELF-AVR-NEXT: Address: 0x0000000000800060 ELF-AVR-NEXT: AddressAlign: 0x0000000000000001 -ELF-AVR-NEXT: Content: '' ELF-AVR-NEXT: Symbols: ELF-AVR-NEXT: - Name: .text ELF-AVR-NEXT: Type: STT_SECTION @@ -706,7 +700,6 @@ ELF-X86-64-UNWIND-NEXT: Type: SHT_X86_64_UNWIND ELF-X86-64-UNWIND-NEXT: Flags: [ SHF_ALLOC ] ELF-X86-64-UNWIND-NEXT: AddressAlign: 0x0000000000000001 -ELF-X86-64-UNWIND-NEXT: Content: '' RUN: not obj2yaml %t.blah 2>&1 | FileCheck --check-prefix=ENOENT %s ENOENT: Error reading file: {{.*}}.blah: {{[Nn]}}o such file or directory Index: test/tools/obj2yaml/elf-shinfo.yaml =================================================================== --- test/tools/obj2yaml/elf-shinfo.yaml +++ test/tools/obj2yaml/elf-shinfo.yaml @@ -5,7 +5,6 @@ # CHECK: - Name: .test # CHECK-NEXT: Type: SHT_PROGBITS -# CHECK-NEXT: Content: '' # CHECK-NEXT: Info: 0x000000000000002A --- !ELF Index: test/tools/yaml2obj/section-size-content.yaml =================================================================== --- /dev/null +++ test/tools/yaml2obj/section-size-content.yaml @@ -0,0 +1,146 @@ +## For regular sections, it is common to specify `Size` and/or `Content` fields in YAML. +## Here we test the behavior in different cases. + +## In this case, we have both `Content` and `Size` fields specified and `Size` +## is less than content size. Check we report an error. + +# RUN: not yaml2obj --docnum=1 %s -o %t 2>&1 | FileCheck %s --check-prefix=ERR +# ERR: error: Section size must be greater or equal to the content size + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + Content: "FF" + Size: 0 + +## In this case, we have both `Content` and `Size` fields specified and +## `Size` is equal to the content size. We check that this is allowed and +## the output section has a correct size value. + +# RUN: yaml2obj --docnum=2 %s -o %t +# RUN: llvm-readobj %t --sections | FileCheck %s --check-prefix=CASE2 + +# CASE2: Name: .foo +# CASE2-NEXT: Type: SHT_PROGBITS +# CASE2-NEXT: Flags [ +# CASE2-NEXT: ] +# CASE2-NEXT: Address: 0x0 +# CASE2-NEXT: Offset: 0x180 +# CASE2-NEXT: Size: 1 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + Content: "FF" + Size: 1 + +## Check we can specify only `Content`. + +# RUN: yaml2obj --docnum=3 %s -o %t +# RUN: llvm-readobj %t --sections | FileCheck %s --check-prefix=CASE2 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + Content: "FF" + +## Check we can specify only `Size`. + +# RUN: yaml2obj --docnum=4 %s -o %t +# RUN: llvm-readobj %t --sections | FileCheck %s --check-prefix=CASE2 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + Size: 1 + +## Check we can specify both `Size` and `Content` when size is greater +## than or equal to content size. In this case the zeroes padding is +## added after content specified. (Check "greater then" case here). + +# RUN: yaml2obj --docnum=5 %s -o %t +# RUN: llvm-objdump %t -s | FileCheck %s --check-prefix=CASE3 + +# CASE3: Contents of section .foo: +# CASE3-NEXT: 0000 ff0000 ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + Content: "FF" + Size: 3 + +## Check we can specify both `Size` and `Content` when size is greater +## than or equal to content size. In this case the zeroes padding is +## added after content specified. (Check "equal" case here). + +# RUN: yaml2obj --docnum=6 %s -o %t +# RUN: llvm-objdump %t -s | FileCheck %s --check-prefix=CASE4 + +# CASE4: Contents of section .foo: +# CASE4-NEXT: 0000 ff . + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + Content: "FF" + Size: 1 + +## Check we emit an empty section if neither 'Content' or 'Size' were set. + +# RUN: yaml2obj --docnum=7 %s -o %t +# RUN: llvm-readobj %t --sections | FileCheck %s --check-prefix=CASE5 + +# CASE5: Name: .foo +# CASE5-NEXT: Type: SHT_PROGBITS +# CASE5-NEXT: Flags [ +# CASE5-NEXT: ] +# CASE5-NEXT: Address: 0x0 +# CASE5-NEXT: Offset: 0x180 +# CASE5-NEXT: Size: 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS Index: test/tools/yaml2obj/strtab-implicit-sections-size-content.yaml =================================================================== --- /dev/null +++ test/tools/yaml2obj/strtab-implicit-sections-size-content.yaml @@ -0,0 +1,123 @@ +## For implicit string table sections, `Size` and/or `Content` fields can also +## be specified in YAML. Here we test the behavior in different cases. + +## When no `Size` or `Content` is specified for string table section, +## yaml2obj writes the default implicitly created string table as a content. + +# RUN: yaml2obj --docnum=1 %s -o %t +# RUN: llvm-objdump %t -s | FileCheck %s --check-prefix=CASE1 + +# CASE1: Contents of section .strtab: +# CASE1-NEXT: 0000 00666f6f 00 .foo. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .strtab + Type: SHT_STRTAB +## Used to trigger adding string `foo` to the string table section. +Symbols: + - Name: foo + +## For string table sections, `Size` can be used along to override the +## implicit string table data. Content is filled by zeroes in this case. + +# RUN: yaml2obj --docnum=2 %s -o %t +# RUN: llvm-objdump %t -s -h | FileCheck %s --check-prefix=CASE2 + +# CASE2: Idx Name Size +# CASE2: 1 .strtab 00000002 + +# CASE2: Contents of section .strtab: +# CASE2-NEXT: 0000 0000 .. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .strtab + Type: SHT_STRTAB + Size: 2 +## Used to trigger adding string `foo` to the string table section. +Symbols: + - Name: foo + +## For string table sections, `Content` can be used along to override the +## implicit string table data. + +# RUN: yaml2obj --docnum=3 %s -o %t +# RUN: llvm-objdump %t -s | FileCheck %s --check-prefix=CASE3 + +# CASE3: Contents of section .strtab: +# CASE3-NEXT: 0000 0102 .. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .strtab + Type: SHT_STRTAB + Content: "0102" +## Used to trigger adding string `foo` to the string table section. +Symbols: + - Name: foo + +## For string table sections, check we can specify both `Size` and `Content` +## when size is greater than or equal to content size. In this case the zeroes +## padding is added after content specified. (Check "greater then" case here) + +# RUN: yaml2obj --docnum=4 %s -o %t +# RUN: llvm-objdump %t -s | FileCheck %s --check-prefix=CASE4 + +# CASE4: Contents of section .strtab: +# CASE4-NEXT: 0000 010200 ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .strtab + Type: SHT_STRTAB + Content: "0102" + Size: 3 +## Used to trigger adding string `foo` to the string table section. +Symbols: + - Name: foo + +## For string table sections, check we can specify both `Size` and `Content` +## when size is greater than or equal to content size. In this case the zeroes +## padding is added after content specified. (Check "equal" case here) + +# RUN: yaml2obj --docnum=5 %s -o %t +# RUN: llvm-objdump %t -s | FileCheck %s --check-prefix=CASE5 + +# CASE5: Contents of section .strtab: +# CASE5-NEXT: 0000 0102 .. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .strtab + Type: SHT_STRTAB + Content: "0102" + Size: 2 +## Used to trigger adding string `foo` to the string table section. +Symbols: + - Name: foo Index: test/tools/yaml2obj/symtab-implicit-sections-size-content.yaml =================================================================== --- /dev/null +++ test/tools/yaml2obj/symtab-implicit-sections-size-content.yaml @@ -0,0 +1,145 @@ +## For implicit symbol table sections, `Size` and/or `Content` fields can also +## be specified in YAML. Here we test the behavior in different cases. + +## When no `Size` or `Content` is specified for symbol table section, +## yaml2obj writes the default implicitly created symbol table as a content. +# RUN: yaml2obj --docnum=1 %s -o %t +# RUN: llvm-readelf %t -s | FileCheck %s --check-prefix=CASE1 + +# CASE1: Symbol table '.symtab' contains 2 entries: +# CASE1-NEXT: Num: Value Size Type Bind Vis Ndx Name +# CASE1-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND +# CASE1-NEXT: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND foo +# CASE1-EMPTY: + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB +Symbols: + - Name: foo + +## Specifying both `Size` and symbols at the same time is not allowed. +# RUN: not yaml2obj --docnum=2 %s -o %t 2>&1 | FileCheck %s --check-prefix=CASE2 + +# CASE2: error: Cannot specify both `Size` and `Symbols` for symbol table section '.symtab'. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Size: 0x100 +Symbols: + - Name: foo + +## Specifying both `Content` and symbols at the same time is not allowed. +# RUN: not yaml2obj --docnum=3 %s -o %t 2>&1 | FileCheck %s --check-prefix=CASE3 + +# CASE3: error: Cannot specify both `Content` and `Symbols` for symbol table section '.symtab'. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Content: "00" +Symbols: + - Name: foo + +## Check we can use just `Content` to emit the custom data in the symbol table section. +# RUN: yaml2obj --docnum=4 %s -o %t +# RUN: llvm-objdump %t -s | FileCheck %s --check-prefix=CASE4 + +# CASE4: Contents of section .symtab: +# CASE4-NEXT: 0000 0123 .# +# CASE4-NEXT: Contents of + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Content: "0123" + +## Check we can use just `Size` to emit the custom data filled with zeroes +## in the symbol table section. +# RUN: yaml2obj --docnum=5 %s -o %t +# RUN: llvm-objdump %t -s | FileCheck %s --check-prefix=CASE5 + +# CASE5: Contents of section .symtab: +# CASE5-NEXT: 0000 00000000 00 ..... +# CASE5-NEXT: Contents of + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Size: 5 + +## Check we can specify both `Size` and `Content` when size is greater +## than or equal to content size. In this case the zeroes padding is +## added after content specified. (Check "greater then" case here). +# RUN: yaml2obj --docnum=6 %s -o %t +# RUN: llvm-objdump %t -s | FileCheck %s --check-prefix=CASE6 + +# CASE6: Contents of section .symtab: +# CASE6-NEXT: 0000 01230000 .#.. +# CASE6-NEXT: Contents of + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Content: "0123" + Size: 4 + +## Check we can specify both `Size` and `Content` when size is greater +## than or equal to content size. In this case the zeroes padding is +## added after content specified. (Check "equal" case here). + +# RUN: yaml2obj --docnum=7 %s -o %t +# RUN: llvm-objdump %t -s | FileCheck %s --check-prefix=CASE7 + +# CASE7: Contents of section .symtab: +# CASE7-NEXT: 0000 0123 .# +# CASE7-NEXT: Contents of + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Content: "0123" + Size: 2 Index: tools/obj2yaml/elf2yaml.cpp =================================================================== --- tools/obj2yaml/elf2yaml.cpp +++ tools/obj2yaml/elf2yaml.cpp @@ -438,10 +438,10 @@ auto ContentOrErr = Obj.getSectionContents(Shdr); if (!ContentOrErr) return errorToErrorCode(ContentOrErr.takeError()); - S->Content = yaml::BinaryRef(ContentOrErr.get()); - S->Size = S->Content.binary_size(); + ArrayRef Content = *ContentOrErr; + if (!Content.empty()) + S->Content = yaml::BinaryRef(Content); S->Info = Shdr->sh_info; - return S.release(); } Index: tools/yaml2obj/yaml2elf.cpp =================================================================== --- tools/yaml2obj/yaml2elf.cpp +++ tools/yaml2obj/yaml2elf.cpp @@ -380,26 +380,57 @@ return Symbols.size(); } +static uint64_t writeRawSectionData(raw_ostream &OS, + const ELFYAML::RawContentSection &RawSec) { + size_t ContentSize = 0; + if (RawSec.Content) { + RawSec.Content->writeAsBinary(OS); + ContentSize = RawSec.Content->binary_size(); + } + + if (!RawSec.Size) + return ContentSize; + + OS.write_zeros(*RawSec.Size - ContentSize); + return *RawSec.Size; +} + template void ELFState::initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType, ContiguousBlobAccumulator &CBA, ELFYAML::Section *YAMLSec) { - zero(SHeader); + bool IsStatic = STType == SymtabType::Static; + const auto &Symbols = IsStatic ? Doc.Symbols : Doc.DynamicSymbols; + + ELFYAML::RawContentSection *RawSec = + dyn_cast_or_null(YAMLSec); + if (RawSec && !Symbols.empty() && (RawSec->Content || RawSec->Size)) { + if (RawSec->Content) + WithColor::error() << "Cannot specify both `Content` and " + + (IsStatic ? Twine("`Symbols`") + : Twine("`DynamicSymbols`")) + + " for symbol table section '" + << RawSec->Name << "'.\n"; + if (RawSec->Size) + WithColor::error() << "Cannot specify both `Size` and " + + (IsStatic ? Twine("`Symbols`") + : Twine("`DynamicSymbols`")) + + " for symbol table section '" + << RawSec->Name << "'.\n"; + exit(1); + } + + zero(SHeader); SHeader.sh_name = DotShStrtab.getOffset(IsStatic ? ".symtab" : ".dynsym"); SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM; SHeader.sh_link = IsStatic ? getDotStrTabSecNo() : getDotDynStrSecNo(); if (!IsStatic) SHeader.sh_flags |= ELF::SHF_ALLOC; - // One greater than symbol table index of the last local symbol. - const auto &Symbols = IsStatic ? Doc.Symbols : Doc.DynamicSymbols; - // If the symbol table section is explicitly described in the YAML // then we should set the fields requested. - ELFYAML::RawContentSection *RawSec = - dyn_cast_or_null(YAMLSec); SHeader.sh_info = RawSec ? (unsigned)RawSec->Info : findFirstNonGlobal(Symbols) + 1; SHeader.sh_entsize = (YAMLSec && YAMLSec->EntSize) @@ -408,26 +439,24 @@ SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8; SHeader.sh_addr = YAMLSec ? (uint64_t)YAMLSec->Address : 0; - if (RawSec && RawSec->Content.binary_size()) { - RawSec->Content.writeAsBinary( - CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign)); - SHeader.sh_size = RawSec->Size; - } else { - std::vector Syms; - { - // Ensure STN_UNDEF is present - Elf_Sym Sym; - zero(Sym); - Syms.push_back(Sym); - } - - addSymbols(Symbols, Syms, IsStatic ? DotStrtab : DotDynstr); + auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); + if (RawSec && (RawSec->Content || RawSec->Size)) { + assert(Symbols.empty()); + SHeader.sh_size = writeRawSectionData(OS, *RawSec); + return; + } - writeArrayData( - CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign), - makeArrayRef(Syms)); - SHeader.sh_size = arrayDataSize(makeArrayRef(Syms)); + std::vector Syms; + { + // Ensure STN_UNDEF is present + Elf_Sym Sym; + zero(Sym); + Syms.push_back(Sym); } + + addSymbols(Symbols, Syms, IsStatic ? DotStrtab : DotDynstr); + writeArrayData(OS, makeArrayRef(Syms)); + SHeader.sh_size = arrayDataSize(makeArrayRef(Syms)); } template @@ -442,13 +471,12 @@ ELFYAML::RawContentSection *RawSec = dyn_cast_or_null(YAMLSec); - if (RawSec && RawSec->Content.binary_size()) { - RawSec->Content.writeAsBinary( - CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign)); - SHeader.sh_size = RawSec->Size; + + auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); + if (RawSec && (RawSec->Content || RawSec->Size)) { + SHeader.sh_size = writeRawSectionData(OS, *RawSec); } else { - STB.write( - CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign)); + STB.write(OS); SHeader.sh_size = STB.getSize(); } @@ -580,12 +608,9 @@ bool ELFState::writeSectionContent( Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, ContiguousBlobAccumulator &CBA) { - assert(Section.Size >= Section.Content.binary_size() && - "Section size and section content are inconsistent"); raw_ostream &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); - Section.Content.writeAsBinary(OS); - OS.write_zeros(Section.Size - Section.Content.binary_size()); + SHeader.sh_size = writeRawSectionData(OS, Section); if (Section.EntSize) SHeader.sh_entsize = *Section.EntSize; @@ -593,7 +618,6 @@ SHeader.sh_entsize = sizeof(Elf_Relr); else SHeader.sh_entsize = 0; - SHeader.sh_size = Section.Size; SHeader.sh_info = Section.Info; return true; }