This is an archive of the discontinued LLVM Phabricator instance.

[llvm-readef/obj] - Change the design structure of ELF dumper. NFCI.
ClosedPublic

Authored by grimar on Dec 29 2020, 6:18 AM.

Details

Summary

This is a refactoring for design of stuff in ELFDumper.cpp.
The current design of ELF dumper is far from ideal.

Currently most overridden functions (inherited from ObjDumper) in ELFDumper just forward to
the functions of ELFDumperStyle (which can be either GNUStyle or LLVMStyle).
A concrete implementation may be in any of ELFDumper/DumperStyle/GNUStyle/LLVMStyle.

This patch reorganizes the classes by introducing GNUStyleELFDumper/LLVMStyleELFDumper
which inherit from ELFDumper. The implementations are moved:

DumperStyle -> ELFDumper
GNUStyle -> GNUStyleELFDumper
LLVMStyle -> LLVMStyleELFDumper

With that we can avoid having a lot of redirection calls and helper methods.
The number of code lines changes from 7142 to 6922 (reduced by ~3%) and the
code overall looks cleaner.

Diff Detail

Event Timeline

grimar requested review of this revision.Dec 29 2020, 6:18 AM
grimar created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptDec 29 2020, 6:18 AM

Currently we have the ELFDumper class that redirects most of calls to ELFDumperStyle, which can be either GNUStyle or LLVMStyle. Both styles are inhireted from the DumpStyle base class. So we have 4 classes and style classes often have to call methods from the base class (this->dumper()->...). It is not a convenient way.

inhireted -> inherited

"What are the 4 classes and style classes?" needs to be clarified.

I'd rephrase what this patch does:

Currently most overridden functions (inherited from ObjDumper) in ELFDumper just forward to the functions of ELFDumperStyle (which can be either GNUStyle or LLVMStyle).
A concrete implementation may be in any of ELFDumper/DumperStyle/GNUStyle/LLVMStyle.

This patch reorganizes the classes by introducing GNUStyleELFDumper/LLVMStyleELFDumper which inherit from ELFDumper. The implementations are moved:

  • DumperStyle -> ELFDumper
  • GNUStyle -> GNUStyleELFDumper
  • LLVMStyle -> LLVMStyleELFDumper

This refactoring looks good to me.

grimar edited the summary of this revision. (Show Details)Dec 30 2020, 12:09 AM

Currently we have the ELFDumper class that redirects most of calls to ELFDumperStyle, which can be either GNUStyle or LLVMStyle. Both styles are inhireted from the DumpStyle base class. So we have 4 classes and style classes often have to call methods from the base class (this->dumper()->...). It is not a convenient way.

inhireted -> inherited

"What are the 4 classes and style classes?" needs to be clarified.

I'd rephrase what this patch does:

Currently most overridden functions (inherited from ObjDumper) in ELFDumper just forward to the functions of ELFDumperStyle (which can be either GNUStyle or LLVMStyle).
A concrete implementation may be in any of ELFDumper/DumperStyle/GNUStyle/LLVMStyle.

This patch reorganizes the classes by introducing GNUStyleELFDumper/LLVMStyleELFDumper which inherit from ELFDumper. The implementations are moved:

  • DumperStyle -> ELFDumper
  • GNUStyle -> GNUStyleELFDumper
  • LLVMStyle -> LLVMStyleELFDumper

This refactoring looks good to me.

I think your version explains the change better, thanks!

(FYI, I am leaving on new year holidays, will return back on 11 of january)

MaskRay accepted this revision.Dec 30 2020, 9:32 AM

Looks great!

This revision is now accepted and ready to land.Dec 30 2020, 9:32 AM

The original split of the two styles came in D14128, by @khemant. I can't see any explanation in that review for taking the route of using a separate style class as opposed to simply doing what you're doing now. Possibly it was just easier to retrofit it in that way. The style/dumper split would make sense, if the styles were shared between the different dumper kinds, but they aren't, and I suspect the dumping functionality for other tools may be too divergent for them to be easily reusable.

Overall, this looks reasonable. Could you highlight the major changes you've had to make to achieve the refactor? This patch is quite large and tricky for me to review in depth.

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

Maybe the name could be simplified slightly to GNUELFDumper (and the LLVM one to LLVMELFDumper)?

grimar updated this revision to Diff 315781.Jan 11 2021, 6:09 AM
grimar marked an inline comment as done.
  • Addressed review comments.

Could you highlight the major changes you've had to make to achieve the refactor? This patch is quite large and tricky for me to review in depth.

  1. I've introduced 2 dumper classes, derived from the ELFDumper<ELFT> and moved the implementation: GNUStyle -> GNUStyleELFDumper, LLVMStyle -> LLVMStyleELFDumper.
  2. I've removed a bunch of methods from the ELFDumper<ELFT>. Like: printSectionHeaders, printRelocations and many others. They became unneeded, as they only did a redirection to ELFDumperStyle, e.g:
template <class ELFT> void ELFDumper<ELFT>::printSectionHeaders() {
  ELFDumperStyle->printSectionHeaders();
}
  1. Since the DumpStyle class was eliminated, the common implementation was moved to the ELFDumper<ELFT>.
  1. A lot of getters were eliminated:

E.g:

  const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
  const Elf_Shdr *getDotCGProfileSec() const { return DotCGProfileSec; }
...
  const DynRegionInfo &getDynPLTRelRegion() const { return DynPLTRelRegion; }
  const DynRegionInfo &getDynamicTableRegion() const { return DynamicTable; }

because it became possible to use fields directly from the logic.

  1. Some consts were added to make the new code to compile again.
llvm/tools/llvm-readobj/ELFDumper.cpp
729

Done.

danilaml added inline comments.
llvm/tools/llvm-readobj/ELFDumper.cpp
2644

Why was this removed?
I think it broke compilation on GCC older than 7.0+

See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480

 error: specialization of ‘template<class ELFT> void {anonymous}::ELFDumper<ELFT>::printUnwindInfo()’ in different namespace [-fpermissive]
 template <> void ELFDumper<ELF32LE>::printUnwindInfo() {
                                                      ^
../tools/llvm-readobj/ELFDumper.cpp:241:8: error:   from definition of ‘template<class ELFT> void {anonymous}::ELFDumper<ELFT>::printUnwindInfo()’ [-fpermissive]
   void printUnwindInfo() override;

I wonder why wasn't it caught y any of the buildbots.

grimar added inline comments.Jan 15 2021, 12:22 AM
llvm/tools/llvm-readobj/ELFDumper.cpp
2644

Hmm. I wasn't aware this is usefull. That's why. I'll restore shortly with the comment saying that GCC <7 wants it.