kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

consumer.c (1983B)


      1 /* test/link/elf-dso-aa64/consumer.c — DSO consumer; freestanding aarch64.
      2  *
      3  * Dynamically linked against libfoo.so. Provides bar_external so that
      4  * libfoo.so's undefined import is satisfied at runtime via the executable's
      5  * exported symbol table (requires --export-dynamic / -rdynamic at link time).
      6  *
      7  * Uses a direct SVC for exit so the binary needs no libc and no sysroot at
      8  * compile time; only the dynamic linker and libfoo.so are needed at runtime.
      9  *
     10  * Exit codes:
     11  *   0  all checks passed
     12  *   1  foo_add(10, 32) != 42           (function export via PLT)
     13  *   2  foo_get_counter() != 42         (function export via PLT, reads data internally)
     14  *   3  foo_counter (direct read) != 42 (data export via GOT/GLOB_DAT)
     15  */
     16 
     17 extern int foo_add(int a, int b);
     18 extern int foo_get_counter(void);
     19 /* Direct access to the exported data symbol. clang on aarch64 defaults to PIC
     20  * so the compiler reads foo_counter through the GOT; the linker emits
     21  * R_AARCH64_GLOB_DAT so the loader fills the GOT slot with the symbol's
     22  * runtime address at startup. */
     23 extern int foo_counter;
     24 
     25 /* Satisfies libfoo.so's undefined import of bar_external. Exported to the
     26  * runtime dynamic symbol table by --export-dynamic on the consumer link. */
     27 int bar_external(int x) { (void)x; return 0; }
     28 
     29 static __attribute__((noreturn)) void do_exit(int code)
     30 {
     31     /* aarch64 Linux: x8 = NR_exit_group (94), x0 = exit code */
     32     register long x8 __asm__("x8") = 94;
     33     register long x0 __asm__("x0") = (long)code;
     34     __asm__ volatile("svc 0" : : "r"(x8), "r"(x0) : "memory");
     35     __builtin_unreachable();
     36 }
     37 
     38 void _start(void)
     39 {
     40     /* Function export: foo_add(10, 32) = 10 + 32 + bar_external(0) = 42 */
     41     if (foo_add(10, 32) != 42) do_exit(1);
     42     /* Function export: foo_get_counter() returns foo_counter (42) */
     43     if (foo_get_counter() != 42) do_exit(2);
     44     /* Data export: direct read through COPY reloc placed by the linker */
     45     if (foo_counter != 42) do_exit(3);
     46     do_exit(0);
     47 }