/* Copyright (C) 2021-2025 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   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, 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, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#ifndef _DBE_FUNCTION_H
#define _DBE_FUNCTION_H

// A Function object represents an individual function in a .o file.

#include "util.h"
#include "Histable.h"
#include "SourceFile.h"

class Module;
class Symbol;
class InlinedSubr;
struct SrcInfo;
struct PCInfo;
template <class ITEM> class Vector;

const uint64_t FUNC_NO_SAVE = (uint64_t) - 1;
const uint64_t FUNC_ROOT = (uint64_t) - 2;

enum
{
  FUNC_FLAG_PLT = 1,
  FUNC_FLAG_DYNAMIC = 2,
  FUNC_FLAG_RESDER = 4, // set if derived function resolution has been done
  FUNC_FLAG_NO_OFFSET = 8, // set if disassembly should not show offset from function
  FUNC_FLAG_SIMULATED = 16, // not a real function like <Total>, <Unknown>, etc.
  FUNC_FLAG_NATIVE = 32, // no byte code for JMethod
  FUNC_NOT_JNI = 64, // a function name is not "Java_..."
  FUNC_JNI_CHECKED = 128 // already checked for "Java_..."
};

const int MAXDBUF = 32768; // the longest demangled name handled

class Function : public Histable
{
public:

  enum MPFuncTypes
  {
    MPF_DOALL,
    MPF_PAR,
    MPF_SECT,
    MPF_TASK,
    MPF_CLONE,
    MPF_OUTL
  };

  Function (uint64_t _id);
  virtual ~Function ();

  virtual uint64_t get_addr ();
  virtual char *get_name (NameFormat = NA);
  virtual Vector<Histable*> *get_comparable_objs ();
  virtual void set_name (char *);   // Set the demangled name
  virtual Histable *convertto (Histable_type type, Histable *obj = NULL);

  virtual Histable_type
  get_type ()
  {
    return FUNCTION;
  };

  virtual int64_t
  get_size ()
  {
    return size;
  };

  void set_comparable_name (const char *string);
  void set_mangled_name (const char *string);
  void set_match_name (const char *string);

  // Find any derived functions, and set their derivedNode
  void findDerivedFunctions ();
  void findKrakatoaDerivedFunctions ();
  void add_PC_info (uint64_t offset, int lineno, SourceFile *cur_src = NULL);
  void pushSrcFile (SourceFile* source, int lineno);
  SourceFile *popSrcFile ();
  int func_cmp (Function *func, SourceFile *srcContext = NULL);
  void copy_PCInfo (Function *f);
  DbeLine *mapPCtoLine (uint64_t addr, SourceFile *src = NULL);
  DbeInstr *mapLineToPc (DbeLine *dbeLine);
  DbeInstr *find_dbeinstr (int flag, uint64_t addr);
  DbeInstr *create_hide_instr (DbeInstr *instr);
  uint64_t find_previous_addr (uint64_t addr);
  SourceFile *getDefSrc ();
  char *getDefSrcName ();
  void setDefSrc (SourceFile *sf);
  void setLineFirst (int lineno);
  Vector<SourceFile*> *get_sources ();

  char *
  get_mangled_name ()
  {
    return mangled_name;
  }

  char *
  get_match_name ()
  {
    return match_name;
  }

  inline Function *
  cardinal ()
  {
    return alias ? alias : this;
  }

  unsigned int flags;       // FUNC_FLAG_*
  Module *module;           // pointer to module containing source
  int line_first;           // range of line numbers for function
  int line_last;
  int64_t size;             // size of the function in bytes
  uint64_t save_addr;       // used for detection of leaf routines
  DbeInstr *derivedNode;    // If derived from another function
  bool isOutlineFunction;   // if outline (save assumed)
  unsigned int chksum;      // check sum of instructions
  char *img_fname;          // file containing function image
  uint64_t img_offset;      // file offset of the image
  SourceFile *curr_srcfile;
  DbeLine *defaultDbeLine;
  Function *usrfunc;        // User function
  Function *alias;
  bool isUsed;
  bool isHideFunc;
  SourceFile *def_source;
  Function *indexStabsLink; // correspondent function for the .o file
  Symbol *elfSym;
  InlinedSubr *inlinedSubr;
  int inlinedSubrCnt;

private:
  DbeInstr **instHTable;    // hash table for DbeInstr
  int *addrIndexHTable;     // hash table for addrs index
  void setSource ();
  PCInfo *lookup_PCInfo (uint64_t offset);
  SrcInfo *new_srcInfo ();

  char *mangled_name;
  char *match_name;      // mangled name, with globalization stripped
  char *comparable_name; // demangled name, with globalization and blanks stripped
  char *name_buf;
  NameFormat current_name_format;
  Vector<PCInfo*> *linetab;
  Vector<DbeInstr*> *instrs;
  Vector<uint64_t> *addrs;
  uint64_t instr_id;
  Vector<SourceFile*> *sources;
  SrcInfo *curr_srcinfo;    // the current source stack of the function
  SrcInfo *srcinfo_list;    // master list for SrcInfo
};

class JMethod : public Function
{
public:
  JMethod (uint64_t _id);
  virtual ~JMethod ();
  virtual void set_name (char *);
  virtual uint64_t get_addr ();

  void
  set_addr (Vaddr _addr)
  {
    addr = _addr;
  }

  uint64_t
  get_mid ()
  {
    return mid;
  }

  void
  set_mid (uint64_t _mid)
  {
    mid = _mid;
  }

  char *
  get_signature ()
  {
    return signature;
  }

  void
  set_signature (const char *s)
  {
    signature = dbe_strdup (s);
  }

  // Returns true if func's name matches method's as its JNI implementation
  bool jni_match (Function *func);

private:
  uint64_t mid;
  Vaddr addr;
  char *signature;
  Function *jni_function;
};

#endif /* _DBE_FUNCTION_H */
