blob: e7a88924b31b2252a04149619af5b62e381d59b3 [file] [log] [blame]
/* Copyright (C) 2021-2024 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 */