<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Feb 23, 2015 at 12:26 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">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    Rui, see inline.<div><div class="h5"><br>
    <br>
    <div>On 02/20/2015 10:20 PM, Rui Ueyama
      wrote:<br>
    </div>
    <blockquote type="cite">
      <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>
        </div>
      </div>
    </blockquote></div></div>
    The Resolver returns Resolver::MergedFile type as a result of call
    to resolve(), and we can override its addAtom method to put newly
    added atoms to a special separate collection which then may be
    examined for undefines.<span class=""><br>
    <br>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">
            <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>
        </div>
      </div>
    </blockquote></span>
    Since we have a chance to determine newly added atoms after
    resolution, I don't see why to complicate the process with external
    functions and additional call dependencies. It all can be done by
    adding second resolve()-like function call in the Driver::link()
    after PassManager run.</div></blockquote><div><br></div><div>If we run the second pass immediately after the resolver runs, even without returning to the caller of the resolver, the resolver looks like a single pass process from outside, although internally it iterate twice. It makes post processing passes simpler if you can get all atoms that needs to be written to file just by calling the resolver once instead of getting incomplete set.</div><div><br></div><div>I guess you need to run some passes after the second resolver invocation. For example, you need to call the OrderPass to reorder newly added atoms to desired places. If resolver resolves everything in one invocation, you wouldn't think about that, too.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000"><span class="">
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">
            <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" target="_blank">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>
    </blockquote>
    <br>
  </span></div>

</blockquote></div><br></div></div>