xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_loc.h (revision 8aafd47d0dbabbca4365c9565fbe0e051e7346dd)
1 /*
2   Copyright (C) 2000, 2004 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright (C) 2015-2020 David Anderson. All Rights Reserved.
4 
5   This program is free software; you can redistribute it
6   and/or modify it under the terms of version 2.1 of the
7   GNU Lesser General Public License as published by the Free
8   Software Foundation.
9 
10   This program is distributed in the hope that it would be
11   useful, but WITHOUT ANY WARRANTY; without even the implied
12   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13   PURPOSE.
14 
15   Further, this software is distributed without any warranty
16   that it is free of the rightful claim of any third person
17   regarding infringement or the like.  Any license provided
18   herein, whether implied or otherwise, applies only to this
19   software file.  Patent licenses, if any, provided herein
20   do not apply to combinations of this program with other
21   software, or any other product whatsoever.
22 
23   You should have received a copy of the GNU Lesser General
24   Public License along with this program; if not, write the
25   Free Software Foundation, Inc., 51 Franklin Street - Fifth
26   Floor, Boston MA 02110-1301, USA.
27 */
28 #ifndef DWARF_LOC_H
29 #define DWARF_LOC_H
30 #ifdef __cplusplus
31 extern "C" {
32 #endif /* __cplusplus */
33 
34 
35 typedef struct Dwarf_Loc_Chain_s *Dwarf_Loc_Chain;
36 struct Dwarf_Loc_Chain_s {
37     Dwarf_Small lc_atom;
38     Dwarf_Unsigned lc_raw1;
39     Dwarf_Unsigned lc_raw2;
40     Dwarf_Unsigned lc_raw3;
41     Dwarf_Unsigned lc_number;
42     Dwarf_Unsigned lc_number2;
43     Dwarf_Unsigned lc_number3;
44     Dwarf_Unsigned lc_offset;
45     Dwarf_Unsigned lc_opnumber;
46     Dwarf_Loc_Chain lc_next;
47 };
48 
49 /*  Dwarf_Loclists_Context_s contains the data from the .debug_loclists
50     section headers (if that section exists).  Dwarf 2,3,4 .debug_loc
51     has no such data.  The array (one of these per header in
52     .debug_loclists) is recorded in Dwarf_Debug. These
53     are filled in at startup at the same time .debug_info
54     is opened.  Nothing of this struct is exposed to
55     libdwarf callers */
56 struct Dwarf_Loclists_Context_s {
57     Dwarf_Debug    lc_dbg;
58     Dwarf_Unsigned lc_index; /* An index  assigned by
59         libdwarf to each loclists context. Starting
60         with zero at the zero offset in .debug_loclists. */
61 
62     /* Offset of the .debug_loclists header involved. */
63     Dwarf_Unsigned  lc_header_offset;
64     Dwarf_Unsigned  lc_length;
65 
66     /* Many places in in libdwarf this is called length_size. */
67     Dwarf_Small     lc_offset_size;
68 
69     /*  rc_extension_size is zero unless this is standard
70         DWARF3 and later 64bit dwarf using the extension mechanism.
71         64bit DWARF3 and later: rc_extension_size is 4.
72         64bit DWARF2 MIPS/IRIX: rc_extension_size is zero.
73         32bit DWARF:            rc_extension_size is zero.  */
74     Dwarf_Small     lc_extension_size;
75 
76     unsigned        lc_version; /* 5 */
77     Dwarf_Small     lc_address_size;
78     Dwarf_Small     lc_segment_selector_size;
79     Dwarf_Unsigned  lc_offset_entry_count;
80 
81     /* offset in the section of the offset entries */
82     Dwarf_Unsigned  lc_offsets_off_in_sect;
83 
84     /* Do not free. Points into section memory */
85     Dwarf_Small   * lc_offsets_array;
86 
87     /*  Offset in the .debug_loclists section of the
88         first loclist in the set of loclists for the
89         CU. */
90     Dwarf_Unsigned  lc_first_loclist_offset;
91     Dwarf_Unsigned  lc_past_last_loclist_offset;
92 
93     /* pointer to 1st byte of loclist header*/
94     Dwarf_Small *  lc_loclists_header;
95     /*  pointer to first byte of the loclist data
96         for loclist involved. Do not free. */
97     Dwarf_Small    *lc_startaddr;
98     /*  pointer one past end of the loclist data. */
99     Dwarf_Small    *lc_endaddr;
100 };
101 
102 
103 
104 /*  Contains info on an uninterpreted block of data,
105     the data is DWARF location expression operators.  */
106 struct Dwarf_Block_c_s {
107     /* length of block bl_data points at */
108     Dwarf_Unsigned  bl_len;
109 
110     /*  Uninterpreted data, location expressions,
111         DW_OP_reg31 etc */
112     Dwarf_Ptr       bl_data;
113 
114     /*  DW_LKIND, see libdwarf.h.in  */
115     Dwarf_Small     bl_kind;
116 
117     /* Section (not CU) offset which 'data' comes from. */
118     Dwarf_Unsigned  bl_section_offset;
119 
120     /*  Section offset where the location description
121         itself starts.  So a few bytes lower than
122         bl_section_offset */
123     Dwarf_Unsigned  bl_locdesc_offset;
124 };
125 typedef struct Dwarf_Block_c_s Dwarf_Block_c;
126 
127 /* Location record. Records up to 3 operand values.
128    For DWARF5 ops with a 1 byte size and then a block
129    of data of that size we the size in an operand
130    and follow that with the next operand as a
131    pointer to the block. The pointer is inserted
132    via  cast, so an ugly hack.
133    This struct is opaque. Not visible to callers.
134 */
135 typedef struct Dwarf_Loc_Expr_Op_s *Dwarf_Loc_Expr_Op;
136 struct Dwarf_Loc_Expr_Op_s {
137     Dwarf_Small     lr_atom;        /* Location operation */
138 
139     /*  Operands exactly as in DWARF. */
140     Dwarf_Unsigned  lr_raw1;
141     Dwarf_Unsigned  lr_raw2;
142     Dwarf_Unsigned  lr_raw3;
143 
144     Dwarf_Unsigned  lr_number;      /* First operand */
145 
146     /*  Second operand.
147         For OP_bregx, OP_bit_piece, OP_[GNU_]const_type,
148         OP_[GNU_]deref_type, OP_[GNU_]entry_value,
149         OP_implicit_value,
150         OP_[GNU_]implicit_pointer, OP_[GNU_]regval_type,
151         OP_xderef_type,  */
152     Dwarf_Unsigned  lr_number2;
153 
154     /*  Third Operand.
155         For OP_[GNU_]const type, pointer to
156         block of length 'lr_number2'
157         FIXME: retrieve the value at the pointer,
158         store the value here instead*/
159     Dwarf_Unsigned  lr_number3;
160 
161     /*  The number assigned. 0 to the number-of-ops - 1 in
162         the expression we are expanding. */
163     Dwarf_Unsigned  lr_opnumber;
164     Dwarf_Unsigned  lr_offset; /* offset  for OP_BRA etc */
165     Dwarf_Loc_Expr_Op     lr_next; /* When a list is useful.*/
166 };
167 
168 /* Location description DWARF 2,3,4,5
169    Adds the DW_LLE value (new in DWARF5).
170    This struct is opaque. Not visible to callers. */
171 struct Dwarf_Locdesc_c_s {
172     Dwarf_Small      ld_kind; /* DW_LKIND */
173 
174     /*  A DW_LLEX or DW_LLE value, real or synthesized */
175     Dwarf_Small      ld_lle_value;
176     /*  Failed means .debug_addr section needed but missing.
177         (possibly tied file needed) */
178     Dwarf_Bool       ld_index_failed;
179 
180     /*  Beginning of active range. This is actually an offset
181         of an applicable base address, not a pc value.  */
182     Dwarf_Addr       ld_rawlow;
183     /*  Translated to address */
184     Dwarf_Addr       ld_lopc;
185 
186     /*  End of active range. This is actually an offset
187         of an applicable base address,
188         or a length, never a pc value.  */
189     Dwarf_Addr       ld_rawhigh;
190     /*  Translated to address */
191     Dwarf_Addr       ld_highpc;
192 
193     /*  Byte length of the  entire record for this entry,
194         including any DW_OP entries */
195     Dwarf_Unsigned   ld_entrylen;
196 
197     /*   For .debug_loclists, eases building record. */
198     Dwarf_Block_c    ld_opsblock;
199 
200     /*  count of struct Dwarf_Loc_Expr_Op_s (expression operators)
201         in array. */
202     Dwarf_Half       ld_cents;
203     /* pointer to array of expression operator structs */
204     Dwarf_Loc_Expr_Op      ld_s;
205 
206     /* Section (not CU) offset where loc-expr begins*/
207     Dwarf_Unsigned   ld_section_offset;
208 
209     /* Section (not CU) offset where location descr begins*/
210     Dwarf_Unsigned   ld_locdesc_offset;
211 
212     /* Pointer to our header (in which we are located). */
213     Dwarf_Loc_Head_c ld_loclist_head;
214     Dwarf_Locdesc_c  ld_next; /*helps building the locdescs*/
215 };
216 
217 /*  A 'header' to the loclist and  the
218     location description(s)  attached to an attribute.
219     This struct is opaque. The contents not visible to
220     callers. */
221 struct Dwarf_Loc_Head_c_s {
222     /*  The array (1 or more entries) of
223         struct Loc_Desc_c_s
224         If 1 it may really be a locexpr */
225     Dwarf_Locdesc_c  ll_locdesc;
226 
227     /*  Entry count of the ll_locdesc array.  */
228     Dwarf_Unsigned   ll_locdesc_count;
229 
230     unsigned         ll_attrnum;
231     unsigned         ll_attrform;
232     unsigned         ll_cuversion;
233     unsigned         ll_address_size;
234     unsigned         ll_offset_size;
235     /*  The CU Context of this loclist or locexpr. */
236     Dwarf_CU_Context ll_context;
237     /* DW_LKIND*    */
238     Dwarf_Small      ll_kind;
239     Dwarf_Debug      ll_dbg;
240 
241     /*  If ll_kind == DW_LKIND_loclists the following
242         pointer is non-null and index is the index of the localcontext */
243     Dwarf_Unsigned   ll_index;
244     Dwarf_Loclists_Context ll_localcontext;
245 
246     /*  rh_last and rh_first used during build-up.
247         Zero when array rh_loclists built. */
248     Dwarf_Locdesc_c  ll_first;
249     Dwarf_Locdesc_c  ll_last;
250     Dwarf_Unsigned   ll_bytes_total;
251     unsigned         ll_segment_selector_size;
252 
253     /*  DW_AT_loclists_base */
254     Dwarf_Bool       ll_at_loclists_base_present;
255     Dwarf_Unsigned   ll_at_loclists_base;
256 
257     /* DW_AT_low_pc of CU or zero if none. */
258     Dwarf_Bool       ll_cu_base_address_present;
259     Dwarf_Unsigned   ll_cu_base_address;
260 
261     /*  DW_AT_addr_base, so we can use .debug_addr
262         if such is needed. */
263     Dwarf_Bool       ll_cu_addr_base_present;
264     Dwarf_Unsigned   ll_cu_addr_base;
265 
266     Dwarf_Small    * ll_llepointer;
267     Dwarf_Unsigned   ll_llearea_offset;
268     Dwarf_Small    * ll_end_data_area;
269 };
270 
271 int _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg,
272     Dwarf_Unsigned locdesc_index,
273     Dwarf_Loc_Head_c loc_head,
274     Dwarf_Block_c * loc_block,
275     Dwarf_Half address_size,
276     Dwarf_Half offset_size,
277     Dwarf_Small version_stamp,
278     Dwarf_Addr lowpc,
279     Dwarf_Addr highpc,
280     Dwarf_Half lle_op,
281     Dwarf_Error * error);
282 
283 int _dwarf_loc_block_sanity_check(Dwarf_Debug dbg,
284     Dwarf_Block_c *loc_block,Dwarf_Error*error);
285 
286 void _dwarf_loclists_head_destructor(void *l);
287 
288 int _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
289     Dwarf_Attribute attr,
290     Dwarf_Loc_Head_c llhead,
291     Dwarf_Error *error);
292 
293 int _dwarf_loclists_expression_build(Dwarf_Debug dbg,
294     Dwarf_Attribute attr,
295     Dwarf_Loc_Head_c* llhead,
296     Dwarf_Error *error);
297 
298 int _dwarf_read_loc_expr_op(Dwarf_Debug dbg,
299     Dwarf_Block_c * loc_block,
300     /* Caller: Start numbering at 0. */
301     Dwarf_Signed opnumber,
302 
303     /* 2 for DWARF 2 etc. */
304     Dwarf_Half version_stamp,
305     Dwarf_Half offset_size, /* 4 or 8 */
306     Dwarf_Half address_size, /* 2,4, 8  */
307     Dwarf_Signed startoffset_in, /* offset in block,
308         not section offset */
309     Dwarf_Small *section_end,
310 
311     /* nextoffset_out so caller knows next entry startoffset */
312     Dwarf_Unsigned *nextoffset_out,
313 
314     /*  The values picked up. */
315     Dwarf_Loc_Expr_Op curr_loc,
316     Dwarf_Error * error);
317 void _dwarf_free_loclists_head(Dwarf_Loc_Head_c head);
318 
319 #ifdef __cplusplus
320 }
321 #endif /* __cplusplus */
322 #endif /* DWARF_LOC_H */
323