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:
parent
b23780c7f8
commit
802f4229c2
4
main.cc
4
main.cc
@ -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;
|
||||
}
|
||||
|
@ -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
29
test/common.sh
Executable 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
|
Loading…
Reference in New Issue
Block a user