1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[yaml2obj] - Implement the "Offset" property for the Fill Chunk.

Similar to a regular section chunk, a Fill should have this property.
This patch implements it.

Differential revision: https://reviews.llvm.org/D80190
This commit is contained in:
Georgii Rymar 2020-05-18 20:46:28 +03:00
parent 3a4cea3f74
commit 2852155a31
4 changed files with 51 additions and 9 deletions

View File

@ -161,6 +161,7 @@ struct Chunk {
ChunkKind Kind; ChunkKind Kind;
StringRef Name; StringRef Name;
Optional<llvm::yaml::Hex64> Offset;
Chunk(ChunkKind K) : Kind(K) {} Chunk(ChunkKind K) : Kind(K) {}
virtual ~Chunk(); virtual ~Chunk();
@ -173,7 +174,6 @@ struct Section : public Chunk {
StringRef Link; StringRef Link;
llvm::yaml::Hex64 AddressAlign; llvm::yaml::Hex64 AddressAlign;
Optional<llvm::yaml::Hex64> EntSize; Optional<llvm::yaml::Hex64> EntSize;
Optional<llvm::yaml::Hex64> Offset;
// Usually sections are not created implicitly, but loaded from YAML. // Usually sections are not created implicitly, but loaded from YAML.
// When they are, this flag is used to signal about that. // When they are, this flag is used to signal about that.
@ -213,11 +213,6 @@ struct Fill : Chunk {
Optional<yaml::BinaryRef> Pattern; Optional<yaml::BinaryRef> Pattern;
llvm::yaml::Hex64 Size; llvm::yaml::Hex64 Size;
// We have to remember the offset of the fill, because it does not have
// a corresponding section header, unlike a section. We might need this
// information when writing the output.
uint64_t ShOffset;
Fill() : Chunk(ChunkKind::Fill) {} Fill() : Chunk(ChunkKind::Fill) {}
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; } static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }

View File

@ -428,8 +428,8 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
size_t SecNdx = -1; size_t SecNdx = -1;
for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) { for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) {
if (auto S = dyn_cast<ELFYAML::Fill>(D.get())) { if (ELFYAML::Fill *S = dyn_cast<ELFYAML::Fill>(D.get())) {
S->ShOffset = alignToOffset(CBA, /*Align=*/1, /*Offset=*/None); S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset);
writeFill(*S, CBA); writeFill(*S, CBA);
LocationCounter += S->Size; LocationCounter += S->Size;
continue; continue;
@ -755,7 +755,7 @@ ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,
} }
if (ELFYAML::Fill *Fill = NameToFill.lookup(SecName.Section)) { if (ELFYAML::Fill *Fill = NameToFill.lookup(SecName.Section)) {
Ret.push_back({Fill->ShOffset, Fill->Size, llvm::ELF::SHT_PROGBITS, Ret.push_back({*Fill->Offset, Fill->Size, llvm::ELF::SHT_PROGBITS,
/*ShAddrAlign=*/1}); /*ShAddrAlign=*/1});
continue; continue;
} }

View File

@ -1174,6 +1174,7 @@ static void sectionMapping(IO &IO, ELFYAML::AddrsigSection &Section) {
static void fillMapping(IO &IO, ELFYAML::Fill &Fill) { static void fillMapping(IO &IO, ELFYAML::Fill &Fill) {
IO.mapOptional("Name", Fill.Name, StringRef()); IO.mapOptional("Name", Fill.Name, StringRef());
IO.mapOptional("Pattern", Fill.Pattern); IO.mapOptional("Pattern", Fill.Pattern);
IO.mapOptional("Offset", Fill.Offset);
IO.mapRequired("Size", Fill.Size); IO.mapRequired("Size", Fill.Size);
} }

View File

@ -294,3 +294,49 @@ ProgramHeaders:
- Type: PT_LOAD - Type: PT_LOAD
Sections: Sections:
- Section: fill - Section: fill
## Show that we can use the "Offset" key to set an arbitrary offset for a Fill.
## 0x41 is the minimal possible valid offset for Fill,
## because the .foo section of size 0x1 is placed at 0x40.
# RUN: yaml2obj --docnum=11 -DOFFSET=0x41 -o %t11 %s
# RUN: llvm-readelf --section-headers %t11 | FileCheck %s --check-prefix=OFFSET-MIN
## 0x123 is an arbitrary offset.
# RUN: yaml2obj --docnum=11 -DOFFSET=0x123 -o %t12 %s
# RUN: llvm-readelf --section-headers %t12 | FileCheck %s --check-prefix=OFFSET
# OFFSET-MIN: Section Headers:
# OFFSET-MIN-NEXT: [Nr] Name Type Address Off Size
# OFFSET-MIN-NEXT: [ 0] NULL 0000000000000000 000000 000000
# OFFSET-MIN-NEXT: [ 1] .foo PROGBITS 0000000000000000 000040 000001
# OFFSET-MIN-NEXT: [ 2] .bar PROGBITS 0000000000000000 000042 000001
# OFFSET: Section Headers:
# OFFSET-NEXT: [Nr] Name Type Address Off Size
# OFFSET-NEXT: [ 0] NULL 0000000000000000 000000 000000
# OFFSET-NEXT: [ 1] .foo PROGBITS 0000000000000000 000040 000001
# OFFSET-NEXT: [ 2] .bar PROGBITS 0000000000000000 000124 000001
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .foo
Type: SHT_PROGBITS
Size: 1
- Type: Fill
Pattern: "AA"
Size: 0x1
Offset: [[OFFSET]]
- Name: .bar
Type: SHT_PROGBITS
Size: 1
## Show that the "Offset" value can't go backward.
# RUN: not yaml2obj --docnum=11 -DOFFSET=0x40 2>&1 %s | FileCheck %s --check-prefix=OFFSET-ERR
# OFFSET-ERR: error: the 'Offset' value (0x40) goes backward