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