/* Common things used by the various darwin files
   Copyright (C) 1995-2021 Free Software Foundation, Inc.

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

#ifndef DARWIN_NAT_H
#define DARWIN_NAT_H

#include "inf-child.h"
#include <mach/mach.h>
#include "gdbthread.h"

struct darwin_exception_msg
{
  mach_msg_header_t header;

  /* Thread and task taking the exception.  */
  mach_port_t thread_port;
  mach_port_t task_port;

  /* Type of the exception.  */
  exception_type_t ex_type;

  /* Machine dependent details.  */
  mach_msg_type_number_t data_count;
  integer_t ex_data[2];
};

enum darwin_msg_state
{
  /* The thread is running.  */
  DARWIN_RUNNING,

  /* The thread is stopped.  */
  DARWIN_STOPPED,

  /* The thread has sent a message and waits for a reply.  */
  DARWIN_MESSAGE
};

struct darwin_thread_info : public private_thread_info
{
  /* The thread port from a GDB point of view.  */
  thread_t gdb_port = 0;

  /* The thread port from the inferior point of view.  Not to be used inside
     gdb except for get_ada_task_ptid.  */
  thread_t inf_port = 0;

  /* Current message state.
     If the kernel has sent a message it expects a reply and the inferior
     can't be killed before.  */
  enum darwin_msg_state msg_state = DARWIN_RUNNING;

  /* True if this thread is single-stepped.  */
  bool single_step = false;

  /* True if a signal was manually sent to the thread.  */
  bool signaled = false;

  /* The last exception received.  */
  struct darwin_exception_msg event {};
};
typedef struct darwin_thread_info darwin_thread_t;

/* This needs to be overridden by the platform specific nat code.  */

class darwin_nat_target : public inf_child_target
{
  void create_inferior (const char *exec_file,
			const std::string &allargs,
			char **env, int from_tty) override;

  void attach (const char *, int) override;

  void detach (inferior *, int) override;

  ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;

  void mourn_inferior () override;

  void kill () override;

  void interrupt () override;

  void resume (ptid_t, int , enum gdb_signal) override;

  bool thread_alive (ptid_t ptid) override;

  std::string pid_to_str (ptid_t) override;

  char *pid_to_exec_file (int pid) override;

  enum target_xfer_status xfer_partial (enum target_object object,
					const char *annex,
					gdb_byte *readbuf,
					const gdb_byte *writebuf,
					ULONGEST offset, ULONGEST len,
					ULONGEST *xfered_len) override;

  bool supports_multi_process () override;

  ptid_t get_ada_task_ptid (long lwp, long thread) override;

private:
  ptid_t wait_1 (ptid_t, struct target_waitstatus *);
  void check_new_threads (inferior *inf);
  int decode_exception_message (mach_msg_header_t *hdr,
				inferior **pinf,
				darwin_thread_t **pthread);
  ptid_t decode_message (mach_msg_header_t *hdr,
			 darwin_thread_t **pthread,
			 inferior **pinf,
			 target_waitstatus *status);
  void stop_inferior (inferior *inf);
  void init_thread_list (inferior *inf);
  void ptrace_him (int pid);
  int cancel_breakpoint (ptid_t ptid);
};

/* Describe the mach exception handling state for a task.  This state is saved
   before being changed and restored when a process is detached.
   For more information on these fields see task_get_exception_ports manual
   page.  */
struct darwin_exception_info
{
  /* Exceptions handled by the port.  */
  exception_mask_t masks[EXC_TYPES_COUNT] {};

  /* Ports receiving exception messages.  */
  mach_port_t ports[EXC_TYPES_COUNT] {};

  /* Type of messages sent.  */
  exception_behavior_t behaviors[EXC_TYPES_COUNT] {};

  /* Type of state to be sent.  */
  thread_state_flavor_t flavors[EXC_TYPES_COUNT] {};

  /* Number of elements set.  */
  mach_msg_type_number_t count = 0;
};

static inline darwin_thread_info *
get_darwin_thread_info (class thread_info *thread)
{
  return static_cast<darwin_thread_info *> (thread->priv.get ());
}

/* Describe an inferior.  */
struct darwin_inferior : public private_inferior
{
  /* Corresponding task port.  */
  task_t task = 0;

  /* Port which will receive the dead-name notification for the task port.
     This is used to detect the death of the task.  */
  mach_port_t notify_port = 0;

  /* Initial exception handling.  */
  darwin_exception_info exception_info;

  /* Number of messages that have been received but not yet replied.  */
  unsigned int pending_messages = 0;

  /* Set if inferior is not controlled by ptrace(2) but through Mach.  */
  bool no_ptrace = false;

  /* True if this task is suspended.  */
  bool suspended = false;

  /* Sorted vector of known threads.  */
  std::vector<darwin_thread_t *> threads;
};

/* Return the darwin_inferior attached to INF.  */

static inline darwin_inferior *
get_darwin_inferior (inferior *inf)
{
  return static_cast<darwin_inferior *> (inf->priv.get ());
}

/* Exception port.  */
extern mach_port_t darwin_ex_port;

/* Port set.  */
extern mach_port_t darwin_port_set;

/* A copy of mach_host_self ().  */
extern mach_port_t darwin_host_self;

/* FUNCTION_NAME is defined in common-utils.h (or not).  */
#ifdef FUNCTION_NAME
#define MACH_CHECK_ERROR(ret) \
  mach_check_error (ret, __FILE__, __LINE__, FUNCTION_NAME)
#else
#define MACH_CHECK_ERROR(ret) \
  mach_check_error (ret, __FILE__, __LINE__, "??")
#endif

extern void mach_check_error (kern_return_t ret, const char *file,
			      unsigned int line, const char *func);

void darwin_set_sstep (thread_t thread, int enable);

void darwin_check_osabi (darwin_inferior *inf, thread_t thread);

#endif /* DARWIN_NAT_H */
