view src/event/quic/bpf/bpfgen.sh @ 8822:ad046179eb91 quic

QUIC: handle EAGAIN properly on UDP sockets. Previously, the error was ignored leading to unnecessary retransmits. Now, unsent frames are returned into output queue, state is reset, and timer is started for the next send attempt.
author Vladimir Homutov <vl@nginx.com>
date Wed, 28 Jul 2021 17:23:18 +0300
parents 7df607cb2d11
children
line wrap: on
line source

#!/bin/bash

export LANG=C

set -e

if [ $# -lt 1 ]; then
    echo "Usage: PROGNAME=foo LICENSE=bar $0 <bpf object file>"
    exit 1
fi


self=$0
filename=$1
funcname=$PROGNAME

generate_head()
{
    cat << END
/* AUTO-GENERATED, DO NOT EDIT. */

#include <stddef.h>
#include <stdint.h>

#include "ngx_bpf.h"


END
}

generate_tail()
{
    cat << END

ngx_bpf_program_t $PROGNAME = {
    .relocs = bpf_reloc_prog_$funcname,
    .nrelocs = sizeof(bpf_reloc_prog_$funcname)
               / sizeof(bpf_reloc_prog_$funcname[0]),
    .ins = bpf_insn_prog_$funcname,
    .nins = sizeof(bpf_insn_prog_$funcname)
            / sizeof(bpf_insn_prog_$funcname[0]),
    .license = "$LICENSE",
    .type = BPF_PROG_TYPE_SK_REUSEPORT,
};

END
}

process_relocations()
{
    echo "static ngx_bpf_reloc_t bpf_reloc_prog_$funcname[] = {"

    objdump -r $filename | awk '{

    if (enabled && $NF > 0) {
        off = strtonum(sprintf("0x%s", $1));
        name = $3;

        printf("    { \"%s\", %d },\n", name, off/8);
    }

    if ($1 == "OFFSET") {
        enabled=1;
    }
}'
    echo "};"
    echo
}

process_section()
{
    echo "static struct bpf_insn bpf_insn_prog_$funcname[] = {"
    echo "    /* opcode dst          src         offset imm */"

    section_info=$(objdump -h $filename --section=$funcname | grep "1 $funcname")

    # dd doesn't know hex
    length=$(printf "%d" 0x$(echo $section_info | cut -d ' ' -f3))
    offset=$(printf "%d" 0x$(echo $section_info | cut -d ' ' -f6))

    for ins in $(dd if="$filename" bs=1 count=$length skip=$offset status=none | xxd -p -c 8)
    do
        opcode=0x${ins:0:2}
        srcdst=0x${ins:2:2}

        # bytes are dumped in LE order
        offset=0x${ins:6:2}${ins:4:2}                        # short
        immedi=0x${ins:14:2}${ins:12:2}${ins:10:2}${ins:8:2} # int

        dst="$(($srcdst & 0xF))"
        src="$(($srcdst & 0xF0))"
        src="$(($src >> 4))"

        opcode=$(printf "0x%x" $opcode)
        dst=$(printf "BPF_REG_%d" $dst)
        src=$(printf "BPF_REG_%d" $src)
        offset=$(printf "%d" $offset)
        immedi=$(printf "0x%x" $immedi)

        printf "    { %4s, %11s, %11s, (int16_t) %6s, %10s },\n" $opcode $dst $src $offset $immedi
    done

cat << END
};

END
}

generate_head
process_relocations
process_section
generate_tail