This is an archive of the discontinued LLVM Phabricator instance.

[lld][ELF] Ability to resolve undefined symbols lazily
ClosedPublic

Authored by denis-protivensky on Mar 9 2015, 2:34 AM.

Details

Summary

Some symbols like _GLOBAL_OFFSET_TABLE_ may occur in linked object files when not usually expected (for example, glibc uses them for STT_GNU_IFUNC optimization). The patch lets writers override specific method and handle such kind of lazy resolution if needed.
Added implementation of handling _GLOBAL_OFFSET_TABLE_ symbol for ARM platform.

Diff Detail

Repository
rL LLVM

Event Timeline

denis-protivensky retitled this revision from to [lld][ELF] Ability to resolve undefined symbols lazily.
denis-protivensky updated this object.
denis-protivensky edited the test plan for this revision. (Show Details)
denis-protivensky added a project: lld.
denis-protivensky added a subscriber: Unknown Object (MLST).
shankarke requested changes to this revision.Mar 9 2015, 7:44 AM
shankarke added a reviewer: shankarke.
shankarke added a subscriber: shankarke.
shankarke added inline comments.
include/lld/Core/LinkingContext.h
310 ↗(On Diff #21470)

Can you change the comment to specify the new functionality ?

lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h
45 ↗(On Diff #21470)

why static const ? StringRef is already a const. Strange way of initializing.

49 ↗(On Diff #21470)

remove const from StringRef.

lib/ReaderWriter/ELF/OutputELFWriter.h
70–78 ↗(On Diff #21470)

Can you add a test where you have multiple absolute symbols being added, I dont see how this works. This is error prone and could we create a new runtime file for every symbol, like a archive library.

This revision now requires changes to proceed.Mar 9 2015, 7:44 AM
ruiu edited edge metadata.Mar 9 2015, 10:51 AM

This is not a specific comment to this patch, but this patch is too complicated than it can be. It's not your fault, though.

What you are trying to do with this patch is "try to resolve _GLOBAL_OFFSET_TABLE_ as an absolute symbol to .got.plt if there is any reference to the symbol. If .got.plt doesn't exist, use 0 as its address". That's simple. But this patch involves notions of virtual archive file, virtual file, finalizeInputFiles hook and so on and so on. Something is wrong. Maybe the very notion of "virtual archive file generating atoms on demand" is not a good way to do this kind of things, contrary to our expectations. I don't have any specific plan, but I see rooms to simplify this part of the linker. We need to revisit this.

include/lld/Core/Simple.h
105 ↗(On Diff #21470)

I expect all subclasses need to implement this function, so it's better to not define this here, so that the compiler raises an error if definition is missing.

lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h
87 ↗(On Diff #21470)

Remove this line

lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
100 ↗(On Diff #21470)

Thank you for doing this!

Okay, since we drop this patch - I won't make any additional changes to it.

include/lld/Core/Simple.h
105 ↗(On Diff #21470)

I deliberately added it while copying your implementation of virtual archive just because my understanding of Simple group of classes is that they are defaults that can be picked up and used as-is. In general, I agree that this method is excessive for the class. I'd rather say it shouldn't be in the Simple group, but I didn't find better place for it.

lib/ReaderWriter/ELF/OutputELFWriter.h
70–78 ↗(On Diff #21470)

As an alternative, think of such method prototype for derived classes:
File* processUndefinedSymbol(StringRef symName);

It forces the implementor to write spaghetti code that is more error prone than this (I thought about it during the implementation). I prefer to move the complexity to the base class and free the descendants from potential errors.

ruiu accepted this revision.Mar 10 2015, 10:42 AM
ruiu edited edge metadata.

I didn't request a change to this patch -- I pointed out that the way we usually uses needs to be improved some way. This patch is LGTM. Please submit after addressing other comments.

include/lld/Core/Simple.h
105 ↗(On Diff #21470)

Understood.

denis-protivensky edited edge metadata.

Updated:

  • removed const of StringRef
  • added more symbols (__exidx_start/_end) with tests to show how it all works
  • reworked the point of concern in DynamicSymbolFile::find() so it now uses unique_bump_ptr instead of llvm::Optional and the code is a bit cleaner
  • fixed usage of findAbsoluteAtom iterators
  • updated comments for LinkingContext::finalizeInputFiles
ruiu accepted this revision.Mar 11 2015, 12:03 PM
ruiu edited edge metadata.

LGTM

lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h
73 ↗(On Diff #21691)

else if? The next line would override a result of one line above.

shankarke accepted this revision.Mar 13 2015, 11:14 PM
shankarke edited edge metadata.

LGTM.

lib/ReaderWriter/ELF/OutputELFWriter.h
63 ↗(On Diff #21691)

dynamic symbols for executable only ? I think this is applicable for shared libraries as well right ?

This revision is now accepted and ready to land.Mar 13 2015, 11:14 PM
lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h
73 ↗(On Diff #21691)

Ah, thanks, good catch!

lib/ReaderWriter/ELF/OutputELFWriter.h
63 ↗(On Diff #21691)

Right, will update it during commit.

This revision was automatically updated to reflect the committed changes.