Arquivos
hhvm/hphp/runtime/vm/debug/dwarf.h
T
ptc 4507c61901 Include Local Var Info in DWARF Debug
Include locals information in gdb via the preexisting dwarf output.

As discussed I have a top level DIE for 'HPHP::TypedValue' with the same name
which gdb takes care of while doing the opaque type resolution.
2013-02-19 13:41:27 -08:00

191 linhas
5.3 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef _HPHP_DWARF_H_
#define _HPHP_DWARF_H_
#include <string>
#include <runtime/base/types.h>
#include <runtime/vm/translator/translator.h>
#include <libdwarf.h>
#include <dwarf.h>
#include <vector>
using namespace HPHP::VM::Transl;
namespace HPHP {
namespace VM {
namespace Debug {
typedef enum {
RAX,
RDX,
RCX,
RBX,
RSI,
RDI,
RBP,
RSP,
R8,
R9,
R10,
R11,
R12,
R13,
R14,
R15,
RIP
} x86_64_regnum_t;
const int DWARF_CODE_ALIGN = 1;
const int DWARF_DATA_ALIGN = 8;
extern int g_dwarfCallback(char *name, int size, Dwarf_Unsigned type,
Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info,
Dwarf_Unsigned *sect_name_index, Dwarf_Ptr handle, int *error);
class TCRange {
TCA m_start, m_end;
bool m_isAstubs;
void V() const { assert(isValid()); }
public:
TCRange() : m_start(nullptr), m_end(nullptr), m_isAstubs(false) {
assert(!isValid());
}
TCRange(const TCA start, const TCA end, bool isAstubs) :
m_start(start), m_end(end), m_isAstubs(isAstubs) { V(); }
TCRange& operator=(const TCRange& r) {
m_start = r.m_start;
m_end = r.m_end;
m_isAstubs = r.m_isAstubs;
V();
return *this;
}
bool isValid() const {
assert(bool(m_start) == bool(m_end));
assert(!m_start || m_start < m_end);
assert(!m_start || (m_end - m_start) < (1ll << 32));
return bool(m_start);
}
bool isAstubs() const { return m_isAstubs; }
TCA begin() const { V(); return m_start; }
TCA end() const { V(); return m_end; };
uint32_t size() const { V(); return m_end - m_start; }
void extend(const TCA newEnd) {
assert(newEnd >= m_end);
m_end = newEnd;
V();
}
};
struct DwarfBuf {
vector<uint8_t> m_buf;
void byte(uint8_t c);
void byte(int off, uint8_t c);
void word(uint16_t w);
void word(int off, uint16_t w);
void dword(uint32_t d);
void dword(int off, uint32_t d);
void qword(uint64_t q);
void clear();
int size();
uint8_t *getBuf();
void print();
void dwarf_op_const4s(int x);
void dwarf_op_deref_size(uint8_t size);
void dwarf_sfp_expr(int offset, int scale);
void dwarf_cfa_sfp(uint8_t reg, int offset, int scale);
void dwarf_cfa_unwind_rsp();
void dwarf_cfa_set_loc(uint64_t addr);
void dwarf_cfa_same_value(uint8_t reg);
void dwarf_cfa_def_cfa(uint8_t reg, uint8_t offset);
void dwarf_cfa_offset(uint8_t reg, uint8_t offset);
void dwarf_cfa_offset_extended_sf(uint8_t reg, int8_t offset);
};
struct LineEntry {
TCRange range;
int lineNumber;
LineEntry(TCRange r, int l) : range(r), lineNumber(l) {}
};
struct DwarfChunk;
struct FunctionInfo {
std::string name;
const char *file;
TCRange range;
bool exit;
bool m_perfSynced;
std::vector<LineEntry> m_lineTable;
std::vector<std::string> m_namedLocals;
DwarfChunk* m_chunk;
FunctionInfo() : m_chunk(nullptr) { }
FunctionInfo(TCRange r, bool ex)
: range(r), exit(ex), m_perfSynced(false),
m_namedLocals(std::vector<std::string>()), m_chunk(nullptr) {}
void setPerfSynced() { m_perfSynced = true; }
void clearPerfSynced() { m_perfSynced = false; }
bool perfSynced() const { return m_perfSynced; }
};
struct DwarfChunk {
DwarfBuf m_buf;
vector<FunctionInfo *> m_functions;
char *m_symfile;
bool m_synced;
DwarfChunk() : m_symfile(nullptr), m_synced(false) {}
void setSynced() { m_synced = true; }
void clearSynced() { m_synced = false; }
bool isSynced() const { return m_synced; }
};
typedef std::map<TCA, FunctionInfo* > FuncDB;
typedef vector<FunctionInfo* > FuncPtrDB;
struct DwarfInfo {
typedef std::map<TCA, TransRec> TransDB;
vector<DwarfChunk*> m_dwarfChunks;
/* Array of chunks indexed by lg(#functions in chunk) + 1.
* i.e. m_dwarfChunk[i] = pointer to chunk with
* 2^(i-1) * RuntimeOption::EvalGdbSyncChunks functions, or NULL if
* there is no such chunk. The first chunk m_dwarfChunks[0] is special in
* that it can be partially full. All other chunks are completely full.
*/
FuncDB m_functions;
const char *lookupFile(const Unit *unit);
void addLineEntries(TCRange range, const Unit *unit,
const Opcode *instr, FunctionInfo* f);
void transferFuncs(DwarfChunk* from, DwarfChunk* to);
void compactChunks();
DwarfChunk* addTracelet(TCRange range, const char* name,
const Func* func, const Opcode *instr,
bool exit, bool inPrologue);
void syncChunks();
};
}
}
}
#endif