<div dir="ltr"><div dir="auto"><div>Hi, Vlad.</div><div><br></div><div>Sorry for the late answer. I was going to recheck ideas you've proposed, but didn't have time for that.</div><div>So my answer is based on my knowledge only.<br></div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, 20 Jun 2020, 02:39 Vladislav Shpilevoy, <<a href="mailto:v.shpilevoy@tarantool.org" target="_blank">v.shpilevoy@tarantool.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi! Thanks for the investigation!<br>
<br>
On 19/06/2020 15:02, Yaroslav Dynnikov wrote:<br>
> I've researched the linking process and here is what I've found.<br>
> <br>
> First of all, let's talk about symbols removal. Here is an interesting note on<br>
> how it works: <a href="https://stackoverflow.com/questions/55130965/when-and-why-would-the-c-linker-exclude-unused-symbols" rel="noreferrer noreferrer" target="_blank">https://stackoverflow.com/questions/55130965/when-drop unuseddrop unusedand-why-would-the-c-linker-exclude-unused-symbols</a><br>
> One of the basic important concepts is an ELF section. It's a chunk of data<br>
> (assembly code in our case) that linker operates on. A section may contain code<br>
> of one or more functions (depending on build arguments), but it can't be split<br>
> during linking.<br>
> <br>
> Usually, when we build an object file with `gcc libx.c -c -o libx.o`, all<br>
> functions from libx.c go into the single ".text" section. This single object<br>
> file is usually archived with others into single libx.a, which is later<br>
> processed during main executable linking.<br>
> <br>
> By default (but I can't provide the proof), when we call `gcc -lx` linker<br>
> operates on object files from the archive - if at least one symbol is used,<br>
> whole .o (not .a) is included in the resulting binary. There are also two linker<br>
> options that influence this behavior. At first, there is `-Wl,--whole-archive`,<br>
> which makes it to include whole `.a` instead of `.o` granularity. Secondly, there is<br>
> `-Wl,--gc-sections` which could remove unused sections, but in basic example<br>
> it's useless since all symbols from .o belong to the same .text section. To make<br>
> `--gc-sections` have an effect one should compile object files with<br>
> `-ffunction-sections` flag. It'll generate a separate section for every function<br>
> so the linker could gc unused ones.<br>
> <br>
> See:<br>
> ```console$ cat libx.c<br>
> #include <stdio.h><br>
> <br>
> void fA() {<br>
> printf("fA is here\n");<br>
> }<br>
> void fB() {<br>
> printf("fB is here\n");<br>
> }<br>
> $ gcc libx.c -c -o libx.o -ffunction-sections<br>
> $ readelf -S libx.o | grep .text<br>
> [ 1] .text PROGBITS 0000000000000000 00000040<br>
> [ 5] .text.fA PROGBITS 0000000000000000 00000056<br>
> [ 6] .rela.text.fA RELA 0000000000000000 000002d8<br>
> [ 7] .text.fB PROGBITS 0000000000000000 0000006d<br>
> [ 8] .rela.text.fB RELA 0000000000000000 00000308<br>
> ```<br>
> <br>
> Now let's move to the `libbit` which Vlad mentioned.<br>
> I've investigated how compiler options influence the resulting binary. Unused<br>
> functions from bit.c are really remover, but only with Release flags, and here<br>
> is why:<br>
> <br>
> There are only 2 functions implemented in bit.c, and both are unused. All the<br>
> others are inlines in bit.h and externs from luajit. When tarantool is built in<br>
> debug mode, the inlining is off, so other modules truly link to the bit.o and<br>
> all symbols remain including unused functions. But if we specify -O2 flag,<br>
> inlining takes place, and all the symbols from bit.o becomes unused, so the<br>
> linker drops the whole object file.<br>
<br>
So do you mean, that if a library consists of more than 1 C file (and builds<br>
more than one .o file), and functions from some of them are not used, these<br>
.o files and their code will be removed?<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Exactly. Moreover, it depends on the gcc command syntax.</div><div>Suppose we have libx.a with two object files: fA.o and fB.o. Function from fA is used, and fB isn't.</div><div>Then `gcc main.c libx.a` will produce binary with both fA and fB.</div><div>While `gcc main.c -lx` will include fA only, and unused fB will be dropped.</div><div>It's also mentioned in the <a href="https://stackoverflow.com/questions/55130965/when-and-why-would-the-c-linker-exclude-unused-symbols">SO question</a> I linked in the previous message.<br></div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
If it is true, it does not look like green light for the patch and requires<br>
more experiments. For example, try to add a new library with several C files,<br>
use only some of them in the Tarantool executable (just add to exports.h),<br>
and see if code from unused .o files is removed even when they are built into<br>
.a file.<br></blockquote><div><br></div><div>I guess the solution will be adding --whole-archive flag. But i'm not sure yet.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
However, as I said in private - I am ok with pushing this patch now. I just<br>
don't see why is it necessary. Why is it so important to push it? Push just<br>
for push? Just to close an issue? It does not improve anything, EXPORT_LIST<br>
still may appear to be useful along with some other things I removed in 2971,<br>
when I didn't think of the static build.<br></blockquote><div><br></div><div>You're right, it's not that important. I've already told Alex Barulev that we'll postpone this</div><div>cleanup until we finish with static build refactoring.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> Finally, speaking about this patch, my proposal is to merge this PR as is.<br>
> And since we know how to manage linking, other problems can be solved separately<br>
> (if they ever occur).<br>
> <br>
> Best regards<br>
> Yaroslav Dynnikov<br>
</blockquote></div></div></div>
</div>