Skip to content

Commit

Permalink
[ELF} Add --warn-once
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Feb 5, 2022
1 parent f72999a commit f24b997
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 14 deletions.
4 changes: 2 additions & 2 deletions elf/arch-arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ void InputSection<E>::apply_reloc_nonalloc(Context<E> &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;

if (!sym.file) {
report_undef(ctx, sym);
report_undef(ctx, file, sym);
continue;
}

Expand Down Expand Up @@ -400,7 +400,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
Symbol<E> &sym = *file.symbols[rel.r_sym];

if (!sym.file) {
report_undef(ctx, sym);
report_undef(ctx, file, sym);
continue;
}

Expand Down
4 changes: 2 additions & 2 deletions elf/arch-i386.cc
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ void InputSection<E>::apply_reloc_nonalloc(Context<E> &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;

if (!sym.file) {
report_undef(ctx, sym);
report_undef(ctx, file, sym);
continue;
}

Expand Down Expand Up @@ -369,7 +369,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
Symbol<E> &sym = *file.symbols[rel.r_sym];

if (!sym.file) {
report_undef(ctx, sym);
report_undef(ctx, file, sym);
continue;
}

Expand Down
4 changes: 2 additions & 2 deletions elf/arch-riscv64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ void InputSection<E>::apply_reloc_nonalloc(Context<E> &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;

if (!sym.file) {
report_undef(ctx, sym);
report_undef(ctx, file, sym);
continue;
}

Expand Down Expand Up @@ -544,7 +544,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
Symbol<E> &sym = *file.symbols[rel.r_sym];

if (!sym.file) {
report_undef(ctx, sym);
report_undef(ctx, file, sym);
continue;
}

Expand Down
4 changes: 2 additions & 2 deletions elf/arch-x86-64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ void InputSection<E>::apply_reloc_nonalloc(Context<E> &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;

if (!sym.file) {
report_undef(ctx, sym);
report_undef(ctx, file, sym);
continue;
}

Expand Down Expand Up @@ -580,7 +580,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
u8 *loc = (u8 *)(contents.data() + rel.r_offset);

if (!sym.file) {
report_undef(ctx, sym);
report_undef(ctx, file, sym);
continue;
}

Expand Down
3 changes: 3 additions & 0 deletions elf/cmdline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ static const char helpmsg[] = R"(
--version-script FILE Read version script
--warn-common Warn about common symbols
--no-warn-common
--warn-once Only warn once for each undefined symbol
--warn-unresolved-symbols Report unresolved symbols as warnings
--error-unresolved-symbols
Report unresolved symbols as errors (default)
Expand Down Expand Up @@ -584,6 +585,8 @@ void parse_nonpositional_args(Context<E> &ctx,
ctx.arg.warn_common = true;
} else if (read_flag(args, "no-warn-common")) {
ctx.arg.warn_common = false;
} else if (read_flag(args, "warn-once")) {
ctx.arg.warn_once = true;
} else if (read_arg(ctx, args, arg, "compress-debug-sections")) {
if (arg == "zlib" || arg == "zlib-gabi")
ctx.arg.compress_debug_sections = COMPRESS_GABI;
Expand Down
2 changes: 1 addition & 1 deletion elf/input-files.cc
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ void ObjectFile<E>::claim_unresolved_symbols(Context<E> &ctx) {
};

if (ctx.arg.unresolved_symbols == UNRESOLVED_WARN)
Warn(ctx) << "undefined symbol: " << *this << ": " << sym;
report_undef(ctx, *this, sym);

// Convert remaining undefined symbols to dynamic symbols.
if (ctx.arg.shared) {
Expand Down
13 changes: 9 additions & 4 deletions elf/input-sections.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ void InputSection<E>::write_to(Context<E> &ctx, u8 *buf) {
}

template <typename E>
void InputSection<E>::report_undef(Context<E> &ctx, Symbol<E> &sym) {
void report_undef(Context<E> &ctx, InputFile<E> &file, Symbol<E> &sym) {
if (ctx.arg.warn_once && !ctx.warned.insert({(void *)&sym, 1}))
return;

switch (ctx.arg.unresolved_symbols) {
case UNRESOLVED_ERROR:
Error(ctx) << "undefined symbol: " << file << ": " << sym;
Expand All @@ -213,9 +216,11 @@ void InputSection<E>::report_undef(Context<E> &ctx, Symbol<E> &sym) {
}
}

#define INSTANTIATE(E) \
template struct CieRecord<E>; \
template class InputSection<E>;
#define INSTANTIATE(E) \
template struct CieRecord<E>; \
template class InputSection<E>; \
template void report_undef(Context<E> &, InputFile<E> &, Symbol<E> &)


INSTANTIATE(X86_64);
INSTANTIATE(I386);
Expand Down
8 changes: 7 additions & 1 deletion elf/mold.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,6 @@ class InputSection {

void dispatch(Context<E> &ctx, Action table[3][4], i64 i,
const ElfRel<E> &rel, Symbol<E> &sym);
void report_undef(Context<E> &ctx, Symbol<E> &sym);
void copy_contents(Context<E> &ctx, u8 *buf);
void copy_contents_riscv(Context<E> &ctx, u8 *buf);

Expand All @@ -336,6 +335,9 @@ class InputSection {
bool is_relr_reloc(Context<E> &ctx, const ElfRel<E> &rel);
};

template <typename E>
void report_undef(Context<E> &ctx, InputFile<E> &file, Symbol<E> &sym);

//
// output-chunks.cc
//
Expand Down Expand Up @@ -1432,6 +1434,7 @@ struct Context {
bool strip_debug = false;
bool trace = false;
bool warn_common = false;
bool warn_once = false;
bool z_copyreloc = true;
bool z_defs = false;
bool z_delete = true;
Expand Down Expand Up @@ -1535,6 +1538,9 @@ struct Context {
std::atomic_bool has_gottp_rel = false;
std::atomic_bool has_textrel = false;

// For --warn-once
tbb::concurrent_hash_map<void *, int> warned;

// Output chunks
std::unique_ptr<OutputEhdr<E>> ehdr;
std::unique_ptr<OutputShdr<E>> shdr;
Expand Down
30 changes: 30 additions & 0 deletions test/elf/warn-once.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash
export LANG=
set -e
CC="${CC:-cc}"
CXX="${CXX:-c++}"
testname=$(basename "$0" .sh)
echo -n "Testing $testname ... "
cd "$(dirname "$0")"/../..
mold="$(pwd)/mold"
t=out/test/elf/$testname
mkdir -p $t

cat <<EOF | $CC -c -xc -o $t/a.o -
extern int foo;
int x() { return foo; }
EOF

cat <<EOF | $CC -c -xc -o $t/b.o -
extern int foo;
int y() { return foo; }
int main() {}
EOF

$CC -B. -o $t/exe $t/a.o $t/b.o -Wl,--warn-unresolved-symbols >& $t/log1
$CC -B. -o $t/exe $t/a.o $t/b.o -Wl,--warn-unresolved-symbols,--warn-once >& $t/log2

[ "$(grep 'undefined symbol:.* foo$' $t/log1 | wc -l)" = 2 ]
[ "$(grep 'undefined symbol:.* foo$' $t/log2 | wc -l)" = 1 ]

echo OK

0 comments on commit f24b997

Please sign in to comment.