@@ -278,16 +278,26 @@ class ELFFile {
278278 std::vector<Elf_Shdr> FakeSections;
279279 SmallString<0 > FakeSectionStrings;
280280
281- Elf_Word RealPhNum;
282- Elf_Word RealShNum;
283- Elf_Word RealShStrNdx;
281+ //
282+ // According to the ELF gABI, these three fields can be recorded in section 0
283+ // when possible. Therefore, we store this information when it is available.
284+ //
285+ std::optional<uint32_t > RealPhNum;
286+ std::optional<uint32_t > RealShNum;
287+ std::optional<uint32_t > RealShStrNdx;
284288
285289 ELFFile (StringRef Object);
286290
287291public:
288- Elf_Word getPhNum () const { return RealPhNum; }
289- Elf_Word getShNum () const { return RealShNum; }
290- Elf_Word getShStrNdx () const { return RealShStrNdx; }
292+ uint32_t getPhNum () const {
293+ return RealPhNum ? *RealPhNum : getHeader ().e_phnum ;
294+ }
295+ uint32_t getShNum () const {
296+ return RealShNum ? *RealShNum : getHeader ().e_shnum ;
297+ }
298+ uint32_t getShStrNdx () const {
299+ return RealShStrNdx ? *RealShStrNdx : getHeader ().e_shstrndx ;
300+ }
291301 const Elf_Ehdr &getHeader () const {
292302 return *reinterpret_cast <const Elf_Ehdr *>(base ());
293303 }
@@ -386,21 +396,21 @@ class ELFFile {
386396
387397 // / Iterate over program header table.
388398 Expected<Elf_Phdr_Range> program_headers () const {
389- if (RealPhNum && getHeader ().e_phentsize != sizeof (Elf_Phdr))
399+ if (getPhNum () && getHeader ().e_phentsize != sizeof (Elf_Phdr))
390400 return createError (" invalid e_phentsize: " +
391401 Twine (getHeader ().e_phentsize ));
392402
393- uint64_t HeadersSize = (uint64_t )RealPhNum * getHeader ().e_phentsize ;
403+ uint64_t HeadersSize = (uint64_t )getPhNum () * getHeader ().e_phentsize ;
394404 uint64_t PhOff = getHeader ().e_phoff ;
395405 if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize ())
396406 return createError (" program headers are longer than binary of size " +
397407 Twine (getBufSize ()) + " : e_phoff = 0x" +
398408 Twine::utohexstr (getHeader ().e_phoff ) +
399- " , e_phnum = " + Twine (RealPhNum ) +
409+ " , e_phnum = " + Twine (getPhNum () ) +
400410 " , e_phentsize = " + Twine (getHeader ().e_phentsize ));
401411
402412 auto *Begin = reinterpret_cast <const Elf_Phdr *>(base () + PhOff);
403- return ArrayRef (Begin, Begin + RealPhNum );
413+ return ArrayRef (Begin, Begin + getPhNum () );
404414 }
405415
406416 // / Get an iterator over notes in a program header.
@@ -778,11 +788,11 @@ template <class ELFT>
778788Expected<StringRef>
779789ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
780790 WarningHandler WarnHandler) const {
781- uint32_t Index = RealShStrNdx;
782- if (Index == ELF::SHN_XINDEX)
791+ if (getHeader ().e_shstrndx == ELF::SHN_XINDEX && !RealShStrNdx)
783792 return createError (
784793 " e_shstrndx == SHN_XINDEX, but the section header table is empty" );
785794
795+ uint32_t Index = getShStrNdx ();
786796 // There is no section name string table. Return FakeSectionStrings which
787797 // is non-empty if we have created fake sections.
788798 if (!Index)
@@ -889,14 +899,11 @@ Expected<uint64_t> ELFFile<ELFT>::getDynSymtabSize() const {
889899
890900template <class ELFT > ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {
891901 const Elf_Ehdr &Header = getHeader ();
892- RealPhNum = Header.e_phnum ;
893- RealShNum = Header.e_shnum ;
894- RealShStrNdx = Header.e_shstrndx ;
895902 if (!Header.hasPhdrNumExtension ())
896903 return ;
897904
898- // An ELF binary may report `hasExtendedHeader ` as true but not actually
899- // include an extended header . For example, a core dump can contain 65,535
905+ // An ELF binary may report `hasPhdrNumExtension ` as true but not actually
906+ // include an section 0 . For example, a core dump can contain 65,535
900907 // segments but no sections at all. We defer reporting an error until section
901908 // 0 is accessed. Consumers should handle and emit the error themselves when
902909 // they attempt to access it.
@@ -905,11 +912,11 @@ template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {
905912 consumeError (SecOrErr.takeError ());
906913 return ;
907914 }
908- if (RealPhNum == 0xFFFF )
915+ if (Header. e_phnum == 0xFFFF )
909916 RealPhNum = (*SecOrErr)->sh_info ;
910- if (RealShNum == ELF::SHN_UNDEF)
917+ if (Header. e_shnum == ELF::SHN_UNDEF)
911918 RealShNum = (*SecOrErr)->sh_size ;
912- if (RealShStrNdx == ELF::SHN_XINDEX)
919+ if (Header. e_shstrndx == ELF::SHN_XINDEX)
913920 RealShStrNdx = (*SecOrErr)->sh_link ;
914921}
915922
@@ -978,7 +985,7 @@ Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
978985 const Elf_Shdr *First =
979986 reinterpret_cast <const Elf_Shdr *>(base () + SectionTableOffset);
980987
981- uintX_t NumSections = RealShNum ;
988+ uintX_t NumSections = getShNum () ;
982989 if (NumSections == 0 )
983990 NumSections = First->sh_size ;
984991
0 commit comments