LSKELS := kfunc_call_test.c fentry_test.c fexit_test.c fexit_sleep.c \
        test_ringbuf.c atomics.c trace_printk.c trace_vprintk.c
 # Generate both light skeleton and libbpf skeleton for these
-LSKELS_EXTRA := test_ksyms_module.c
+LSKELS_EXTRA := test_ksyms_module.c test_ksyms_weak.c
 SKEL_BLACKLIST += $$(LSKELS)
 
 test_static_linked.skel.h-deps := test_static_linked1.o test_static_linked2.o
        $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked2.o) $$(<:.o=.linked1.o)
        $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked3.o) $$(<:.o=.linked2.o)
        $(Q)diff $$(<:.o=.linked2.o) $$(<:.o=.linked3.o)
-       $(Q)$$(BPFTOOL) gen skeleton -L $$(<:.o=.linked3.o) name $$(notdir $$(<:.o=)) > $$@
+       $(Q)$$(BPFTOOL) gen skeleton -L $$(<:.o=.linked3.o) name $$(notdir $$(<:.o=_lskel)) > $$@
 
 $(TRUNNER_BPF_SKELS_LINKED): $(TRUNNER_BPF_OBJS) $(BPFTOOL) | $(TRUNNER_OUTPUT)
        $$(call msg,LINK-BPF,$(TRUNNER_BINARY),$$(@:.skel.h=.o))
 
 
 #include "atomics.lskel.h"
 
-static void test_add(struct atomics *skel)
+static void test_add(struct atomics_lskel *skel)
 {
        int err, prog_fd;
        __u32 duration = 0, retval;
        int link_fd;
 
-       link_fd = atomics__add__attach(skel);
+       link_fd = atomics_lskel__add__attach(skel);
        if (!ASSERT_GT(link_fd, 0, "attach(add)"))
                return;
 
        close(link_fd);
 }
 
-static void test_sub(struct atomics *skel)
+static void test_sub(struct atomics_lskel *skel)
 {
        int err, prog_fd;
        __u32 duration = 0, retval;
        int link_fd;
 
-       link_fd = atomics__sub__attach(skel);
+       link_fd = atomics_lskel__sub__attach(skel);
        if (!ASSERT_GT(link_fd, 0, "attach(sub)"))
                return;
 
        close(link_fd);
 }
 
-static void test_and(struct atomics *skel)
+static void test_and(struct atomics_lskel *skel)
 {
        int err, prog_fd;
        __u32 duration = 0, retval;
        int link_fd;
 
-       link_fd = atomics__and__attach(skel);
+       link_fd = atomics_lskel__and__attach(skel);
        if (!ASSERT_GT(link_fd, 0, "attach(and)"))
                return;
 
        close(link_fd);
 }
 
-static void test_or(struct atomics *skel)
+static void test_or(struct atomics_lskel *skel)
 {
        int err, prog_fd;
        __u32 duration = 0, retval;
        int link_fd;
 
-       link_fd = atomics__or__attach(skel);
+       link_fd = atomics_lskel__or__attach(skel);
        if (!ASSERT_GT(link_fd, 0, "attach(or)"))
                return;
 
        close(link_fd);
 }
 
-static void test_xor(struct atomics *skel)
+static void test_xor(struct atomics_lskel *skel)
 {
        int err, prog_fd;
        __u32 duration = 0, retval;
        int link_fd;
 
-       link_fd = atomics__xor__attach(skel);
+       link_fd = atomics_lskel__xor__attach(skel);
        if (!ASSERT_GT(link_fd, 0, "attach(xor)"))
                return;
 
        close(link_fd);
 }
 
-static void test_cmpxchg(struct atomics *skel)
+static void test_cmpxchg(struct atomics_lskel *skel)
 {
        int err, prog_fd;
        __u32 duration = 0, retval;
        int link_fd;
 
-       link_fd = atomics__cmpxchg__attach(skel);
+       link_fd = atomics_lskel__cmpxchg__attach(skel);
        if (!ASSERT_GT(link_fd, 0, "attach(cmpxchg)"))
                return;
 
        close(link_fd);
 }
 
