/* 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.  */

#define WANT_CPU_BPFBF
#define WANT_CPU bpfbf

#include "sim-main.h"
#include "cgen-mem.h"
#include "cgen-ops.h"
#include "cpu.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;)
    {
      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.  */

          UDI 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", value);
              break;
            case 'i':
              trace_printf (sd, current_cpu, "%i", value);
              break;
            case 'u':
              trace_printf (sd, current_cpu, "%u", value);
              break;
            case 'x':
              trace_printf (sd, current_cpu, "%x", 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", value);
                    break;
                  case 'i':
                    trace_printf (sd, current_cpu, "%li", value);
                    break;
                  case 'u':
                    trace_printf (sd, current_cpu, "%lu", value);
                    break;
                  case 'x':
                    trace_printf (sd, current_cpu, "%lx", 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", value);
                          break;
                        case 'i':
                          trace_printf (sd, current_cpu, "%lli", value);
                          break;
                        case 'u':
                          trace_printf (sd, current_cpu, "%llu", value);
                          break;
                        case 'x':
                          trace_printf (sd, current_cpu, "%llx", 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;
}
