diff --git a/Documentation/bpf/program_types.csv b/Documentation/bpf/program_types.csv
new file mode 100644
index 000000000000..adec046b0bde
--- /dev/null
+++ b/Documentation/bpf/program_types.csv
@@ -0,0 +1,82 @@
+Program Type,Attach Type,ELF Section Name,Sleepable
+``BPF_PROG_TYPE_SOCKET_FILTER``,,``socket``,
+``BPF_PROG_TYPE_SK_REUSEPORT``,``BPF_SK_REUSEPORT_SELECT_OR_MIGRATE``,``sk_reuseport/migrate``,
+``BPF_PROG_TYPE_SK_REUSEPORT``,``BPF_SK_REUSEPORT_SELECT``,``sk_reuseport``,
+``BPF_PROG_TYPE_KPROBE``,,``kprobe+``,
+``BPF_PROG_TYPE_KPROBE``,,``uprobe+``,
+``BPF_PROG_TYPE_KPROBE``,,``uprobe.s+``,Yes
+``BPF_PROG_TYPE_KPROBE``,,``kretprobe+``,
+``BPF_PROG_TYPE_KPROBE``,,``uretprobe+``,
+``BPF_PROG_TYPE_KPROBE``,,``uretprobe.s+``,Yes
+``BPF_PROG_TYPE_KPROBE``,``BPF_TRACE_KPROBE_MULTI``,``kprobe.multi+``,
+``BPF_PROG_TYPE_KPROBE``,``BPF_TRACE_KPROBE_MULTI``,``kretprobe.multi+``,
+``BPF_PROG_TYPE_KPROBE``,,``ksyscall+``,
+``BPF_PROG_TYPE_KPROBE``,,``kretsyscall+``,
+``BPF_PROG_TYPE_KPROBE``,,``usdt+``,
+``BPF_PROG_TYPE_SCHED_CLS``,,``tc``,
+``BPF_PROG_TYPE_SCHED_CLS``,,``classifier``,
+``BPF_PROG_TYPE_SCHED_ACT``,,``action``,
+``BPF_PROG_TYPE_TRACEPOINT``,,``tracepoint+``,
+``BPF_PROG_TYPE_TRACEPOINT``,,``tp+``,
+``BPF_PROG_TYPE_RAW_TRACEPOINT``,,``raw_tracepoint+``,
+``BPF_PROG_TYPE_RAW_TRACEPOINT``,,``raw_tp+``,
+``BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE``,,``raw_tracepoint.w+``,
+``BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE``,,``raw_tp.w+``,
+``BPF_PROG_TYPE_TRACING``,``BPF_TRACE_RAW_TP``,``tp_btf+``,
+``BPF_PROG_TYPE_TRACING``,``BPF_TRACE_FENTRY``,``fentry+``,
+``BPF_PROG_TYPE_TRACING``,``BPF_MODIFY_RETURN``,``fmod_ret+``,
+``BPF_PROG_TYPE_TRACING``,``BPF_TRACE_FEXIT``,``fexit+``,
+``BPF_PROG_TYPE_TRACING``,``BPF_TRACE_FENTRY``,``fentry.s+``,Yes
+``BPF_PROG_TYPE_TRACING``,``BPF_MODIFY_RETURN``,``fmod_ret.s+``,Yes
+``BPF_PROG_TYPE_TRACING``,``BPF_TRACE_FEXIT``,``fexit.s+``,Yes
+``BPF_PROG_TYPE_EXT``,,``freplace+``,
+``BPF_PROG_TYPE_LSM``,``BPF_LSM_MAC``,``lsm+``,
+``BPF_PROG_TYPE_LSM``,``BPF_LSM_MAC``,``lsm.s+``,Yes
+``BPF_PROG_TYPE_LSM``,``BPF_LSM_CGROUP``,``lsm_cgroup+``,
+``BPF_PROG_TYPE_TRACING``,``BPF_TRACE_ITER``,``iter+``,
+``BPF_PROG_TYPE_TRACING``,``BPF_TRACE_ITER``,``iter.s+``,Yes
+``BPF_PROG_TYPE_SYSCALL``,,``syscall``,Yes
+``BPF_PROG_TYPE_XDP``,``BPF_XDP_DEVMAP``,``xdp.frags/devmap``,
+``BPF_PROG_TYPE_XDP``,``BPF_XDP_DEVMAP``,``xdp/devmap``,
+``BPF_PROG_TYPE_XDP``,``BPF_XDP_CPUMAP``,``xdp.frags/cpumap``,
+``BPF_PROG_TYPE_XDP``,``BPF_XDP_CPUMAP``,``xdp/cpumap``,
+``BPF_PROG_TYPE_XDP``,``BPF_XDP``,``xdp.frags``,
+``BPF_PROG_TYPE_XDP``,``BPF_XDP``,``xdp``,
+``BPF_PROG_TYPE_PERF_EVENT``,,``perf_event``,
+``BPF_PROG_TYPE_LWT_IN``,,``lwt_in``,
+``BPF_PROG_TYPE_LWT_OUT``,,``lwt_out``,
+``BPF_PROG_TYPE_LWT_XMIT``,,``lwt_xmit``,
+``BPF_PROG_TYPE_LWT_SEG6LOCAL``,,``lwt_seg6local``,
+``BPF_PROG_TYPE_SOCK_OPS``,``BPF_CGROUP_SOCK_OPS``,``sockops``,
+``BPF_PROG_TYPE_SK_SKB``,``BPF_SK_SKB_STREAM_PARSER``,``sk_skb/stream_parser``,
+``BPF_PROG_TYPE_SK_SKB``,``BPF_SK_SKB_STREAM_VERDICT``,``sk_skb/stream_verdict``,
+``BPF_PROG_TYPE_SK_SKB``,,``sk_skb``,
+``BPF_PROG_TYPE_SK_MSG``,``BPF_SK_MSG_VERDICT``,``sk_msg``,
+``BPF_PROG_TYPE_LIRC_MODE2``,``BPF_LIRC_MODE2``,``lirc_mode2``,
+``BPF_PROG_TYPE_FLOW_DISSECTOR``,``BPF_FLOW_DISSECTOR``,``flow_dissector``,
+``BPF_PROG_TYPE_CGROUP_SKB``,``BPF_CGROUP_INET_INGRESS``,``cgroup_skb/ingress``,
+``BPF_PROG_TYPE_CGROUP_SKB``,``BPF_CGROUP_INET_EGRESS``,``cgroup_skb/egress``,
+``BPF_PROG_TYPE_CGROUP_SKB``,,``cgroup/skb``,
+``BPF_PROG_TYPE_CGROUP_SOCK``,``BPF_CGROUP_INET_SOCK_CREATE``,``cgroup/sock_create``,
+``BPF_PROG_TYPE_CGROUP_SOCK``,``BPF_CGROUP_INET_SOCK_RELEASE``,``cgroup/sock_release``,
+``BPF_PROG_TYPE_CGROUP_SOCK``,``BPF_CGROUP_INET_SOCK_CREATE``,``cgroup/sock``,
+``BPF_PROG_TYPE_CGROUP_SOCK``,``BPF_CGROUP_INET4_POST_BIND``,``cgroup/post_bind4``,
+``BPF_PROG_TYPE_CGROUP_SOCK``,``BPF_CGROUP_INET6_POST_BIND``,``cgroup/post_bind6``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_INET4_BIND``,``cgroup/bind4``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_INET6_BIND``,``cgroup/bind6``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_INET4_CONNECT``,``cgroup/connect4``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_INET6_CONNECT``,``cgroup/connect6``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_UDP4_SENDMSG``,``cgroup/sendmsg4``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_UDP6_SENDMSG``,``cgroup/sendmsg6``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_UDP4_RECVMSG``,``cgroup/recvmsg4``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_UDP6_RECVMSG``,``cgroup/recvmsg6``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_INET4_GETPEERNAME``,``cgroup/getpeername4``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_INET6_GETPEERNAME``,``cgroup/getpeername6``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_INET4_GETSOCKNAME``,``cgroup/getsockname4``,
+``BPF_PROG_TYPE_CGROUP_SOCK_ADDR``,``BPF_CGROUP_INET6_GETSOCKNAME``,``cgroup/getsockname6``,
+``BPF_PROG_TYPE_CGROUP_SYSCTL``,``BPF_CGROUP_SYSCTL``,``cgroup/sysctl``,
+``BPF_PROG_TYPE_CGROUP_SOCKOPT``,``BPF_CGROUP_GETSOCKOPT``,``cgroup/getsockopt``,
+``BPF_PROG_TYPE_CGROUP_SOCKOPT``,``BPF_CGROUP_SETSOCKOPT``,``cgroup/setsockopt``,
+``BPF_PROG_TYPE_CGROUP_DEVICE``,``BPF_CGROUP_DEVICE``,``cgroup/dev``,
+``BPF_PROG_TYPE_STRUCT_OPS``,,``struct_ops+``,
+``BPF_PROG_TYPE_SK_LOOKUP``,``BPF_SK_LOOKUP``,``sk_lookup``,
diff --git a/Documentation/bpf/programs.rst b/Documentation/bpf/programs.rst
index 620eb667ac7a..71448fe0b955 100644
--- a/Documentation/bpf/programs.rst
+++ b/Documentation/bpf/programs.rst
@@ -7,3 +7,18 @@ Program Types
    :glob:
 
    prog_*
