Skip to content

Commit 7570d38

Browse files
author
Georgii Rymar
committed
[yaml2obj/obj2yaml] - Add support for SHT_RELR sections.
Note: this is a reland with a trivial 2 lines fix in ELFState<ELFT>::writeSectionContent. It adds a check similar to ones we already have for other sections to fix the case revealed by bots, like http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast/builds/60744. The encoded sequence of Elf*_Relr entries in a SHT_RELR section looks like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ] i.e. start with an address, followed by any number of bitmaps. The address entry encodes 1 relocation. The subsequent bitmap entries encode up to 63(31) relocations each, at subsequent offsets following the last address entry. More information is here: https://github.com/llvm-mirror/llvm/blob/master/lib/Object/ELF.cpp#L272 This patch adds a support for these sections. Differential revision: https://reviews.llvm.org/D71872
1 parent 13f22f5 commit 7570d38

File tree

4 files changed

+95
-7
lines changed

4 files changed

+95
-7
lines changed

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ struct Chunk {
138138
Group,
139139
RawContent,
140140
Relocation,
141+
Relr,
141142
NoBits,
142143
Note,
143144
Hash,
@@ -440,6 +441,17 @@ struct RelocationSection : Section {
440441
}
441442
};
442443

444+
struct RelrSection : Section {
445+
Optional<std::vector<llvm::yaml::Hex64>> Entries;
446+
Optional<yaml::BinaryRef> Content;
447+
448+
RelrSection() : Section(ChunkKind::Relr) {}
449+
450+
static bool classof(const Chunk *S) {
451+
return S->Kind == ChunkKind::Relr;
452+
}
453+
};
454+
443455
struct SymtabShndxSection : Section {
444456
std::vector<uint32_t> Entries;
445457

llvm/lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ template <class ELFT> class ELFState {
110110
typedef typename ELFT::Rela Elf_Rela;
111111
typedef typename ELFT::Relr Elf_Relr;
112112
typedef typename ELFT::Dyn Elf_Dyn;
113+
typedef typename ELFT::uint uintX_t;
113114

114115
enum class SymtabType { Static, Dynamic };
115116

@@ -165,6 +166,9 @@ template <class ELFT> class ELFState {
165166
void writeSectionContent(Elf_Shdr &SHeader,
166167
const ELFYAML::RelocationSection &Section,
167168
ContiguousBlobAccumulator &CBA);
169+
void writeSectionContent(Elf_Shdr &SHeader,
170+
const ELFYAML::RelrSection &Section,
171+
ContiguousBlobAccumulator &CBA);
168172
void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group,
169173
ContiguousBlobAccumulator &CBA);
170174
void writeSectionContent(Elf_Shdr &SHeader,
@@ -454,6 +458,8 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
454458
writeSectionContent(SHeader, *S, CBA);
455459
} else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) {
456460
writeSectionContent(SHeader, *S, CBA);
461+
} else if (auto S = dyn_cast<ELFYAML::RelrSection>(Sec)) {
462+
writeSectionContent(SHeader, *S, CBA);
457463
} else if (auto S = dyn_cast<ELFYAML::Group>(Sec)) {
458464
writeSectionContent(SHeader, *S, CBA);
459465
} else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec)) {
@@ -770,10 +776,6 @@ void ELFState<ELFT>::writeSectionContent(
770776

771777
if (Section.EntSize)
772778
SHeader.sh_entsize = *Section.EntSize;
773-
else if (Section.Type == llvm::ELF::SHT_RELR)
774-
SHeader.sh_entsize = sizeof(Elf_Relr);
775-
else
776-
SHeader.sh_entsize = 0;
777779

778780
if (Section.Info)
779781
SHeader.sh_info = *Section.Info;
@@ -827,6 +829,33 @@ void ELFState<ELFT>::writeSectionContent(
827829
}
828830
}
829831

832+
template <class ELFT>
833+
void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
834+
const ELFYAML::RelrSection &Section,
835+
ContiguousBlobAccumulator &CBA) {
836+
raw_ostream &OS =
837+
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
838+
SHeader.sh_entsize =
839+
Section.EntSize ? uint64_t(*Section.EntSize) : sizeof(Elf_Relr);
840+
841+
if (Section.Content) {
842+
SHeader.sh_size = writeContent(OS, Section.Content, None);
843+
return;
844+
}
845+
846+
if (!Section.Entries)
847+
return;
848+
849+
for (llvm::yaml::Hex64 E : *Section.Entries) {
850+
if (!ELFT::Is64Bits && E > UINT32_MAX)
851+
reportError(Section.Name + ": the value is too large for 32-bits: 0x" +
852+
Twine::utohexstr(E));
853+
support::endian::write<uintX_t>(OS, E, ELFT::TargetEndianness);
854+
}
855+
856+
SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size();
857+
}
858+
830859
template <class ELFT>
831860
void ELFState<ELFT>::writeSectionContent(
832861
Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx,
@@ -889,7 +918,6 @@ template <class ELFT>
889918
void ELFState<ELFT>::writeSectionContent(
890919
Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section,
891920
ContiguousBlobAccumulator &CBA) {
892-
using uintX_t = typename ELFT::uint;
893921
raw_ostream &OS =
894922
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
895923

@@ -1115,8 +1143,6 @@ template <class ELFT>
11151143
void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
11161144
const ELFYAML::DynamicSection &Section,
11171145
ContiguousBlobAccumulator &CBA) {
1118-
typedef typename ELFT::uint uintX_t;
1119-
11201146
assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
11211147
"Section type is not SHT_DYNAMIC");
11221148

llvm/lib/ObjectYAML/ELFYAML.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,12 @@ static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
11011101
IO.mapOptional("Relocations", Section.Relocations);
11021102
}
11031103

