Index: llvm/trunk/lib/ObjectYAML/ELFEmitter.cpp =================================================================== --- llvm/trunk/lib/ObjectYAML/ELFEmitter.cpp +++ llvm/trunk/lib/ObjectYAML/ELFEmitter.cpp @@ -627,36 +627,24 @@ PHeader.p_offset = std::min(PHeader.p_offset, SHeader->sh_offset); } - // Find the maximum offset of the end of a section in order to set p_filesz, - // if not set explicitly. - if (YamlPhdr.FileSize) { - PHeader.p_filesz = *YamlPhdr.FileSize; - } else { - PHeader.p_filesz = 0; - for (Elf_Shdr *SHeader : Sections) { - uint64_t EndOfSection; - if (SHeader->sh_type == llvm::ELF::SHT_NOBITS) - EndOfSection = SHeader->sh_offset; - else - EndOfSection = SHeader->sh_offset + SHeader->sh_size; - uint64_t EndOfSegment = PHeader.p_offset + PHeader.p_filesz; - EndOfSegment = std::max(EndOfSegment, EndOfSection); - PHeader.p_filesz = EndOfSegment - PHeader.p_offset; - } - } + // Find the maximum offset of the end of a section in order to set p_filesz + // and p_memsz. When setting p_filesz, trailing SHT_NOBITS sections are not + // counted. + uint64_t FileOffset = PHeader.p_offset, MemOffset = PHeader.p_offset; + for (Elf_Shdr *SHeader : Sections) { + uint64_t End = SHeader->sh_offset + SHeader->sh_size; + MemOffset = std::max(MemOffset, End); - // If not set explicitly, find the memory size by adding the size of - // sections at the end of the segment. These should be empty (size of zero) - // and NOBITS sections. - if (YamlPhdr.MemSize) { - PHeader.p_memsz = *YamlPhdr.MemSize; - } else { - PHeader.p_memsz = PHeader.p_filesz; - for (Elf_Shdr *SHeader : Sections) - if (SHeader->sh_offset == PHeader.p_offset + PHeader.p_filesz) - PHeader.p_memsz += SHeader->sh_size; + if (SHeader->sh_type != llvm::ELF::SHT_NOBITS) + FileOffset = std::max(FileOffset, End); } + // Set the file size and the memory size if not set explicitly. + PHeader.p_filesz = YamlPhdr.FileSize ? uint64_t(*YamlPhdr.FileSize) + : FileOffset - PHeader.p_offset; + PHeader.p_memsz = YamlPhdr.MemSize ? uint64_t(*YamlPhdr.MemSize) + : MemOffset - PHeader.p_offset; + // Set the alignment of the segment to be the same as the maximum alignment // of the sections with the same offset so that by default the segment // has a valid and sensible alignment. Index: llvm/trunk/test/tools/yaml2obj/program-header-size-offset.yaml =================================================================== --- llvm/trunk/test/tools/yaml2obj/program-header-size-offset.yaml +++ llvm/trunk/test/tools/yaml2obj/program-header-size-offset.yaml @@ -11,7 +11,7 @@ # CHECK: Offset: 0x2000 # CHECK: FileSize: 6 -# CHECK: MemSize: 6 +# CHECK: MemSize: 4 # CHECK: Offset: 0x2000 # CHECK: FileSize: 4 @@ -28,6 +28,10 @@ # CHECK: Offset: 0x3000 # CHECK: FileSize: 3 # CHECK: MemSize: 2 + +# CHECK: Offset: 0x2004 +# CHECK: FileSize: 4 +# CHECK: MemSize: 6 # CHECK: ] !ELF @@ -40,14 +44,26 @@ - Name: .text Type: SHT_PROGBITS Size: 4 + ShOffset: 0x1000 AddressAlign: 0x1000 - Name: .rodata Type: SHT_PROGBITS Size: 4 + ShOffset: 0x2000 AddressAlign: 0x1000 - Name: .data Type: SHT_PROGBITS + ShOffset: 0x2004 Size: 4 + - Name: .nobits1 + Type: SHT_NOBITS + ShOffset: 0x2008 + Size: 1 + - Name: .nobits2 + Type: SHT_NOBITS + # Intentionally set to 0x2009 though the previous section is SHT_NOBITS. + ShOffset: 0x2009 + Size: 1 ProgramHeaders: # Program header with no sections. - Type: 0x6abcdef0 # arbitrary type @@ -83,3 +99,10 @@ MemSize: 2 Sections: - Section: .data + # Program header with 2 SHT_NOBITS sections. + - Type: 0x6abcdef0 + Offset: 0x2004 + Sections: + - Section: .data + - Section: .nobits1 + - Section: .nobits2