-static void test_xchg(struct atomics *skel)
+static void test_xchg(struct atomics_lskel *skel)
 {
        int err, prog_fd;
        __u32 duration = 0, retval;
        int link_fd;
 
-       link_fd = atomics__xchg__attach(skel);
+       link_fd = atomics_lskel__xchg__attach(skel);
        if (!ASSERT_GT(link_fd, 0, "attach(xchg)"))
                return;
 
 
 void test_atomics(void)
 {
-       struct atomics *skel;
+       struct atomics_lskel *skel;
        __u32 duration = 0;
 
-       skel = atomics__open_and_load();
+       skel = atomics_lskel__open_and_load();
        if (CHECK(!skel, "skel_load", "atomics skeleton failed\n"))
                return;
 
                test_xchg(skel);
 
 cleanup:
-       atomics__destroy(skel);
+       atomics_lskel__destroy(skel);
 }
 
 
 void test_fentry_fexit(void)
 {
-       struct fentry_test *fentry_skel = NULL;
-       struct fexit_test *fexit_skel = NULL;
+       struct fentry_test_lskel *fentry_skel = NULL;
+       struct fexit_test_lskel *fexit_skel = NULL;
        __u64 *fentry_res, *fexit_res;
        __u32 duration = 0, retval;
        int err, prog_fd, i;
 
-       fentry_skel = fentry_test__open_and_load();
+       fentry_skel = fentry_test_lskel__open_and_load();
        if (CHECK(!fentry_skel, "fentry_skel_load", "fentry skeleton failed\n"))
                goto close_prog;
-       fexit_skel = fexit_test__open_and_load();
+       fexit_skel = fexit_test_lskel__open_and_load();
        if (CHECK(!fexit_skel, "fexit_skel_load", "fexit skeleton failed\n"))
                goto close_prog;
 
-       err = fentry_test__attach(fentry_skel);
+       err = fentry_test_lskel__attach(fentry_skel);
        if (CHECK(err, "fentry_attach", "fentry attach failed: %d\n", err))
                goto close_prog;
-       err = fexit_test__attach(fexit_skel);
+       err = fexit_test_lskel__attach(fexit_skel);
        if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err))
                goto close_prog;
 
        }
 
 close_prog:
-       fentry_test__destroy(fentry_skel);
-       fexit_test__destroy(fexit_skel);
+       fentry_test_lskel__destroy(fentry_skel);
+       fexit_test_lskel__destroy(fexit_skel);
 }
 
 #include <test_progs.h>
 #include "fentry_test.lskel.h"
 
-static int fentry_test(struct fentry_test *fentry_skel)
+static int fentry_test(struct fentry_test_lskel *fentry_skel)
 {
        int err, prog_fd, i;
        __u32 duration = 0, retval;
        int link_fd;
        __u64 *result;
 
-       err = fentry_test__attach(fentry_skel);
+       err = fentry_test_lskel__attach(fentry_skel);
        if (!ASSERT_OK(err, "fentry_attach"))
                return err;
 
        /* Check that already linked program can't be attached again. */
-       link_fd = fentry_test__test1__attach(fentry_skel);
+       link_fd = fentry_test_lskel__test1__attach(fentry_skel);
        if (!ASSERT_LT(link_fd, 0, "fentry_attach_link"))
                return -1;
 
                        return -1;
        }
 
