aboutsummaryrefslogtreecommitdiff
path: root/gprofng/src/Stabs.h
blob: 6308e0cf370bf84fdc7d4e3ad5ec0bba9704bc31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* Copyright (C) 2021-2023 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;
class Reloc;
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
    };

    static Stabs *NewStabs(char *_path, char *lo_name);
    Stabs(char *_path, 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;}

    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);
    char	*sym_name(uint64_t target, uint64_t instr, int flag);
  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	*append_Function(Module *module, char *linkerName, uint64_t pc);
    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(unsigned int sec, Elf *elf);
    void                check_Relocs();
    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<Reloc*>	*RelLst;		// list of text relocations
    Vector<Reloc*>	*RelPLTLst;		// list of PLT relocations
    Vector<Symbol*>	*LocalLst;		// list of local func symbols
    Vector<char*>	*LocalFile;		// list of local files
    Vector<int>		*LocalFileIdx;		// start index in LocalLst

    Elf         *openElf(char *fname, Stab_status &st);
    Map<const char*, Symbol*> *get_elf_symbols();
    Dwarf       *dwarf;

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

    // Interface with dwarf
    Dwarf       *openDwarf();

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

#endif  /* _STABS_H */