This is an archive of the discontinued LLVM Phabricator instance.

[llvm-objcopy] Add support for dynamic relocations
ClosedPublic

Authored by jakehehrlich on Sep 15 2017, 11:46 AM.

Details

Summary

This change adds support for dynamic relocations (allocated SHT_REL/SHT_RELA sections with a dynamic symbol table as their link).

There's a bit of code duplication with RelocationSections which is unfortunate. I'm not sure how to get rid of the duplication right now. If we make RelocationSection and DynamicRelocationSection have a common base class then they wind up not really having make sure that SymbolTableSection and DynamicSymbolTableSection also have a common base class. That would be fine with me except that RelocationSection::setSymTab would have to do a cast to expose the proper methods of SymbolTableSection anyway. If we go this route then there's the cast in RelocationSection::setSymTab plus a tiny bit of code duplication with Section. If we go the route I've uploaded here we duplicate a tiny bit of code in RelocationSection but we have a bit of heavier code duplication in Object::readSectionHeaders. I wasn't really sure what the best trade off was here. I settled on this but I could still be swayed to the other way. Ideally I'd like something better than either of the ways I've proposed.

The binary I added for the test is here: https://drive.google.com/file/d/0B3gtIAmiMwZXSjJUZE9pUjd4M0k/view?usp=sharing

Unless support for dynamic symbol tables in yaml2obj is added this is needed.

Diff Detail

Repository
rL LLVM

Event Timeline

jakehehrlich created this revision.Sep 15 2017, 11:46 AM
jakehehrlich edited the summary of this revision. (Show Details)Sep 15 2017, 11:49 AM
jhenderson edited edge metadata.Sep 18 2017, 7:02 AM

I definitely agree with your TODO comment. Could we simply add a function a bit like "finalize" but for late initialization to the SectionBase interface, and implemented/overridden in the various sub-classes as required? It would, I think, just need to take the list of sections, or the Object itself as an argument. That should be another change anyway.

As for the whole code-duplication situation, I think it may be possible to derive from a templated base class like so:

class RelocationSectionBase <typename SymtabType>: public SectionBase
{
   SymtabType Symbols;
   void setSymTab(SymtabType * SymTab) { Symbols = SymTab; }
   //other shared code here, e.g. finalize, setSection etc
}

class RelocationSection : public RelocationSectionBase<SymbolTableSection>
{
  // Stuff specific to static relocation sections, e.g. addRelocation, writeSection
}

class DynamicRelocationSection : public RelocationSectionBase<DynamicSymbolTableSection>
{
  // Stuff specific to dynamic relocation sections, e.g. writeSection (which would probably just be a copy of Section's writeSection)
}

I believe this would avoid any additional casting, though without actually trying to implement it, I'm not certain.

Used James' idea along with https://reviews.llvm.org/D38008 to factor out almost all code duplication. Thanks James!

A couple points on the precise choices I made:

  1. I don't want to just pass a vector because the only way to pass a vector/array is to copy the pointers into a new array or to pass an array of unique pointers.
  2. I don't want to make the getSection* methods public but that's kind of a small point
  3. Because Object takes an ELFT parameter we can't have it be an argument to a virtual method. So something without the ELFT template dependency has to be passed.

The result is that a new type needs to be made and it handles retrieving sections by index. I'm fairly happy with the overall choice here. A slight blemish is that a few of the types need special initialization beyond setting link/info fields. But there are only two of those so far (SymbolTableSection and RelocationSection) and the only other one I anticipate will ever occur is for SHT_GROUP which isn't a concern right now.

Yes, the SectionTable refactor definitely has improved things. Once the other change is ready, I'll approve this one.

Updated diff to be relative to origin now that the initialize methods are upstream.

This revision is now accepted and ready to land.Sep 26 2017, 1:43 AM
This revision was automatically updated to reflect the committed changes.

The issues is that I'm not Symbols or SecToApplyRel in the relocation. I'll fix that soon.