mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 15:10:33 +00:00
[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
This commit is contained in:
parent
8bde857088
commit
080d7a819f
53
test/Object/yaml2obj-elf-alignment.yaml
Normal file
53
test/Object/yaml2obj-elf-alignment.yaml
Normal file
@ -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
|
||||
...
|
@ -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 <class Integer>
|
||||
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<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &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<ELFT>::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<ELFT>::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<ELFT>::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<ELFT>::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<ELFT>::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<ELFT>::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;
|
||||
|
Loading…
Reference in New Issue
Block a user