see here for .section directive flags and _type_s
- also see the solaris ELF object file format docs
https://c.godbolt.org/z/T4j9GP91n https://assembly.godbolt.org/z/TGnGMWWWd
i.e.:
.section .tbss,"awT",@note
// ...
.section .tbss,"awT",@nobits❯ clang -c diff-flags.s -Wno-unused-command-line-argument
diff-flags.s:3:9: error: changed section type for .tbss, expected: 0x8
.section .tbss,"awT",@note
^
❯ gcc -c diff-flags.s
diff-flags.s: Assembler messages:
diff-flags.s:3: Warning: setting incorrect section type for .tbss
diff-flags.s:10: Warning: ignoring changed section type for .tbss
diff-flags.s:10: Warning: ignoring changed section attributes for .tbssi.e.:
.section .tbss,"aS",@nobits
// ...
.section .tbss,"wx",@nobits❯ clang -c diff-types.s -Wno-unused-command-line-argument
diff-types.s:3:9: error: changed section flags for .tbss, expected: 0x403
.section .tbss,"aS",@nobits
^
diff-types.s:10:9: error: changed section flags for .tbss, expected: 0x403
.section .tbss,"wx",@nobits
^
❯ gcc -c diff-types.s
diff-types.s: Assembler messages:
diff-types.s:3: Warning: bogus SHF_MERGE / SHF_STRINGS for SHT_NOBITS section
diff-types.s:3: Warning: setting incorrect section attributes for .tbss
diff-types.s:10: Warning: ignoring changed section attributes for .tbsswith -fdata-sections, separate "objects" are given their own sections (so that the linker is able to garbage collect ones that aren't referenced); i.e.:
__thread int f = 0;
__thread int g = 0;is lowered as (with -fdata-sections):
.globl f
.section .tbss.f,"awT",@nobits
.align 4
.type f, @object
.size f, 4
f:
.zero 4
.globl g
.section .tbss.g,"awT",@nobits // !!!
.align 4
.type g, @object
.size g, 4
g:
.zero 4instead of:
.globl f
.section .tbss,"awT",@nobits // note: `.tbss`, not `.tbss.f`
.align 4
.type f, @object
.size f, 4
f:
.zero 4
.globl g // note: still in `.tbss`
.align 4
.type g, @object
.size g, 4
g:
.zero 4
the linker ultimately merges these sections:
❯ ld --verbose | rg "tbss\t"
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }this begs the question: how does merging handle sections that have conflicting attributes?
# $1: section basename
# $2: `.tbss.f` flags
# $3: `.tbss.g` flags
# $4: `.tbss.f` type
# $5: `.tbss.g` type
test() {
cat <<EOF | clang -Wno-unused-command-line-argument -x assembler -c - -o a.o
.section .$1.f,"$2",@$4
.align 4
.type f, @object
.size f, 4
f:
.zero 4
.section .$1.g,"$3",@$5
.align 4
.type g, @object
.size g, 4
g:
.zero 4
EOF
ld -shared a.o -o b.o
readelf -We b.o | grep "] .$1"
}❯ test tbss aS wx progbits nobits
/nix/store/wi0nl3i48dl27dalzrrlq4n9a6mrl63y-binutils-2.44/bin/ld: warning: b.o has a LOAD segment with RWX permissions
[ 6] .tbss PROGBITS 0000000000001f08 001f08 000008 00 WAXT 0 0 4
❯ test tbss awT S note note
/nix/store/wi0nl3i48dl27dalzrrlq4n9a6mrl63y-binutils-2.44/bin/ld: BFD (GNU Binutils) 2.44 assertion fail /build/binutils-with-gold-2.44/bfd/elf.c:5405
readelf: Error: 'b.o': No such file
ordering (SHN_BEFORE/SHN_AFTER):