-       fentry_test__detach(fentry_skel);
+       fentry_test_lskel__detach(fentry_skel);
 
        /* zero results for re-attach test */
        memset(fentry_skel->bss, 0, sizeof(*fentry_skel->bss));
 
 void test_fentry_test(void)
 {
-       struct fentry_test *fentry_skel = NULL;
+       struct fentry_test_lskel *fentry_skel = NULL;
        int err;
 
-       fentry_skel = fentry_test__open_and_load();
+       fentry_skel = fentry_test_lskel__open_and_load();
        if (!ASSERT_OK_PTR(fentry_skel, "fentry_skel_load"))
                goto cleanup;
 
        ASSERT_OK(err, "fentry_second_attach");
 
 cleanup:
-       fentry_test__destroy(fentry_skel);
+       fentry_test_lskel__destroy(fentry_skel);
 }
 
 
 static int do_sleep(void *skel)
 {
-       struct fexit_sleep *fexit_skel = skel;
+       struct fexit_sleep_lskel *fexit_skel = skel;
        struct timespec ts1 = { .tv_nsec = 1 };
        struct timespec ts2 = { .tv_sec = 10 };
 
 
 void test_fexit_sleep(void)
 {
-       struct fexit_sleep *fexit_skel = NULL;
+       struct fexit_sleep_lskel *fexit_skel = NULL;
        int wstatus, duration = 0;
        pid_t cpid;
        int err, fexit_cnt;
 
-       fexit_skel = fexit_sleep__open_and_load();
+       fexit_skel = fexit_sleep_lskel__open_and_load();
        if (CHECK(!fexit_skel, "fexit_skel_load", "fexit skeleton failed\n"))
                goto cleanup;
 
-       err = fexit_sleep__attach(fexit_skel);
+       err = fexit_sleep_lskel__attach(fexit_skel);
        if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err))
                goto cleanup;
 
         */
        close(fexit_skel->progs.nanosleep_fentry.prog_fd);
        close(fexit_skel->progs.nanosleep_fexit.prog_fd);
-       fexit_sleep__detach(fexit_skel);
+       fexit_sleep_lskel__detach(fexit_skel);
 
        /* kill the thread to unwind sys_nanosleep stack through the trampoline */
        kill(cpid, 9);
                goto cleanup;
 
 cleanup:
-       fexit_sleep__destroy(fexit_skel);
+       fexit_sleep_lskel__destroy(fexit_skel);
 }
 
 #include <test_progs.h>
 #include "fexit_test.lskel.h"
 
-static int fexit_test(struct fexit_test *fexit_skel)
+static int fexit_test(struct fexit_test_lskel *fexit_skel)
 {
        int err, prog_fd, i;
        __u32 duration = 0, retval;
        int link_fd;
        __u64 *result;
 
-       err = fexit_test__attach(fexit_skel);
+       err = fexit_test_lskel__attach(fexit_skel);
        if (!ASSERT_OK(err, "fexit_attach"))
                return err;
 
        /* Check that already linked program can't be attached again. */
-       link_fd = fexit_test__test1__attach(fexit_skel);
+       link_fd = fexit_test_lskel__test1__attach(fexit_skel);
        if (!ASSERT_LT(link_fd, 0, "fexit_attach_link"))
                return -1;
 
                        return -1;
        }
 
-       fexit_test__detach(fexit_skel);
+       fexit_test_lskel__detach(fexit_skel);
 
        /* zero results for re-attach test */
        memset(fexit_skel->bss, 0, sizeof(*fexit_skel->bss));
 
 void test_fexit_test(void)
 {
-       struct fexit_test *fexit_skel = NULL;
+       struct fexit_test_lskel *fexit_skel = NULL;
        int err;
 
-       fexit_skel = fexit_test__open_and_load();
+       fexit_skel = fexit_test_lskel__open_and_load();
        if (!ASSERT_OK_PTR(fexit_skel, "fexit_skel_load"))
                goto cleanup;
 
        ASSERT_OK(err, "fexit_second_attach");
 
 cleanup:
-       fexit_test__destroy(fexit_skel);
+       fexit_test_lskel__destroy(fexit_skel);
 }
 
 
 static void test_main(void)
 {
-       struct kfunc_call_test *skel;
+       struct kfunc_call_test_lskel *skel;
        int prog_fd, retval, err;
 
-       skel = kfunc_call_test__open_and_load();
+       skel = kfunc_call_test_lskel__open_and_load();
        if (!ASSERT_OK_PTR(skel, "skel"))
                return;
 
        ASSERT_OK(err, "bpf_prog_test_run(test2)");
        ASSERT_EQ(retval, 3, "test2-retval");
 
-       kfunc_call_test__destroy(skel);
+       kfunc_call_test_lskel__destroy(skel);
 }
 
 static void test_subprog(void)
 
 #include "test_ksyms_btf.skel.h"
 #include "test_ksyms_btf_null_check.skel.h"
 #include "test_ksyms_weak.skel.h"
