<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Feb 18, 2015 at 1:38 AM, Denis Protivensky <span dir="ltr"><<a href="mailto:dprotivensky@accesssoftek.com" target="_blank">dprotivensky@accesssoftek.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi everyone,<br>
<br>
In lld, I need to conditionally add symbols (like GLOBAL_OFFSET_TABLE)<br>
during<br>
static linking because they may be used by relocations (R_ARM_TLS_IE32) or<br>
by some other stuff like STT_GNU_IFUNC symbols.<br>
The problem is that now symbols are added in a declarative way by<br>
specifying in ExecutableWriter::addDefaultAtoms() override.<br>
At that stage, there's no way to determine if additional symbols are<br>
required.<br>
But libraries providing optimizations like STT_GNU_IFUNC<br>
(glibc, for example) expect the GOT symbol to be defined, so the linking<br>
process<br>
fails in Resolver::resolve() if the symbol is not found.<br>
<br>
I propose to add the ability to ignore undefined symbols during initial<br>
resolution, and then postprocess only those undefines for the second time<br>
after the pass manager execution.<br>
<br>
Technically, this shouldn't be a problem:<br>
- there will be a new option in the linking context that should signal<br>
that the postprocessing of undefined symbols should be performed.<br>
- if postprocessing option is set, newly added symbols will be collected<br>
in the MergedFile returned by the Resolver, and then only those new symbols<br>
will take part in the resolution process very similar to what<br>
Resolver::resolve() does.<br>
- available implementations will not break and keep working without use of<br>
postprocessing feature.<br></blockquote><div><br></div><div>I'm fine with the basic idea of allowing undefined symbols in the first resolver pass. A few questions about the implementation.</div><div><br></div><div>- How do you know which atom is newly added and which is not? Once an atom is added to a MutableFile, there's no easy way to recognize that, I guess.</div><div><br></div><div>- Does the second resolver pass need to be run after all other passes? Why don't you run the resolver once, and then call some externally-given function (from the resolver) to get a list of atoms that needs to be added to the result, and then resolve again, all inside the resolver?</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
So my proposal is to move from the declarative style towards imperative<br>
and more flexible approach. Of course, there's a downside as the code<br>
loses some of its regularity and becomes more volatile, but in the end -<br>
we have tests to cover such things and ensure everything works as expected.<br>
<br>
Any ideas?<br>
<br>
- Denis Protivensky.<br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</blockquote></div><br></div></div>