Bug 219717 - lang/ccl: linker error: SHF_MERGE section size must be a multiple of sh_entsize
Summary: lang/ccl: linker error: SHF_MERGE section size must be a multiple of sh_entsize
Status: New
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Many People
Assignee: Jimmy Olgeni
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-06-02 05:50 UTC by O. Hartmann
Modified: 2020-03-30 17:34 UTC (History)
5 users (show)

See Also:
bugzilla: maintainer-feedback? (olgeni)


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description O. Hartmann 2017-06-02 05:50:16 UTC
On CURRENT (FreeBSD 12.0-CURRENT #4 r319490: Fri Jun  2 00:18:30 CEST 2017 amd64, WITH_LLD_IS_LD=yes), updating/building (also via poudriere) port lang/ccl fails due to the error shown below:

[...]
cc -m64 -g  -Wl,--export-dynamic    -o ../../fx86cl64  pad.o x86-spjump64.o x86-spentry64.o x86-subprims64.o pmcl-kernel.o gc-common.o  x86-gc.o bits.o  x86-exceptions.o  x86-utils.o  image.o thread_manager.o lisp-debug.o memory.o unix-calls.o x86-asmutils64.o  imports.o lispdcmd.o plprint.o plsym.o xlbt.o x86_print.o -lm -lthr
/usr/bin/ld: error: x86-spentry64.o: SHF_MERGE section size must be a multiple of sh_entsize
cc: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error code 1
Comment 1 Ed Maste freebsd_committer 2017-08-22 20:28:45 UTC
Confirmed with LLD 5.0.0 in FreeBSD-current:
/usr/bin/ld: error: x86-spentry64.o: SHF_MERGE section size must be a multiple of sh_entsize

It appears LLD_UNSAFE does not work with this port as ccl/lisp-kernel/freebsdx8664/Makefile does not pass through any ${CFLAGS} or {LDFLAGS}:

../../fx86cl64: $(KSPOBJ) $(KERNELOBJ) $(DEBUGOBJ) $(LINKSCRIPTFILE)
        $(CC) -m64 $(CDEBUG)  -Wl,--export-dynamic  $(LINKSCRIPT)  -o $@  $(KSPOBJ) $(KERNELOBJ) $(DEBUGOBJ) $(OSLIBS)
Comment 2 Ed Maste freebsd_committer 2018-03-27 20:36:55 UTC
Via tobik@ in ports r465725, BINARY_ALIAS=ld=ld.bfd may be an effective workaround if LLD_UNSAFE does not work.
Comment 3 Kirill Ponomarev freebsd_committer 2018-04-01 11:44:14 UTC
I suppose we've to mark it BROKEN on x64, it segfaults with ld.bfd as well:

cc -m64 -g  -Wl,--export-dynamic    -o ../../fx86cl64  pad.o x86-spjump64.o x86-spentry64.o x86-subprims64.o pmcl-kernel.o gc-common.o  x86-gc.o bits.o  x86-exceptions.o  x86-utils.o  image.o thread_manager.o lisp-debug.o memory.o unix-calls.o x86-asmutils64.o  imports.o lispdcmd.o plprint.o plsym.o xlbt.o x86_print.o -lm -lthr
Segmentation fault (core dumped)
Comment 4 Ed Maste freebsd_committer 2018-04-02 14:49:13 UTC
(In reply to Kirill Ponomarev from comment #3)
Just to confirm, was your segfault with ld.bfd on an otherwise-stock -CURRENT system?

I presume this works on stable/10 and stable/11 -- olgeni@?
Comment 5 Kirill Ponomarev freebsd_committer 2018-04-02 14:57:27 UTC
(In reply to Ed Maste from comment #4)
Yes, it segfaults with ld.bfd on recent CURRENT as well
Comment 6 Ed Maste freebsd_committer 2018-04-05 02:46:57 UTC
Move lld exp-run from "Blocks" to "See Also" as this fails on stock 12 as well.
Comment 7 R. Matthew Emerson 2020-01-01 00:22:37 UTC
Hi, upstream maintainer here.

We addressed the "SHF_MERGE section size must be a multiple of sh_entsize" on (amd64) 12.0-RELEASE by linking with "-fuse-ld=bfd", but on 12.1-RELEASE, /usr/bin/ld.bfd was removed.

What are our options here?

https://github.com/Clozure/ccl/issues/273
Comment 8 andrew 2020-03-28 05:11:46 UTC
What's actually happening here is an lld bug, either in the logic or in the error message, combined with what may be a bug in either the upstream code or in the assembler.

lld is checking that size is a multiple of sh_entsize BEFORE checking whether the section has SHF_MERGE set at all. Either this is the wrong logic (if size is only supposed to be a multiple of sh_entsize for merge sections, in which case the order of checks is backwards), or the wrong error message (if size is always supposed to be a multiple of sh_entsize, then the error message should not mention SHF_MERGE).

See function ObjFile<ELFT>::shouldMerge in lld/ELF/InputFiles.cpp

Now, the next question is why is `as` generating files with a .stab section in which the section size is not a multiple of sh_entsize. I guess that should not be happening either, but I don't know enough about ELF to be sure.

The specific files the linker fails on are all handcrafted assembler with various .stab directives. BFD seems to always set the sh_entsize of .stab sections to 4 + 2*sizeof(void*), i.e. 20 on 64-bit, but whatever `as` is putting in these sections does not conform to this size in all cases. Looking at dumps of the object files, the stride of the data they contain appears to be 12, not 20?
Comment 9 andrew 2020-03-30 02:52:09 UTC
Adding here for future reference: a workaround for the problem is using -Wl,-O0 which disables merging in the linker.