/* Emulation of eBPF helpers.
   Copyright (C) 2020-2021 Free Software Foundation, Inc.

   This file is part of GDB, the GNU debugger.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* BPF programs rely on the existence of several helper functions,
   which are provided by the kernel.  This simulator provides an
   implementation of the helpers, which can be customized by the
   user.  */

/* This must come before any other includes.  */
#include "defs.h"

#define WANT_CPU_BPFBF
#define WANT_CPU bpfbf

#include "sim-main.h"
#include "cgen-mem.h"
#include "cgen-ops.h"
#include "cpu.h"

#include "bpf-helpers.h"

/* bpf_trace_printk is a printk-like facility for debugging.

   In the kernel, it appends a line to the Linux's tracing debugging
   interface.

   In this simulator, it uses the simulator's tracing interface
   instead.

   The format tags recognized by this helper are:
   %d, %i, %u, %x, %ld, %li, %lu, %lx, %lld, %lli, %llu, %llx,
   %p, %s

   A maximum of three tags are supported.

   This helper returns the number of bytes written, or a negative
   value in case of failure.  */

int
bpf_trace_printk (SIM_CPU *current_cpu)
{
  va_list ap;
  SIM_DESC sd = CPU_STATE (current_cpu);

  DI fmt_address;
  uint32_t size, tags_processed;
  size_t i, bytes_written = 0;

  /* The first argument is the format string, which is passed as a
     pointer in %r1.  */
  fmt_address = GET_H_GPR (1);

  /* The second argument is the length of the format string, as an
     unsigned 32-bit number in %r2.  */
  size = GET_H_GPR (2);

  /* Read the format string from the memory pointed by %r2, printing
     out the stuff as we go.  There is a maximum of three format tags
     supported, which are read from %r3, %r4 and %r5 respectively.  */
  for (i = 0, tags_processed = 0; i < size;)
    {
      UDI value;
      QI c = GETMEMUQI (current_cpu, CPU_PC_GET (current_cpu),
                        fmt_address + i);

      switch (c)
        {
        case '%':
          /* Check we are not exceeding the limit of three format
             tags.  */
          if (tags_processed > 2)
            return -1; /* XXX look for kernel error code.  */

          /* Depending on the kind of tag, extract the value from the
             proper argument.  */
          if (i++ >= size)
            return -1; /* XXX look for kernel error code.  */

          value = GET_H_GPR (3 + tags_processed);

          switch ((GETMEMUQI (current_cpu, CPU_PC_GET (current_cpu),
                             fmt_address + i)))
            {
            case 'd':
              trace_printf (sd, current_cpu, "%d", (int) value);
              break;
            case 'i':
              trace_printf (sd, current_cpu, "%i", (int) value);
              break;
            case 'u':
              trace_printf (sd, current_cpu, "%u", (unsigned int) value);
              break;
            case 'x':
              trace_printf (sd, current_cpu, "%x", (unsigned int) value);
              break;
            case 'l':
              {
                if (i++ >= size)
                  return -1;
                switch (GETMEMUQI (current_cpu, CPU_PC_GET (current_cpu),
                             fmt_address + i))
                  {
                  case 'd':
                    trace_printf (sd, current_cpu, "%ld", (long) value);
                    break;
                  case 'i':
                    trace_printf (sd, current_cpu, "%li", (long) value);
                    break;
                  case 'u':
                    trace_printf (sd, current_cpu, "%lu", (unsigned long) value);
                    break;
                  case 'x':
                    trace_printf (sd, current_cpu, "%lx", (unsigned long) value);
                    break;
                  case 'l':
                    {
                      if (i++ >= size)
                        return -1;
                      switch (GETMEMUQI (current_cpu, CPU_PC_GET (current_cpu),
                                fmt_address + i)) {
                        case 'd':
                          trace_printf (sd, current_cpu, "%lld", (long long) value);
                          break;
                        case 'i':
                          trace_printf (sd, current_cpu, "%lli", (long long) value);
                          break;
                        case 'u':
                          trace_printf (sd, current_cpu, "%llu", (unsigned long long) value);
                          break;
                        case 'x':
                          trace_printf (sd, current_cpu, "%llx", (unsigned long long) value);
                          break;
                        default:
                          assert (0);
                          break;
                      }
                      break;
                    }
                  default:
                    assert (0);
                    break;
                }
                break;
              }
            default:
              /* XXX completeme */
              assert (0);
              break;
            }

          tags_processed++;
          i++;
          break;
        case '\0':
          i = size;
          break;
        default:
          trace_printf (sd, current_cpu, "%c", c);
          bytes_written++;
          i++;
          break;
        }
    }

  return bytes_written;
}
