kit

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

a.c (1153B)


      1 /* &my_fn round-trips through a function pointer (cross-TU).
      2  *
      3  * a.c defines the IFUNC; b.c references it via &my_fn so the
      4  * address taken in b.c is observed across a TU boundary.  After
      5  * layout_iplt, the canonical IFUNC LinkSymbol is redirected to
      6  * the iplt stub; the per-input undef LinkSymbol in b.c had its
      7  * fields copied from the def by resolve_undefs (pre-redirect).
      8  * The propagation pass at the tail of layout_iplt re-syncs that
      9  * undef to the post-redirect (stub) vaddr, so the function
     10  * pointer in b.c carries the stub's address.
     11  *
     12  * Calling through the pointer goes through the stub: ADRP /
     13  * LDR / BR x16, hitting impl_a via the .igot.plt slot.  The
     14  * raw resolver address would have returned a function-pointer-
     15  * to-resolver that, when invoked, returns impl_a (a different
     16  * call shape we'd notice via test_main's return value). */
     17 
     18 extern int impl_a(void);
     19 extern int impl_b(void);
     20 extern int (*resolve(void))(void);
     21 
     22 int impl_a(void) { return 42; }
     23 int impl_b(void) { return 99; }
     24 
     25 int (*resolve(void))(void) {
     26   volatile int x = 1;
     27   return x ? impl_a : impl_b;
     28 }
     29 
     30 int my_fn(void) __attribute__((ifunc("resolve")));