commit 2efb3802d3b9f032447fcc69b8c3142bc305a466
parent ae5a02a4ae3f15832cae5b972d6b928320f26623
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 17 Jun 2026 08:04:28 -0700
test(dso-aa64): add direct data symbol access to consumer
foo_counter was only checked structurally (.dynsym presence) but the
runtime consumer never read it directly — only through foo_get_counter().
Add extern int foo_counter and a direct read in _start (exit code 3 on
mismatch). clang on aarch64 defaults to PIC so the access goes through
the GOT; lld emits R_AARCH64_GLOB_DAT, filled at startup by the loader.
Both musl and glibc runtime lanes still pass.
Diffstat:
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/test/link/elf-dso-aa64/consumer.c b/test/link/elf-dso-aa64/consumer.c
@@ -9,12 +9,18 @@
*
* Exit codes:
* 0 all checks passed
- * 1 foo_add(10, 32) != 42
- * 2 foo_get_counter() != 42
+ * 1 foo_add(10, 32) != 42 (function export via PLT)
+ * 2 foo_get_counter() != 42 (function export via PLT, reads data internally)
+ * 3 foo_counter (direct read) != 42 (data export via GOT/GLOB_DAT)
*/
extern int foo_add(int a, int b);
extern int foo_get_counter(void);
+/* Direct access to the exported data symbol. clang on aarch64 defaults to PIC
+ * so the compiler reads foo_counter through the GOT; the linker emits
+ * R_AARCH64_GLOB_DAT so the loader fills the GOT slot with the symbol's
+ * runtime address at startup. */
+extern int foo_counter;
/* Satisfies libfoo.so's undefined import of bar_external. Exported to the
* runtime dynamic symbol table by --export-dynamic on the consumer link. */
@@ -31,9 +37,11 @@ static __attribute__((noreturn)) void do_exit(int code)
void _start(void)
{
- /* foo_add(10, 32) = 10 + 32 + bar_external(0) = 10 + 32 + 0 = 42 */
+ /* Function export: foo_add(10, 32) = 10 + 32 + bar_external(0) = 42 */
if (foo_add(10, 32) != 42) do_exit(1);
- /* foo_get_counter() reads foo_counter which was initialised to 42 */
+ /* Function export: foo_get_counter() returns foo_counter (42) */
if (foo_get_counter() != 42) do_exit(2);
+ /* Data export: direct read through COPY reloc placed by the linker */
+ if (foo_counter != 42) do_exit(3);
do_exit(0);
}