1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-22 10:27:48 +03:00

Handle common symbols

This commit is contained in:
Rui Ueyama 2021-03-24 01:06:24 +09:00
parent b23780c7f8
commit 802f4229c2
3 changed files with 40 additions and 6 deletions

View File

@ -431,11 +431,13 @@ static void check_duplicate_symbols() {
for (i64 i = file->first_global; i < file->elf_syms.size(); i++) {
const ElfSym &esym = file->elf_syms[i];
Symbol &sym = *file->symbols[i];
bool is_common = esym.is_common();
bool is_weak = (esym.st_bind == STB_WEAK);
bool is_eliminated =
!esym.is_abs() && !esym.is_common() && !file->get_section(esym);
if (esym.is_defined() && !is_weak && !is_eliminated && sym.file != file)
if (sym.file != file && esym.is_defined() && !is_common &&
!is_weak && !is_eliminated)
Error() << "duplicate symbol: " << *file << ": " << *sym.file
<< ": " << sym;
}

View File

@ -586,22 +586,25 @@ void ObjectFile::parse() {
// Here is the list of priorities, from the highest to the lowest.
//
// 1. Strong defined symbol
// 2. Weak defined symbol
// 3. Strong or weak defined symbol in an archive member
// 4. Unclaimed (nonexistent) symbol
// 2. Common symbol
// 3. Weak defined symbol
// 4. Strong or weak defined symbol in an archive member
// 5. Unclaimed (nonexistent) symbol
//
// Ties are broken by file priority.
static u64 get_rank(InputFile *file, const ElfSym &esym, InputSection *isec) {
if (esym.st_bind == STB_WEAK)
return (3 << 24) + file->priority;
if (esym.is_common())
return (2 << 24) + file->priority;
return (1 << 24) + file->priority;
}
static u64 get_rank(const Symbol &sym) {
if (!sym.file)
return 4 << 24;
return 5 << 24;
if (sym.is_lazy)
return (3 << 24) + sym.file->priority;
return (4 << 24) + sym.file->priority;
return get_rank(sym.file, *sym.esym, sym.input_section);
}

29
test/common.sh Executable file
View File

@ -0,0 +1,29 @@
#!/bin/bash
set -e
cd $(dirname $0)
echo -n "Testing $(basename -s .sh $0) ... "
t=$(pwd)/tmp/$(basename -s .sh $0)
mkdir -p $t
cat <<EOF | clang -fcommon -xc -c -o $t/a.o -
int foo;
int bar;
int baz = 42;
EOF
cat <<EOF | clang -fcommon -xc -c -o $t/b.o -
#include <stdio.h>
int foo;
int bar = 5;
int baz;
int main() {
printf("%d %d %d\n", foo, bar, baz);
}
EOF
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o $t/b.o
$t/exe | grep '0 5 42'
echo OK