From: Simon Atanasyan Date: Wed, 8 Jul 2015 10:12:40 +0000 (+0000) Subject: [yaml2obj] Align section content using AddressAlign field's value X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=080d7a819f4fd04883e6ac2e13617f5c8a14be6d;p=oota-llvm.git [yaml2obj] Align section content using AddressAlign field's value Use AddressAlign field's value to properly align sections content in the yaml2obj tool. Before this change the yaml2obj ignored AddressAlign and always aligned section on 16 bytes boundary. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241674 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Object/yaml2obj-elf-alignment.yaml b/test/Object/yaml2obj-elf-alignment.yaml new file mode 100644 index 00000000000..8f2f985177f --- /dev/null +++ b/test/Object/yaml2obj-elf-alignment.yaml @@ -0,0 +1,53 @@ +# Check that yaml2obj takes in account section AddressAlign field. + +# RUN: yaml2obj -format=elf %s > %t +# RUN: llvm-readobj -s %t | FileCheck %s + +# CHECK: Section { +# CHECK: Index: 2 +# CHECK-NEXT: Name: .data +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x{{[0-9A-F]*}}00 +# CHECK-NEXT: Size: 4 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 256 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } + +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [ EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32 ] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 8 + Size: 4 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 256 + Size: 4 + +Symbols: + Global: + - Name: T0 + Type: STT_FUNC + Section: .text + Size: 4 + - Name: D0 + Type: STT_OBJECT + Section: .data + Size: 4 +... diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index 2cbc3380358..4940e837367 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -35,6 +35,8 @@ class ContiguousBlobAccumulator { /// \returns The new offset. uint64_t padToAlignment(unsigned Align) { + if (Align == 0) + Align = 1; uint64_t CurrentOffset = InitialOffset + OS.tell(); uint64_t AlignedOffset = RoundUpToAlignment(CurrentOffset, Align); for (; CurrentOffset != AlignedOffset; ++CurrentOffset) @@ -46,7 +48,7 @@ public: ContiguousBlobAccumulator(uint64_t InitialOffset_) : InitialOffset(InitialOffset_), Buf(), OS(Buf) {} template - raw_ostream &getOSAndAlignedOffset(Integer &Offset, unsigned Align = 16) { + raw_ostream &getOSAndAlignedOffset(Integer &Offset, unsigned Align) { Offset = padToAlignment(Align); return OS; } @@ -246,7 +248,7 @@ bool ELFState::initSectionHeaders(std::vector &SHeaders, SHeader.sh_size = S->Size; // SHT_NOBITS section does not have content // so just to setup the section offset. - CBA.getOSAndAlignedOffset(SHeader.sh_offset); + CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); } else llvm_unreachable("Unknown section type"); @@ -287,8 +289,9 @@ void ELFState::initSymtabSectionHeader(Elf_Shdr &SHeader, addSymbols(Doc.Symbols.Global, Syms, ELF::STB_GLOBAL); addSymbols(Doc.Symbols.Weak, Syms, ELF::STB_WEAK); - writeArrayData(CBA.getOSAndAlignedOffset(SHeader.sh_offset), - makeArrayRef(Syms)); + writeArrayData( + CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign), + makeArrayRef(Syms)); SHeader.sh_size = arrayDataSize(makeArrayRef(Syms)); } @@ -299,7 +302,8 @@ void ELFState::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, zero(SHeader); SHeader.sh_name = DotShStrtab.getOffset(Name); SHeader.sh_type = ELF::SHT_STRTAB; - CBA.getOSAndAlignedOffset(SHeader.sh_offset) << STB.data(); + CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign) + << STB.data(); SHeader.sh_size = STB.data().size(); SHeader.sh_addralign = 1; } @@ -337,7 +341,8 @@ ELFState::writeSectionContent(Elf_Shdr &SHeader, ContiguousBlobAccumulator &CBA) { assert(Section.Size >= Section.Content.binary_size() && "Section size and section content are inconsistent"); - raw_ostream &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset); + raw_ostream &OS = + CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); Section.Content.writeAsBinary(OS); for (auto i = Section.Content.binary_size(); i < Section.Size; ++i) OS.write(0); @@ -364,7 +369,7 @@ ELFState::writeSectionContent(Elf_Shdr &SHeader, SHeader.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); SHeader.sh_size = SHeader.sh_entsize * Section.Relocations.size(); - auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset); + auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); for (const auto &Rel : Section.Relocations) { unsigned SymIdx = 0; @@ -402,7 +407,7 @@ bool ELFState::writeSectionContent(Elf_Shdr &SHeader, SHeader.sh_entsize = sizeof(Elf_Word); SHeader.sh_size = SHeader.sh_entsize * Section.Members.size(); - auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset); + auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); for (auto member : Section.Members) { Elf_Word SIdx; @@ -433,7 +438,7 @@ bool ELFState::writeSectionContent(Elf_Shdr &SHeader, SHeader.sh_entsize = sizeof(Flags); SHeader.sh_size = SHeader.sh_entsize; - auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset); + auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); Flags.version = Section.Version; Flags.isa_level = Section.ISALevel; Flags.isa_rev = Section.ISARevision;