From 080d7a819f4fd04883e6ac2e13617f5c8a14be6d Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Wed, 8 Jul 2015 10:12:40 +0000 Subject: [PATCH] [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 --- test/Object/yaml2obj-elf-alignment.yaml | 53 +++++++++++++++++++++++++ tools/yaml2obj/yaml2elf.cpp | 23 ++++++----- 2 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 test/Object/yaml2obj-elf-alignment.yaml 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; -- 2.34.1