def generate_readargs(feature_list):
    """
    Generate bpf_usdt_readargs_p() calls for the given feature list.

    This function assumes that the following are in scope:
    - struct pt_regs *ctx
    - struct SUBST_OU_output *output

    Parameters
    ----------
    feature_list : List[model.Feature]
        List of BPF features being emitted.

    Returns
    -------
    code : str
        bpf_usdt_readarg() and bpf_usdt_readarg_p() invocations.
    """
    code = []
    non_feature_usdt_args = 1  # Currently just ou_instance. If any other non-feature args are added, increment this.
    for idx, feature in enumerate(feature_list, 1):
        first_member = feature.bpf_tuple[0].name
        if feature.readarg_p:
            readarg_p = [
                "  bpf_usdt_readarg_p(",
                f"{idx + non_feature_usdt_args}, ",
                "ctx, ",
                f"&(features->{first_member}), ",
                f"sizeof(struct DECL_{feature.name})",
                ");\n",
            ]
            code.append("".join(readarg_p))
        else:
            readarg = [
                "  bpf_usdt_readarg(",
                f"{idx + non_feature_usdt_args}, ",
                "ctx, ",
                f"&(features->{first_member})",
                ");\n",
            ]
            code.append("".join(readarg))
    return "".join(code)