This is an archive of the discontinued LLVM Phabricator instance.

ELF: Move relocation predicates out of the context class.
Needs RevisionPublic

Authored by ruiu on Feb 12 2015, 9:28 PM.

Details

Summary

Looks like each subdirectory in ELF directory was created as a copy of
some architecture (x86_64 perhaps?) as a template. They contain many
similar-looking code. They are not always identical since they diverged
over time. Some differences between the subdirectories are real, and
some are not but just different.

A patch for ELF often has to update multiple occurrences of
similar-looking code in the subdirectories. r228905 is an example.
This is not a good shape. It's probably time to visit all subdirectories,
and if there's architecture-independent stuff there, move that to the
ELF parent directory.

This patch is a starter. This is not totally architecture-independent
since relocations depend on architecture types, but this reduces the
amount of code from the subdirectories and also cut dependencies between
code, so I think it's not bad as a starter. After submitting this,
we have less code there, which makes it easier to find code duplicates.

We have bunch of predicates for relocations for questions like "is
this relocation is for PLT?" We can say whether a relocation is a PLT
or not, for example, by just looking at the relocation. Currently the
predicates are members of LinkingContext, but no context is needed to
answer to that question. And in general if we can make the same decision
by looking at not both X and Y but only X, the latter is preferred.

It is now clear that some architectures didn't define some predicates.
For example, x86 didn't have a predicate function for the copy relocation.
I think this is a missing feature, we may want to revisit that later.

By moving the code out of LinkingContext, each <arch>LinkingContext
becomes smaller, which helps find duplicates in the subdirectories.

Diff Detail

Event Timeline

ruiu updated this revision to Diff 19871.Feb 12 2015, 9:28 PM
ruiu retitled this revision from to ELF: Move relocation predicates out of the context class..
ruiu updated this object.
ruiu edited the test plan for this revision. (Show Details)
ruiu added a project: lld.
ruiu added a subscriber: Unknown Object (MLST).
ruiu added a comment.Feb 12 2015, 9:41 PM

I'd like to add a note that, like r227784, using vtable for dispatching is not always a win, if there's anyone who doesn't like the switch statements.

I am sorry, but I do not see how this patch helps to reduce code duplication. I think commit rL222313 is a good example of sharing a common ELF code among targets. In that case Shankar found the code applicable to all ELF target and relocated them to the base class DefaultLayout. In this patch we just replace virtual functions by switch cases.

shankar.easwaran requested changes to this revision.Feb 13 2015, 5:02 AM

Please don't move architecture specific code to common code.

I don't see a need of doing this right now.

Bigcheese?

This revision now requires changes to proceed.Feb 13 2015, 5:02 AM

other reasons I dont like this design is

  • IMO, this would become hard to maintain and not clean.
  • Checks all architecture specific relocations in one common place, it would hurt performance.
    • For example, if x86_64 is the current link type, the case checks for all other architectures, and this happens for every relocation.

A good alternative is to move this code to the TargetHandler, as its specific to only that target.

What do you think ? Simon / Bigcheese ?

I think all target related code should be separated by LinkingContext, TargetHandler etc descendant classes. If moving relocation predicates to the TargetHandler descendants makes the code clear, it is a good idea.

ruiu added a comment.Feb 13 2015, 11:17 AM

But the relocation type is not architecture dependent, right? The
relocation itself knows what the relocation type of itself is. Maybe I can
make this member functions of relocation, but adding that predicates to
linking context object is not logically correct.

relocation types are very much architecture dependent, thats why they are handled in each architecture/target. Its ok to move this to the TargetHandler, and the code would be more clear.

ruiu added a comment.Feb 17 2015, 2:30 PM

Shankar,

Are you saying that a relocation type cannot be interpreted if we don't
have a prior knowledge what machine type the reference is? It is true that
relocation types are machine dependent, of course, but that's different
from what I'm trying to do here.

We are currently passing a reference to a linking context object to ask
"what this reference type is?" But as I wrote before the reference itself
has the machine type info, so we don't have to involve the linking context.
The function to get the reference type can be an independent function, or a
member function of the reference, but the linking context is a wrong place,
because it's not related to the context.

I do agree that LinkingContext is not the place to have these functions defined. Moving this to lld::Reference is not the right thing to do IMO as its a base class for all references. We do have TargetHandler for this purpose where each target would override this functionality.

ruiu added a comment.Feb 17 2015, 2:59 PM

As the same reason they don't belong to the linking context, they don't
belong to the target handler too. The predicates for relocations don't need
any knowledge on a target and will never be overridden depending on
architecture. They are just independent predicates on references.

I think I read about this in Effective C++ and that's a good practice -- if
your functionality uses only public interface of other classes, making it a
non-member function is preferred. By doing that it cuts dependencies and it
also make it obvious that the function doesn't depend on any hidden
information. I believe this is exactly what I'm trying to do in this patch.

I disagree. This kind of code is commonly placed in the TargetHandler. I was just browsing MachO and mach-o too has these utility functions in the ArchHandler. Myself/Simon do agree that this code pattern when moved to the TargetHandler for ELF/Gnu flavor makes the code much better too.

rnk added a subscriber: rnk.Feb 18 2015, 11:17 AM

One thing to consider is, will lld support compiling out different ELF targets to reduce linker size? By using the virtual interface, you can compile out a few switch tables. It may not be worth it, though. For example, you can't compile out MS ABI support from Clang because it's too intertwined with the regular code.

In addition to what we discussed in this review, that was one of my intention to have a linker to support just a particular ELF target.

Bigcheese requested changes to this revision.Feb 19 2015, 2:47 PM
Bigcheese added a reviewer: Bigcheese.
Bigcheese added a subscriber: Bigcheese.

I really dislike pulling architecture specific stuff up out of the architecture it belongs to and shoving it all in a single file. I get that it doesn't need the context, but I feel this is a worse solution.