#include "config.h"
#include "libdwarfdefs.h"
#include <stdio.h>
#include <string.h>
#include "pro_incl.h"
#include <stddef.h>
#include "dwarf.h"
#include "libdwarf.h"
#include "pro_opaque.h"
#include "pro_error.h"
#include "pro_alloc.h"
#include "pro_encode_nm.h"
#include "pro_line.h"
static int _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_Bool isepilbeg,
Dwarf_Bool isprolend,
Dwarf_Unsigned isa,
Dwarf_Unsigned discriminator,
Dwarf_Error * error);
Dwarf_Unsigned
dwarf_add_line_entry_b(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_Bool isepilbeg,
Dwarf_Bool isprolend,
Dwarf_Unsigned isa,
Dwarf_Unsigned discriminator,
Dwarf_Error * error)
{
Dwarf_Unsigned retval = 0;
Dwarf_Ubyte opc = 0;
Dwarf_Unsigned symidx = 0;
retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address,
symidx,
line_no, col_no, is_stmt_begin,
is_bb_begin,
opc,
isepilbeg,isprolend,isa,discriminator, error);
if (retval != DW_DLV_OK) {
return DW_DLV_NOCOUNT;
}
return 0;
}
int
dwarf_add_line_entry_c(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_Bool isepilbeg,
Dwarf_Bool isprolend,
Dwarf_Unsigned isa,
Dwarf_Unsigned discriminator,
Dwarf_Error * error)
{
int retval = 0;
Dwarf_Ubyte opc = 0;
Dwarf_Unsigned symidx = 0;
retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address,
symidx,
line_no, col_no, is_stmt_begin,
is_bb_begin,
opc,
isepilbeg,isprolend,isa,discriminator, error);
return retval;
}
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)
{
int retval = 0;
Dwarf_Ubyte opc = 0;
Dwarf_Unsigned symidx = 0;
Dwarf_Bool isepilbeg = 0;
Dwarf_Bool isprolend = 0;
Dwarf_Unsigned isa = 0;
Dwarf_Unsigned discriminator = 0;
retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address,
symidx,
line_no, col_no, is_stmt_begin,
is_bb_begin,
opc,
isepilbeg, isprolend, isa, discriminator,
error);
if (retval != DW_DLV_OK) {
return DW_DLV_NOCOUNT;
}
return 0;
}
void
_dwarf_init_default_line_header_vals(Dwarf_P_Debug dbg)
{
dbg->de_line_inits.pi_linetable_version = dbg->de_output_version;
dbg->de_line_inits.pi_default_is_stmt =
DEFAULT_IS_STMT;
dbg->de_line_inits.pi_minimum_instruction_length =
MIN_INST_LENGTH;
dbg->de_line_inits.pi_maximum_operations_per_instruction =
1;
dbg->de_line_inits.pi_opcode_base =
OPCODE_BASE;
dbg->de_line_inits.pi_line_base =
LINE_BASE;
dbg->de_line_inits.pi_line_range =
LINE_RANGE;
dbg->de_line_inits.pi_address_size = dbg->de_pointer_size;
dbg->de_line_inits.pi_segment_selector_size = 0;
dbg->de_line_inits.pi_segment_size = 0;
}
Dwarf_Unsigned
dwarf_lne_set_address(Dwarf_P_Debug dbg,
Dwarf_Addr offs,
Dwarf_Unsigned symidx, Dwarf_Error * error)
{
int res = 0;
res = dwarf_lne_set_address_a(dbg,offs,symidx,error);
if (res != DW_DLV_OK) {
return DW_DLV_NOCOUNT;
}
return 0;
}
int
dwarf_lne_set_address_a(Dwarf_P_Debug dbg,
Dwarf_Addr offs,
Dwarf_Unsigned symidx, Dwarf_Error * error)
{
int retval = 0;
Dwarf_Ubyte opc = 0;
Dwarf_Unsigned file_index = 0;
Dwarf_Unsigned line_no = 0;
Dwarf_Signed col_no = 0;
Dwarf_Bool is_stmt = 0;
Dwarf_Bool is_bb = 0;
Dwarf_Bool isepilbeg = 0;
Dwarf_Bool isprolend = 0;
Dwarf_Unsigned isa = 0;
Dwarf_Unsigned discriminator = 0;
opc = DW_LNE_set_address;
retval = _dwarf_pro_add_line_entry(dbg, file_index, offs,
symidx,
line_no, col_no, is_stmt,
is_bb,
opc,
isepilbeg, isprolend, isa, discriminator,
error);
return retval;
}
Dwarf_Unsigned
dwarf_lne_end_sequence(Dwarf_P_Debug dbg,
Dwarf_Addr end_address, Dwarf_Error * error)
{
int retval = 0;
retval = dwarf_lne_end_sequence_a(dbg,end_address,error);
if (retval != DW_DLV_OK) {
return DW_DLV_NOCOUNT;
}
return 0;
}
int
dwarf_lne_end_sequence_a(Dwarf_P_Debug dbg,
Dwarf_Addr end_address, Dwarf_Error * error)
{
Dwarf_Ubyte opc = 0;
int retval = 0;
Dwarf_Unsigned file_index = 0;
Dwarf_Unsigned symidx = 0;
Dwarf_Unsigned line_no = 0;
Dwarf_Bool is_stmt = 0;
Dwarf_Bool is_bb = 0;
Dwarf_Signed col_no = 0;
Dwarf_Bool isepilbeg = 0;
Dwarf_Bool isprolend = 0;
Dwarf_Unsigned isa = 0;
Dwarf_Unsigned discriminator = 0;
opc = DW_LNE_end_sequence;
retval = _dwarf_pro_add_line_entry(dbg, file_index, end_address,
symidx,
line_no, col_no, is_stmt,
is_bb,
opc,
isepilbeg, isprolend, isa, discriminator,
error);
return retval;
}
static int
_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_Bool isepilbeg,
Dwarf_Bool isprolend,
Dwarf_Unsigned isa,
Dwarf_Unsigned discriminator,
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_ERROR);
}
dbg->de_last_line = dbg->de_lines;
_dwarf_pro_reg_init(dbg,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_ERROR);
}
dbg->de_last_line = dbg->de_last_line->dpl_next;
_dwarf_pro_reg_init(dbg,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;
dbg->de_last_line->dpl_prologue_end = isprolend;
dbg->de_last_line->dpl_epilogue_begin = isepilbeg;
dbg->de_last_line->dpl_isa = isa;
dbg->de_last_line->dpl_discriminator = discriminator;
return DW_DLV_OK;
}
Dwarf_Unsigned
dwarf_add_directory_decl(Dwarf_P_Debug dbg,
char *name,
Dwarf_Error * error)
{
Dwarf_Unsigned index = 0;
int res = 0;
res = dwarf_add_directory_decl_a(dbg,name,&index,error);
if (res != DW_DLV_OK) {
return (Dwarf_Unsigned)DW_DLV_NOCOUNT;
}
return index;
}
int
dwarf_add_directory_decl_a(Dwarf_P_Debug dbg,
char *name,
Dwarf_Unsigned *index_in_directories,
Dwarf_Error * error)
{
if (dbg->de_inc_dirs == NULL) {
dbg->de_inc_dirs = (Dwarf_P_F_Entry)
_dwarf_p_get_alloc(dbg,
sizeof(struct Dwarf_P_F_Entry_s));
if (dbg->de_inc_dirs == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC,
DW_DLV_ERROR);
}
dbg->de_last_inc_dir = dbg->de_inc_dirs;
dbg->de_n_inc_dirs = 1;
} else {
dbg->de_last_inc_dir->dfe_next = (Dwarf_P_F_Entry)
_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
if (dbg->de_last_inc_dir->dfe_next == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC,
DW_DLV_ERROR);
}
dbg->de_last_inc_dir = dbg->de_last_inc_dir->dfe_next;
dbg->de_n_inc_dirs++;
}
dbg->de_last_inc_dir->dfe_name =
(char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1);
if (dbg->de_last_inc_dir->dfe_name == NULL) {
DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_ERROR);
}
strcpy(dbg->de_last_inc_dir->dfe_name, name);
dbg->de_last_inc_dir->dfe_next = NULL;
*index_in_directories = dbg->de_n_inc_dirs;
return DW_DLV_OK;
}
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_Unsigned filecount = 0;
int res = 0;
res = dwarf_add_file_decl_a(dbg,name,dir_idx,
time_mod,length,&filecount,error);
if (res != DW_DLV_OK) {
return DW_DLV_NOCOUNT;
}
return filecount;
}
int
dwarf_add_file_decl_a(Dwarf_P_Debug dbg,
char *name,
Dwarf_Unsigned dir_idx,
Dwarf_Unsigned time_mod,
Dwarf_Unsigned length,
Dwarf_Unsigned *file_entry_count_out,
Dwarf_Error * error)
{
Dwarf_P_F_Entry cur;
char *ptr = 0;
int nbytes_idx, nbytes_time, nbytes_len;
char buffidx[ENCODE_SPACE_NEEDED];
char bufftime[ENCODE_SPACE_NEEDED];
char bufflen[ENCODE_SPACE_NEEDED];
int res = 0;
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_ERROR);
}
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_ERROR);
}
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_ERROR);
}
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_LEB_OUT_ERROR, DW_DLV_ERROR);
}
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_LEB_OUT_ERROR, DW_DLV_ERROR);
}
res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len,
bufflen, sizeof(bufflen));
if (res != DW_DLV_OK) {
DWARF_P_DBG_ERROR(dbg,DW_DLE_LEB_OUT_ERROR,DW_DLV_ERROR);
}
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_ERROR);
}
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);
cur->dfe_nbytes = nbytes_idx + nbytes_time + nbytes_len;
cur->dfe_next = NULL;
*file_entry_count_out = dbg->de_n_file_entries;
return DW_DLV_OK;
}
void
_dwarf_pro_reg_init(Dwarf_P_Debug dbg, 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 = dbg->de_line_inits.pi_default_is_stmt;
cur_line->dpl_basic_block = false;
cur_line->dpl_next = NULL;
cur_line->dpl_prologue_end = 0;
cur_line->dpl_epilogue_begin = 0;
cur_line->dpl_isa = 0;
cur_line->dpl_discriminator = 0;
cur_line->dpl_opc = 0;
}