1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. 4*7fd79137SRobert Mustacchi 5*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 6*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 7*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 8*7fd79137SRobert Mustacchi 9*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 10*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 11*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12*7fd79137SRobert Mustacchi 13*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 14*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 15*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 16*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 17*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 18*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 19*7fd79137SRobert Mustacchi 20*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 21*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 22*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 23*7fd79137SRobert Mustacchi USA. 24*7fd79137SRobert Mustacchi 25*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 26*7fd79137SRobert Mustacchi Mountain View, CA 94043, or: 27*7fd79137SRobert Mustacchi 28*7fd79137SRobert Mustacchi http://www.sgi.com 29*7fd79137SRobert Mustacchi 30*7fd79137SRobert Mustacchi For further information regarding this notice, see: 31*7fd79137SRobert Mustacchi 32*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan 33*7fd79137SRobert Mustacchi 34*7fd79137SRobert Mustacchi */ 35*7fd79137SRobert Mustacchi 36*7fd79137SRobert Mustacchi 37*7fd79137SRobert Mustacchi 38*7fd79137SRobert Mustacchi #include "config.h" 39*7fd79137SRobert Mustacchi #include "libdwarfdefs.h" 40*7fd79137SRobert Mustacchi #include <stdio.h> 41*7fd79137SRobert Mustacchi #include <string.h> 42*7fd79137SRobert Mustacchi #ifdef HAVE_ELF_H 43*7fd79137SRobert Mustacchi #include <elf.h> 44*7fd79137SRobert Mustacchi #endif 45*7fd79137SRobert Mustacchi #include "pro_incl.h" 46*7fd79137SRobert Mustacchi #include "pro_line.h" 47*7fd79137SRobert Mustacchi 48*7fd79137SRobert Mustacchi Dwarf_Unsigned _dwarf_pro_add_line_entry(Dwarf_P_Debug, 49*7fd79137SRobert Mustacchi Dwarf_Unsigned file_index, 50*7fd79137SRobert Mustacchi Dwarf_Addr code_address, 51*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx, 52*7fd79137SRobert Mustacchi Dwarf_Unsigned line_no, 53*7fd79137SRobert Mustacchi Dwarf_Signed col_no, 54*7fd79137SRobert Mustacchi Dwarf_Bool is_stmt_begin, 55*7fd79137SRobert Mustacchi Dwarf_Bool is_bb_begin, 56*7fd79137SRobert Mustacchi Dwarf_Ubyte opc, 57*7fd79137SRobert Mustacchi Dwarf_Error * error); 58*7fd79137SRobert Mustacchi 59*7fd79137SRobert Mustacchi /*------------------------------------------------------------------------- 60*7fd79137SRobert Mustacchi Add a entry to the line information section 61*7fd79137SRobert Mustacchi file_index: index of file in file entries, obtained from 62*7fd79137SRobert Mustacchi add_file_entry() call. 63*7fd79137SRobert Mustacchi 64*7fd79137SRobert Mustacchi This function actually calls _dwarf_pro_add_line_entry(), with 65*7fd79137SRobert Mustacchi an extra parameter, the opcode. Done so that interface calls 66*7fd79137SRobert Mustacchi dwarf_lne_set_address() and dwarf_lne_end_sequence() can use 67*7fd79137SRobert Mustacchi this internal routine. 68*7fd79137SRobert Mustacchi ---------------------------------------------------------------------------*/ 69*7fd79137SRobert Mustacchi Dwarf_Unsigned 70*7fd79137SRobert Mustacchi dwarf_add_line_entry(Dwarf_P_Debug dbg, 71*7fd79137SRobert Mustacchi Dwarf_Unsigned file_index, 72*7fd79137SRobert Mustacchi Dwarf_Addr code_address, 73*7fd79137SRobert Mustacchi Dwarf_Unsigned line_no, 74*7fd79137SRobert Mustacchi Dwarf_Signed col_no, 75*7fd79137SRobert Mustacchi Dwarf_Bool is_stmt_begin, 76*7fd79137SRobert Mustacchi Dwarf_Bool is_bb_begin, Dwarf_Error * error) 77*7fd79137SRobert Mustacchi { 78*7fd79137SRobert Mustacchi Dwarf_Unsigned retval; 79*7fd79137SRobert Mustacchi 80*7fd79137SRobert Mustacchi retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, 0, 81*7fd79137SRobert Mustacchi line_no, col_no, is_stmt_begin, 82*7fd79137SRobert Mustacchi is_bb_begin, 0, error); 83*7fd79137SRobert Mustacchi return retval; 84*7fd79137SRobert Mustacchi } 85*7fd79137SRobert Mustacchi 86*7fd79137SRobert Mustacchi /*------------------------------------------------------------------------ 87*7fd79137SRobert Mustacchi Ask to emit DW_LNE_set_address opcode explicitly. Used by be 88*7fd79137SRobert Mustacchi to emit start of a new .text section, or to force a relocated 89*7fd79137SRobert Mustacchi address into debug line information entry. 90*7fd79137SRobert Mustacchi -------------------------------------------------------------------------*/ 91*7fd79137SRobert Mustacchi Dwarf_Unsigned 92*7fd79137SRobert Mustacchi dwarf_lne_set_address(Dwarf_P_Debug dbg, 93*7fd79137SRobert Mustacchi Dwarf_Addr offs, 94*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx, Dwarf_Error * error) 95*7fd79137SRobert Mustacchi { 96*7fd79137SRobert Mustacchi Dwarf_Ubyte opc; 97*7fd79137SRobert Mustacchi Dwarf_Unsigned retval; 98*7fd79137SRobert Mustacchi 99*7fd79137SRobert Mustacchi opc = DW_LNE_set_address; 100*7fd79137SRobert Mustacchi retval = 101*7fd79137SRobert Mustacchi _dwarf_pro_add_line_entry(dbg, 0, offs, symidx, 0, 0, 0, 0, opc, 102*7fd79137SRobert Mustacchi error); 103*7fd79137SRobert Mustacchi return retval; 104*7fd79137SRobert Mustacchi } 105*7fd79137SRobert Mustacchi 106*7fd79137SRobert Mustacchi /*------------------------------------------------------------------------ 107*7fd79137SRobert Mustacchi Ask to emit end_seqence opcode. Used normally at the end of a 108*7fd79137SRobert Mustacchi compilation unit. Can also be used in the middle if there 109*7fd79137SRobert Mustacchi are gaps in the region described by the code address. 110*7fd79137SRobert Mustacchi -------------------------------------------------------------------------*/ 111*7fd79137SRobert Mustacchi Dwarf_Unsigned 112*7fd79137SRobert Mustacchi dwarf_lne_end_sequence(Dwarf_P_Debug dbg, 113*7fd79137SRobert Mustacchi Dwarf_Addr end_address, Dwarf_Error * error) 114*7fd79137SRobert Mustacchi { 115*7fd79137SRobert Mustacchi Dwarf_Ubyte opc; 116*7fd79137SRobert Mustacchi Dwarf_Unsigned retval; 117*7fd79137SRobert Mustacchi 118*7fd79137SRobert Mustacchi opc = DW_LNE_end_sequence; 119*7fd79137SRobert Mustacchi retval = 120*7fd79137SRobert Mustacchi _dwarf_pro_add_line_entry(dbg, 0, end_address, 0, 0, 0, 0, 0, 121*7fd79137SRobert Mustacchi opc, error); 122*7fd79137SRobert Mustacchi return retval; 123*7fd79137SRobert Mustacchi } 124*7fd79137SRobert Mustacchi 125*7fd79137SRobert Mustacchi /*---------------------------------------------------------------------------- 126*7fd79137SRobert Mustacchi Add an entry in the internal list of lines mantained by producer. 127*7fd79137SRobert Mustacchi Opc indicates if an opcode needs to be generated, rather than just 128*7fd79137SRobert Mustacchi an entry in the matrix. During opcodes generation time, these 129*7fd79137SRobert Mustacchi opcodes will be used. 130*7fd79137SRobert Mustacchi -----------------------------------------------------------------------------*/ 131*7fd79137SRobert Mustacchi Dwarf_Unsigned 132*7fd79137SRobert Mustacchi _dwarf_pro_add_line_entry(Dwarf_P_Debug dbg, 133*7fd79137SRobert Mustacchi Dwarf_Unsigned file_index, 134*7fd79137SRobert Mustacchi Dwarf_Addr code_address, 135*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx, 136*7fd79137SRobert Mustacchi Dwarf_Unsigned line_no, 137*7fd79137SRobert Mustacchi Dwarf_Signed col_no, 138*7fd79137SRobert Mustacchi Dwarf_Bool is_stmt_begin, 139*7fd79137SRobert Mustacchi Dwarf_Bool is_bb_begin, 140*7fd79137SRobert Mustacchi Dwarf_Ubyte opc, Dwarf_Error * error) 141*7fd79137SRobert Mustacchi { 142*7fd79137SRobert Mustacchi if (dbg->de_lines == NULL) { 143*7fd79137SRobert Mustacchi dbg->de_lines = (Dwarf_P_Line) 144*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); 145*7fd79137SRobert Mustacchi if (dbg->de_lines == NULL) { 146*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT); 147*7fd79137SRobert Mustacchi } 148*7fd79137SRobert Mustacchi dbg->de_last_line = dbg->de_lines; 149*7fd79137SRobert Mustacchi _dwarf_pro_reg_init(dbg->de_lines); 150*7fd79137SRobert Mustacchi 151*7fd79137SRobert Mustacchi } else { 152*7fd79137SRobert Mustacchi dbg->de_last_line->dpl_next = (Dwarf_P_Line) 153*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); 154*7fd79137SRobert Mustacchi if (dbg->de_last_line->dpl_next == NULL) { 155*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT); 156*7fd79137SRobert Mustacchi } 157*7fd79137SRobert Mustacchi dbg->de_last_line = dbg->de_last_line->dpl_next; 158*7fd79137SRobert Mustacchi _dwarf_pro_reg_init(dbg->de_last_line); 159*7fd79137SRobert Mustacchi } 160*7fd79137SRobert Mustacchi dbg->de_last_line->dpl_address = code_address; 161*7fd79137SRobert Mustacchi dbg->de_last_line->dpl_file = (unsigned long) file_index; 162*7fd79137SRobert Mustacchi dbg->de_last_line->dpl_line = (unsigned long) line_no; 163*7fd79137SRobert Mustacchi dbg->de_last_line->dpl_column = (unsigned long) col_no; 164*7fd79137SRobert Mustacchi dbg->de_last_line->dpl_is_stmt = is_stmt_begin; 165*7fd79137SRobert Mustacchi dbg->de_last_line->dpl_basic_block = is_bb_begin; 166*7fd79137SRobert Mustacchi dbg->de_last_line->dpl_opc = opc; 167*7fd79137SRobert Mustacchi dbg->de_last_line->dpl_r_symidx = symidx; 168*7fd79137SRobert Mustacchi 169*7fd79137SRobert Mustacchi return (0); 170*7fd79137SRobert Mustacchi } 171*7fd79137SRobert Mustacchi 172*7fd79137SRobert Mustacchi /*----------------------------------------------------------------------- 173*7fd79137SRobert Mustacchi Add a directory declaration to the debug_line section. Stored 174*7fd79137SRobert Mustacchi in linked list. 175*7fd79137SRobert Mustacchi ------------------------------------------------------------------------*/ 176*7fd79137SRobert Mustacchi Dwarf_Unsigned 177*7fd79137SRobert Mustacchi dwarf_add_directory_decl(Dwarf_P_Debug dbg, 178*7fd79137SRobert Mustacchi char *name, Dwarf_Error * error) 179*7fd79137SRobert Mustacchi { 180*7fd79137SRobert Mustacchi if (dbg->de_inc_dirs == NULL) { 181*7fd79137SRobert Mustacchi dbg->de_inc_dirs = (Dwarf_P_Inc_Dir) 182*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s)); 183*7fd79137SRobert Mustacchi if (dbg->de_inc_dirs == NULL) { 184*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT); 185*7fd79137SRobert Mustacchi } 186*7fd79137SRobert Mustacchi dbg->de_last_inc_dir = dbg->de_inc_dirs; 187*7fd79137SRobert Mustacchi dbg->de_n_inc_dirs = 1; 188*7fd79137SRobert Mustacchi } else { 189*7fd79137SRobert Mustacchi dbg->de_last_inc_dir->did_next = (Dwarf_P_Inc_Dir) 190*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s)); 191*7fd79137SRobert Mustacchi if (dbg->de_last_inc_dir->did_next == NULL) { 192*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT); 193*7fd79137SRobert Mustacchi } 194*7fd79137SRobert Mustacchi dbg->de_last_inc_dir = dbg->de_last_inc_dir->did_next; 195*7fd79137SRobert Mustacchi dbg->de_n_inc_dirs++; 196*7fd79137SRobert Mustacchi } 197*7fd79137SRobert Mustacchi dbg->de_last_inc_dir->did_name = 198*7fd79137SRobert Mustacchi (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1); 199*7fd79137SRobert Mustacchi if (dbg->de_last_inc_dir->did_name == NULL) { 200*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_NOCOUNT); 201*7fd79137SRobert Mustacchi } 202*7fd79137SRobert Mustacchi strcpy(dbg->de_last_inc_dir->did_name, name); 203*7fd79137SRobert Mustacchi dbg->de_last_inc_dir->did_next = NULL; 204*7fd79137SRobert Mustacchi 205*7fd79137SRobert Mustacchi return dbg->de_n_inc_dirs; 206*7fd79137SRobert Mustacchi } 207*7fd79137SRobert Mustacchi 208*7fd79137SRobert Mustacchi /*----------------------------------------------------------------------- 209*7fd79137SRobert Mustacchi Add a file entry declaration to the debug_line section. Stored 210*7fd79137SRobert Mustacchi in linked list. The data is immediately encodes as leb128 211*7fd79137SRobert Mustacchi and stored in Dwarf_P_F_Entry_s struct. 212*7fd79137SRobert Mustacchi ------------------------------------------------------------------------*/ 213*7fd79137SRobert Mustacchi Dwarf_Unsigned 214*7fd79137SRobert Mustacchi dwarf_add_file_decl(Dwarf_P_Debug dbg, 215*7fd79137SRobert Mustacchi char *name, 216*7fd79137SRobert Mustacchi Dwarf_Unsigned dir_idx, 217*7fd79137SRobert Mustacchi Dwarf_Unsigned time_mod, 218*7fd79137SRobert Mustacchi Dwarf_Unsigned length, Dwarf_Error * error) 219*7fd79137SRobert Mustacchi { 220*7fd79137SRobert Mustacchi Dwarf_P_F_Entry cur; 221*7fd79137SRobert Mustacchi char *ptr; 222*7fd79137SRobert Mustacchi int nbytes_idx, nbytes_time, nbytes_len; 223*7fd79137SRobert Mustacchi char buffidx[ENCODE_SPACE_NEEDED]; 224*7fd79137SRobert Mustacchi char bufftime[ENCODE_SPACE_NEEDED]; 225*7fd79137SRobert Mustacchi char bufflen[ENCODE_SPACE_NEEDED]; 226*7fd79137SRobert Mustacchi int res; 227*7fd79137SRobert Mustacchi 228*7fd79137SRobert Mustacchi if (dbg->de_file_entries == NULL) { 229*7fd79137SRobert Mustacchi dbg->de_file_entries = (Dwarf_P_F_Entry) 230*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); 231*7fd79137SRobert Mustacchi if (dbg->de_file_entries == NULL) { 232*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC, 233*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 234*7fd79137SRobert Mustacchi } 235*7fd79137SRobert Mustacchi cur = dbg->de_file_entries; 236*7fd79137SRobert Mustacchi dbg->de_last_file_entry = cur; 237*7fd79137SRobert Mustacchi dbg->de_n_file_entries = 1; 238*7fd79137SRobert Mustacchi } else { 239*7fd79137SRobert Mustacchi cur = dbg->de_last_file_entry; 240*7fd79137SRobert Mustacchi cur->dfe_next = (Dwarf_P_F_Entry) 241*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); 242*7fd79137SRobert Mustacchi if (cur->dfe_next == NULL) { 243*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC, 244*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 245*7fd79137SRobert Mustacchi } 246*7fd79137SRobert Mustacchi cur = cur->dfe_next; 247*7fd79137SRobert Mustacchi dbg->de_last_file_entry = cur; 248*7fd79137SRobert Mustacchi dbg->de_n_file_entries++; 249*7fd79137SRobert Mustacchi } 250*7fd79137SRobert Mustacchi cur->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1); 251*7fd79137SRobert Mustacchi if (cur->dfe_name == NULL) { 252*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); 253*7fd79137SRobert Mustacchi } 254*7fd79137SRobert Mustacchi strcpy((char *) cur->dfe_name, name); 255*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(dir_idx, &nbytes_idx, 256*7fd79137SRobert Mustacchi buffidx, sizeof(buffidx)); 257*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 258*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); 259*7fd79137SRobert Mustacchi } 260*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(time_mod, &nbytes_time, 261*7fd79137SRobert Mustacchi bufftime, sizeof(bufftime)); 262*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 263*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); 264*7fd79137SRobert Mustacchi } 265*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len, 266*7fd79137SRobert Mustacchi bufflen, sizeof(bufflen)); 267*7fd79137SRobert Mustacchi cur->dfe_args = (char *) 268*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, nbytes_idx + nbytes_time + nbytes_len); 269*7fd79137SRobert Mustacchi if (cur->dfe_args == NULL) { 270*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); 271*7fd79137SRobert Mustacchi } 272*7fd79137SRobert Mustacchi ptr = cur->dfe_args; 273*7fd79137SRobert Mustacchi memcpy((void *) ptr, buffidx, nbytes_idx); 274*7fd79137SRobert Mustacchi ptr += nbytes_idx; 275*7fd79137SRobert Mustacchi memcpy((void *) ptr, bufftime, nbytes_time); 276*7fd79137SRobert Mustacchi ptr += nbytes_time; 277*7fd79137SRobert Mustacchi memcpy((void *) ptr, bufflen, nbytes_len); 278*7fd79137SRobert Mustacchi ptr += nbytes_len; 279*7fd79137SRobert Mustacchi cur->dfe_nbytes = nbytes_idx + nbytes_time + nbytes_len; 280*7fd79137SRobert Mustacchi cur->dfe_next = NULL; 281*7fd79137SRobert Mustacchi 282*7fd79137SRobert Mustacchi return dbg->de_n_file_entries; 283*7fd79137SRobert Mustacchi } 284*7fd79137SRobert Mustacchi 285*7fd79137SRobert Mustacchi 286*7fd79137SRobert Mustacchi /*--------------------------------------------------------------------- 287*7fd79137SRobert Mustacchi Initialize a row of the matrix for line numbers, meaning 288*7fd79137SRobert Mustacchi initialize the struct corresponding to it 289*7fd79137SRobert Mustacchi ----------------------------------------------------------------------*/ 290*7fd79137SRobert Mustacchi void 291*7fd79137SRobert Mustacchi _dwarf_pro_reg_init(Dwarf_P_Line cur_line) 292*7fd79137SRobert Mustacchi { 293*7fd79137SRobert Mustacchi cur_line->dpl_address = 0; 294*7fd79137SRobert Mustacchi cur_line->dpl_file = 1; 295*7fd79137SRobert Mustacchi cur_line->dpl_line = 1; 296*7fd79137SRobert Mustacchi cur_line->dpl_column = 0; 297*7fd79137SRobert Mustacchi cur_line->dpl_is_stmt = DEFAULT_IS_STMT; 298*7fd79137SRobert Mustacchi cur_line->dpl_basic_block = false; 299*7fd79137SRobert Mustacchi cur_line->dpl_next = NULL; 300*7fd79137SRobert Mustacchi } 301