xref: /titanic_41/usr/src/tools/ctf/dwarf/common/dwarf_line.h (revision 5aeb94743e3be0c51e86f73096334611ae3a058e)
1 /*
2 
3   Copyright (C) 2000 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., 59 Temple Place - Suite 330, Boston MA 02111-1307,
23   USA.
24 
25   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
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 #define DW_EXTENDED_OPCODE	0
39 
40 /*
41     This is used as the starting value for an algorithm
42     to get the minimum difference between 2 values.
43     UINT_MAX is used as our approximation to infinity.
44 */
45 #define MAX_LINE_DIFF       UINT_MAX
46 
47 
48 /*
49     This structure is used to build a list of all the
50     files that are used in the current compilation unit.
51     All of the fields execpt fi_next have meanings that
52     are obvious from section 6.2.4 of the Libdwarf Doc.
53 */
54 struct Dwarf_File_Entry_s {
55     /* Points to string naming the file. */
56     Dwarf_Small *fi_file_name;
57 
58     /*
59        Index into the list of directories of the directory in which
60        this file exits. */
61     Dwarf_Sword fi_dir_index;
62 
63     /* Time of last modification of the file. */
64     Dwarf_Unsigned fi_time_last_mod;
65 
66     /* Length in bytes of the file. */
67     Dwarf_Unsigned fi_file_length;
68 
69     /* Pointer for chaining file entries. */
70     Dwarf_File_Entry fi_next;
71 };
72 
73 
74 typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context;
75 
76 /*
77     This structure provides the context in which the fields of
78     a Dwarf_Line structure are interpreted.  They come from the
79     statement program prologue.  **Updated by dwarf_srclines in
80     dwarf_line.c.
81 */
82 struct Dwarf_Line_Context_s {
83     /*
84        Points to a chain of entries providing info about source files
85        for the current set of Dwarf_Line structures. */
86     Dwarf_File_Entry lc_file_entries;
87     /*
88        Count of number of source files for this set of Dwarf_Line
89        structures. */
90     Dwarf_Sword lc_file_entry_count;
91     /*
92        Points to the portion of .debug_line section that contains a
93        list of strings naming the included directories. */
94     Dwarf_Small *lc_include_directories;
95 
96     /* Count of the number of included directories. */
97     Dwarf_Sword lc_include_directories_count;
98 
99     /* Count of the number of lines for this cu. */
100     Dwarf_Sword lc_line_count;
101 
102     /* Points to name of compilation directory. */
103     Dwarf_Small *lc_compilation_directory;
104 
105     Dwarf_Debug lc_dbg;
106 };
107 
108 
109 /*
110     This structure defines a row of the line table.
111     All of the fields except li_offset have the exact
112     same meaning that is defined in Section 6.2.2
113     of the Libdwarf Document.
114 
115     li_offset is used by _dwarf_addr_finder() which is called
116     by rqs(1), an sgi utility for 'moving' shared libraries
117     as if the static linker (ld) had linked the shared library
118     at the newly-specified address.  Most libdwarf-using
119     apps will ignore li_offset and _dwarf_addr_finder().
120 
121 */
122 struct Dwarf_Line_s {
123     Dwarf_Addr li_address;	/* pc value of machine instr */
124     union addr_or_line_s {
125 	struct li_inner_s {
126 	    Dwarf_Sword li_file;	/* int identifying src file */
127 	    Dwarf_Sword li_line;	/* source file line number. */
128 	    Dwarf_Half li_column;	/* source file column number */
129 	    Dwarf_Small li_is_stmt;	/* indicate start of stmt */
130 	    Dwarf_Small li_basic_block;	/* indicate start basic block */
131 	    Dwarf_Small li_end_sequence;	/* first post sequence
132 						   instr */
133 	} li_l_data;
134 	Dwarf_Off li_offset;	/* for rqs */
135     } li_addr_line;
136     Dwarf_Line_Context li_context;	/* assoc Dwarf_Line_Context_s */
137 };
138 
139 
140 int
141   _dwarf_line_address_offsets(Dwarf_Debug dbg,
142 			      Dwarf_Die die,
143 			      Dwarf_Addr ** addrs,
144 			      Dwarf_Off ** offs,
145 			      Dwarf_Unsigned * returncount,
146 			      Dwarf_Error * err);
147 
148 
149 /* The LOP, WHAT_IS_OPCODE stuff is here so it can
150    be reused in 3 places.  Seemed hard to keep
151    the 3 places the same without an inline func or
152    a macro.
153 
154    Handling the line section where the header and the
155     file being process do not match (unusual, but
156    planned for in the  design of .debug_line)
157    is too tricky to recode this several times and keep
158    it right.
159 */
160 #define LOP_EXTENDED 1
161 #define LOP_DISCARD  2
162 #define LOP_STANDARD 3
163 #define LOP_SPECIAL  4
164 
165 #define HIGHEST_STANDARD_OPCODE  DW_LNS_fixed_advance_pc
166 
167 #define WHAT_IS_OPCODE(type,opcode,base,opcode_length,line_ptr) \
168         if( opcode < base ) {                              \
169            /* we know we must treat as a standard op       \
170                 or a special case.                         \
171            */                                              \
172            if(opcode == DW_EXTENDED_OPCODE) {              \
173                 type = LOP_EXTENDED;                       \
174            } else  if( (HIGHEST_STANDARD_OPCODE+1) >=      \
175                         base) {                            \
176                 /* == Standard case: compile of            \
177                    dwarf_line.c and object                 \
178                    have same standard op codes set.        \
179                                                            \
180                    >  Special case: compile of dwarf_line.c\
181                    has things in standard op codes list    \
182                    in dwarf.h header not                   \
183                    in the object: handle this as a standard\
184                    op code in switch below.                \
185                    The header special ops overlap the      \
186                    object standard ops.                    \
187                    The new standard op codes will not      \
188                    appear in the object.                   \
189                 */                                         \
190                 type = LOP_STANDARD;                       \
191            } else  {                                       \
192                 /* These are standard opcodes in the object\
193                 ** that were not defined  in the header    \
194                 ** at the time dwarf_line.c                \
195                 ** was compiled. Provides the ability of   \
196                 ** out-of-date dwarf reader to read newer  \
197                 ** line table data transparently.          \
198                 */                                         \
199                 int opcnt =  opcode_length[opcode];        \
200                 int oc;                                    \
201                 for(oc = 0; oc < opcnt; oc++)              \
202                   {                                         \
203                       /*                                    \
204                       ** Read and discard operands we don't \
205                       ** understand.                        \
206                       ** arbitrary choice of unsigned read. \
207                       ** signed read would work as well.    \
208                       */                                    \
209                       Dwarf_Unsigned utmp2;                 \
210                       DECODE_LEB128_UWORD(line_ptr, utmp2)  \
211                   }                                         \
212                 /* Done processing this, do not             \
213                    do the switch , nor do                   \
214                    special op code processing.              \
215                 */                                          \
216                 type = LOP_DISCARD;                         \
217            }                                                \
218                                                             \
219         } else {                                            \
220 	   /* Is  a special op code.                        \
221 	   */                                               \
222            type =  LOP_SPECIAL;                             \
223         }
224 
225 /* The following is from  the dwarf definition of 'ubyte'
226    and is specifically  mentioned in section  6.2.5.1, page 54
227    of the Rev 2.0.0 dwarf specification.
228 */
229 
230 #define MAX_LINE_OP_CODE  255
231