/* 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 _STABS_H
#define _STABS_H

#include "dbe_structs.h"
#include "vec.h"

enum cpf_instr_type_t {
    CPF_INSTR_TYPE_LD = 0,              // profiled load instruction
    CPF_INSTR_TYPE_ST,                  // profiled store instruction
    CPF_INSTR_TYPE_PREFETCH,            // profiled prefetch instruction
    CPF_INSTR_TYPE_BRTARGET,            // branch target
    CPF_INSTR_TYPE_UNKNOWN,             // unidentified instruction
    CPF_INSTR_TYPE_NTYPES               // total # of instr types
};

class Function;
class LoadObject;
class Module;
class ComC;
class Elf;
class Dwarf;
class Symbol;
struct cpf_stabs_t;
class SourceFile;
template <typename Key_t, typename Value_t> class Map;

class Include {
  public:
    typedef struct {
	SourceFile  *srcfile;
	int         lineno;
    } SrcFileInfo;
    Include();
    ~Include();
    void    new_src_file(SourceFile *source, int lineno, Function *func = NULL);
    void    new_include_file(SourceFile *source, Function *func);
    void    end_include_file(Function *func);
    void    push_src_files(Function *func);

  private:
    Vector<SrcFileInfo*> *stack;
};

// Stabs object
class Stabs {
  public:

    enum Stab_status {
	DBGD_ERR_NONE,
	DBGD_ERR_CANT_OPEN_FILE,
	DBGD_ERR_BAD_ELF_LIB,
	DBGD_ERR_BAD_ELF_FORMAT,
	DBGD_ERR_NO_STABS,
	DBGD_ERR_BAD_STABS,
	DBGD_ERR_NO_DWARF,
	DBGD_ERR_CHK_SUM
    };

    Stabs(Elf *elf, char *_lo_name);
    ~Stabs();

    bool	is_relocatable(){ return isRelocatable; }
    long long	get_textsz()	{ return textsz; }
    Platform_t	get_platform()	{ return platform; }
    WSize_t	get_class()	{ return wsize;}
    Stab_status	get_status()    { return status;}
    Vector<Symbol *> *get_symbols() { return SymLst; }

    Stab_status	read_stabs(ino64_t srcInode, Module *module, Vector<ComC*> *comComs, bool readDwarf = false);
    Stab_status	read_archive(LoadObject *lo);
    bool	read_symbols(Vector<Function*> *functions);
    uint64_t	mapOffsetToAddress(uint64_t img_offset);
  Elf *openElf (bool dbg_info = false);
    void        read_hwcprof_info(Module *module);
    void        dump();
    void        read_dwarf_from_dot_o(Module *mod);

    static bool is_fortran(Sp_lang_code lc) { return (lc == Sp_lang_fortran) || (lc == Sp_lang_fortran90); }
    static Function *find_func(char *fname, Vector<Function*> *functions, bool fortran, bool inner_names=false);
    Module	*append_Module(LoadObject *lo, char *name, int lastMod = 0);
    Function	*append_Function(Module *module, char *fname);
    Function	*map_PC_to_func(uint64_t pc, uint64_t &low_pc, Vector<Function*> *functions);
    char		*path;			// path to the object file
    char                *lo_name;       // User name of load object

  private:
  Elf *elfDbg; // ELF with debug info
  Elf *elfDis; // ELF for disasm
    Stab_status		status;			// current stabs status

    long long		textsz;			// text segment size
    Platform_t		platform;		// Sparc, Sparcv9, Intel
    WSize_t		wsize;			// word size: 32 or 64
    bool		isRelocatable;
    Symbol              *last_PC_to_sym;

    Vector<cpf_stabs_t> analyzerInfoMap;        // stabs->section mapping

    bool		check_Comm(Vector<ComC*> *comComs);
    void		check_Info(Vector<ComC*> *comComs);
    void		check_Loop(Vector<ComC*> *comComs);
    void                check_AnalyzerInfo();
    void                append_local_funcs(Module *module, int first_ind);
  Stab_status srcline_Stabs (Module *module, unsigned int StabSec, unsigned int StabStrSec, bool comdat);
  Stab_status archive_Stabs (LoadObject *lo, unsigned int StabSec, unsigned int StabStrSec, bool comdat);

    // Interface with Elf Symbol Table
    void                check_Symtab();
    void		readSymSec (Elf *elf, bool is_dynamic);
    void                get_save_addr(bool need_swap_endian);
    Symbol              *map_PC_to_sym(uint64_t pc);
    Symbol              *pltSym;
    Vector<Symbol*>	*SymLst;		// list of func symbols
    Vector<Symbol*>	*SymLstByName;		// list of func symbols sorted by Name
    Vector<Symbol*>	*LocalLst;		// list of local func symbols
    Vector<char*>	*LocalFile;		// list of local files
    Vector<int>		*LocalFileIdx;		// start index in LocalLst

    Map<const char*, Symbol*> *get_elf_symbols();
    Dwarf       *dwarf;

    bool	st_check_symtab;
    Function	*createFunction(LoadObject *lo, Module *module, Symbol *sym);
    void        fixSymtabAlias();
    void	removeDupSyms ();

    // Interface with dwarf
    Dwarf       *openDwarf();

    Vector<Module*> *stabsModules;
    static char *get_type_name(int t);
};

#endif  /* _STABS_H */