1104+
static void sectionMapping(IO &IO, ELFYAML::RelrSection &Section) {
1105+
commonSectionMapping(IO, Section);
1106+
IO.mapOptional("Entries", Section.Entries);
1107+
IO.mapOptional("Content", Section.Content);
1108+
}
1109+
11041110
static void groupSectionMapping(IO &IO, ELFYAML::Group &Group) {
11051111
commonSectionMapping(IO, Group);
11061112
IO.mapOptional("Info", Group.Signature);
@@ -1200,6 +1206,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
12001206
Section.reset(new ELFYAML::RelocationSection());
12011207
sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
12021208
break;
1209+
case ELF::SHT_RELR:
1210+
if (!IO.outputting())
1211+
Section.reset(new ELFYAML::RelrSection());
1212+
sectionMapping(IO, *cast<ELFYAML::RelrSection>(Section.get()));
1213+
break;
12031214
case ELF::SHT_GROUP:
12041215
if (!IO.outputting())
12051216
Section.reset(new ELFYAML::Group());
@@ -1441,6 +1452,12 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
14411452
return {};
14421453
}
14431454

1455+
if (const auto *RS = dyn_cast<ELFYAML::RelrSection>(C.get())) {
1456+
if (RS->Entries && RS->Content)
1457+
return "\"Entries\" and \"Content\" can't be used together";
1458+
return {};
1459+
}
1460+
14441461
return {};
14451462
}
14461463

llvm/tools/obj2yaml/elf2yaml.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class ELFDumper {
2727
typedef typename ELFT::Word Elf_Word;
2828
typedef typename ELFT::Rel Elf_Rel;
2929
typedef typename ELFT::Rela Elf_Rela;
30+
using Elf_Relr = typename ELFT::Relr;
3031
using Elf_Nhdr = typename ELFT::Nhdr;
3132
using Elf_Note = typename ELFT::Note;
3233

@@ -66,6 +67,7 @@ class ELFDumper {
6667
dumpDependentLibrariesSection(const Elf_Shdr *Shdr);
6768
Expected<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr);
6869
Expected<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr);
70+
Expected<ELFYAML::RelrSection *> dumpRelrSection(const Elf_Shdr *Shdr);
6971
Expected<ELFYAML::RawContentSection *>
7072
dumpContentSection(const Elf_Shdr *Shdr);
7173
Expected<ELFYAML::SymtabShndxSection *>
@@ -251,6 +253,13 @@ template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
251253
Y->Chunks.emplace_back(*SecOrErr);
252254
break;
253255
}
256+
case ELF::SHT_RELR: {
257+
Expected<ELFYAML::RelrSection *> SecOrErr = dumpRelrSection(&Sec);
258+
if (!SecOrErr)
259+
return SecOrErr.takeError();
260+
Y->Chunks.emplace_back(*SecOrErr);
261+
break;
262+
}
254263
case ELF::SHT_GROUP: {
255264
Expected<ELFYAML::Group *> GroupOrErr = dumpGroup(&Sec);
256265
if (!GroupOrErr)
@@ -723,6 +732,30 @@ ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
723732
return S.release();
724733
}
725734

735+
template <class ELFT>
736+
Expected<ELFYAML::RelrSection *>
737+
ELFDumper<ELFT>::dumpRelrSection(const Elf_Shdr *Shdr) {
738+
auto S = std::make_unique<ELFYAML::RelrSection>();
739+
if (auto E = dumpCommonSection(Shdr, *S))
740+
return std::move(E);
741+
742+
if (Expected<ArrayRef<Elf_Relr>> Relrs = Obj.relrs(Shdr)) {
743+
S->Entries.emplace();
744+
for (Elf_Relr Rel : *Relrs)
745+
S->Entries->emplace_back(Rel);
746+
return S.release();
747+
} else {
748+
// Ignore. We are going to dump the data as raw content below.
749+
consumeError(Relrs.takeError());
750+
}
751+
752+
Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr);
753+
if (!ContentOrErr)
754+
return ContentOrErr.takeError();
755+
S->Content = *ContentOrErr;
756+
return S.release();
757+
}
758+
726759
template <class ELFT>
727760
Expected<ELFYAML::RawContentSection *>
728761
ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {

0 commit comments

Comments
 (0)