This is an archive of the discontinued LLVM Phabricator instance.

[llvm-readobj/llvm-readelf] - Reimplement dumping of the SHT_GNU_verdef section.
ClosedPublic

Authored by grimar on Nov 20 2019, 7:56 AM.

Details

Summary

Currently we have following issues:

  1. We have 2 different implementations with a different behaviors for GNU/LLVM styles.
  2. Errors are either not handled at all or we call report_fatal_error with not helpfull messages.
  3. There is no test coverage even for those errors that are reported.

This patch reimplements parsing of the SHT_GNU_verdef section entries
in a single place, adds a few error messages and test coverage.

Diff Detail

Event Timeline

grimar created this revision.Nov 20 2019, 7:56 AM
Herald added a project: Restricted Project. · View Herald Transcript
MaskRay added inline comments.Nov 20 2019, 6:37 PM
llvm/tools/llvm-readobj/ELFDumper.cpp
4035

ContentsOrErr->data()

4051

->

4060

Use for (unsigned I = 1; I <= Sec->sh_info; ++I) to avoid I + 1 below.

MaskRay added inline comments.Nov 20 2019, 6:46 PM
llvm/test/tools/llvm-readobj/elf-versioninfo.test
292

How about "report an error ... sh_link references a non-existent section"

llvm/tools/llvm-readobj/ELFDumper.cpp
4045

Probably just auto *

4074

Check alignment, probably D->vd_aux % alignof(VerdAux) == 0,
otherwise this may trigger a misaligned exception on some architectures.

grimar updated this revision to Diff 230421.Nov 21 2019, 4:10 AM
grimar marked 7 inline comments as done.
  • Addressed review comments.
llvm/tools/llvm-readobj/ELFDumper.cpp
4074

Good point!
There was a problem: for me alignof(Elf_Verdef) == 1, but I think the alignment for verdef should be 32
Seems it is because, for example, Elf_Word is a packed<uint32_t> which is packed_endian_specific_integral, which use
an array of chars for representing the storage buffer. And alignof(char) == 1.

I've used hardcoded constants instead. I've added 2 additional errors: one for "unaligned auxiliary entry" and another for
"unaligned version definition entry". Unfortunately I believe there is no way to test the first one with use of yaml2obj.

The logic looks good to me now. I've only got a few nits.

llvm/test/tools/llvm-readobj/elf-versioninfo.test
317

Probably ".. the sh_link field of a SHT_GNU_verdef section references a non-string table section"

I think the error/warning messages are a bit unnatural but I am not confident enough to suggest alternative messages. Thankfully we've got native speakers to suggest the wording :)

llvm/tools/llvm-readobj/ELFDumper.cpp
4046

We should probably only use FIXME for real code problems. Here we should "TODO".

Actually I think the alignment check should be done outside the function. Maybe we should check the alignments of both VerdefBuf and D->vd_aux.

4071

I guess this should be called "misaligned", not "unaligned", but I am not a native speaker and not very confident about this...

Not checking "misaligned auxiliary entry" should be fine.

5830

For consistency, shall we simply drop this if statement to print an empty list?

jhenderson added inline comments.Nov 22 2019, 2:03 AM
llvm/test/tools/llvm-readobj/elf-versioninfo.test
300

also should -> should also

is more natural

323

I'd change this to:

sh_link field of SHT_GNU_verdef section at index N is invalid: the section at index 0 is not a string table: expected SHT_STRTAB but got SHT_NULL

338

This comment doesn't line up with the warning we see below. I'd expect a similar warning to the previous test case.

344

How about "cannot read content of SHT_GNU_verdef section: ..."

I'd ideally put the [index 1] before the colon, i.e. "... of SHT_GNU_verdef section with index 1: the section has a ...", but I'm not sure if that risks losing useful context elsewhere.

353–357

Nit: this lot all need an extra space of padding to line up with ShOffset.

369

invalid SHT_GNU_verdef section with index N: ...

400

invalid SHT_GNU_verdef section with index N: version definition 1 refers ...

425

overruns -> overrun
the string table linked -> the linked string table

Perhaps worth checking that no warning is printed?

475

invalid SHT_GNU_verdef section with index N: found a misaligned definition entry at offset X

llvm/tools/llvm-readobj/ELFDumper.cpp
523–524

I'm not sure getVersionDefinitions belongs in the DumpStyle class, as it isn't a property of the style. I think it should be moved to the ElfDumper class, along with the other get* functions that are common to both dumping styles.

4025

Maybe since we now have it, use reportUniqueWarning?

4046

Is there a reason we can't just test this as part of this change?

4071

"misaligned" sounds good to me and matches the LoadVersionNeeds function.

5818

reportUniqueWarning?

5833

Do we have any tests for multiple predecessors?

grimar updated this revision to Diff 230613.Nov 22 2019, 2:05 AM
grimar marked 7 inline comments as done.
  • Addressed review comments.
