Please merge linker bugfix into Ubuntu 20.04 LTS
Bug #1902760 reported by
Barry M Tannenbaum
This bug affects 1 person
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
binutils |
Fix Released
|
Medium
|
|||
intel |
New
|
Undecided
|
Unassigned | ||
binutils (Ubuntu) |
Incomplete
|
Undecided
|
Unassigned |
Bug Description
Binutils bug https:/
Changed in binutils: | |
importance: | Unknown → Medium |
status: | Unknown → Fix Released |
tags: | added: rls-ff-incoming |
tags: | added: focal |
tags: | added: fr-926 |
To post a comment you must log in.
This can be reproduced with clang 10 (likely also 9; and all master commits before https:/ /reviews. llvm.org/ D83967 ). LLVMgold.so is needed.
% cat a.c bin/clang -fuse-ld=bfd -fprofile-generate -flto a.c -Wl,-plugin- opt=save- temps -Wl,-y, __llvm_ profile_ raw_version -Wl,-plugin- opt=save- temps profile_ raw_version lib/clang/ 12.0.0/ lib/linux/ libclang_ rt.profile- x86_64. a(InstrProfilin g.c.o): definition of __llvm_ profile_ raw_version
int main() {}
% /tmp/Debug/
/usr/bin/ld.bfd: /tmp/a-e575a9.o (symbol from plugin): definition of __llvm_
/usr/bin/ld.bfd: /tmp/Debug/
/tmp/a-e575a9.o (symbol from plugin) provides a definition in a prevailing comdat group. rt.profile- x86_64. a(InstrProfilin g.c.o) is an weak definition which should not override the IR definition.
libclang_
% cat a.out.resolutio n.txt a-e575a9. o,main, plx a-e575a9. o,__llvm_ profile_ raw_version, l # should be 'plx' instead of 'l' a-e575a9. o,__llvm_ profile_ filename, plx
/tmp/a-e575a9.o
-r=/tmp/
-r=/tmp/
-r=/tmp/
Gold and LLD are correct.
% /tmp/Debug/ bin/clang -fuse-ld=gold -fprofile-generate -flto a.c -Wl,-plugin- opt=save- temps -Wl,-y, __llvm_ profile_ raw_version profile_ raw_version lib/clang/ 12.0.0/ lib/linux/ libclang_ rt.profile- x86_64. a(InstrProfilin g.c.o): definition of __llvm_ profile_ raw_version profile_ raw_version n.txt a-668c9c. o,main, plx a-668c9c. o,__llvm_ profile_ raw_version, plx a-668c9c. o,__llvm_ profile_ filename, plx
/tmp/a-668c9c.o: definition of __llvm_
/tmp/Debug/
a.out.o: definition of __llvm_
% cat a.out.resolutio
/tmp/a-668c9c.o
-r=/tmp/
-r=/tmp/
-r=/tmp/
% /tmp/Debug/ bin/clang -fuse-ld=lld -fprofile-generate -flto a.c -Wl,-plugin- opt=save- temps -Wl,-y, __llvm_ profile_ raw_version profile_ raw_version profile_ raw_version profile_ raw_version n.txt a-afb841. o,main, plx a-afb841. o,__llvm_ profile_ raw_version, plx a-afb841. o,__llvm_ profile_ filename, plx
/tmp/a-afb841.o: definition of __llvm_
<internal>: reference to __llvm_
lto.tmp: definition of __llvm_
% cat a.out.resolutio
/tmp/a-afb841.o
-r=/tmp/
-r=/tmp/
-r=/tmp/
The ld bug is in ld/plugin. c:plugin_ notice . ld somehow drops bfd_link_ hash_defined (provided by "/tmp/a-e575a9.o (symbol from plugin)") in favor of bfd_link_ hash_undefweak. Then bfd_link_ hash_undefweak is overridden by the weak definition in libclang_ rt.profile- x86_64. a(InstrProfilin g.c.o)
/* Otherwise, it must be a new def. hash_defweak hash_defined) section- >owner) ) hash_common p->section- >owner) )) hash_undefweak;
Ensure any symbol defined in an IR dummy BFD takes on a
new value from a real BFD. Weak symbols are not normally
overridden by a new weak definition, and strong symbols
will normally cause multiple definition errors. Avoid
this by making the symbol appear to be undefined. */
else if (((h->type == bfd_link_
|| h->type == bfd_link_
&& is_ir_dummy_bfd (sym_bfd = h->u.def.
|| (h->type == bfd_link_
&& is_ir_dummy_bfd (sym_bfd = h->u.c.
{
h->type = bfd_link_
h->u.undef.abfd = sym_bfd;
}
The intended behavior is to let "/tmp/a-e575a9.o (symbol from plugin)" provide the definition.