Skip to content

Commit feeb81a

Browse files
committed
fixup! [Object, ELF] Implement PN_XNUM extension for program headers
1 parent 389b52c commit feeb81a

File tree

1 file changed

+20
-33
lines changed
  • llvm/include/llvm/Object

1 file changed

+20
-33
lines changed

llvm/include/llvm/Object/ELF.h

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -278,10 +278,14 @@ class ELFFile {
278278
std::vector<Elf_Shdr> FakeSections;
279279
SmallString<0> FakeSectionStrings;
280280

281-
// According to the ELF gABI, these three fields can be recorded in section 0
282-
// when possible. Therefore, we store this information when it is available.
281+
// When the number of program headers is >= 0xffff, the actual number is
282+
// contained in the sh_info field of the section header at index 0.
283283
std::optional<uint32_t> RealPhNum;
284-
std::optional<uint32_t> RealShNum;
284+
// When the number of section headers is >= 0xff00, the actual number is
285+
// contained in the sh_size field of the section header at index 0.
286+
std::optional<uint64_t> RealShNum;
287+
// When the index of str section is >= 0xff00, the actual number is
288+
// contained in the sh_link field of the section header at index 0.
285289
std::optional<uint32_t> RealShStrNdx;
286290

287291
ELFFile(StringRef Object);
@@ -296,7 +300,7 @@ class ELFFile {
296300
}
297301
return *RealPhNum;
298302
}
299-
Expected<uint32_t> getShNum() const {
303+
Expected<uint64_t> getShNum() const {
300304
if (!RealShNum) {
301305
if (Error E = const_cast<ELFFile<ELFT> *>(this)->readShdrZero())
302306
return std::move(E);
@@ -813,12 +817,7 @@ ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
813817
"e_shstrndx == SHN_XINDEX, but the section header table is empty");
814818
}
815819

816-
uint32_t Index;
817-
if (Expected<uint32_t> IndexOrErr = getShStrNdx())
818-
Index = *IndexOrErr;
819-
else
820-
return IndexOrErr.takeError();
821-
820+
uint32_t Index = *ShStrNdxOrErr;
822821
// There is no section name string table. Return FakeSectionStrings which
823822
// is non-empty if we have created fake sections.
824823
if (!Index)
@@ -934,30 +933,20 @@ template <class ELFT> Error ELFFile<ELFT>::readShdrZero() {
934933

935934
// Pretend we have section 0 or sections() would call getShNum and thus
936935
// become an infinite recursion
937-
RealShNum = 0;
938-
auto SecsOrErr = sections();
939-
if (!SecsOrErr) {
936+
if (Header.e_shnum == 0)
937+
RealShNum = 1;
938+
else
939+
RealShNum = Header.e_shnum;
940+
auto SecOrErr = getSection(0);
941+
if (!SecOrErr) {
940942
RealShNum = std::nullopt;
941-
return SecsOrErr.takeError();
942-
}
943-
944-
// We can really have 0 number of seciton
945-
if ((*SecsOrErr).size() == 0) {
946-
if (Header.e_phnum == ELF::PN_XNUM ||
947-
Header.e_shstrndx == ELF::SHN_XINDEX) {
948-
return createError("Unable to find Section 0");
949-
}
950-
RealShNum = 0;
951-
RealPhNum = Header.e_phnum;
952-
RealShStrNdx = Header.e_shstrndx;
953-
return Error::success();
943+
return SecOrErr.takeError();
954944
}
955945

956-
auto &Section = (*SecsOrErr)[0];
957946
RealPhNum =
958-
Header.e_phnum == ELF::PN_XNUM ? Section.sh_info : Header.e_phnum;
959-
RealShNum = Header.e_shnum == 0 ? Section.sh_size : Header.e_shnum;
960-
RealShStrNdx = Header.e_shstrndx == ELF::SHN_XINDEX ? Section.sh_link
947+
Header.e_phnum == ELF::PN_XNUM ? (*SecOrErr)->sh_info : Header.e_phnum;
948+
RealShNum = Header.e_shnum == 0 ? (*SecOrErr)->sh_size : Header.e_shnum;
949+
RealShStrNdx = Header.e_shstrndx == ELF::SHN_XINDEX ? (*SecOrErr)->sh_link
961950
: Header.e_shstrndx;
962951
} else {
963952
RealPhNum = Header.e_phnum;
@@ -1034,12 +1023,10 @@ Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
10341023
reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
10351024

10361025
uintX_t NumSections = 0;
1037-
if (Expected<uint32_t> ShNumOrErr = getShNum())
1026+
if (Expected<uint64_t> ShNumOrErr = getShNum())
10381027
NumSections = *ShNumOrErr;
10391028
else
10401029
return ShNumOrErr.takeError();
1041-
if (NumSections == 0)
1042-
NumSections = First->sh_size;
10431030

10441031
if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
10451032
return createError("invalid number of sections specified in the NULL "

0 commit comments

Comments
 (0)