<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>I've rewritten a lot of what I was doing, now as a clang driver action invoked by -emit-ifso. The change is at <a href="https://reviews.llvm.org/D60974">https://reviews.llvm.org/D60974</a></div><div>I'd like to get some skeleton of clang-ifsos upstream at some point in the not too distant future; could this change be reviewed? <br></div><div><br></div><div>Please let me know what you think. I have inlined replied to your comments, thanks for the feedback BTW!</div><div><br></div><div>Puyan<br></div><div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 9, 2019 at 2:06 AM Jake Ehrlich <<a href="mailto:jakehehrlich@google.com">jakehehrlich@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div dir="auto">I think using .o files is possible from llvm-elfabi. It should also be possible to support doing this from headers. I think both of those methods have issues however. In particular I think producing this from .o files isn't worth it when you can just produce it from the fully linked binary anyways.<div dir="auto"><br></div><div dir="auto">Let's explore some options and some trade offs.</div><div dir="auto"><br></div><div dir="auto">1) Producing from headers: This let's you build the .tbe file and/or stub before anything is compiled or linked. It however requires you to keep track of headers which is slightly complicated or verbose depending nonnhow you do it. It also requires reparsing everything. Further still you have to make sure you have all the same flags and you also have to make lots.of assumptions about the linker. It's basically very redundant and requires a lot of matching of behavior of the compiler and linker. Also keep in mind that you can at most match the behavior of 1 compiler and 1 linker. They're similar but not exactly the same and there are 4 major combinations of these things between GNU and llvm. Also keep in mind that in general you actually need to use arbitrary source nfiles not just headers files.</div><div dir="auto"><br></div></div></div></blockquote><div><br></div><div>Yes, you are definitely right. I talked some with alexshap and compnerd and we'vce decided that a header processor is not the way to go because of this and also because you dont know all the flags that the build system invoked the driver with. <br></div><div>So D60974 is a different approach that traverses every TU and is invoked by the actual driver. Right now the patch only writes a list of mangled names to the file, but I think it could do something like tbe or elf or yaml. <br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div dir="auto"><div dir="auto"></div><div dir="auto">2) Producing .tbe files from .o files: This means that all compilation must be performed first but linking can be done in parallel. That's a pyrrhic victory however when you consider the IO cost. Additionally while you no longer have to match the behavior of the compiler you still have to match linker behavior. The pro is that this probably fits nicely into existing builds. It also requires no changes to clang.</div><div dir="auto"><br></div></div></div></blockquote><div><br></div><div>Yeah, I think generating tbe's from the frontend Translation Units could be a good place to start. It's honestly probably the best way to account for the flags that the build is invoking on the actual compiles; by adding -emit-ifso I think it could produce something thats more consistent with that would be exposed by the intended build flags.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div dir="auto"><div dir="auto"></div><div dir="auto">3) Outputting a single file for each translation unit that can eventually be linked just like above: this is just a slightly better version if the above. Keep in mind that .tbe files match the ABI if a DSO so they have things like soname and dynamic library dependencies so you can't reuse the same format. This still has most of the draw backs of the above but I cost is probably slightly less overall but you increase the amount of IO output by the compiler. This also requires a <a href="http://change.to" target="_blank">change.to</a> clang</div><div dir="auto"><br></div></div></div></blockquote><div><br></div><div>Yep.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div dir="auto"><div dir="auto"></div><div dir="auto">4) Producing from fully linked DSO. This should be just as easy to incorporate into a build and uses far less IO than using a bunch of special files or object files. It also requires no matching of behavior with the linker. This seems strictly better to me than the above methods. This also requires no modifications to clang. This is intended to be a supported mode for llvm-elfabi.</div><div dir="auto"><br></div></div></div></blockquote><div><br></div><div>I think the next thing I will look at once I decide on a proper output format to start with is, setting up something like llvm-elftapi as a link command in clang.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div dir="auto"><div dir="auto"></div></div><div dir="auto">5) keep .tbe files in your source tree and produce stubs from .the files. This has all the benefits of 4 and then some at the consequence of requiring users to maintain these files themselves (via llvm-elfabi mind you) and the consequence of being far more complicated to incorporate into a build. But the benefits are huge. Your ABI becomes a reviewable part of your source. Your modules build in 100% since linking one module no longer depends on linking another module, just building the stub (or potentially just the .tbe file). This is an intended mode for llvm-elfabi and the situation I want our personal builds to work towards. I think 4) is still important to make work however.</div><div dir="auto"><br></div></div></blockquote><div><br></div><div>This could work, or they tbes could be regenerated as a result of the visibility attributes/visibility flags/dllexports (in the case of MS).<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div dir="auto"></div><div dir="auto">From my perspective, llvm-elfabi already is intended to support the optimal use cases. Other ways of operating seem strictly less optimal. For timelines I plan on picking llvm-elfabi back up on April 16th. Contributions welcome. I can start filling bugs for features if you'd like.</div><div dir="auto"><br></div><div dir="auto">There was some other talk if using yaml2obj or code from llvm-objcopy to emit ELF files. I think this should be more carefully considered before proceeding. Neither it these things are quite in ideal fidelity with the needs at play here. I can talk more about it but if we use llvm-elfabi, or at least use the same writer from it, I don't think that's really need. Making llvm-objcopy into a library is a big task and the result is probably not ideally suited for this but we could speak more about that.</div><div dir="auto"><br></div></div></blockquote><div><br></div><div>Cool. Lets talk more on this. Looking forward to it.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div dir="auto"></div><div dir="auto">Best,</div><div dir="auto">Jake</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 9, 2019, 1:58 AM Puyan Lotfi via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" rel="noreferrer" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>So, we are actually now thinking of redoing this patch but using a similar idea.</div><div><br></div><div>Petr, would llvm-elfabi be capable of merging multiple of these tbe files?</div><div><br></div><div>I'm looking at implementing something in the Driver that basically generates a tbe file for each .o file. The benefit would be that you could pretty easily just let loose your standard clang build invocation already in your build system with a couple added flags, and that's all you'd need to do to generate the ifsos assuming llvm-elfabi could consume all of the tbe's and link them together etc.<br></div><div><br></div><div>I think tbe could be a point of collaboration on this. Thoughts? <br></div><div><br></div><div>PL<br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Apr 5, 2019 at 2:35 PM Puyan Lotfi <<a href="mailto:puyan.lotfi.llvm@gmail.com" rel="noreferrer noreferrer" target="_blank">puyan.lotfi.llvm@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div>A few of us (Alex, Saleem and I) have discussed ideas for ELF generation. It sounds like aside from yaml2obj, lld, and MC's ELFObjectWriter there is also all of the ELF emission done by llvm-objcopy.</div><div>Alex tells me he's actually been intending to extract a lot of the ELF emission code from llvm-objcopy (llvm/tools/llvm-objcopy/ELF/Object.cpp/h) into a library somewhere in lib/Object.</div><div>We think it's probably best to do this refactoring, then eventually have llvm-elfabi, clang-ifso, yaml2obj, etc all do their ELF writing through it in some capacity (either going through one of the text formats, or directly). <br></div><div><br></div><div>As far as clang-ifso goes, I think it should be a standalone tool that is capable of generating multiple ifso formats (yaml, tbe, raw elf, etc).</div><div>At some point soon I will probably put up a phabricator patch that only includes the yaml emission along with some tests; I think that could work for now.<br></div><div><br></div><div>Thoughts?<br></div><div><br></div><div>PL<br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Apr 5, 2019 at 9:47 AM Puyan Lotfi <<a href="mailto:puyan.lotfi.llvm@gmail.com" rel="noreferrer noreferrer" target="_blank">puyan.lotfi.llvm@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>CC'ing George and Alex:<br></div><div><br></div><div>I was thinking along these lines, that it would be nice to have some kind of common code base for things like yaml2obj as well. I spent some time at first looking at and trying to decouple yaml2elf from the yaml parts until I realized that it'd be a lot better to just generate the yaml in memory and pass it on to yaml2elf. <br></div><div><br></div><div>Is llvm-elfabi planning to interop with yaml2obj any? As far as I can tell, currently in the monorepo the only places that are creating ELF .dyn* sections are in yaml2obj and lld. I agree it'd be nice to figure out some kind of code reuse plan.</div><div><br></div><div>PL</div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Apr 4, 2019 at 6:21 PM Petr Hosek <<a href="mailto:phosek@chromium.org" rel="noreferrer noreferrer" target="_blank">phosek@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>llvm-elfabi is going to generate ELF binaries directly as well (we originally considered extending lld to support tbe files directly but we later decided not to do that to avoid introducing the additional complexity). It'd be great if clang-ifso could emit tbe files and use the same implementation for generating ELF binaries to avoid duplication between the two tools.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Apr 4, 2019 at 5:42 PM Puyan Lotfi <<a href="mailto:puyan.lotfi.llvm@gmail.com" rel="noreferrer noreferrer" target="_blank">puyan.lotfi.llvm@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div dir="auto">Shoaib, Petr:</div><div dir="auto"><br></div><div dir="auto">I don’t yet know the full details of elf-tapi, but the two ways I believe these differs are:</div></div><div dir="auto"><br></div><div dir="auto">1) clang-ifso is a clang based tool that scans from the source level and uses visibility attributes to put together a set of symbols to expose in the ifso file.</div><div dir="auto"><br></div><div dir="auto">2) clang-ifso primarily aims to generate the ELF binary directly, but also can generate yaml that yaml2obj can generate the ifso from. Currently the aim is to avoid introducing linker changes.</div><div dir="auto"><br></div><div dir="auto">It’s possible clang-ifso could also support generating said text stubs (tbe’s) too. </div><div dir="auto"><br></div><div dir="auto">PL</div><div dir="auto"><br></div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Apr 4, 2019 at 5:23 PM Petr Hosek <<a href="mailto:phosek@chromium.org" rel="noreferrer noreferrer" target="_blank">phosek@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">To expand on Shoaib's answer, <a href="https://github.com/llvm/llvm-project/tree/master/llvm/tools/llvm-elfabi" rel="noreferrer noreferrer" target="_blank">llvm-elfabi</a> is a very similar tool that we've been working on for the past few months in upstream. The current implementation is still incomplete, but once <a href="https://reviews.llvm.org/D56569" rel="noreferrer noreferrer" target="_blank">D56569</a>, <a href="https://reviews.llvm.org/D55839" rel="noreferrer noreferrer" target="_blank">D55839</a> and <a href="https://reviews.llvm.org/D55864" rel="noreferrer noreferrer" target="_blank">D55864</a> land (hopefully within the next few weeks), it should be possible to use llvm-elfabi to produce text stubs (called .tbe files) and generate ELF interface libraries out of those.</div><br><div class="gmail_quote"></div></div><div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Apr 4, 2019 at 5:18 PM Shoaib Meenai via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" rel="noreferrer noreferrer" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div></div></div><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"></blockquote></div></div><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div lang="EN-US">
<div class="gmail-m_7552073925301895018m_2108536495774980073m_7483233099741783304gmail-m_2798825586137396903gmail-m_-3550973895312573038gmail-m_-6398311049467403694gmail-m_6902049836027588738gmail-m_-407637124857708792m_-1450170119475932521gmail-m_-1546291320869488466WordSection1">
<p class="MsoNormal">How does this compare to the ELF TAPI implementation in LLVM (<a href="http://lists.llvm.org/pipermail/llvm-dev/2018-September/126472.html" rel="noreferrer noreferrer" target="_blank">http://lists.llvm.org/pipermail/llvm-dev/2018-September/126472.html</a> and
<a href="https://reviews.llvm.org/D53051" rel="noreferrer noreferrer" target="_blank">https://reviews.llvm.org/D53051</a>)? <u></u>
<u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border-color:rgb(181,196,223) currentcolor currentcolor;border-style:solid none none;border-width:1pt medium medium;padding:3pt 0in 0in">
<p class="MsoNormal"><b><span style="font-size:12pt;color:black">From: </span></b><span style="font-size:12pt;color:black">cfe-dev <<a href="mailto:cfe-dev-bounces@lists.llvm.org" rel="noreferrer noreferrer" target="_blank">cfe-dev-bounces@lists.llvm.org</a>> on behalf of cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" rel="noreferrer noreferrer" target="_blank">cfe-dev@lists.llvm.org</a>><br>
<b>Reply-To: </b>Puyan Lotfi <<a href="mailto:puyan.lotfi.llvm@gmail.com" rel="noreferrer noreferrer" target="_blank">puyan.lotfi.llvm@gmail.com</a>><br>
<b>Date: </b>Thursday, April 4, 2019 at 4:52 PM<br>
<b>To: </b>cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" rel="noreferrer noreferrer" target="_blank">cfe-dev@lists.llvm.org</a>><br>
<b>Cc: </b>Puyan Lotfi <<a href="mailto:puyan@puyan.org" rel="noreferrer noreferrer" target="_blank">puyan@puyan.org</a>><br>
<b>Subject: </b>[cfe-dev] [RFC] clang-ifso: A new clang-based tool for generating interface libraries.<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<div>
<div>
<p class="MsoNormal">Hi All,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">The following is our proposal for clang-ifso, we hope to get some valuable feedback from the community on this and we hope this work helps SDK authors in the future:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">On platforms such as Darwin and Windows, there exist library interface files (TAPI tbd files, Windows Import Library files) that appear to the compile-time linker as just another library file (i.e. dylib, dll, etc) but are in-fact only
empty listings of symbols to interface functions that were intended for exposure by the library writer (i.e. their `.text` sections are stripped, but they have the API symbols needed for linking). These library interfaces can be used to both limit access to
internals of a library at static compile time, and can be used to speedup link time in the case of linking with extremely large dynamic libraries. Aside from providing more controlled API exposure and reduced memory usage in linking, there is also the benefit
of having a much smaller distribution size for development SDKs (in the case where you’ve got an SDK with applications that are built and linked on a PC but then deployed to run on a totally different device). Finally, these interface libraries can in many
cases be used to break up build dependencies as well if they can be cached or generated quickly in some way prior to building all the different libraries in a build.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">clang-ifso is a tool that intends to bring the concept of interface libraries to ELF shared objects. We call it ifso as a shorthand for InterFace-Shared-Object: as in, we intend to support ELF by producing a .so that looks just like a regular
.so file to the linker but has most of the .text and other contents dropped and has only the intended API interface symbols populated. That means a .so file generated by clang-ifso contains only a stripped .text section plus the `.dynsym` and `.dynstr` sections
along with the global symbols populated. Currently it is in a prototype state and is capable of generating object-yaml or ELF, and is implemented using the ClangTool interface.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">As mentioned at the beginning, there is prior art in this area with things like TBD files on Darwin as well as Microsoft’s import libraries. As an aside, there is evidence that ELF versions of ifsos are also deployed in production in some
settings, so this is not completely new with ELF either but the effort to make all of the work upstream is. One other way that clang-ifso does differ from a lot of the prior work is that it uses the clang parser to glean what visible NamedDecls are present
in the library headers.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Because clang-ifso operates from the clang level we can and do enable the programmer to use visibility attributes to expose or hide whatever interface libraries they want in their actual code rather than relying on a separate file to strip
symbols as a post-build step. And since all compile-time linking will be done with the ifso rather than the .so, all clients of the library will need to completely rely on whatever was exposed through visibility attributes.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">We are eager to to hear feedback and ideas in this space. Code for clang-ifso is available at:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><a href="https://github.com/plotfi/llvm-project/tree/master/clang/tools/clang-ifso" rel="noreferrer noreferrer" target="_blank">https://github.com/plotfi/llvm-project/tree/master/clang/tools/clang-ifso</a>.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">PL<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div>
</div>
</div></blockquote></div></div><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" rel="noreferrer noreferrer" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer noreferrer noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div>
</blockquote></div></div>
</blockquote></div></div>
</blockquote></div>
</blockquote></div>
</blockquote></div>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" rel="noreferrer noreferrer" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer noreferrer noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div>
</blockquote></div></div></div></div></div>