view src/event/quic/bpf/bpfgen.sh @ 8962:47f45a98f892 quic

QUIC: fixed handling STREAM FIN. Previously, when a STREAM FIN frame with no data bytes was received after all prior stream data were already read by the application layer, the frame was ignored and eof was not reported to the application.
author Roman Arutyunyan <arut@nginx.com>
date Tue, 11 Jan 2022 18:57:02 +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