mirror of
https://github.com/rui314/mold.git
synced 2024-10-04 08:37:28 +03:00
[ELF] Handle TLS common symbols
Fixes https://github.com/rui314/mold/issues/447
This commit is contained in:
parent
ec062f7241
commit
cf850f8993
@ -1060,10 +1060,14 @@ void ObjectFile<E>::convert_common_symbols(Context<E> &ctx) {
|
||||
if (!has_common_symbol)
|
||||
return;
|
||||
|
||||
OutputSection<E> *osec =
|
||||
OutputSection<E> *common =
|
||||
OutputSection<E>::get_instance(ctx, ".common", SHT_NOBITS,
|
||||
SHF_WRITE | SHF_ALLOC);
|
||||
|
||||
OutputSection<E> *tls_common =
|
||||
OutputSection<E>::get_instance(ctx, ".tls_common", SHT_NOBITS,
|
||||
SHF_WRITE | SHF_ALLOC | SHF_TLS);
|
||||
|
||||
for (i64 i = this->first_global; i < this->elf_syms.size(); i++) {
|
||||
if (!this->elf_syms[i].is_common())
|
||||
continue;
|
||||
@ -1079,17 +1083,20 @@ void ObjectFile<E>::convert_common_symbols(Context<E> &ctx) {
|
||||
|
||||
elf_sections2.push_back({});
|
||||
ElfShdr<E> &shdr = elf_sections2.back();
|
||||
|
||||
memset(&shdr, 0, sizeof(shdr));
|
||||
shdr.sh_flags = SHF_ALLOC;
|
||||
|
||||
bool is_tls = (sym.get_type() == STT_TLS);
|
||||
shdr.sh_flags = is_tls ? (SHF_ALLOC | SHF_TLS) : SHF_ALLOC;
|
||||
shdr.sh_type = SHT_NOBITS;
|
||||
shdr.sh_size = this->elf_syms[i].st_size;
|
||||
shdr.sh_addralign = this->elf_syms[i].st_value;
|
||||
|
||||
i64 idx = this->elf_sections.size() + elf_sections2.size() - 1;
|
||||
std::unique_ptr<InputSection<E>> isec =
|
||||
std::make_unique<InputSection<E>>(ctx, *this, ".common", idx);
|
||||
isec->output_section = osec;
|
||||
std::make_unique<InputSection<E>>(ctx, *this,
|
||||
is_tls ? ".tls_common" : ".common",
|
||||
idx);
|
||||
isec->output_section = is_tls ? tls_common : common;
|
||||
|
||||
sym.file = this;
|
||||
sym.shndx = idx;
|
||||
|
35
test/elf/tls-common.sh
Executable file
35
test/elf/tls-common.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
export LC_ALL=C
|
||||
set -e
|
||||
CC="${CC:-cc}"
|
||||
CXX="${CXX:-c++}"
|
||||
GCC="${GCC:-gcc}"
|
||||
GXX="${GXX:-g++}"
|
||||
OBJDUMP="${OBJDUMP:-objdump}"
|
||||
MACHINE="${MACHINE:-$(uname -m)}"
|
||||
testname=$(basename "$0" .sh)
|
||||
echo -n "Testing $testname ... "
|
||||
cd "$(dirname "$0")"/../..
|
||||
mold="$(pwd)/mold"
|
||||
t=out/test/elf/$testname
|
||||
mkdir -p $t
|
||||
|
||||
cat <<EOF | $GCC -o $t/a.o -c -xassembler -
|
||||
.globl foo
|
||||
.tls_common foo,4,4
|
||||
EOF
|
||||
|
||||
cat <<EOF | $CC -o $t/b.o -c -xc -std=c11 -
|
||||
#include <stdio.h>
|
||||
|
||||
extern _Thread_local int foo;
|
||||
|
||||
int main() {
|
||||
printf("foo=%d\n", foo);
|
||||
}
|
||||
EOF
|
||||
|
||||
$CC -B. -o $t/exe $t/a.o $t/b.o
|
||||
$QEMU $t/exe | grep -q '^foo=0$'
|
||||
|
||||
echo OK
|
Loading…
Reference in New Issue
Block a user