This is an archive of the discontinued LLVM Phabricator instance.

[llvm-readobj] - Move out the common code from printRelocations() methods.
ClosedPublic

Authored by grimar on Jul 16 2020, 2:37 AM.

Details

Summary

This introduces the printRelocationsHelper() which now contains the common
code used by both GNU and LLVM output styles.

Depends on https://reviews.llvm.org/D83871

Diff Detail

Event Timeline

grimar created this revision.Jul 16 2020, 2:37 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 16 2020, 2:37 AM
Herald added a subscriber: rupprecht. · View Herald Transcript
grimar updated this revision to Diff 278410.Jul 16 2020, 2:46 AM
  • Minor simplification.
MaskRay added inline comments.Jul 17 2020, 12:15 AM
llvm/tools/llvm-readobj/ELFDumper.cpp
5611

I am a bit unsure this simplifies the code (number of lines increased...).

We changed two dispatching switches to 3 lambdas plus 2 dispatching switches? Did not see how the new organization simplifies code or improves readability...

grimar marked an inline comment as done.Jul 17 2020, 1:41 AM
grimar added inline comments.
llvm/tools/llvm-readobj/ELFDumper.cpp
5611

This method has 6 unwrapOrError calls and now shares the logic which previously was duplicated.
With this patch we will be able to replace these unwrapOrError calls with a proper error reporting code in a single shared place.

grimar updated this revision to Diff 278746.Jul 17 2020, 6:18 AM
  • Slightly changed the approavh used (3 lambdas -> 1 lambda).
jhenderson added inline comments.Jul 20 2020, 1:47 AM
llvm/tools/llvm-readobj/ELFDumper.cpp
6269–6274

This lambda (and the identical one in printSectionHeaders) seems a little unfortunate to me, if I'm honest. The printRelocationsHelper function switches on the section header type, whilst this switches on the relocation type, which can be inferred from the section header type. Would it not be simpler to call printRelocation inline? I'm not sure I see how the lambda improves things.

grimar updated this revision to Diff 279181.Jul 20 2020, 4:39 AM
grimar marked an inline comment as done.
  • Addressed review comments.
llvm/tools/llvm-readobj/ELFDumper.cpp
6269–6274

The printRelocationsHelper function switches on the section header type, whilst this switches on the relocation type, which can be inferred from the section header type.

Inferring the relocation type is not that straightforward. It can be Rel/Relr depending on the opts::RawRelr switch, for example:

case ELF::SHT_RELR:
case ELF::SHT_ANDROID_RELR: {
  Elf_Relr_Range Relrs = unwrapOrError(this->FileName, Obj->relrs(&Sec));
  if (opts::RawRelr) {
    for (const Elf_Relr &R : Relrs)
      printRelrReloc(R);
    break;
  }
  std::vector<Elf_Rel> RelrRels =
      unwrapOrError(this->FileName, Obj->decode_relrs(Relrs));
  for (const Elf_Rel &R : RelrRels)
    printRelReloc(Obj, SecNdx, SymTab, R, ++RelNdx);
  break;
}

And we want to avoid the duplication of the inferring logic probably, it is not that easy/convenient to share it I think.

Would it not be simpler to call printRelocation inline?

It is possible, but we have different implementations of printRelocation for GNU/LLVM style.
And it is a template function that only handles Rel/Rela currently, but not Relr:

template <class RelTy>
void printRelocation(const ELFO *Obj, unsigned SecIndex, const RelTy &Rel,
                     unsigned RelIndex, const Elf_Shdr *SymTab);

So we can't jsut call/inline the existent logic. To be able to remove lambda, I see 2 ways:

  1. Introduce 3 more virtual functions that will be overriden by GNU/LLVM dumpers:

printRelReloc, printRelaReloc and printRelrReloc.

  1. Introduce a Relocation struct/union (like was done in the diff 3) and a single new virtual function.

I've updated the code to remove lambda and implemented (1). What do you think?

jhenderson added inline comments.Jul 21 2020, 1:47 AM
llvm/tools/llvm-readobj/ELFDumper.cpp
3636–3647

It seems to me like this pair of functions (and the equivalent LLVM pair) is unnecessary. You should be able to call printRelRelaReloc directly.

grimar marked an inline comment as done.Jul 21 2020, 2:14 AM
grimar added inline comments.
llvm/tools/llvm-readobj/ELFDumper.cpp
3636–3647

printRelRelaReloc is a non-virtual template method, defined for both LLVMStyle<ELFT> and GNUStyle<ELFT> output styles.

template <class ELFT>
template <class RelTy>
void LLVMStyle<ELFT>::printRelRelaReloc(const ELFO *Obj, unsigned SecIndex,
                                        const RelTy &Rel, unsigned RelIndex,
                                        const Elf_Shdr *SymTab)
template <class ELFT>
template <class RelTy>
void GNUStyle<ELFT>::printRelRelaReloc(const ELFO *Obj, unsigned SecIndex,
                                       const Elf_Shdr *SymTab, const RelTy &R,
                                       unsigned RelIndex)

The only way I can imagine how to call it directly from the base class is to detemplate it, make it virtual and return to having Elf_Rela R, bool IsRela or something alike in the signature, what didn't work good (D83871).
Or, may be we can pass both Elf_Rela and Elf_Rel at the same time. E.g:

void GNUStyle<ELFT>::printRelRelaReloc(const ELFO *Obj, unsigned SecIndex,
                                       const Elf_Shdr *SymTab, unsigned RelIndex, const Elf_Rela *Rela, const Elf_Rela *Rel) {
assert((Rela || Rel) && !(Rela && Rel));
...
}

or introduce a helper struct to store either both relocations ot Elf_Rel + optional addend. In all that cases this needs printRelRelaReloc to be detemplated and virtualized. Want me to try this way?

jhenderson accepted this revision.Jul 22 2020, 6:18 AM

LGTM, I think, but it would be wise to get @MaskRay's thoughts too.

llvm/tools/llvm-readobj/ELFDumper.cpp
3636–3647

No, it's okay. I hadn't quite registered templates + virtual methods not combining well in this way.

This revision is now accepted and ready to land.Jul 22 2020, 6:18 AM
grimar marked an inline comment as done.Jul 22 2020, 6:54 AM
grimar added inline comments.
llvm/tools/llvm-readobj/ELFDumper.cpp
3636–3647

I've experimented with de-templating and it looks not so bad as I thought it seems.
I've posted the D84323 as a possible follow-up that we can land on top if we decide to detemplate it.

@MaskRay, are you OK to land it?

grimar closed this revision.Jul 29 2020, 3:55 AM

There was no new objections/comments for about 7 days after I got LGTM, so I've committed it as 08a265435bc359841c8618081db6a698cef1f668 (phab does not autocloses any reviews currently it seems).