#include "config.h"
#include "libdwarfdefs.h"
#include <stdio.h>
#include <string.h>
#ifdef HAVE_ELF_H
#include <elf.h>
#endif
#include "pro_incl.h"
#include "pro_line.h"
Dwarf_Unsigned _dwarf_pro_add_line_entry(Dwarf_P_Debug,
Dwarf_Unsigned file_index,
Dwarf_Addr code_address,
Dwarf_Unsigned symidx,
Dwarf_Unsigned line_no,
Dwarf_Signed col_no,
Dwarf_Bool is_stmt_begin,
Dwarf_Bool is_bb_begin,
Dwarf_Ubyte opc,
Dwarf_Error * error);
Dwarf_Unsigned
dwarf_add_line_entry(Dwarf_P_Debug dbg,
Dwarf_Unsigned file_index,
Dwarf_Addr code_address,
Dwarf_Unsigned line_no,
Dwarf_Signed col_no,
Dwarf_Bool is_stmt_begin,
Dwarf_Bool is_bb_begin, Dwarf_Error * error)
{
Dwarf_Unsigned retval;
retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, 0,
line_no, col_no, is_stmt_begin,
is_bb_begin, 0, error);
return retval;
}
Dwarf_Unsigned
dwarf_lne_set_address(Dwarf_P_Debug dbg,
Dwarf_Addr offs,
Dwarf_Unsigned symidx, Dwarf_Error * error)
{
Dwarf_Ubyte opc;
Dwarf_Unsigned retval;
opc = DW_LNE_set_address;
retval =
_dwarf_pro_add_line_entry(dbg, 0, offs, symidx, 0, 0, 0, 0, opc,
error);
return retval;
}
Dwarf_Unsigned
dwarf_lne_end_sequence(Dwarf_P_Debug dbg,
Dwarf_Addr end_address, Dwarf_Error * error)
{
Dwarf_Ubyte opc;
Dwarf_Unsigned retval;
opc = DW_LNE_end_sequence;
retval =
_dwarf_pro_add_line_entry(dbg, 0, end_address, 0, 0, 0, 0, 0,
opc, error);
return retval;
}
Dwarf_Unsigned
_dwarf_pro_add_line_entry(Dwarf_P_Debug dbg,
Dwarf_Unsigned file_index,
Dwarf_Addr code_address,
Dwarf_Unsigned symidx,
Dwarf_Unsigned line_no,
Dwarf_Signed col_no,
Dwarf_Bool is_stmt_begin,
Dwarf_Bool is_bb_begin,
Dwarf_Ubyte opc, Dwarf_Error * error)
{
if (dbg->de_lines == NULL) {
dbg->de_lines = (Dwarf_P_Line)
_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
if (dbg->de_lines == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT);
}
dbg->de_last_line = dbg->de_lines;
_dwarf_pro_reg_init(dbg->de_lines);
} else {
dbg->de_last_line->dpl_next = (Dwarf_P_Line)
_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
if (dbg->de_last_line->dpl_next == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT);
}
dbg->de_last_line = dbg->de_last_line->dpl_next;
_dwarf_pro_reg_init(dbg->de_last_line);
}
dbg->de_last_line->dpl_address = code_address;
dbg->de_last_line->dpl_file = (unsigned long) file_index;
dbg->de_last_line->dpl_line = (unsigned long) line_no;
dbg->de_last_line->dpl_column = (unsigned long) col_no;
dbg->de_last_line->dpl_is_stmt = is_stmt_begin;
dbg->de_last_line->dpl_basic_block = is_bb_begin;
dbg->de_last_line->dpl_opc = opc;
dbg->de_last_line->dpl_r_symidx = symidx;
return (0);
}
Dwarf_Unsigned
dwarf_add_directory_decl(Dwarf_P_Debug dbg,
char *name, Dwarf_Error * error)
{
if (dbg->de_inc_dirs == NULL) {
dbg->de_inc_dirs = (Dwarf_P_Inc_Dir)
_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
if (dbg->de_inc_dirs == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT);
}
dbg->de_last_inc_dir = dbg->de_inc_dirs;
dbg->de_n_inc_dirs = 1;
} else {
dbg->de_last_inc_dir->did_next = (Dwarf_P_Inc_Dir)
_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
if (dbg->de_last_inc_dir->did_next == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT);
}
dbg->de_last_inc_dir = dbg->de_last_inc_dir->did_next;
dbg->de_n_inc_dirs++;
}
dbg->de_last_inc_dir->did_name =
(char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1);
if (dbg->de_last_inc_dir->did_name == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_NOCOUNT);
}
strcpy(dbg->de_last_inc_dir->did_name, name);
dbg->de_last_inc_dir->did_next = NULL;
return dbg->de_n_inc_dirs;
}
Dwarf_Unsigned
dwarf_add_file_decl(Dwarf_P_Debug dbg,
char *name,
Dwarf_Unsigned dir_idx,
Dwarf_Unsigned time_mod,
Dwarf_Unsigned length, Dwarf_Error * error)
{
Dwarf_P_F_Entry cur;
char *ptr;
int nbytes_idx, nbytes_time, nbytes_len;
char buffidx[ENCODE_SPACE_NEEDED];
char bufftime[ENCODE_SPACE_NEEDED];
char bufflen[ENCODE_SPACE_NEEDED];
int res;
if (dbg->de_file_entries == NULL) {
dbg->de_file_entries = (Dwarf_P_F_Entry)
_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
if (dbg->de_file_entries == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC,
DW_DLV_NOCOUNT);
}
cur = dbg->de_file_entries;
dbg->de_last_file_entry = cur;
dbg->de_n_file_entries = 1;
} else {
cur = dbg->de_last_file_entry;
cur->dfe_next = (Dwarf_P_F_Entry)
_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
if (cur->dfe_next == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC,
DW_DLV_NOCOUNT);
}
cur = cur->dfe_next;
dbg->de_last_file_entry = cur;
dbg->de_n_file_entries++;
}
cur->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1);
if (cur->dfe_name == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
}
strcpy((char *) cur->dfe_name, name);
res = _dwarf_pro_encode_leb128_nm(dir_idx, &nbytes_idx,
buffidx, sizeof(buffidx));
if (res != DW_DLV_OK) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
}
res = _dwarf_pro_encode_leb128_nm(time_mod, &nbytes_time,
bufftime, sizeof(bufftime));
if (res != DW_DLV_OK) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
}
res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len,
bufflen, sizeof(bufflen));
cur->dfe_args = (char *)
_dwarf_p_get_alloc(dbg, nbytes_idx + nbytes_time + nbytes_len);
if (cur->dfe_args == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
}
ptr = cur->dfe_args;
memcpy((void *) ptr, buffidx, nbytes_idx);
ptr += nbytes_idx;
memcpy((void *) ptr, bufftime, nbytes_time);
ptr += nbytes_time;
memcpy((void *) ptr, bufflen, nbytes_len);
ptr += nbytes_len;
cur->dfe_nbytes = nbytes_idx + nbytes_time + nbytes_len;
cur->dfe_next = NULL;
return dbg->de_n_file_entries;
}
void
_dwarf_pro_reg_init(Dwarf_P_Line cur_line)
{
cur_line->dpl_address = 0;
cur_line->dpl_file = 1;
cur_line->dpl_line = 1;
cur_line->dpl_column = 0;
cur_line->dpl_is_stmt = DEFAULT_IS_STMT;
cur_line->dpl_basic_block = false;
cur_line->dpl_next = NULL;
}