[LLVMdev] Need to create symbols only once

Nick Kledzik kledzik at apple.com
Mon Jan 7 15:39:53 PST 2013

On Jan 7, 2013, at 3:23 PM, Shankar Easwaran wrote:
> On 12/7/2012 4:59 PM, Nick Kledzik wrote:
>> We have a similar requirement in darwin's ld64 linker, but even more general.  Any binary can do the following to introspect itself:
>> struct stuff { int a; int b; };
>> extern struct stuff*  stuff_start  __asm("section$start$__DATA$__my");
>> extern struct stuff*  stuff_end   __asm("section$end$__DATA$__my");
>> void examineSection() {
>> 	const struct stuff* p;
>> 	for (p = stuff_start; p < stuff_end; ++p) {
>> 		// do stuff with p
>> 	}
>> }
>> That is, there are magic symbol names which reference the beginning or ending of any particular section.   To support this, the linker lazily creates atoms when references to these magic symbols are discovered during resolving.
>> I have some hooks for this already in place in lld:
>> 1) There is Writer::addFiles().  This method gives any writer a change to add files/atoms to the set of atoms the Resolver works on.   The Writer::addFiles() method is called after all input files are added.  If you want to add something lazily (like darwin linker does for section$start$ symbols), the writer returns a File object akin to a static library.  That it, it provides no initial atoms, but can provide atoms as a last resort (so an .o files would override it).  The WriterMachO already uses the addFiles() method to add CRuntime symbols.
>> 2) DefinedAtom::ContentType already has typeFirstInSection and typeLastInSection.  These are intended to be used for the content type of the atoms which represent the magic symbols for the start and end of a section.  The key here is that the Pass (not written yet) which sorts atoms, knows to sort these atoms to the start or end of their respective sections.
>> If you don't want this full general, lazy approach, you could have your WriteELF::addFiles() return a regular object file that has atoms named __bss_start and __bss_end, but they are marked mergeAsWeak so that any user defined atoms will override them.
> The case I have is a bit different now. I added symbols __bss_start/__bss_end/_end using WriterELF::addFiles(). The symbols get overridden appropriately but the value of the symbols are known only after the sections have been merged and the virtual addresses assigned to those symbols.
> So when I am trying to write these atoms to the output file, I want to set the value of these symbols to the values computed by the ELF Writer.
> These atoms are NativeAtoms and i dont see a function to set the value of the atom, How do I go about accomplishing this functionality.

The same way you any atom gets an address.  When the Writer gets the set of atoms to write out, the Writer is the one that assigns them addresses.  And by "assign" I mean the Writer maintains some extra information for each atom, such as its assigned section, segment, and address.  So, your writer just needs to assign the value of the section start to the __bss_start atom.

Note: this is why it does not make sense for a Reader and Writer to share common Atom classes.  When the Writer finally gets the atoms, they may not be of that class.  The Writer can only depend on the standard attributes of an atom - not something special it can do when the atom's class is known.


More information about the llvm-dev mailing list