From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.210.173 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793799139; b=47FqZiW4c6oLFZF62QMINnNhVGzDlMWuZoTump2IlQFH8Tfvks7TOyqLLeXlX3aWiJlC /8Js4R1Vo04RRfpwdFOvfHQvnag2u12NQ2xdv4kYyp6uv4BLgkNRGV3rbhoHNfaVF7Qfk aQEgBcX66UfsHDu/92wilRM4Y/pk8wxbsXAO1xBpryzCg7RW5FNWuhOMl9dJYx8O2cs/U gJMEZU5tL1BBRiKJk+QSVvCj9VEn/3zJQ2s2aJ7rwmBQkVyni2UJc4lgBZ3MglAsNYkAo 2Zi2AOwwHfaj0yRqYhytaD6XkKwppMzeJzvkNq0I4VmQdUYKCsCTqAzfMZBLe0p1vSw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793799139; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received:Received: From:To:Cc:Subject:Date:Message-ID:X-Mailer:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding; bh=Vuv7EyJ3FeJLmao5XoxH0RpJWoU3/L6ji2pLxjLqoaA=; b=vTN/w+eJM6rzjOkZP/wLYfLp9rvyyEAX7x+ViWrMDjsijNa0HVmbgWXbdE2imWkcP5UW lNQUGbSjmeNHKfSMtNOBv3XkIETr9JSdWdxD4lDVTvsHCpd1xfaxW/RF/6LVUVYWxnF5T eJzyqVZOECoYeRj2x+7TUxJqSVlly7qTOlUyrXHibu6LQySl6SzIlWpznOzoUhBZTG/gh m8OjnVLzEcG0bUjesCGBdoRSLzvQfNNIs6LeLErHw6l8Cdvpb1QJwN+Sjra01x0RotPYE /on+L6xRtHHqNsHyiecjE7o/JxbFCVkPmFAv9O7xlyjl/wfIUHdmO5I1w5/AIZOkV6g== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=goSNWRCH; arc=none smtp.remote-ip=209.85.210.173 Received: from mail-pf1-f173.google.com (mail-pf1-f173.google.com [209.85.210.173]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E5EF606A32C for ; Wed, 4 Nov 2026 13:32:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 8E5EF606A32C Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=goSNWRCH Received: by mail-pf1-f173.google.com with SMTP id d2e1a72fcca58-8a064fac8cbso571034b3a.1 for ; Wed, 04 Nov 2026 05:32:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793799138; x=1794403938; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Vuv7EyJ3FeJLmao5XoxH0RpJWoU3/L6ji2pLxjLqoaA=; b=goSNWRCHVscmN/t9HffQ+IUZzCmbR952B0O2EM6oeYF05Wwrz9962+/J3/gkCmFHCz Mgz83OsGzccB4GxBcsrYYipcNHmiylhY6CJEUCMSWMes2Uk9NiUpIADmDd8cRFXXVpNJ DNH5u5J4FQMgfCrU61DWj9jUiYGhl5l2/kuJiFygExqump4eO4N5MUpNcHBZJPH8Es0e KdqsBirMJBUnNT/JaizVQ766q2awgFbLKcLuKufga6EPD3XkUJ6d4Fuqr3ALIhnnUnHa tVD6ekgQkOwmZhlG9nVrhOt0geFTSVkc/z7TSWj9jzXIwL6/hUbypK+5ep/DHInFkJGS uoXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793799138; x=1794403938; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Vuv7EyJ3FeJLmao5XoxH0RpJWoU3/L6ji2pLxjLqoaA=; b=GtrzUeRUGopaNV8N7vg6mJ28DFglRK6aOf+QRrkjunMxTSP9n+YTBWyRKvk9TFTVIE vVygh8q8HTsHgz/+JJrNs23SCGsFJQeD8EwGcS6zxbh/tQBvBgLFVHs33oENX1wLjymH T35L2h7/NsyLlE9zBxZ1JFRo1QjA54hn8r/A+Ow25VssITynoAmNbnwsoHdHKKpF0gyB RqBqfAslWej7mSthbcbZ2XhPyiIJoGN80WrnEJKGS8+mj+vdap3GRHp0ij3gHxaEaFK8 Q/ta7IRhj/pe7lea/uoffVWtDHnbMvx0MjJpSsJGb+iAZdjZN4+oTfTHQSK1c9JV0hH7 aU9A== X-Forwarded-Encrypted: i=1; AKwUvBxnoBRulOwKx/HbSHOwSA+lcBGNSqNxQ21LIfTwCO4SABbuddg2Sb3H7FqN7EdkZYI/bxF+YociHAQKrM8=@vger.kernel.org X-Gm-Message-State: APuU4Z+tNOtl0OtOmARpzNzXvi64qAlO1ABX4ch6OZsVekVoXWUzuoEy 0yFFxcX/AMDx9J436Skc41/1oYM33QbPjVT/XjaSCRRcFvLxhqJPnaKm X-Gm-Gg: AYBFou2sgtfdkl/P7S3kTLkFUzGlxyUWSVTRqBQpScqxzm0bCsZwgFgW2zWWFSyUXQD DLZ/7a0OBCnpwcu5AIOKFMs24TsiqVDVfWTWYtePIkMfaXybxEqaNiP97Fbhg0CJg5hKKZcx/MD XFOxkaT9v3/6SyQoRygxSglIBE+b3JWAqSM0KWkWzpDDAKOxYqR7Hcg/aIqoBTKk1q5VZ/2QJ2l VwUH9fx3oliDt8fzRa8N+6/ieUsrvsslnKOD6q9hOAzeQ9s/slzATCWdX3/fs+9PG7PL00ai05f uTYOyRskc54WtIXHaIGdWEkuVRYS9VB6X6mht6Q9Gi8Bp+2msR1FhNrRy0CsQ2qGBZx0LefbPzg a+89LV1WYnwHaXlRttqLJRjTsO8sUTKgj90/+kyraYI6ivKU8ltZ3w8iChmykM+bY4rxYch/Zn5 H3CW3mngv3LfoOL6euOUI3sgN6PLqEh4VOfk1dHSP/2necwOWH2j5cXG5aiUIz8gOUKfu0AL6TY YLNJx1qYAyHNH9OTGiW7LyBKf4l9trdiPE0icB3bCyA8FxUYdkGz+Qn29XPeJhWDM/Yty+zgSlF QdnXM71fOJ/f4uVdRcR1LZxBHy1QPLF8JEjWdv58Gpisoz92aQ== X-Received: by 2002:a05:6a00:140f:b0:89e:f8e9:205e with SMTP id d2e1a72fcca58-8a9bf71c0f3mr13345178b3a.40.1793799137622; Wed, 04 Nov 2026 05:32:17 -0800 (PST) Received: from anatasluo-Precision-5560 ([139.226.166.21]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8b09a7ce84fsm911369b3a.13.2026.11.04.05.32.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 05:32:17 -0800 (PST) From: Longjun Luo To: jpoimboe@kernel.org, peterz@infradead.org Cc: mbenes@suse.cz, pmladek@suse.com, joe.lawrence@redhat.com, song@kernel.org, puranjay@kernel.org, nathan@kernel.org, ndesaulniers@google.com, morbo@google.com, justinstitt@google.com, live-patching@vger.kernel.org, llvm@lists.linux.dev, linux-kernel@vger.kernel.org, Longjun Luo Subject: [RFC PATCH v2 01/11] objtool/klp: Fix checksums and copying of wide strings Date: Wed, 4 Nov 2026 21:31:47 +0800 Message-ID: <20261104133158.3187525-2-luolongjuna@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261104133158.3187525-1-luolongjuna@gmail.com> References: <20261104133158.3187525-1-luolongjuna@gmail.com> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit SHF_STRINGS sections can contain elements wider than one byte. Using strlen() truncates their contents at an embedded zero byte, hiding changes and copying incomplete strings into the patch. Find the terminating zero element using sh_entsize. Use the resulting length for both reference checksums and copying, and propagate errors through checksum calculation. Keep single-byte string handling unchanged. Add a test for two- and four-byte strings, including references from data. Validated the available objtool tests with GCC 16.2.1 and Clang 22.1.8. No failures. Fixes: 0d83da43b1e1 ("objtool/klp: Add --checksum option to generate per-function checksums") Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files") Fixes: 873a2208ea31 ("objtool/klp: Calculate object checksums") Assisted-by: LLM Signed-off-by: Longjun Luo --- tools/objtool/elf.c | 29 +++++++++ tools/objtool/include/objtool/elf.h | 1 + tools/objtool/klp-checksum.c | 44 ++++++++----- tools/objtool/klp-diff.c | 14 ++-- .../tests/generic/fixtures/identity/common.h | 15 +++++ .../generic/fixtures/identity/wide_string.c | 36 ++++++++++ .../generic/test-checksum-wide-string.sh | 39 +++++++++++ tools/objtool/tests/identity-lib.sh | 65 +++++++++++++++++++ 8 files changed, 223 insertions(+), 20 deletions(-) create mode 100644 tools/objtool/tests/generic/fixtures/identity/common.h create mode 100644 tools/objtool/tests/generic/fixtures/identity/wide_string.c create mode 100755 tools/objtool/tests/generic/test-checksum-wide-string.sh create mode 100644 tools/objtool/tests/identity-lib.sh diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index a791f4ea6ec1..71f1a272e468 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -1382,6 +1382,35 @@ struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name) return elf; } +/* Wide strings, such as the u16 PSR setup table, end at an all-zero element. */ +ssize_t elf_string_len(struct section *sec, unsigned long offset) +{ + size_t entsize = sec->sh.sh_entsize, size, len; + const char *str; + + /* + * FIXME: GCC's range_string() uses a one-past-end string pointer. + * strlen() reads past the section; preserve the string base and addend. + */ + if (entsize == 1) + return strlen(sec->data->d_buf + offset); + + if (!entsize || offset >= sec_size(sec)) { + ERROR("%s+%#lx: invalid string offset or character size", sec->name, offset); + return -1; + } + + str = sec->data->d_buf + offset; + size = sec_size(sec) - offset; + for (len = 0; size - len >= entsize; len += entsize) { + if (!memchr_inv(str + len, 0, entsize)) + return len; + } + + ERROR("%s+%#lx: unterminated string", sec->name, offset); + return -1; +} + unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char *str) { unsigned int offset; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h index a82517a76a0f..5d7ddadf9471 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -179,6 +179,7 @@ struct symbol *elf_create_section_symbol(struct elf *elf, struct section *sec); void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_t size); +ssize_t elf_string_len(struct section *sec, unsigned long offset); unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char *str); struct reloc *elf_create_reloc(struct elf *elf, struct section *sec, diff --git a/tools/objtool/klp-checksum.c b/tools/objtool/klp-checksum.c index ebe25f9c5260..efaf083c03a1 100644 --- a/tools/objtool/klp-checksum.c +++ b/tools/objtool/klp-checksum.c @@ -67,8 +67,8 @@ static bool is_anonymous_const_data(struct symbol *sym) (is_sec_sym(sym) || strstarts(sym->name, ".LC")); } -static void checksum_update_insn(struct objtool_file *file, struct symbol *func, - struct instruction *insn) +static int checksum_update_insn(struct objtool_file *file, struct symbol *func, + struct instruction *insn) { struct reloc *reloc = insn_reloc(file, insn); struct alternative *alt; @@ -77,7 +77,7 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func, static bool in_alt; if (insn->fake) - return; + return 0; if (!reloc) { struct symbol *call_dest = insn_call_dest(insn); @@ -135,10 +135,13 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func, offset = arch_insn_adjusted_addend(insn, reloc); if (is_string_sec(sym->sec)) { - char *str; + ssize_t size = elf_string_len(sym->sec, sym->offset + offset); + const void *data; - str = sym->sec->data->d_buf + sym->offset + offset; - __checksum_update_insn(func, insn, str, strlen(str)); + if (size < 0) + return -1; + data = sym->sec->data->d_buf + sym->offset + offset; + __checksum_update_insn(func, insn, data, size); goto alts; } @@ -180,19 +183,22 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func, __checksum_update_insn(func, insn, &alt_group->feature,sizeof(alt_group->feature)); for (alt_insn = alt->insn; alt_insn; alt_insn = next_insn_same_sec(file, alt_insn)) { - checksum_update_insn(file, func, alt_insn); + if (checksum_update_insn(file, func, alt_insn)) + return -1; if (!alt_group->last_insn || alt_insn == alt_group->last_insn) break; } } else { - checksum_update_insn(file, func, alt->insn); + if (checksum_update_insn(file, func, alt->insn)) + return -1; } in_alt = false; } + return 0; } -static void checksum_update_object(struct objtool_file *file, struct symbol *sym) +static int checksum_update_object(struct objtool_file *file, struct symbol *sym) { struct reloc *reloc; @@ -211,11 +217,13 @@ static void checksum_update_object(struct objtool_file *file, struct symbol *sym offset = reloc_addend(reloc); if (is_string_sec(target->sec)) { - char *str; + ssize_t size = elf_string_len(target->sec, target->offset + offset); + const void *data; - str = target->sec->data->d_buf + target->offset + offset; - __checksum_update_object(sym, sym_offset, - "reloc string", str, strlen(str)); + if (size < 0) + return -1; + data = target->sec->data->d_buf + target->offset + offset; + __checksum_update_object(sym, sym_offset, "reloc string", data, size); continue; } @@ -233,6 +241,7 @@ static void checksum_update_object(struct objtool_file *file, struct symbol *sym __checksum_update_object(sym, sym_offset, "reloc addend", &offset, sizeof(offset)); } + return 0; } int calculate_checksums(struct objtool_file *file) @@ -256,13 +265,16 @@ int calculate_checksums(struct objtool_file *file) if (is_func_sym(sym)) { checksum_init(sym); - func_for_each_insn(file, sym, insn) - checksum_update_insn(file, sym, insn); + func_for_each_insn(file, sym, insn) { + if (checksum_update_insn(file, sym, insn)) + return -1; + } checksum_finish(sym); } else if (is_object_sym(sym)) { checksum_init(sym); - checksum_update_object(file, sym); + if (checksum_update_object(file, sym)) + return -1; checksum_finish(sym); } diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 34da55e45609..6321f691adbb 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -1548,12 +1548,18 @@ static int clone_reloc(struct elfs *e, struct reloc *patched_reloc, * version of the string section. Now copy the string itself. */ if (is_string_sec(patched_sym->sec)) { - const char *str = patched_sym->sec->data->d_buf + addend; + ssize_t len = elf_string_len(patched_sym->sec, addend); + const char *str; - __dbg_clone("\"%s\"", escape_str(str)); + if (len < 0) + return -1; + str = patched_sym->sec->data->d_buf + addend; + if (patched_sym->sec->sh.sh_entsize == 1) + __dbg_clone("\"%s\"", escape_str(str)); - addend = elf_add_string(e->out, out_sym->sec, str); - if (addend == -1) + addend = ALIGN(sec_size(out_sym->sec), out_sym->sec->sh.sh_addralign); + if (!elf_add_data(e->out, out_sym->sec, str, + len + patched_sym->sec->sh.sh_entsize)) return -1; } diff --git a/tools/objtool/tests/generic/fixtures/identity/common.h b/tools/objtool/tests/generic/fixtures/identity/common.h new file mode 100644 index 000000000000..d0f56751fcd9 --- /dev/null +++ b/tools/objtool/tests/generic/fixtures/identity/common.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2026 Longjun Luo */ +#ifndef KLP_TEST_IDENTITY_H +#define KLP_TEST_IDENTITY_H + +#ifdef __clang__ +/* Use noinline on Clang to keep calls visible in these tests. */ +#define NOIPA __attribute__((noinline)) +#else +#define NOIPA __attribute__((noipa)) +#endif +#define MODINFO static const char modinfo[] \ + __attribute__((used, section(".modinfo"))) = "name=vmlinux" + +#endif diff --git a/tools/objtool/tests/generic/fixtures/identity/wide_string.c b/tools/objtool/tests/generic/fixtures/identity/wide_string.c new file mode 100644 index 000000000000..4b25781e1827 --- /dev/null +++ b/tools/objtool/tests/generic/fixtures/identity/wide_string.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2026 Longjun Luo */ +#include "common.h" +MODINFO; + +#ifdef WIDE32 +#ifdef PATCHED +#define TEXT U"\x014a\x0113\x00dc\x00a5\x006e\x0038" +#else +#define TEXT U"\x014a\x0113\x00dc\x00a5\x006e\x0037" +#endif +#else +#ifdef PATCHED +#define TEXT u"\x014a\x0113\x00dc\x00a5\x006e\x0038" +#else +#define TEXT u"\x014a\x0113\x00dc\x00a5\x006e\x0037" +#endif +#endif + +#ifdef OBJECT +struct descriptor { + const void *text; +}; + +const struct descriptor descriptor = { TEXT }; + +NOIPA const struct descriptor *target(void) +{ + return &descriptor; +} +#else +NOIPA const void *target(void) +{ + return TEXT; +} +#endif diff --git a/tools/objtool/tests/generic/test-checksum-wide-string.sh b/tools/objtool/tests/generic/test-checksum-wide-string.sh new file mode 100755 index 000000000000..426adc42337a --- /dev/null +++ b/tools/objtool/tests/generic/test-checksum-wide-string.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2026 Longjun Luo +# Wide strings contain zero bytes before their terminating zero element. +. "$(dirname "$0")/../identity-lib.sh" + +wide_section() +{ + in_sections "$1" | sed 's/^ *\[[ 0-9]*\] *//' | + awk -v width="$width" '$7 ~ /S/ && $6+0 == width { print $1; exit }' +} + +setup +for width in 2 4; do + flags=() + [ "$width" = 4 ] && flags=(-DWIDE32) + build_pair identity/wide_string.c "${flags[@]}" + input="$(wide_section patched.o)" + [ -n "$input" ] || fail "missing $width-byte string section" + + assert_checksum_differs target + run_diff + assert_patched target + output="$(wide_section out.o)" + [ -n "$output" ] || fail "wide string was not copied" + $OBJCOPY -O binary --only-section="$input" "$workdir/patched.o" "$workdir/expected.bin" || + fail "cannot extract input string" + $OBJCOPY -O binary --only-section="$output" "$workdir/out.o" "$workdir/actual.bin" || + fail "cannot extract output string" + cmp -s "$workdir/expected.bin" "$workdir/actual.bin" || fail "wide string was truncated" + partial_link "$workdir/linked.o" "$workdir/out.o" || fail "wide-string output does not link" + + build_pair identity/wide_string.c "${flags[@]}" -DOBJECT + assert_checksum_differs descriptor + run_diff 255 + assert_diff_log 'changed data: descriptor' +done + +pass "wide-string checksums and copies cover every element" diff --git a/tools/objtool/tests/identity-lib.sh b/tools/objtool/tests/identity-lib.sh new file mode 100644 index 000000000000..fc7014a88bc8 --- /dev/null +++ b/tools/objtool/tests/identity-lib.sh @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2026 Longjun Luo +# Shared build helpers for the multi-TU identity fixtures. +. "$(dirname "$0")/../lib.sh" + +FIXTURE_CFLAGS="$FIXTURE_CFLAGS -fno-pie -fno-pic" + +# build_identity_pair +build_identity_pair() +{ + local mode="$1" cflags="$2" side file i + local CC="$CC" + local flags=() parts=() patched=() + shift 2 + if [ "$mode" != none ]; then + clang_only "LTO fixtures require clang" + find_thinlto_toolchain || probe_skip "no matching clang/lld pair" + flags=("-flto=$mode") + CC="$THIN_CC" + fi + orig_obj=orig.o + patched_obj=patched.o + for side in orig patched; do + patched=() + [ "$side" = patched ] && patched=(-DPATCHED) + parts=() + i=0 + for file in "$@"; do + build_one "$file" "$side-$i.o" "${flags[@]}" "${patched[@]}" $cflags + parts+=("$workdir/$side-$i.o") + i=$((i + 1)) + done + if [ "$mode" = none ]; then + partial_link "$workdir/$side.o" "${parts[@]}" || fail "partial link failed" + else + "$THIN_LD" -r "${parts[@]}" -o "$workdir/$side.o" || fail "LTO link failed" + fi + done +} + +# identity_relocs +identity_relocs() +{ + # readelf prints the section name in single quotes. + in_relocs "$1" | awk -v sec="'$2'" ' + /Relocation section/ { active = $3 == sec } + active && $1 ~ /^[[:xdigit:]]+$/ { print }' +} + +# The fixture's function references one static in .bss, .data or .rodata. +identity_object_for() +{ + identity_relocs "$1" ".rela.text.$2" | awk ' + $5 ~ /^\.(bss|data|rodata)\./ { + sub(/^\.(bss|data|rodata)\./, "", $5); print $5; exit + }' +} + +# After post-link, check the reference to the original symbol, not just its presence. +assert_original_reference() +{ + identity_relocs out.o ".klp.rela.orig..text.$1" | + awk -v n=".klp.sym.orig.$2," 'index($5, n) == 1' | grep -q . || + fail "expected '$1' to reference original '$2'" +} -- 2.55.0