<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, May 4, 2015 at 1:29 AM, James Courtier-Dutton <span dir="ltr"><<a href="mailto:james.dutton@gmail.com" target="_blank">james.dutton@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On 1 May 2015 at 20:31, Rui Ueyama <<a href="mailto:ruiu@google.com" target="_blank">ruiu@google.com</a>> wrote:<br>
><br>
> One symbol resolution model doesn’t fit all The symbol resolution semantics<br>
> are not the same on three architectures (ELF, Mach-O and PE/COFF), but we<br>
> only have only one "core" linker for the symbol resolution. The core linker<br>
> implements the Unix linker semantics; the linker visits a file at a time<br>
> until all undefined symbols are resolved. For archive files having circular<br>
> dependencies, you can group them to tell the linker to visit them more than<br>
> once. This is not the only model to create a linker. It’s not the simplest<br>
> nor fastest. It’s just that the Unix linker semantics is designed this way,<br>
> and we all follow for compatibility. For PE/COFF, the linker semantics are<br>
> different. The order of files in the command line doesn’t matter. The linker<br>
> scans all files first to create a map from symbols to files, and use the map<br>
> to resolve all undefined symbols. The PE/COFF semantics are currently<br>
> simulated using the Unix linker semantics and groups. That made the linker<br>
> inefficient because of the overhead to visit archive files again and again.<br>
> Also it made the code bloated and awkward. In short, we generalize too much,<br>
> and we share code too much.<br>
><br>
<br>
</span>Why can't LLD be free to implement a resolving algorithm that performs better.<br>
The PE/COFF method you describe seems more efficient that the existing<br>
ELF method.<br>
What is stopping LLD from using the PE/COFF method for ELF. It could<br>
also do further optimizations such as caching the resolved symbols.<br>
To me,the existing algorithms read as ELF == Full table scan,  PE/COEF<br>
== Indexed.<br></blockquote><div><br></div><div>The two semantics are not compatible. The results of the two are not always the same.</div><div><br></div><div>For example, this is why we have to pass -lc after object files instead of the beginning of the command line. "ln -lc foo.o" would just skip libc because when it visits the library, there's no undefined symbols to be resolved. foo.o would then add undefined symbols that could have been resolved using libc, but it's too late. The link would fail. This is how linkers on Unix works. There are other differences resulting from the difference, so we cannot change that unless we break the compatibility.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Also, could some of the symbol resolution be done at compile time?<br>
E.g. If I include stdio.h, I know which link time library that is<br>
associated with, so I can resolve those symbols at compile time.<br>
Maybe we could store that information in the pre-compiled headers file<br>
format, and subsequently in the .o files.<br>
This would then leave far fewer symbols to resolve at link time.<br></blockquote><div><br></div><div>You can link against an alternative libc, for example, so that's not usually doable.</div></div></div></div>