src/event/quic/bpf/bpfgen.sh - nginx source code

Functions defined

Source code

  1. #!/bin/bash

  2. export LANG=C

  3. set -e

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


  8. self=$0
  9. filename=$1
  10. funcname=$PROGNAME

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

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

  17. #include "ngx_bpf.h"


  18. END
  19. }

  20. generate_tail()
  21. {
  22.     cat << END

  23. ngx_bpf_program_t $PROGNAME = {
  24.     .relocs = bpf_reloc_prog_$funcname,
  25.     .nrelocs = sizeof(bpf_reloc_prog_$funcname)
  26.                / sizeof(bpf_reloc_prog_$funcname[0]),
  27.     .ins = bpf_insn_prog_$funcname,
  28.     .nins = sizeof(bpf_insn_prog_$funcname)
  29.             / sizeof(bpf_insn_prog_$funcname[0]),
  30.     .license = "$LICENSE",
  31.     .type = BPF_PROG_TYPE_SK_REUSEPORT,
  32. };

  33. END
  34. }

  35. process_relocations()
  36. {
  37.     echo "static ngx_bpf_reloc_t bpf_reloc_prog_$funcname[] = {"

  38.     objdump -r $filename | awk '{

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

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

  44.     if ($1 == "OFFSET") {
  45.         enabled=1;
  46.     }
  47. }'
  48.     echo "};"
  49.     echo
  50. }

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

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

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

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

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

  66.         dst="$(($srcdst & 0xF))"
  67.         src="$(($srcdst & 0xF0))"
  68.         src="$(($src >> 4))"

  69.         opcode=$(printf "0x%x" $opcode)
  70.         dst=$(printf "BPF_REG_%d" $dst)
  71.         src=$(printf "BPF_REG_%d" $src)
  72.         offset=$(printf "%d" $offset)
  73.         immedi=$(printf "0x%x" $immedi)

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

  76. cat << END
  77. };

  78. END
  79. }

  80. generate_head
  81. process_relocations
  82. process_section
  83. generate_tail