llvm/tools/llvm-readobj/ELFDumper.cpp
4046

We should probably only use FIXME for real code problems. Here we should "TODO".

Done.

Actually I think the alignment check should be done outside the function.

Done.

Maybe we should check the alignments of both VerdefBuf and D->vd_aux.

This is checked already:

  1. VerdefBuf is checked to be 4-bytes aligned.
  2. I do VerdauxBuf = VerdefBuf + D->vd_aux and check VerdauxBuf. This checks D->vd_aux.
  3. I do VerdefBuf += D->vd_next and check VerdefBuf. This checks D->vd_next.
4071

I guess this should be called "misaligned", not "unaligned", but I am not a native speaker and not very confident about this...

Perhaps "misaligned" is correct, since "If something is misaligned, then there's a correct alignment that has not been adhered to" and we have one in mind.
(https://www.reddit.com/r/grammar/comments/6x1sov/difference_between_unaligned_and_misaligned/)

5830

I think yes. I was going to suggest a follow-up for this. I find it strange to print or not print a tag basing on a "if empty" condition.
It's like if we would drop printing "Alignment: 0", just because it is not set. And it can be a problem for machine parsing,
so I believe we just should always print tags..

But I did not do it in this patch, because this introduces more changes in the existent tests, which
are probably unrelated to this patch. (I wasn't happy to change Predecessor -> Predecessors either, but I had to).

grimar updated this revision to Diff 230901.Nov 25 2019, 7:21 AM
grimar marked 20 inline comments as done.
  • Addressed review comments.
llvm/test/tools/llvm-readobj/elf-versioninfo.test
323

It comes from:

Expected<StringRef> StrTabOrErr = Obj->getStringTable(*StrTabSecOrErr);
  if (!StrTabOrErr)
    return createError(
        "SHT_GNU_verdef section: can't use the string table linked: " +
        toString(StrTabOrErr.takeError()));

i.e. we know that getStringTable failed, but can't do any additional assumptions about details. getStringTable() reports the reason and it's text is
out of the area of this patch. I've changed the prefix part.

344

How about "cannot read content of SHT_GNU_verdef section: ..."

Done.

I'd ideally put the [index 1] before the colon, i.e. "... of SHT_GNU_verdef section with index 1: the section has a ...", but I'm not sure if that risks losing useful context elsewhere.

I can only change the prefix, the rest part of the error comes from elsewhere.

Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj->getSectionContents(Sec);
 if (!ContentsOrErr)
   return createError("cannot read content of SHT_GNU_verdef section: " +
                      toString(ContentsOrErr.takeError()));
llvm/tools/llvm-readobj/ELFDumper.cpp
523–524

Yeah, looks true. Done.

4046

Is there a reason we can't just test this as part of this change?

I believe it is impossible to use yaml2obj here. So the only way to do that is probably to craft and checking a binary. Do you want me to do that?

5833

I've added one.

grimar marked an inline comment as done.Nov 25 2019, 7:22 AM
grimar added inline comments.
llvm/tools/llvm-readobj/ELFDumper.cpp
4046

checking -> commit

MaskRay accepted this revision.Nov 25 2019, 4:03 PM

LGTM, but please make sure @jhenderson is happy about the untested part.

This revision is now accepted and ready to land.Nov 25 2019, 4:03 PM
grimar marked an inline comment as done.Nov 26 2019, 12:14 AM
grimar added inline comments.
llvm/tools/llvm-readobj/ELFDumper.cpp
4046

One of the simple way to avoid binary being committed is to teach yaml2obj to accept raw Content field for VerdefSection sections it seems. But again, this needs a separate yaml2obj change to be done. I am to work on this.

grimar marked an inline comment as done.Nov 26 2019, 12:15 AM
grimar added inline comments.
llvm/tools/llvm-readobj/ELFDumper.cpp
4046

"I am to work on this." -> " I am going to work on this."

LGTM, but please make sure @jhenderson is happy about the untested part.

I'd prefer the yaml2obj change land first if possible. However, if it's a sizeable change (I doubt it is, but just in case), I don't think it's worth blocking this change from landing if there's a particular need for it. I would like the error message improvement discussed inline though.

llvm/test/tools/llvm-readobj/elf-versioninfo.test
323

The "can't get the string table linked" is the bit I'm most concerned about, as it is not good English and is part of this patch. How about this instead: "invalid string table linked to SHT_GNU_verdef secion with index 1: invalid sh_type ..." (or simply "invalid section linked to...")?

Same goes for the similar message above.

338

can't read a content -> we can't read the content

grimar updated this revision to Diff 231059.Nov 26 2019, 5:50 AM
grimar marked an inline comment as done.
  • Addressed review comments.
jhenderson accepted this revision.Nov 26 2019, 6:06 AM

Thanks! LGTM.

This revision was automatically updated to reflect the committed changes.