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

[ELF] Add --warn-shared-textrel

This commit is contained in:
Rui Ueyama 2022-02-05 11:57:36 +09:00
parent a4d9bc7550
commit 03e0cef726
5 changed files with 53 additions and 2 deletions

View File

@ -133,6 +133,7 @@ Options:
--warn-common Warn about common symbols --warn-common Warn about common symbols
--no-warn-common --no-warn-common
--warn-once Only warn once for each undefined symbol --warn-once Only warn once for each undefined symbol
--warn-shared-textrel Warn if the output .so needs text relocations
--warn-unresolved-symbols Report unresolved symbols as warnings --warn-unresolved-symbols Report unresolved symbols as warnings
--error-unresolved-symbols --error-unresolved-symbols
Report unresolved symbols as errors (default) Report unresolved symbols as errors (default)
@ -587,6 +588,8 @@ void parse_nonpositional_args(Context<E> &ctx,
ctx.arg.warn_common = false; ctx.arg.warn_common = false;
} else if (read_flag(args, "warn-once")) { } else if (read_flag(args, "warn-once")) {
ctx.arg.warn_once = true; ctx.arg.warn_once = true;
} else if (read_flag(args, "warn-shared-textrel")) {
ctx.arg.warn_shared_textrel = true;
} else if (read_arg(ctx, args, arg, "compress-debug-sections")) { } else if (read_arg(ctx, args, arg, "compress-debug-sections")) {
if (arg == "zlib" || arg == "zlib-gabi") if (arg == "zlib" || arg == "zlib-gabi")
ctx.arg.compress_debug_sections = COMPRESS_GABI; ctx.arg.compress_debug_sections = COMPRESS_GABI;

View File

@ -121,6 +121,12 @@ void InputSection<E>::dispatch(Context<E> &ctx, Action table[3][4], i64 i,
<< sym << "' can not be used; recompile with -fPIC"; << sym << "' can not be used; recompile with -fPIC";
}; };
auto warn_textrel = [&]() {
if (ctx.arg.shared && ctx.arg.warn_shared_textrel)
Warn(ctx) << *this << ": relocation against symbol `" << sym
<< "' in read-only section";
};
switch (action) { switch (action) {
case NONE: case NONE:
return; return;
@ -148,10 +154,11 @@ void InputSection<E>::dispatch(Context<E> &ctx, Action table[3][4], i64 i,
return; return;
case DYNREL: case DYNREL:
if (!is_writable) { if (!is_writable) {
if (!is_code || ctx.arg.z_text) { if (ctx.arg.z_text) {
error(); error();
return; return;
} }
warn_textrel();
ctx.has_textrel = true; ctx.has_textrel = true;
} }
@ -161,10 +168,11 @@ void InputSection<E>::dispatch(Context<E> &ctx, Action table[3][4], i64 i,
return; return;
case BASEREL: case BASEREL:
if (!is_writable) { if (!is_writable) {
if (!is_code || ctx.arg.z_text) { if (ctx.arg.z_text) {
error(); error();
return; return;
} }
warn_textrel();
ctx.has_textrel = true; ctx.has_textrel = true;
} }

View File

@ -1435,6 +1435,7 @@ struct Context {
bool trace = false; bool trace = false;
bool warn_common = false; bool warn_common = false;
bool warn_once = false; bool warn_once = false;
bool warn_shared_textrel = false;
bool z_copyreloc = true; bool z_copyreloc = true;
bool z_defs = false; bool z_defs = false;
bool z_delete = true; bool z_delete = true;

View File

@ -678,6 +678,9 @@ void scan_rels(Context<E> &ctx) {
if (ctx.needs_tlsld) if (ctx.needs_tlsld)
ctx.got->add_tlsld(ctx); ctx.got->add_tlsld(ctx);
if (ctx.arg.shared && ctx.arg.warn_shared_textrel && ctx.has_textrel)
Warn(ctx) << "--warn-shared-textrel: creating a DT_TEXTREL in a shared object";
} }
template <typename E> template <typename E>

36
test/elf/warn-shared-textrel.sh Executable file
View File

@ -0,0 +1,36 @@
#!/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
# Skip if libc is musl
echo 'int main() {}' | $CC -o $t/exe -xc -
ldd $t/exe | grep -q ld-musl && { echo OK; exit; }
# Skip if target is not x86-64
[ "$(uname -m)" = x86_64 ] || { echo skipped; exit; }
cat <<'EOF' | $CC -c -o $t/a.o -x assembler -
.globl fn
fn:
movabs main, %rax
ret
EOF
cat <<EOF | $CC -c -o $t/b.o -fPIC -xc -
void fn();
int main() { fn(); }
EOF
$CC -B. -shared -o $t/c.so $t/a.o $t/b.o -Wl,-warn-shared-textrel >& $t/log
grep -q 'relocation against symbol `main'\'' in read-only section' $t/log
grep -q 'creating a DT_TEXTREL in a shared object' $t/log
echo OK