+#include "test_ksyms_weak.lskel.h"
 
 static int duration;
 
        int err;
 
        skel = test_ksyms_weak__open_and_load();
-       if (CHECK(!skel, "test_ksyms_weak__open_and_load", "failed\n"))
+       if (!ASSERT_OK_PTR(skel, "test_ksyms_weak__open_and_load"))
                return;
 
        err = test_ksyms_weak__attach(skel);
-       if (CHECK(err, "test_ksyms_weak__attach", "skeleton attach failed: %d\n", err))
+       if (!ASSERT_OK(err, "test_ksyms_weak__attach"))
                goto cleanup;
 
        /* trigger tracepoint */
        test_ksyms_weak__destroy(skel);
 }
 
+static void test_weak_syms_lskel(void)
+{
+       struct test_ksyms_weak_lskel *skel;
+       struct test_ksyms_weak_lskel__data *data;
+       int err;
+
+       skel = test_ksyms_weak_lskel__open_and_load();
+       if (!ASSERT_OK_PTR(skel, "test_ksyms_weak_lskel__open_and_load"))
+               return;
+
+       err = test_ksyms_weak_lskel__attach(skel);
+       if (!ASSERT_OK(err, "test_ksyms_weak_lskel__attach"))
+               goto cleanup;
+
+       /* trigger tracepoint */
+       usleep(1);
+
+       data = skel->data;
+       ASSERT_EQ(data->out__existing_typed, 0, "existing typed ksym");
+       ASSERT_NEQ(data->out__existing_typeless, -1, "existing typeless ksym");
+       ASSERT_EQ(data->out__non_existent_typeless, 0, "nonexistent typeless ksym");
+       ASSERT_EQ(data->out__non_existent_typed, 0, "nonexistent typed ksym");
+
+cleanup:
+       test_ksyms_weak_lskel__destroy(skel);
+}
+
 void test_ksyms_btf(void)
 {
        int percpu_datasec;
 
        if (test__start_subtest("weak_ksyms"))
                test_weak_syms();
+
+       if (test__start_subtest("weak_ksyms_lskel"))
+               test_weak_syms_lskel();
 }
 
 #include <test_progs.h>
 #include <network_helpers.h>
 #include "test_ksyms_module.lskel.h"
+#include "test_ksyms_module.skel.h"
 
-void test_ksyms_module(void)
+void test_ksyms_module_lskel(void)
 {
-       struct test_ksyms_module *skel;
+       struct test_ksyms_module_lskel *skel;
        int retval;
        int err;
 
                return;
        }
 
-       skel = test_ksyms_module__open_and_load();
-       if (!ASSERT_OK_PTR(skel, "test_ksyms_module__open_and_load"))
+       skel = test_ksyms_module_lskel__open_and_load();
+       if (!ASSERT_OK_PTR(skel, "test_ksyms_module_lskel__open_and_load"))
                return;
        err = bpf_prog_test_run(skel->progs.load.prog_fd, 1, &pkt_v4, sizeof(pkt_v4),
                                NULL, NULL, (__u32 *)&retval, NULL);
                goto cleanup;
        ASSERT_EQ(retval, 0, "retval");
        ASSERT_EQ(skel->bss->out_bpf_testmod_ksym, 42, "bpf_testmod_ksym");
