[PATCH] [Layout] Assign ordinals in resolution order

Nick Kledzik kledzik at apple.com
Wed Oct 9 19:06:33 PDT 2013


On Oct 9, 2013, at 6:53 PM, Shankar Easwaran <shankare at codeaurora.org> wrote:
> Hi Nick,
> 
> On 10/9/2013 7:15 PM, Nick Kledzik wrote:
>> On Oct 8, 2013, at 10:44 PM, Shankar Easwaran <shankare at codeaurora.org> wrote:
>> 
>>> On 10/9/2013 12:40 AM, kledzik at apple.com wrote:
>>>>   It looks to me like the ordinals are assigned to archive members as the members are used.  This will result in unstable output because the lazy loading nature of archives loads the members in some what chaotic way (small changes to what if referenced by initial .o files can radically change the load order of members).
>>> ELF needs the symbols to appear in resolution order.
>> Is this so the layout matches the gnu linker? or some semantic issue?
> Yes it helps to match the layout, so that comparing binaries produced by the Gnu linker and lld would be quite similiar.
> 
>> 
>> I can see that simply appending section content in load order is simple and predictable.  But it just pushes the stability problem off to the resolver.  Now it is important that the archive members are loaded in a stable order.  For instance say you have a couple of .o files on the command line followed by a couple of archives.  After all the object files are loaded and atom graphs merged, you have two undefined symbols foo and bar left to resolve.  Which should the resolver look for first?  That is important because it now effect the layout.  Some possibilities:
> I dont think the order of unresolved symbols resolved is documented. This is upto each linker to handle.
> 
> Even if we want to do that, foo and bar are going to pulled from the archive irrespective of the order isnt it ? Am I missing some details here.
You said you wanted the layout to match gnu linker, but the layout is based on the order in which archive members are loaded, and the order they are loaded depends on the order the undefined symbols are processed.  So, unless the undefined order matches the gnu linker, then the layout will not match either.



> May be lld could do the same as darwin to sort the unresolved symbols by name before resolution, could be an option if the user wants to tune the link.
>> 1) base the order on the ordinal of the object files the undefines came from.  If the first .o needs foo and the second needs bar, then looking for foo then bar, is understandable and stable.  But the current lld resolver does not sort undefines by ordinal, or guarantee that coaelseced undefines keep the lower ordinal.
> Imposing a order requirement of unresolved symbols might slow down the link too in my opinion isnt it. If we decide to have this functionality, we could use a vector and sort it file ordinal followed by atom ordinal.
>> 2) base the order on the hash table order of the undefines.  This is what lld currently does.  I hope it is not what gnu ld does.  Since the file ordinals are now based on load order, that means that the final layout depends on the hashing function used!  Not something a user would expect.
>> 3) sort all undefined alphabetically, and resolve them in that order.  This is what the darwin linker does.  But, there are two ways to do this.  One is that once the linker gets a sorted list of undefines, it tries to resolve each one, then ask the symbol table for a new list of undefines.  The other variant is that each time the linker has loaded an archive member, it asks the symbol table for a new sorted list of undefines.
> I think this could be a user option. But I dont know how many users would do this.
These are not user options.  These are possible algorithms.  You’ll need to pick the one that matches gnu’s linker if you want the same layout as the gnu linker.

Note that the the darwin linker, the undefine processing order does not matter because the final layout is based on command line order and member order within archives, so the order in which members are loaded does not effect layout.

-Nick



>> 
>> 
>> 
>>>>   For the darwin linker, we gave each archive a range of ordinals.  For instance if you link with -lfoo -lbar, the library ordinal for libfoo.a might be 100 and for libbar.a be 200.  Later when members are loaded from each, the member's ordinal is the owning libraries ordinal plus the member index (libfoo.a(foo.o) might have an ordinal of 100+3=103).
>>> DarwinLinkingContext would need to override the getNextOrdinalAndIncrement function, that would use the currentInputElement and the file returned to associate ordinals like earlier.
>> When I get to the point I need to fix this for mach-o, I’ll probably need to change this design a little.  For instance, getNextOrdinalAndIncrement() will need to some context parameters (e.g. being called for member archive vs top level object file).
> The LinkingContext already has that information. This is contained in the currentInputElement. The currentInputElement always points to what InputElement in the graph, the resolver is processing. If the currentInputElement is a FileNode, it contains Files which have ordinals. If the currentInputElement is a controlNode, the currentElementIndex in the
> control node, specifies the element thats processed.  You might want to store the current file also being processed.
> 
> Shankar Easwaran
> -- 
> 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation
> 





More information about the llvm-commits mailing list