@@ -297,6 +297,43 @@ void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
297297 }
298298}
299299
300+ template <class ELFT >
301+ void printSymbolVersionDefinition (const typename ELFT::Shdr &Shdr,
302+ ArrayRef<uint8_t > Contents,
303+ StringRef StrTab) {
304+ typedef ELFFile<ELFT> ELFO;
305+ typedef typename ELFO::Elf_Verdef Elf_Verdef;
306+ typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
307+
308+ outs () << " Version definitions:\n " ;
309+
310+ const uint8_t *Buf = Contents.data ();
311+ uint32_t VerdefIndex = 1 ;
312+ // sh_info contains the number of entries in the SHT_GNU_verdef section. To
313+ // make the index column have consistent width, we should insert blank spaces
314+ // according to sh_info.
315+ uint16_t VerdefIndexWidth = std::to_string (Shdr.sh_info ).size ();
316+ while (Buf) {
317+ const Elf_Verdef *Verdef = reinterpret_cast <const Elf_Verdef *>(Buf);
318+ outs () << format_decimal (VerdefIndex++, VerdefIndexWidth) << " "
319+ << format (" 0x%02" PRIx16 " " , (uint16_t )Verdef->vd_flags )
320+ << format (" 0x%08" PRIx32 " " , (uint32_t )Verdef->vd_hash );
321+
322+ const uint8_t *BufAux = Buf + Verdef->vd_aux ;
323+ uint16_t VerdauxIndex = 0 ;
324+ while (BufAux) {
325+ const Elf_Verdaux *Verdaux =
326+ reinterpret_cast <const Elf_Verdaux *>(BufAux);
327+ if (VerdauxIndex)
328+ outs () << std::string (VerdefIndexWidth + 17 , ' ' );
329+ outs () << StringRef (StrTab.drop_front (Verdaux->vda_name ).data ()) << ' \n ' ;
330+ BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr ;
331+ ++VerdauxIndex;
332+ }
333+ Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr ;
334+ }
335+ }
336+
300337template <class ELFT >
301338void printSymbolVersionInfo (const ELFFile<ELFT> *Elf, StringRef FileName) {
302339 typedef typename ELFT::Shdr Elf_Shdr;
@@ -306,7 +343,8 @@ void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
306343 report_error (FileName, SectionsOrError.takeError ());
307344
308345 for (const Elf_Shdr &Shdr : *SectionsOrError) {
309- if (Shdr.sh_type != ELF::SHT_GNU_verneed)
346+ if (Shdr.sh_type != ELF::SHT_GNU_verneed &&
347+ Shdr.sh_type != ELF::SHT_GNU_verdef)
310348 continue ;
311349
312350 auto ContentsOrError = Elf->getSectionContents (&Shdr);
@@ -321,8 +359,11 @@ void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
321359 if (!StrTabOrError)
322360 report_error (FileName, StrTabOrError.takeError ());
323361
324- printSymbolVersionDependency<ELFT>(*ContentsOrError, *StrTabOrError);
325- // TODO: Implement symbol version definitions dumper.
362+ if (Shdr.sh_type == ELF::SHT_GNU_verneed)
363+ printSymbolVersionDependency<ELFT>(*ContentsOrError, *StrTabOrError);
364+ else
365+ printSymbolVersionDefinition<ELFT>(Shdr, *ContentsOrError,
366+ *StrTabOrError);
326367 }
327368}
328369
0 commit comments