+cleanup:
+       test_ksyms_module_lskel__destroy(skel);
+}
+
+void test_ksyms_module_libbpf(void)
+{
+       struct test_ksyms_module *skel;
+       int retval, err;
+
+       if (!env.has_testmod) {
+               test__skip();
+               return;
+       }
+
+       skel = test_ksyms_module__open_and_load();
+       if (!ASSERT_OK_PTR(skel, "test_ksyms_module__open"))
+               return;
+       err = bpf_prog_test_run(bpf_program__fd(skel->progs.load), 1, &pkt_v4,
+                               sizeof(pkt_v4), NULL, NULL, (__u32 *)&retval, NULL);
+       if (!ASSERT_OK(err, "bpf_prog_test_run"))
+               goto cleanup;
+       ASSERT_EQ(retval, 0, "retval");
+       ASSERT_EQ(skel->bss->out_bpf_testmod_ksym, 42, "bpf_testmod_ksym");
 cleanup:
        test_ksyms_module__destroy(skel);
 }
+
+void test_ksyms_module(void)
+{
+       if (test__start_subtest("lskel"))
+               test_ksyms_module_lskel();
+       if (test__start_subtest("libbpf"))
+               test_ksyms_module_libbpf();
+}
 
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0
-
-#include <test_progs.h>
-#include <network_helpers.h>
-#include "test_ksyms_module.skel.h"
-
-void test_ksyms_module_libbpf(void)
-{
-       struct test_ksyms_module *skel;
-       int retval, err;
-
-       if (!env.has_testmod) {
-               test__skip();
-               return;
-       }
-
-       skel = test_ksyms_module__open_and_load();
-       if (!ASSERT_OK_PTR(skel, "test_ksyms_module__open"))
-               return;
-       err = bpf_prog_test_run(bpf_program__fd(skel->progs.load), 1, &pkt_v4,
-                               sizeof(pkt_v4), NULL, NULL, (__u32 *)&retval, NULL);
-       if (!ASSERT_OK(err, "bpf_prog_test_run"))
-               goto cleanup;
-       ASSERT_EQ(retval, 0, "retval");
-       ASSERT_EQ(skel->bss->out_bpf_testmod_ksym, 42, "bpf_testmod_ksym");
-cleanup:
-       test_ksyms_module__destroy(skel);
-}
 
        }
 }
 
-static struct test_ringbuf *skel;
+static struct test_ringbuf_lskel *skel;
 static struct ring_buffer *ringbuf;
 
 static void trigger_samples()
        int page_size = getpagesize();
        void *mmap_ptr, *tmp_ptr;
 
-       skel = test_ringbuf__open();
+       skel = test_ringbuf_lskel__open();
        if (CHECK(!skel, "skel_open", "skeleton open failed\n"))
                return;
 
        skel->maps.ringbuf.max_entries = page_size;
 
-       err = test_ringbuf__load(skel);
+       err = test_ringbuf_lskel__load(skel);
        if (CHECK(err != 0, "skel_load", "skeleton load failed\n"))
                goto cleanup;
 
        if (CHECK(!ringbuf, "ringbuf_create", "failed to create ringbuf\n"))
                goto cleanup;
 
-       err = test_ringbuf__attach(skel);
+       err = test_ringbuf_lskel__attach(skel);
        if (CHECK(err, "skel_attach", "skeleton attachment failed: %d\n", err))
                goto cleanup;
 
        CHECK(skel->bss->discarded != 1, "err_discarded", "exp %ld, got %ld\n",
              1L, skel->bss->discarded);
 
-       test_ringbuf__detach(skel);
+       test_ringbuf_lskel__detach(skel);
 cleanup:
        ring_buffer__free(ringbuf);
