RFR: 8336849: Remove .llvm_addrsig section from JDK/VM static libraries (.a files)
Jiangli Zhou
jiangli at openjdk.org
Tue Aug 6 23:44:31 UTC 2024
On Tue, 6 Aug 2024 18:58:42 GMT, Magnus Ihse Bursie <ihse at openjdk.org> wrote:
> > No, it's not when building libjvm.a. It's when linking the final elf executable using libjvm.a (or libnet.a, etc) that's created with ld -r or objcopy. During the final elf executable linking time, user could include additional desired linker flags, such as -Wl,--icf=safe. That's the case where things can run into trouble.
>
> Ok, I see. The static library that we generate is not usable by a later invocation of lld.
Yes, that's the problem.
>
> Just out of curiousity, is running objcopy required to reproduce this problem, or is it enough to run lld first with -r and then for linking the static library into an executable? If it is the latter, I think it is a really sorry implementation in lld, if they can't even use their own output. (If objcopy messes up the file, then it's a different story -- I can't really blame them if that would happen).
Either `objcopy` **or** `ld -r` could invalidate the `.llvm_addrsig` according to the linked blog (which has the nice description of the related details).
While searching for additional information today to help make things more clear for our discussion in this thread, I just found `strip` could also invalidate the section. https://sourceware.org/bugzilla/show_bug.cgi?id=23817 mentions about the issue with `strip`. Also, according to the comments in https://sourceware.org/bugzilla/show_bug.cgi?id=23817, it seems tools might not be updated to address the corrupted `.llvm_addrsig` section.
>
> > We don't have control of the linker flags that users might want to use.
>
> Well, that is indeed correct, but we can tell them that there is a know problem with lld that it cannot link these binaries with --icf=safe. (At this point I am primarily treating this as an lld bug/limitation.)
>
> > > If you were to remove these sections, then the linker will believe that all functions are safe to merge.
>
> > How did you arrive the conclusion?
>
> I quoted the part from one of the links you sent: "Functions that are not mentioned in the section are not address-taken (no one takes its pointer), so they are safe to merge."
https://llvm.org/docs/Extensions.html#sht-llvm-addrsig-section-address-significance-table probably (found today) is more clear:
"Any sections referred to by symbols that are not marked as address-significant in any object file may be safely merged ..."
So if symbols are treated as "address-significant", then referring object file may not be safely merged. See more related comments below.
>
> Prior to reading this PR, I did not know about icf, so I have no other knowledge about how it works. I interpreted the paragraph above as it would be risky to remove this section (given that it might have contained relevant content before it was mangled by ld -r/objcopy), since it would apply that there were no functions that needed preserving.
>
> > When .llvm_addrsig section is removed (not present), my understanding is that the linker would only do conservative identical code folding safely.
>
> Well, my contrary question is then: How did you arrive at this conclusion? I'd like to get some definite, authoritative documentation on how icf works in the presence of a mangled .llvm_addrsig section vs an intentionally removed .llvm_addrsig section.
My understanding is based on the descriptions in the linked blog, specifically the part quoted from the blog in my pervious comment (quoted below again to be more clear):
"ld.lld --icf=safe uses a special section .llvm_addrsig (LLVM address significance table, type SHT_LLVM_ADDRSIG) produced by Clang -faddrsig....If the section is absent, ld.lld is conservative and assumes every section defining a symbol in the table is address significant."
>
> As I see it, unless there is documentation stating that removing the .llvm_addrsig section is safe to combine with --icf=safe, then the only reliable option is to not use icf at all. Reasonably, lld should fall back to that behavior if it is missing .llvm_addrsig sections, but apparently it chooses to fail instead.
>
> I'm not sure what this "conservative" icf you talk about means. My understanding, after trying to read the docs now, is that there is only three modes that ICF works in: safe, all or none. If this understanding is correct, then you only have two options if lld can't do safe icf: namely all or none. And all seems to be a dangerous choice, since it can lead to UB.
>
> > Removing .llvm_addrsig is safe.
>
> You keep saying this. Please show me some documentation that supports this claim.
Unfortunately, the blog article was the most comprehensive summary about the issue with the corrupted .llvm_addrsig that I was able to find. I could not find any official documentation about removing the `.llvm_addrsig` section. In this case, I trust the expert. Additionally, the comment in https://lists.llvm.org/pipermail/llvm-dev/2018-May/123528.html (I found today) matches with the blog info, specifically:
"but now I see you assume all symbols are address-significant if there's no address-significance table in the file"
Anyway, we can't **safely** keep the corrupted `.llvm_addrsig` section in `libjvm.a` and etc.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/20265#issuecomment-2272346203
More information about the build-dev
mailing list