I’m compiling existing code developed against gcc with clang/lld. The code has construct similar to:
__attribute__((section(".my_const,\"MSa\",@progbits,1 #")))
which is applied to every data symbol which should reside in this section, the goal being that the toolchain performs string deduplication and merging to save space.
On gcc, this works fine. On clang, it’s not possible to “inject” assembler input into section
attribute like this.
As alternative, I’ve tried adding __asm__(".section \".my_const\",\"MSa\",@progbits,1\n")
, hoping that the data symbols marked with section((".my_const"))
will then fall into that pre-defined section. Instead, I see that the output file has both “.my_const” sections: 1 with my given SHF_MERGE|SHF_STRINGS|SHF_ALLOC, sh_entsize=1 settings, and another that is created by the toolchain. All symbols actually wind up getting allocated into the toolchain-defined section, instead of the mergeable one. e.g.
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 3] .my_const PROGBITS 0000000000000000 000040 000000 01 AMS 0 0 1
[ 9] .my_const PROGBITS 0000000000000000 0004a0 000124 00 A 0 0 1
There is no space savings with this approach. It’s confusing to me as a user that the section name is not unique.
Another thing I’ve tried is to run llvm-objcopy --set-section-flags=.my_const=merge,strings,alloc
as a post-build step (in this build, the objects are compiled and then linked in another step - I’ve added the objcopy
step before the final link). While this does set the flags correctly on the intermediate object files, there is still no space savings/merging occurring when doing the final link.
Is there a way to get similar behavior on llvm as gcc in this case?
Completely different approach I’m considering is to compress the sections with -Wl,--compress-sections==.my_const=zlib
, however being compatible with existing construct would be better.