-       test_ringbuf__destroy(skel);
+       test_ringbuf_lskel__destroy(skel);
 }
 
 
 void serial_test_trace_printk(void)
 {
+       struct trace_printk_lskel__bss *bss;
        int err = 0, iter = 0, found = 0;
-       struct trace_printk__bss *bss;
-       struct trace_printk *skel;
+       struct trace_printk_lskel *skel;
        char *buf = NULL;
        FILE *fp = NULL;
        size_t buflen;
 
-       skel = trace_printk__open();
+       skel = trace_printk_lskel__open();
        if (!ASSERT_OK_PTR(skel, "trace_printk__open"))
                return;
 
        ASSERT_EQ(skel->rodata->fmt[0], 'T', "skel->rodata->fmt[0]");
        skel->rodata->fmt[0] = 't';
 
-       err = trace_printk__load(skel);
+       err = trace_printk_lskel__load(skel);
        if (!ASSERT_OK(err, "trace_printk__load"))
                goto cleanup;
 
        bss = skel->bss;
 
-       err = trace_printk__attach(skel);
+       err = trace_printk_lskel__attach(skel);
        if (!ASSERT_OK(err, "trace_printk__attach"))
                goto cleanup;
 
 
        /* wait for tracepoint to trigger */
        usleep(1);
-       trace_printk__detach(skel);
+       trace_printk_lskel__detach(skel);
 
        if (!ASSERT_GT(bss->trace_printk_ran, 0, "bss->trace_printk_ran"))
                goto cleanup;
                goto cleanup;
 
 cleanup:
-       trace_printk__destroy(skel);
+       trace_printk_lskel__destroy(skel);
        free(buf);
        if (fp)
                fclose(fp);
 
 
 void serial_test_trace_vprintk(void)
 {
+       struct trace_vprintk_lskel__bss *bss;
        int err = 0, iter = 0, found = 0;
-       struct trace_vprintk__bss *bss;
-       struct trace_vprintk *skel;
+       struct trace_vprintk_lskel *skel;
        char *buf = NULL;
        FILE *fp = NULL;
        size_t buflen;
 
-       skel = trace_vprintk__open_and_load();
+       skel = trace_vprintk_lskel__open_and_load();
        if (!ASSERT_OK_PTR(skel, "trace_vprintk__open_and_load"))
                goto cleanup;
 
        bss = skel->bss;
 
-       err = trace_vprintk__attach(skel);
+       err = trace_vprintk_lskel__attach(skel);
        if (!ASSERT_OK(err, "trace_vprintk__attach"))
                goto cleanup;
 
 
        /* wait for tracepoint to trigger */
        usleep(1);
-       trace_vprintk__detach(skel);
+       trace_vprintk_lskel__detach(skel);
 
        if (!ASSERT_GT(bss->trace_vprintk_ran, 0, "bss->trace_vprintk_ran"))
                goto cleanup;
                goto cleanup;
 
 cleanup:
-       trace_vprintk__destroy(skel);
+       trace_vprintk_lskel__destroy(skel);
        free(buf);
        if (fp)
                fclose(fp);
 
 void test_verif_stats(void)
 {
        __u32 len = sizeof(struct bpf_prog_info);
+       struct trace_vprintk_lskel *skel;
        struct bpf_prog_info info = {};
-       struct trace_vprintk *skel;
        int err;
 
-       skel = trace_vprintk__open_and_load();
+       skel = trace_vprintk_lskel__open_and_load();
        if (!ASSERT_OK_PTR(skel, "trace_vprintk__open_and_load"))
                goto cleanup;
 
                goto cleanup;
 
 cleanup:
-       trace_vprintk__destroy(skel);
+       trace_vprintk_lskel__destroy(skel);
 }
 
        /* tests existing symbols. */
        rq = (struct rq *)bpf_per_cpu_ptr(&runqueues, 0);
        if (rq)
-               out__existing_typed = rq->cpu;
+               out__existing_typed = 0;
        out__existing_typeless = (__u64)&bpf_prog_active;
 
        /* tests non-existent symbols. */