+
+Program Types and libbpf
+========================
+
+The table below lists the program types, their attach types where relevant and the ELF section
+names supported by libbpf for them. The ELF section names follow these rules:
+
+- ``type`` is an exact match, e.g. ``SEC("socket")``
+- ``type+`` means it can be either exact ``SEC("type")`` or well-formed ``SEC("type/extras")``
+  with a ‘``/``’ separator, e.g. ``SEC("tracepoint/syscalls/sys_enter_open")``
+
+.. csv-table:: Program Types and Their ELF Section Names
+   :file: program_types.csv
+   :widths: 40 30 20 10
+   :header-rows: 1
diff --git a/scripts/gen-bpf-progtypes.sh b/scripts/gen-bpf-progtypes.sh
new file mode 100755
index 000000000000..fb9650bd5c1b
--- /dev/null
+++ b/scripts/gen-bpf-progtypes.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) Red Hat.
+#
+# Generate a .csv table of BPF program types
+
+if ! [ -d "tools/lib/bpf" -a -d "Documentation" ]; then
+    echo "Run from top level of kernel tree"
+    exit 1
+fi
+
+awk -F'[",[:space:]]+' \
+    'BEGIN { print "Program Type,Attach Type,ELF Section Name,Sleepable" }
+    /SEC_DEF\(\"/ && !/SEC_DEPRECATED/ {
+    type = "``BPF_PROG_TYPE_" $4 "``"
+    attach = index($5, "0") ? "" : "``" $5 "``";
+    section = "``" $3 "``"
+    sleepable = index($0, "SEC_SLEEPABLE") ? "Yes" : "";
+    print type "," attach "," section "," sleepable }' \
+tools/lib/bpf/libbpf.c > Documentation/bpf/program_types.csv
