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. */
54static int
55read_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*/
113int
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