xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_locationop_read.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1 /*
2   Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved.
4   Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved.
5 
6   This program is free software; you can redistribute it
7   and/or modify it under the terms of version 2.1 of the
8   GNU Lesser General Public License as published by the Free
9   Software Foundation.
10 
11   This program is distributed in the hope that it would be
12   useful, but WITHOUT ANY WARRANTY; without even the implied
13   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14   PURPOSE.
15 
16   Further, this software is distributed without any warranty
17   that it is free of the rightful claim of any third person
18   regarding infringement or the like.  Any license provided
19   herein, whether implied or otherwise, applies only to this
20   software file.  Patent licenses, if any, provided herein
21   do not apply to combinations of this program with other
22   software, or any other product whatsoever.
23 
24   You should have received a copy of the GNU Lesser General
25   Public License along with this program; if not, write the
26   Free Software Foundation, Inc., 51 Franklin Street - Fifth
27   Floor, Boston MA 02110-1301, USA.
28 
29 */
30 
31 #include "config.h"
32 #include <stdio.h> /* for debugging only. */
33 #ifdef HAVE_STDINT_H
34 #include <stdint.h> /* For uintptr_t */
35 #endif /* HAVE_STDINT_H */
36 #include "dwarf_incl.h"
37 #include "dwarf_alloc.h"
38 #include "dwarf_error.h"
39 #include "dwarf_util.h"
40 #include "dwarf_loc.h"
41 #include "dwarfstring.h"
42 
43 #define TRUE 1
44 #define FALSE 0
45 
46 
47 /*  Richard Henderson, on DW_OP_GNU_encoded_addr:
48     The operand is an absolute
49     address.  The first byte of the value
50     is an encoding length: 0 2 4 or 8.  If zero
51     it means the following is address-size.
52     The address then follows immediately for
53     that number of bytes. */
54 static int
read_encoded_addr(Dwarf_Small * loc_ptr,Dwarf_Debug dbg,Dwarf_Small * section_end_ptr,Dwarf_Unsigned * val_out,int * len_out,Dwarf_Error * error)55 read_encoded_addr(Dwarf_Small *loc_ptr,
56    Dwarf_Debug dbg,
57    Dwarf_Small *section_end_ptr,
58    Dwarf_Unsigned * val_out,
59    int * len_out,
60    Dwarf_Error *error)
61 {
62     int len = 0;
63     Dwarf_Small op = *loc_ptr;
64     Dwarf_Unsigned operand = 0;
65     len++;
66     if (op == 0) {
67         /* FIXME: should be CU specific. */
68         op = dbg->de_pointer_size;
69     }
70     switch (op) {
71     case 1:
72         *val_out = *loc_ptr;
73         len++;
74         break;
75 
76     case 2:
77         READ_UNALIGNED_CK(dbg, operand, Dwarf_Unsigned, loc_ptr, 2,
78             error,section_end_ptr);
79         *val_out = operand;
80         len +=2;
81         break;
82     case 4:
83         READ_UNALIGNED_CK(dbg, operand, Dwarf_Unsigned, loc_ptr, 4,
84             error,section_end_ptr);
85         *val_out = operand;
86         len +=4;
87         break;
88     case 8:
89         READ_UNALIGNED_CK(dbg, operand, Dwarf_Unsigned, loc_ptr, 8,
90             error,section_end_ptr);
91         *val_out = operand;
92         len +=8;
93         break;
94     default:
95         /* We do not know how much to read. */
96         _dwarf_error(dbg, error, DW_DLE_GNU_OPCODE_ERROR);
97         return DW_DLV_ERROR;
98     };
99     *len_out = len;
100     return DW_DLV_OK;
101 }
102 
103 
104 /*  Return DW_DLV_NO_ENTRY when at the end of
105     the ops for this block (a single Dwarf_Loccesc
106     and multiple Dwarf_Locs will eventually result
107     from calling this till DW_DLV_NO_ENTRY).
108 
109     All op reader code should call this to
110     extract operator fields. For any
111     DWARF version.
112 */
113 int
_dwarf_read_loc_expr_op(Dwarf_Debug dbg,Dwarf_Block_c * loc_block,Dwarf_Signed opnumber,Dwarf_Half version_stamp,Dwarf_Half offset_size,Dwarf_Half address_size,Dwarf_Signed startoffset_in,Dwarf_Small * section_end,Dwarf_Unsigned * nextoffset_out,Dwarf_Loc_Expr_Op curr_loc,Dwarf_Error * error)114 _dwarf_read_loc_expr_op(Dwarf_Debug dbg,
115     Dwarf_Block_c * loc_block,
116     /* Caller: Start numbering at 0. */
117     Dwarf_Signed opnumber,
118 
119     /* 2 for DWARF 2 etc. */
120     Dwarf_Half version_stamp,
121     Dwarf_Half offset_size, /* 4 or 8 */
122     Dwarf_Half address_size, /* 2,4, 8  */
123     Dwarf_Signed startoffset_in, /* offset in block,
124         not section offset */
125     Dwarf_Small *section_end,
126 
127     /* nextoffset_out so caller knows next entry startoffset */
128     Dwarf_Unsigned *nextoffset_out,
129 
130     /*  The values picked up. */
131     Dwarf_Loc_Expr_Op curr_loc,
132     Dwarf_Error * error)
133 {
134     Dwarf_Small *loc_ptr = 0;
135     Dwarf_Unsigned loc_len = 0;
136     Dwarf_Unsigned offset = startoffset_in;
137     Dwarf_Unsigned operand1 = 0;
138     Dwarf_Unsigned operand2 = 0;
139     Dwarf_Unsigned operand3 = 0;
140     Dwarf_Small atom = 0;
141     Dwarf_Unsigned leb128_length = 0;
142 
143     if (offset > loc_block->bl_len) {
144         _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
145         return DW_DLV_ERROR;
146     }
147     loc_len = loc_block->bl_len;
148     if (offset == loc_len) {
149         return DW_DLV_NO_ENTRY;
150     }
151 
152     loc_ptr = (Dwarf_Small*)loc_block->bl_data + offset;
153     if ((loc_ptr+1) > section_end) {
154         _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
155         return DW_DLV_ERROR;
156     }
157     memset(curr_loc,0,sizeof(*curr_loc));
158 
159     curr_loc->lr_opnumber = opnumber;
160     curr_loc->lr_offset = offset;
161 
162     /*  loc_ptr is ok to deref, see loc_ptr+1 test just above. */
163     atom = *(Dwarf_Small *) loc_ptr;
164     loc_ptr++;
165     offset++;
166     curr_loc->lr_atom = atom;
167     switch (atom) {
168 
169     case DW_OP_reg0:
170     case DW_OP_reg1:
171     case DW_OP_reg2:
172     case DW_OP_reg3:
173     case DW_OP_reg4:
174     case DW_OP_reg5:
175     case DW_OP_reg6:
176     case DW_OP_reg7:
177     case DW_OP_reg8:
178     case DW_OP_reg9:
179     case DW_OP_reg10:
180     case DW_OP_reg11:
181     case DW_OP_reg12:
182     case DW_OP_reg13:
183     case DW_OP_reg14:
184     case DW_OP_reg15:
185     case DW_OP_reg16:
186     case DW_OP_reg17:
187     case DW_OP_reg18:
188     case DW_OP_reg19:
189     case DW_OP_reg20:
190     case DW_OP_reg21:
191     case DW_OP_reg22:
192     case DW_OP_reg23:
193     case DW_OP_reg24:
194     case DW_OP_reg25:
195     case DW_OP_reg26:
196     case DW_OP_reg27:
197     case DW_OP_reg28:
198     case DW_OP_reg29:
199     case DW_OP_reg30:
200     case DW_OP_reg31:
201         break;
202 
203     case DW_OP_regx:
204         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
205             dbg,error,section_end);
206         offset = offset + leb128_length;
207         break;
208 
209     case DW_OP_lit0:
210     case DW_OP_lit1:
211     case DW_OP_lit2:
212     case DW_OP_lit3:
213     case DW_OP_lit4:
214     case DW_OP_lit5:
215     case DW_OP_lit6:
216     case DW_OP_lit7:
217     case DW_OP_lit8:
218     case DW_OP_lit9:
219     case DW_OP_lit10:
220     case DW_OP_lit11:
221     case DW_OP_lit12:
222     case DW_OP_lit13:
223     case DW_OP_lit14:
224     case DW_OP_lit15:
225     case DW_OP_lit16:
226     case DW_OP_lit17:
227     case DW_OP_lit18:
228     case DW_OP_lit19:
229     case DW_OP_lit20:
230     case DW_OP_lit21:
231     case DW_OP_lit22:
232     case DW_OP_lit23:
233     case DW_OP_lit24:
234     case DW_OP_lit25:
235     case DW_OP_lit26:
236     case DW_OP_lit27:
237     case DW_OP_lit28:
238     case DW_OP_lit29:
239     case DW_OP_lit30:
240     case DW_OP_lit31:
241         operand1 = atom - DW_OP_lit0;
242         break;
243 
244     case DW_OP_addr:
245         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned,
246             loc_ptr, address_size,
247             error,section_end);
248         loc_ptr += address_size;
249         offset += address_size;
250         break;
251 
252     case DW_OP_const1u:
253         if (loc_ptr >= section_end) {
254             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
255             return DW_DLV_ERROR;
256         }
257         operand1 = *(Dwarf_Small *) loc_ptr;
258         loc_ptr = loc_ptr + 1;
259         if (loc_ptr > section_end) {
260             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
261             return DW_DLV_ERROR;
262         }
263         offset = offset + 1;
264         break;
265 
266     case DW_OP_const1s:
267         if (loc_ptr >= section_end) {
268             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
269             return DW_DLV_ERROR;
270         }
271         operand1 = *(Dwarf_Sbyte *) loc_ptr;
272         SIGN_EXTEND(operand1,1);
273         loc_ptr = loc_ptr + 1;
274         if (loc_ptr > section_end) {
275             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
276             return DW_DLV_ERROR;
277         }
278         offset = offset + 1;
279         break;
280 
281     case DW_OP_const2u:
282         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2,
283             error,section_end);
284         loc_ptr = loc_ptr + 2;
285         offset = offset + 2;
286         break;
287 
288     case DW_OP_const2s:
289         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2,
290             error, section_end);
291         SIGN_EXTEND(operand1,2);
292         loc_ptr = loc_ptr + 2;
293         offset = offset + 2;
294         break;
295 
296     case DW_OP_const4u:
297         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4,
298             error, section_end);
299         loc_ptr = loc_ptr + 4;
300         offset = offset + 4;
301         break;
302 
303     case DW_OP_const4s:
304         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4,
305             error, section_end);
306         SIGN_EXTEND(operand1,4);
307         loc_ptr = loc_ptr + 4;
308         offset = offset + 4;
309         break;
310 
311     case DW_OP_const8u:
312         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8,
313             error, section_end);
314         loc_ptr = loc_ptr + 8;
315         offset = offset + 8;
316         break;
317 
318     case DW_OP_const8s:
319         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8,
320             error, section_end);
321         loc_ptr = loc_ptr + 8;
322         offset = offset + 8;
323         break;
324 
325     case DW_OP_constu:
326         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
327             dbg,error,section_end);
328         offset = offset + leb128_length;
329         break;
330 
331     case DW_OP_consts:
332         DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand1,leb128_length,
333             dbg,error,section_end);
334         offset = offset + leb128_length;
335         break;
336 
337     case DW_OP_fbreg:
338         DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand1,leb128_length,
339             dbg,error,section_end);
340         offset = offset + leb128_length;
341         break;
342 
343     case DW_OP_breg0:
344     case DW_OP_breg1:
345     case DW_OP_breg2:
346     case DW_OP_breg3:
347     case DW_OP_breg4:
348     case DW_OP_breg5:
349     case DW_OP_breg6:
350     case DW_OP_breg7:
351     case DW_OP_breg8:
352     case DW_OP_breg9:
353     case DW_OP_breg10:
354     case DW_OP_breg11:
355     case DW_OP_breg12:
356     case DW_OP_breg13:
357     case DW_OP_breg14:
358     case DW_OP_breg15:
359     case DW_OP_breg16:
360     case DW_OP_breg17:
361     case DW_OP_breg18:
362     case DW_OP_breg19:
363     case DW_OP_breg20:
364     case DW_OP_breg21:
365     case DW_OP_breg22:
366     case DW_OP_breg23:
367     case DW_OP_breg24:
368     case DW_OP_breg25:
369     case DW_OP_breg26:
370     case DW_OP_breg27:
371     case DW_OP_breg28:
372     case DW_OP_breg29:
373     case DW_OP_breg30:
374     case DW_OP_breg31:
375         DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand1,leb128_length,
376             dbg,error,section_end);
377         offset = offset + leb128_length;
378         break;
379 
380     case DW_OP_bregx:
381         /* uleb reg num followed by sleb offset */
382         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
383             dbg,error,section_end);
384         offset = offset + leb128_length;
385 
386         DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand2,leb128_length,
387             dbg,error,section_end);
388         offset = offset + leb128_length;
389         break;
390 
391     case DW_OP_dup:
392     case DW_OP_drop:
393         break;
394 
395     case DW_OP_pick:
396         if (loc_ptr >= section_end) {
397             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
398             return DW_DLV_ERROR;
399         }
400         operand1 = *(Dwarf_Small *) loc_ptr;
401         loc_ptr = loc_ptr + 1;
402         if (loc_ptr > section_end) {
403             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
404             return DW_DLV_ERROR;
405         }
406         offset = offset + 1;
407         break;
408 
409     case DW_OP_over:
410     case DW_OP_swap:
411     case DW_OP_rot:
412     case DW_OP_deref:
413         break;
414 
415     case DW_OP_deref_size:
416         if (loc_ptr >= section_end) {
417             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
418             return DW_DLV_ERROR;
419         }
420         operand1 = *(Dwarf_Small *) loc_ptr;
421         loc_ptr = loc_ptr + 1;
422         if (loc_ptr > section_end) {
423             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
424             return DW_DLV_ERROR;
425         }
426         offset = offset + 1;
427         break;
428 
429     case DW_OP_xderef:
430         break;
431 
432     case DW_OP_xderef_type:        /* DWARF5 */
433         if (loc_ptr >= section_end) {
434             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
435             return DW_DLV_ERROR;
436         }
437         operand1 = *(Dwarf_Small *) loc_ptr;
438         loc_ptr = loc_ptr + 1;
439         if (loc_ptr > section_end) {
440             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
441             return DW_DLV_ERROR;
442         }
443         offset = offset + 1;
444         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length,
445             dbg,error,section_end);
446         offset = offset + leb128_length;
447 
448         break;
449 
450     case DW_OP_xderef_size:
451         if (loc_ptr >= section_end) {
452             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
453             return DW_DLV_ERROR;
454         }
455         operand1 = *(Dwarf_Small *) loc_ptr;
456         loc_ptr = loc_ptr + 1;
457         if (loc_ptr > section_end) {
458             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
459             return DW_DLV_ERROR;
460         }
461         offset = offset + 1;
462         break;
463 
464     case DW_OP_abs:
465     case DW_OP_and:
466     case DW_OP_div:
467     case DW_OP_minus:
468     case DW_OP_mod:
469     case DW_OP_mul:
470     case DW_OP_neg:
471     case DW_OP_not:
472     case DW_OP_or:
473     case DW_OP_plus:
474         break;
475 
476     case DW_OP_plus_uconst:
477         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
478             dbg,error,section_end);
479         offset = offset + leb128_length;
480         break;
481 
482     case DW_OP_shl:
483     case DW_OP_shr:
484     case DW_OP_shra:
485     case DW_OP_xor:
486         break;
487 
488     case DW_OP_le:
489     case DW_OP_ge:
490     case DW_OP_eq:
491     case DW_OP_lt:
492     case DW_OP_gt:
493     case DW_OP_ne:
494         break;
495 
496     case DW_OP_skip:
497     case DW_OP_bra:
498         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2,
499             error,section_end);
500         loc_ptr = loc_ptr + 2;
501         offset = offset + 2;
502         break;
503 
504     case DW_OP_piece:
505         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
506             dbg,error,section_end);
507         offset = offset + leb128_length;
508         break;
509 
510     case DW_OP_nop:
511         break;
512     case DW_OP_push_object_address: /* DWARF3 */
513         break;
514     case DW_OP_call2:       /* DWARF3 */
515         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2,
516             error,section_end);
517         loc_ptr = loc_ptr + 2;
518         offset = offset + 2;
519         break;
520 
521     case DW_OP_call4:       /* DWARF3 */
522         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4,
523             error,section_end);
524         loc_ptr = loc_ptr + 4;
525         offset = offset + 4;
526         break;
527     case DW_OP_call_ref:    /* DWARF3 */
528         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr,
529             offset_size,
530             error,section_end);
531         loc_ptr = loc_ptr + offset_size;
532         offset = offset + offset_size;
533         break;
534 
535     case DW_OP_form_tls_address:    /* DWARF3f */
536         break;
537     case DW_OP_call_frame_cfa:      /* DWARF3f */
538         break;
539     case DW_OP_bit_piece:   /* DWARF3f */
540         /* uleb size in bits followed by uleb offset in bits */
541         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
542             dbg,error,section_end);
543         offset = offset + leb128_length;
544 
545         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length,
546             dbg,error,section_end);
547         offset = offset + leb128_length;
548         break;
549 
550         /*  The operator means: push the currently computed
551             (by the operations encountered so far in this
552             expression) onto the expression stack as the offset
553             in thread-local-storage of the variable. */
554     case DW_OP_GNU_push_tls_address: /* 0xe0  */
555         /* Believed to have no operands. */
556         /* Unimplemented in gdb 7.5.1 ? */
557         break;
558     case DW_OP_deref_type:     /* DWARF5 */
559     case DW_OP_GNU_deref_type: /* 0xf6 */
560         if (loc_ptr >= section_end) {
561             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
562             return DW_DLV_ERROR;
563         }
564         operand1 = *(Dwarf_Small *) loc_ptr;
565         loc_ptr = loc_ptr + 1;
566         if (loc_ptr > section_end) {
567             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
568             return DW_DLV_ERROR;
569         }
570         offset = offset + 1;
571 
572         /* die offset (uleb128). */
573         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length,
574             dbg,error,section_end);
575         offset = offset + leb128_length;
576         break;
577 
578     case DW_OP_implicit_value: /* DWARF4 0xa0 */
579         /*  uleb length of value bytes followed by that
580             number of bytes of the value. */
581         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
582             dbg,error,section_end);
583         offset = offset + leb128_length;
584 
585         /*  Second operand is block of 'operand1' bytes of stuff. */
586         /*  This using the second operand as a pointer
587             is quite ugly. */
588         /*  This gets an ugly compiler warning. Sorry. */
589         operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr;
590         offset = offset + operand1;
591         loc_ptr = loc_ptr + operand1;
592         if (loc_ptr > section_end) {
593             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
594             return DW_DLV_ERROR;
595         }
596         break;
597     case DW_OP_stack_value:  /* DWARF4 */
598         break;
599     case DW_OP_GNU_uninit:            /* 0xf0 */
600         /*  Unimplemented in gdb 7.5.1  */
601         /*  Carolyn Tice: Follws a DW_OP_reg or DW_OP_regx
602             and marks the reg as being uninitialized. */
603         break;
604     case DW_OP_GNU_encoded_addr: {      /*  0xf1 */
605         /*  Richard Henderson: The operand is an absolute
606             address.  The first byte of the value
607             is an encoding length: 0 2 4 or 8.  If zero
608             it means the following is address-size.
609             The address then follows immediately for
610             that number of bytes. */
611         int length = 0;
612             int reares = read_encoded_addr(loc_ptr,dbg,
613                 section_end,
614                 &operand1, &length,error);
615             if (reares != DW_DLV_OK) {
616                 return reares;
617             }
618             loc_ptr += length;
619             if (loc_ptr > section_end) {
620                 _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
621                 return DW_DLV_ERROR;
622             }
623             offset  += length;
624         }
625         break;
626     case DW_OP_implicit_pointer:       /* DWARF5 */
627     case DW_OP_GNU_implicit_pointer:{  /* 0xf2 */
628         /*  Jakub Jelinek: The value is an optimized-out
629             pointer value. Represented as
630             an offset_size DIE offset
631             (a simple unsigned integer) in DWARF3,4
632             followed by a signed leb128 offset.
633             For DWARF2, it is actually pointer size
634             (address size).
635             http://www.dwarfstd.org/ShowIssue.php?issue=100831.1 */
636         Dwarf_Small iplen = offset_size;
637         if (version_stamp == DW_CU_VERSION2 /* 2 */ ) {
638             iplen = address_size;
639         }
640         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr,
641             iplen,error,section_end);
642         loc_ptr = loc_ptr + iplen;
643         if (loc_ptr > section_end) {
644             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
645             return DW_DLV_ERROR;
646         }
647         offset = offset + iplen;
648 
649         DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand2,leb128_length,
650             dbg,error,section_end);
651         offset = offset + leb128_length;
652         }
653 
654         break;
655     case DW_OP_entry_value:       /* DWARF5 */
656     case DW_OP_GNU_entry_value:       /* 0xf3 */
657         /*  Jakub Jelinek: A register reused really soon,
658             but the value is unchanged.  So to represent
659             that value we have a uleb128 size followed
660             by a DWARF expression block that size.
661             http://www.dwarfstd.org/ShowIssue.php?issue=100909.1 */
662 
663         /*  uleb length of value bytes followed by that
664             number of bytes of the value. */
665         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
666             dbg,error,section_end);
667         offset = offset + leb128_length;
668 
669         /*  Second operand is block of 'operand1' bytes of stuff. */
670         /*  This using the second operand as a pointer
671             is quite ugly. */
672         /*  This gets an ugly compiler warning. Sorry. */
673         operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr;
674         offset = offset + operand1;
675         loc_ptr = loc_ptr + operand1;
676         if (loc_ptr > section_end) {
677             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
678             return DW_DLV_ERROR;
679         }
680         break;
681     case DW_OP_const_type:           /* DWARF5 */
682     case DW_OP_GNU_const_type:       /* 0xf4 */
683         {
684         /* die offset as uleb. */
685         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
686             dbg,error,section_end);
687         offset = offset + leb128_length;
688 
689         /*  Next byte is size of following data block.  */
690         operand2 = *loc_ptr;
691         loc_ptr = loc_ptr + 1;
692         offset = offset + 1;
693 
694         /*  Operand 3 points to a value in the block of size
695             just gotten as operand2.
696             It must fit in a Dwarf_Unsigned.
697             Get the type from the die at operand1
698             (a CU relative offset). */
699         /*  FIXME: We should do something very different than
700             what we do here! */
701         operand3 = (Dwarf_Unsigned)(uintptr_t)loc_ptr;
702         loc_ptr = loc_ptr + operand2;
703         if (loc_ptr > section_end) {
704             _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
705             return DW_DLV_ERROR;
706         }
707         offset = offset + operand2;
708         }
709         break;
710 
711     case DW_OP_regval_type:           /* DWARF5 */
712     case DW_OP_GNU_regval_type:       /* 0xf5 */
713         /* reg num uleb*/
714         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
715             dbg,error,section_end);
716         offset = offset + leb128_length;
717         /* cu die off uleb*/
718         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length,
719             dbg,error,section_end);
720         offset = offset + leb128_length;
721         break;
722     case DW_OP_convert:           /* DWARF5 */
723     case DW_OP_GNU_convert:       /* 0xf7 */
724     case DW_OP_reinterpret:       /* DWARF5 */
725     case DW_OP_GNU_reinterpret:       /* 0xf9 */
726         /* die offset  or zero */
727         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
728             dbg,error,section_end);
729         offset = offset + leb128_length;
730         break;
731     case DW_OP_GNU_parameter_ref :       /* 0xfa */
732         /* 4 byte unsigned int */
733         READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4,
734             error,section_end);;
735         loc_ptr = loc_ptr + 4;
736         offset = offset + 4;
737         break;
738     case DW_OP_addrx :           /* DWARF5 */
739     case DW_OP_GNU_addr_index :  /* 0xfb DebugFission */
740         /*  Index into .debug_addr. The value in .debug_addr
741             is an address. */
742         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
743             dbg,error,section_end);
744         offset = offset + leb128_length;
745         break;
746     case DW_OP_constx :          /* DWARF5 */
747     case DW_OP_GNU_const_index : /* 0xfc DebugFission */
748         /*  Index into .debug_addr. The value in .debug_addr
749             is a constant that fits in an address. */
750         DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length,
751             dbg,error,section_end);
752         offset = offset + leb128_length;
753         break;
754     default:
755         _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
756         return DW_DLV_ERROR;
757     }
758     if (loc_ptr > section_end) {
759         _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END);
760         return DW_DLV_ERROR;
761     }
762     /* If offset == loc_len this would be normal end-of-expression. */
763     if (offset > loc_len) {
764         /*  We stepped past the end of the expression.
765             This has to be a compiler bug.
766             Operators missing their values cannot be detected
767             as such except at the end of an expression (like this).
768             The results would be wrong if returned.
769         */
770         _dwarf_error(dbg, error, DW_DLE_LOC_BAD_TERMINATION);
771         return DW_DLV_ERROR;
772     }
773     curr_loc->lr_atom = atom;
774     curr_loc->lr_raw1 =  operand1;
775     curr_loc->lr_number =  operand1;
776     curr_loc->lr_raw2 =  operand2;
777     curr_loc->lr_number2 = operand2;
778     /*  lr_number 3 is a pointer to a value iff DW_OP_const or
779         DW_OP_GNU_const_type */
780     curr_loc->lr_raw3 = operand3;
781     curr_loc->lr_number3 = operand3;
782     *nextoffset_out = offset;
783     return DW_DLV_OK;
784 }
785