xref: /titanic_41/usr/src/tools/ctf/dwarf/common/dwarf_loc.c (revision 07dc1947c362e187fb955d283b692f8769dd5def)
149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe 
3*07dc1947SRichard Lowe   Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
4*07dc1947SRichard Lowe   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
549d3bc91SRichard Lowe 
649d3bc91SRichard Lowe   This program is free software; you can redistribute it and/or modify it
749d3bc91SRichard Lowe   under the terms of version 2.1 of the GNU Lesser General Public License
849d3bc91SRichard Lowe   as published by the Free Software Foundation.
949d3bc91SRichard Lowe 
1049d3bc91SRichard Lowe   This program is distributed in the hope that it would be useful, but
1149d3bc91SRichard Lowe   WITHOUT ANY WARRANTY; without even the implied warranty of
1249d3bc91SRichard Lowe   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349d3bc91SRichard Lowe 
1449d3bc91SRichard Lowe   Further, this software is distributed without any warranty that it is
1549d3bc91SRichard Lowe   free of the rightful claim of any third person regarding infringement
1649d3bc91SRichard Lowe   or the like.  Any license provided herein, whether implied or
1749d3bc91SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
1849d3bc91SRichard Lowe   any, provided herein do not apply to combinations of this program with
1949d3bc91SRichard Lowe   other software, or any other product whatsoever.
2049d3bc91SRichard Lowe 
2149d3bc91SRichard Lowe   You should have received a copy of the GNU Lesser General Public
2249d3bc91SRichard Lowe   License along with this program; if not, write the Free Software
23*07dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2449d3bc91SRichard Lowe   USA.
2549d3bc91SRichard Lowe 
26*07dc1947SRichard Lowe   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2749d3bc91SRichard Lowe   Mountain View, CA 94043, or:
2849d3bc91SRichard Lowe 
2949d3bc91SRichard Lowe   http://www.sgi.com
3049d3bc91SRichard Lowe 
3149d3bc91SRichard Lowe   For further information regarding this notice, see:
3249d3bc91SRichard Lowe 
3349d3bc91SRichard Lowe   http://oss.sgi.com/projects/GenInfo/NoticeExplan
3449d3bc91SRichard Lowe 
3549d3bc91SRichard Lowe */
36*07dc1947SRichard Lowe /* The address of the Free Software Foundation is
37*07dc1947SRichard Lowe    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*07dc1947SRichard Lowe    Boston, MA 02110-1301, USA.
39*07dc1947SRichard Lowe    SGI has moved from the Crittenden Lane address.
40*07dc1947SRichard Lowe */
41*07dc1947SRichard Lowe 
4249d3bc91SRichard Lowe 
4349d3bc91SRichard Lowe 
4449d3bc91SRichard Lowe 
4549d3bc91SRichard Lowe #include "config.h"
4649d3bc91SRichard Lowe #include "dwarf_incl.h"
4749d3bc91SRichard Lowe #include "dwarf_loc.h"
48*07dc1947SRichard Lowe #include <stdio.h> /* for debugging only. */
49*07dc1947SRichard Lowe #include <sys/types.h>
5049d3bc91SRichard Lowe 
5149d3bc91SRichard Lowe /*
5249d3bc91SRichard Lowe     Given a Dwarf_Block that represents a location expression,
5349d3bc91SRichard Lowe     this function returns a pointer to a Dwarf_Locdesc struct
5449d3bc91SRichard Lowe     that has its ld_cents field set to the number of location
5549d3bc91SRichard Lowe     operators in the block, and its ld_s field pointing to a
5649d3bc91SRichard Lowe     contiguous block of Dwarf_Loc structs.  However, the
5749d3bc91SRichard Lowe     ld_lopc and ld_hipc values are uninitialized.  Returns
5849d3bc91SRichard Lowe     NULL on error.  This function assumes that the length of
5949d3bc91SRichard Lowe     the block is greater than 0.  Zero length location expressions
6049d3bc91SRichard Lowe     to represent variables that have been optimized away are
6149d3bc91SRichard Lowe     handled in the calling function.
6249d3bc91SRichard Lowe */
6349d3bc91SRichard Lowe static Dwarf_Locdesc *
_dwarf_get_locdesc(Dwarf_Debug dbg,Dwarf_Block * loc_block,Dwarf_Half address_size,Dwarf_Addr lowpc,Dwarf_Addr highpc,Dwarf_Error * error)6449d3bc91SRichard Lowe _dwarf_get_locdesc(Dwarf_Debug dbg,
6549d3bc91SRichard Lowe     Dwarf_Block * loc_block,
66*07dc1947SRichard Lowe     Dwarf_Half address_size,
6749d3bc91SRichard Lowe     Dwarf_Addr lowpc,
68*07dc1947SRichard Lowe     Dwarf_Addr highpc,
69*07dc1947SRichard Lowe     Dwarf_Error * error)
7049d3bc91SRichard Lowe {
7149d3bc91SRichard Lowe     /* Size of the block containing the location expression. */
72*07dc1947SRichard Lowe     Dwarf_Unsigned loc_len = 0;
7349d3bc91SRichard Lowe 
7449d3bc91SRichard Lowe     /* Sweeps the block containing the location expression. */
75*07dc1947SRichard Lowe     Dwarf_Small *loc_ptr = 0;
7649d3bc91SRichard Lowe 
7749d3bc91SRichard Lowe     /* Current location operator. */
78*07dc1947SRichard Lowe     Dwarf_Small atom = 0;
7949d3bc91SRichard Lowe 
8049d3bc91SRichard Lowe     /* Offset of current operator from start of block. */
81*07dc1947SRichard Lowe     Dwarf_Unsigned offset = 0;
8249d3bc91SRichard Lowe 
8349d3bc91SRichard Lowe     /* Operands of current location operator. */
8449d3bc91SRichard Lowe     Dwarf_Unsigned operand1, operand2;
8549d3bc91SRichard Lowe 
8649d3bc91SRichard Lowe     /* Used to chain the Dwarf_Loc_Chain_s structs. */
87*07dc1947SRichard Lowe     Dwarf_Loc_Chain curr_loc = NULL;
88*07dc1947SRichard Lowe     Dwarf_Loc_Chain prev_loc = NULL;
89*07dc1947SRichard Lowe     Dwarf_Loc_Chain head_loc = NULL;
9049d3bc91SRichard Lowe 
9149d3bc91SRichard Lowe     /* Count of the number of location operators. */
92*07dc1947SRichard Lowe     Dwarf_Unsigned op_count = 0;
9349d3bc91SRichard Lowe 
9449d3bc91SRichard Lowe     /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */
95*07dc1947SRichard Lowe     Dwarf_Loc *block_loc = 0;
9649d3bc91SRichard Lowe 
9749d3bc91SRichard Lowe     /* Dwarf_Locdesc pointer to be returned. */
98*07dc1947SRichard Lowe     Dwarf_Locdesc *locdesc = 0;
9949d3bc91SRichard Lowe 
100*07dc1947SRichard Lowe     Dwarf_Word leb128_length = 0;
101*07dc1947SRichard Lowe     Dwarf_Unsigned i = 0;
10249d3bc91SRichard Lowe 
10349d3bc91SRichard Lowe     /* ***** BEGIN CODE ***** */
10449d3bc91SRichard Lowe 
10549d3bc91SRichard Lowe     loc_len = loc_block->bl_len;
10649d3bc91SRichard Lowe     loc_ptr = loc_block->bl_data;
10749d3bc91SRichard Lowe 
10849d3bc91SRichard Lowe     offset = 0;
10949d3bc91SRichard Lowe     op_count = 0;
11049d3bc91SRichard Lowe     while (offset < loc_len) {
11149d3bc91SRichard Lowe 
11249d3bc91SRichard Lowe         operand1 = 0;
11349d3bc91SRichard Lowe         operand2 = 0;
11449d3bc91SRichard Lowe         op_count++;
11549d3bc91SRichard Lowe 
11649d3bc91SRichard Lowe         atom = *(Dwarf_Small *) loc_ptr;
11749d3bc91SRichard Lowe         loc_ptr++;
11849d3bc91SRichard Lowe         offset++;
11949d3bc91SRichard Lowe 
12049d3bc91SRichard Lowe         curr_loc =
12149d3bc91SRichard Lowe             (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN,
12249d3bc91SRichard Lowe                                                1);
12349d3bc91SRichard Lowe         if (curr_loc == NULL) {
12449d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
12549d3bc91SRichard Lowe             return (NULL);
12649d3bc91SRichard Lowe         }
12749d3bc91SRichard Lowe         curr_loc->lc_offset = offset;
12849d3bc91SRichard Lowe         curr_loc->lc_atom = atom;
12949d3bc91SRichard Lowe         switch (atom) {
13049d3bc91SRichard Lowe 
13149d3bc91SRichard Lowe         case DW_OP_reg0:
13249d3bc91SRichard Lowe         case DW_OP_reg1:
13349d3bc91SRichard Lowe         case DW_OP_reg2:
13449d3bc91SRichard Lowe         case DW_OP_reg3:
13549d3bc91SRichard Lowe         case DW_OP_reg4:
13649d3bc91SRichard Lowe         case DW_OP_reg5:
13749d3bc91SRichard Lowe         case DW_OP_reg6:
13849d3bc91SRichard Lowe         case DW_OP_reg7:
13949d3bc91SRichard Lowe         case DW_OP_reg8:
14049d3bc91SRichard Lowe         case DW_OP_reg9:
14149d3bc91SRichard Lowe         case DW_OP_reg10:
14249d3bc91SRichard Lowe         case DW_OP_reg11:
14349d3bc91SRichard Lowe         case DW_OP_reg12:
14449d3bc91SRichard Lowe         case DW_OP_reg13:
14549d3bc91SRichard Lowe         case DW_OP_reg14:
14649d3bc91SRichard Lowe         case DW_OP_reg15:
14749d3bc91SRichard Lowe         case DW_OP_reg16:
14849d3bc91SRichard Lowe         case DW_OP_reg17:
14949d3bc91SRichard Lowe         case DW_OP_reg18:
15049d3bc91SRichard Lowe         case DW_OP_reg19:
15149d3bc91SRichard Lowe         case DW_OP_reg20:
15249d3bc91SRichard Lowe         case DW_OP_reg21:
15349d3bc91SRichard Lowe         case DW_OP_reg22:
15449d3bc91SRichard Lowe         case DW_OP_reg23:
15549d3bc91SRichard Lowe         case DW_OP_reg24:
15649d3bc91SRichard Lowe         case DW_OP_reg25:
15749d3bc91SRichard Lowe         case DW_OP_reg26:
15849d3bc91SRichard Lowe         case DW_OP_reg27:
15949d3bc91SRichard Lowe         case DW_OP_reg28:
16049d3bc91SRichard Lowe         case DW_OP_reg29:
16149d3bc91SRichard Lowe         case DW_OP_reg30:
16249d3bc91SRichard Lowe         case DW_OP_reg31:
16349d3bc91SRichard Lowe             break;
16449d3bc91SRichard Lowe 
16549d3bc91SRichard Lowe         case DW_OP_regx:
16649d3bc91SRichard Lowe             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
16749d3bc91SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
16849d3bc91SRichard Lowe             offset = offset + leb128_length;
16949d3bc91SRichard Lowe             break;
17049d3bc91SRichard Lowe 
17149d3bc91SRichard Lowe         case DW_OP_lit0:
17249d3bc91SRichard Lowe         case DW_OP_lit1:
17349d3bc91SRichard Lowe         case DW_OP_lit2:
17449d3bc91SRichard Lowe         case DW_OP_lit3:
17549d3bc91SRichard Lowe         case DW_OP_lit4:
17649d3bc91SRichard Lowe         case DW_OP_lit5:
17749d3bc91SRichard Lowe         case DW_OP_lit6:
17849d3bc91SRichard Lowe         case DW_OP_lit7:
17949d3bc91SRichard Lowe         case DW_OP_lit8:
18049d3bc91SRichard Lowe         case DW_OP_lit9:
18149d3bc91SRichard Lowe         case DW_OP_lit10:
18249d3bc91SRichard Lowe         case DW_OP_lit11:
18349d3bc91SRichard Lowe         case DW_OP_lit12:
18449d3bc91SRichard Lowe         case DW_OP_lit13:
18549d3bc91SRichard Lowe         case DW_OP_lit14:
18649d3bc91SRichard Lowe         case DW_OP_lit15:
18749d3bc91SRichard Lowe         case DW_OP_lit16:
18849d3bc91SRichard Lowe         case DW_OP_lit17:
18949d3bc91SRichard Lowe         case DW_OP_lit18:
19049d3bc91SRichard Lowe         case DW_OP_lit19:
19149d3bc91SRichard Lowe         case DW_OP_lit20:
19249d3bc91SRichard Lowe         case DW_OP_lit21:
19349d3bc91SRichard Lowe         case DW_OP_lit22:
19449d3bc91SRichard Lowe         case DW_OP_lit23:
19549d3bc91SRichard Lowe         case DW_OP_lit24:
19649d3bc91SRichard Lowe         case DW_OP_lit25:
19749d3bc91SRichard Lowe         case DW_OP_lit26:
19849d3bc91SRichard Lowe         case DW_OP_lit27:
19949d3bc91SRichard Lowe         case DW_OP_lit28:
20049d3bc91SRichard Lowe         case DW_OP_lit29:
20149d3bc91SRichard Lowe         case DW_OP_lit30:
20249d3bc91SRichard Lowe         case DW_OP_lit31:
20349d3bc91SRichard Lowe             operand1 = atom - DW_OP_lit0;
20449d3bc91SRichard Lowe             break;
20549d3bc91SRichard Lowe 
20649d3bc91SRichard Lowe         case DW_OP_addr:
20749d3bc91SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned,
208*07dc1947SRichard Lowe                            loc_ptr, address_size);
209*07dc1947SRichard Lowe             loc_ptr += address_size;
210*07dc1947SRichard Lowe             offset += address_size;
21149d3bc91SRichard Lowe             break;
21249d3bc91SRichard Lowe 
21349d3bc91SRichard Lowe         case DW_OP_const1u:
21449d3bc91SRichard Lowe             operand1 = *(Dwarf_Small *) loc_ptr;
21549d3bc91SRichard Lowe             loc_ptr = loc_ptr + 1;
21649d3bc91SRichard Lowe             offset = offset + 1;
21749d3bc91SRichard Lowe             break;
21849d3bc91SRichard Lowe 
21949d3bc91SRichard Lowe         case DW_OP_const1s:
22049d3bc91SRichard Lowe             operand1 = *(Dwarf_Sbyte *) loc_ptr;
221*07dc1947SRichard Lowe             SIGN_EXTEND(operand1,1);
22249d3bc91SRichard Lowe             loc_ptr = loc_ptr + 1;
22349d3bc91SRichard Lowe             offset = offset + 1;
22449d3bc91SRichard Lowe             break;
22549d3bc91SRichard Lowe 
22649d3bc91SRichard Lowe         case DW_OP_const2u:
22749d3bc91SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
22849d3bc91SRichard Lowe             loc_ptr = loc_ptr + 2;
22949d3bc91SRichard Lowe             offset = offset + 2;
23049d3bc91SRichard Lowe             break;
23149d3bc91SRichard Lowe 
23249d3bc91SRichard Lowe         case DW_OP_const2s:
23349d3bc91SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
234*07dc1947SRichard Lowe             SIGN_EXTEND(operand1,2);
23549d3bc91SRichard Lowe             loc_ptr = loc_ptr + 2;
23649d3bc91SRichard Lowe             offset = offset + 2;
23749d3bc91SRichard Lowe             break;
23849d3bc91SRichard Lowe 
23949d3bc91SRichard Lowe         case DW_OP_const4u:
24049d3bc91SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
24149d3bc91SRichard Lowe             loc_ptr = loc_ptr + 4;
24249d3bc91SRichard Lowe             offset = offset + 4;
24349d3bc91SRichard Lowe             break;
24449d3bc91SRichard Lowe 
24549d3bc91SRichard Lowe         case DW_OP_const4s:
24649d3bc91SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
247*07dc1947SRichard Lowe             SIGN_EXTEND(operand1,4);
24849d3bc91SRichard Lowe             loc_ptr = loc_ptr + 4;
24949d3bc91SRichard Lowe             offset = offset + 4;
25049d3bc91SRichard Lowe             break;
25149d3bc91SRichard Lowe 
25249d3bc91SRichard Lowe         case DW_OP_const8u:
25349d3bc91SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
25449d3bc91SRichard Lowe             loc_ptr = loc_ptr + 8;
25549d3bc91SRichard Lowe             offset = offset + 8;
25649d3bc91SRichard Lowe             break;
25749d3bc91SRichard Lowe 
25849d3bc91SRichard Lowe         case DW_OP_const8s:
25949d3bc91SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
26049d3bc91SRichard Lowe             loc_ptr = loc_ptr + 8;
26149d3bc91SRichard Lowe             offset = offset + 8;
26249d3bc91SRichard Lowe             break;
26349d3bc91SRichard Lowe 
26449d3bc91SRichard Lowe         case DW_OP_constu:
26549d3bc91SRichard Lowe             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
26649d3bc91SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
26749d3bc91SRichard Lowe             offset = offset + leb128_length;
26849d3bc91SRichard Lowe             break;
26949d3bc91SRichard Lowe 
27049d3bc91SRichard Lowe         case DW_OP_consts:
27149d3bc91SRichard Lowe             operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
27249d3bc91SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
27349d3bc91SRichard Lowe             offset = offset + leb128_length;
27449d3bc91SRichard Lowe             break;
27549d3bc91SRichard Lowe 
27649d3bc91SRichard Lowe         case DW_OP_fbreg:
27749d3bc91SRichard Lowe             operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
27849d3bc91SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
27949d3bc91SRichard Lowe             offset = offset + leb128_length;
28049d3bc91SRichard Lowe             break;
28149d3bc91SRichard Lowe 
28249d3bc91SRichard Lowe         case DW_OP_breg0:
28349d3bc91SRichard Lowe         case DW_OP_breg1:
28449d3bc91SRichard Lowe         case DW_OP_breg2:
28549d3bc91SRichard Lowe         case DW_OP_breg3:
28649d3bc91SRichard Lowe         case DW_OP_breg4:
28749d3bc91SRichard Lowe         case DW_OP_breg5:
28849d3bc91SRichard Lowe         case DW_OP_breg6:
28949d3bc91SRichard Lowe         case DW_OP_breg7:
29049d3bc91SRichard Lowe         case DW_OP_breg8:
29149d3bc91SRichard Lowe         case DW_OP_breg9:
29249d3bc91SRichard Lowe         case DW_OP_breg10:
29349d3bc91SRichard Lowe         case DW_OP_breg11:
29449d3bc91SRichard Lowe         case DW_OP_breg12:
29549d3bc91SRichard Lowe         case DW_OP_breg13:
29649d3bc91SRichard Lowe         case DW_OP_breg14:
29749d3bc91SRichard Lowe         case DW_OP_breg15:
29849d3bc91SRichard Lowe         case DW_OP_breg16:
29949d3bc91SRichard Lowe         case DW_OP_breg17:
30049d3bc91SRichard Lowe         case DW_OP_breg18:
30149d3bc91SRichard Lowe         case DW_OP_breg19:
30249d3bc91SRichard Lowe         case DW_OP_breg20:
30349d3bc91SRichard Lowe         case DW_OP_breg21:
30449d3bc91SRichard Lowe         case DW_OP_breg22:
30549d3bc91SRichard Lowe         case DW_OP_breg23:
30649d3bc91SRichard Lowe         case DW_OP_breg24:
30749d3bc91SRichard Lowe         case DW_OP_breg25:
30849d3bc91SRichard Lowe         case DW_OP_breg26:
30949d3bc91SRichard Lowe         case DW_OP_breg27:
31049d3bc91SRichard Lowe         case DW_OP_breg28:
31149d3bc91SRichard Lowe         case DW_OP_breg29:
31249d3bc91SRichard Lowe         case DW_OP_breg30:
31349d3bc91SRichard Lowe         case DW_OP_breg31:
31449d3bc91SRichard Lowe             operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
31549d3bc91SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
31649d3bc91SRichard Lowe             offset = offset + leb128_length;
31749d3bc91SRichard Lowe             break;
31849d3bc91SRichard Lowe 
31949d3bc91SRichard Lowe         case DW_OP_bregx:
32049d3bc91SRichard Lowe             /* uleb reg num followed by sleb offset */
32149d3bc91SRichard Lowe             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
32249d3bc91SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
32349d3bc91SRichard Lowe             offset = offset + leb128_length;
32449d3bc91SRichard Lowe 
32549d3bc91SRichard Lowe             operand2 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
32649d3bc91SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
32749d3bc91SRichard Lowe             offset = offset + leb128_length;
32849d3bc91SRichard Lowe             break;
32949d3bc91SRichard Lowe 
33049d3bc91SRichard Lowe         case DW_OP_dup:
33149d3bc91SRichard Lowe         case DW_OP_drop:
33249d3bc91SRichard Lowe             break;
33349d3bc91SRichard Lowe 
33449d3bc91SRichard Lowe         case DW_OP_pick:
33549d3bc91SRichard Lowe             operand1 = *(Dwarf_Small *) loc_ptr;
33649d3bc91SRichard Lowe             loc_ptr = loc_ptr + 1;
33749d3bc91SRichard Lowe             offset = offset + 1;
33849d3bc91SRichard Lowe             break;
33949d3bc91SRichard Lowe 
34049d3bc91SRichard Lowe         case DW_OP_over:
34149d3bc91SRichard Lowe         case DW_OP_swap:
34249d3bc91SRichard Lowe         case DW_OP_rot:
34349d3bc91SRichard Lowe         case DW_OP_deref:
34449d3bc91SRichard Lowe             break;
34549d3bc91SRichard Lowe 
34649d3bc91SRichard Lowe         case DW_OP_deref_size:
34749d3bc91SRichard Lowe             operand1 = *(Dwarf_Small *) loc_ptr;
34849d3bc91SRichard Lowe             loc_ptr = loc_ptr + 1;
34949d3bc91SRichard Lowe             offset = offset + 1;
35049d3bc91SRichard Lowe             break;
35149d3bc91SRichard Lowe 
35249d3bc91SRichard Lowe         case DW_OP_xderef:
35349d3bc91SRichard Lowe             break;
35449d3bc91SRichard Lowe 
35549d3bc91SRichard Lowe         case DW_OP_xderef_size:
35649d3bc91SRichard Lowe             operand1 = *(Dwarf_Small *) loc_ptr;
35749d3bc91SRichard Lowe             loc_ptr = loc_ptr + 1;
35849d3bc91SRichard Lowe             offset = offset + 1;
35949d3bc91SRichard Lowe             break;
36049d3bc91SRichard Lowe 
36149d3bc91SRichard Lowe         case DW_OP_abs:
36249d3bc91SRichard Lowe         case DW_OP_and:
36349d3bc91SRichard Lowe         case DW_OP_div:
36449d3bc91SRichard Lowe         case DW_OP_minus:
36549d3bc91SRichard Lowe         case DW_OP_mod:
36649d3bc91SRichard Lowe         case DW_OP_mul:
36749d3bc91SRichard Lowe         case DW_OP_neg:
36849d3bc91SRichard Lowe         case DW_OP_not:
36949d3bc91SRichard Lowe         case DW_OP_or:
37049d3bc91SRichard Lowe         case DW_OP_plus:
37149d3bc91SRichard Lowe             break;
37249d3bc91SRichard Lowe 
37349d3bc91SRichard Lowe         case DW_OP_plus_uconst:
37449d3bc91SRichard Lowe             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
37549d3bc91SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
37649d3bc91SRichard Lowe             offset = offset + leb128_length;
37749d3bc91SRichard Lowe             break;
37849d3bc91SRichard Lowe 
37949d3bc91SRichard Lowe         case DW_OP_shl:
38049d3bc91SRichard Lowe         case DW_OP_shr:
38149d3bc91SRichard Lowe         case DW_OP_shra:
38249d3bc91SRichard Lowe         case DW_OP_xor:
38349d3bc91SRichard Lowe             break;
38449d3bc91SRichard Lowe 
38549d3bc91SRichard Lowe         case DW_OP_le:
38649d3bc91SRichard Lowe         case DW_OP_ge:
38749d3bc91SRichard Lowe         case DW_OP_eq:
38849d3bc91SRichard Lowe         case DW_OP_lt:
38949d3bc91SRichard Lowe         case DW_OP_gt:
39049d3bc91SRichard Lowe         case DW_OP_ne:
39149d3bc91SRichard Lowe             break;
39249d3bc91SRichard Lowe 
39349d3bc91SRichard Lowe         case DW_OP_skip:
39449d3bc91SRichard Lowe         case DW_OP_bra:
39549d3bc91SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
39649d3bc91SRichard Lowe             loc_ptr = loc_ptr + 2;
39749d3bc91SRichard Lowe             offset = offset + 2;
39849d3bc91SRichard Lowe             break;
39949d3bc91SRichard Lowe 
40049d3bc91SRichard Lowe         case DW_OP_piece:
40149d3bc91SRichard Lowe             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
40249d3bc91SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
40349d3bc91SRichard Lowe             offset = offset + leb128_length;
40449d3bc91SRichard Lowe             break;
40549d3bc91SRichard Lowe 
40649d3bc91SRichard Lowe         case DW_OP_nop:
40749d3bc91SRichard Lowe             break;
408*07dc1947SRichard Lowe         case DW_OP_push_object_address: /* DWARF3 */
409*07dc1947SRichard Lowe             break;
410*07dc1947SRichard Lowe         case DW_OP_call2:       /* DWARF3 */
411*07dc1947SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
412*07dc1947SRichard Lowe             loc_ptr = loc_ptr + 2;
413*07dc1947SRichard Lowe             offset = offset + 2;
414*07dc1947SRichard Lowe             break;
415*07dc1947SRichard Lowe 
416*07dc1947SRichard Lowe         case DW_OP_call4:       /* DWARF3 */
417*07dc1947SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
418*07dc1947SRichard Lowe             loc_ptr = loc_ptr + 4;
419*07dc1947SRichard Lowe             offset = offset + 4;
420*07dc1947SRichard Lowe             break;
421*07dc1947SRichard Lowe         case DW_OP_call_ref:    /* DWARF3 */
422*07dc1947SRichard Lowe             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr,
423*07dc1947SRichard Lowe                            dbg->de_length_size);
424*07dc1947SRichard Lowe             loc_ptr = loc_ptr + dbg->de_length_size;
425*07dc1947SRichard Lowe             offset = offset + dbg->de_length_size;
426*07dc1947SRichard Lowe             break;
427*07dc1947SRichard Lowe 
428*07dc1947SRichard Lowe         case DW_OP_form_tls_address:    /* DWARF3f */
429*07dc1947SRichard Lowe             break;
430*07dc1947SRichard Lowe         case DW_OP_call_frame_cfa:      /* DWARF3f */
431*07dc1947SRichard Lowe             break;
432*07dc1947SRichard Lowe         case DW_OP_bit_piece:   /* DWARF3f */
433*07dc1947SRichard Lowe             /* uleb size in bits followed by uleb offset in bits */
434*07dc1947SRichard Lowe             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
435*07dc1947SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
436*07dc1947SRichard Lowe             offset = offset + leb128_length;
437*07dc1947SRichard Lowe 
438*07dc1947SRichard Lowe             operand2 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
439*07dc1947SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
440*07dc1947SRichard Lowe             offset = offset + leb128_length;
441*07dc1947SRichard Lowe             break;
442*07dc1947SRichard Lowe         case DW_OP_implicit_value: /* DWARF4 */
443*07dc1947SRichard Lowe             /* uleb length of value bytes followed by that
444*07dc1947SRichard Lowe                number of bytes of the value. */
445*07dc1947SRichard Lowe             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
446*07dc1947SRichard Lowe             loc_ptr = loc_ptr + leb128_length;
447*07dc1947SRichard Lowe             offset = offset + leb128_length;
448*07dc1947SRichard Lowe 
449*07dc1947SRichard Lowe             /* Second operand is block of 'operand1' bytes of stuff. */
450*07dc1947SRichard Lowe             /* This using the second operand as a pointer
451*07dc1947SRichard Lowe                is quite ugly. */
452*07dc1947SRichard Lowe             /* This gets an ugly compiler warning. Sorry. */
453*07dc1947SRichard Lowe             operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr;
454*07dc1947SRichard Lowe             offset = offset + operand1;
455*07dc1947SRichard Lowe             loc_ptr = loc_ptr + operand1;
456*07dc1947SRichard Lowe             break;
457*07dc1947SRichard Lowe         case DW_OP_stack_value:  /* DWARF4 */
458*07dc1947SRichard Lowe             break;
459*07dc1947SRichard Lowe 
46049d3bc91SRichard Lowe 
46149d3bc91SRichard Lowe         default:
46249d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
46349d3bc91SRichard Lowe             return (NULL);
46449d3bc91SRichard Lowe         }
46549d3bc91SRichard Lowe 
46649d3bc91SRichard Lowe 
46749d3bc91SRichard Lowe         curr_loc->lc_number = operand1;
46849d3bc91SRichard Lowe         curr_loc->lc_number2 = operand2;
46949d3bc91SRichard Lowe 
47049d3bc91SRichard Lowe         if (head_loc == NULL)
47149d3bc91SRichard Lowe             head_loc = prev_loc = curr_loc;
47249d3bc91SRichard Lowe         else {
47349d3bc91SRichard Lowe             prev_loc->lc_next = curr_loc;
47449d3bc91SRichard Lowe             prev_loc = curr_loc;
47549d3bc91SRichard Lowe         }
47649d3bc91SRichard Lowe     }
47749d3bc91SRichard Lowe 
47849d3bc91SRichard Lowe     block_loc =
47949d3bc91SRichard Lowe         (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count);
48049d3bc91SRichard Lowe     if (block_loc == NULL) {
48149d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
48249d3bc91SRichard Lowe         return (NULL);
48349d3bc91SRichard Lowe     }
48449d3bc91SRichard Lowe 
48549d3bc91SRichard Lowe     curr_loc = head_loc;
48649d3bc91SRichard Lowe     for (i = 0; i < op_count; i++) {
48749d3bc91SRichard Lowe         (block_loc + i)->lr_atom = curr_loc->lc_atom;
48849d3bc91SRichard Lowe         (block_loc + i)->lr_number = curr_loc->lc_number;
48949d3bc91SRichard Lowe         (block_loc + i)->lr_number2 = curr_loc->lc_number2;
49049d3bc91SRichard Lowe         (block_loc + i)->lr_offset = curr_loc->lc_offset;
49149d3bc91SRichard Lowe 
49249d3bc91SRichard Lowe         prev_loc = curr_loc;
49349d3bc91SRichard Lowe         curr_loc = curr_loc->lc_next;
49449d3bc91SRichard Lowe         dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
49549d3bc91SRichard Lowe     }
49649d3bc91SRichard Lowe 
49749d3bc91SRichard Lowe     locdesc =
49849d3bc91SRichard Lowe         (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1);
49949d3bc91SRichard Lowe     if (locdesc == NULL) {
50049d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
50149d3bc91SRichard Lowe         return (NULL);
50249d3bc91SRichard Lowe     }
50349d3bc91SRichard Lowe 
50449d3bc91SRichard Lowe     locdesc->ld_cents = op_count;
50549d3bc91SRichard Lowe     locdesc->ld_s = block_loc;
50649d3bc91SRichard Lowe     locdesc->ld_from_loclist = loc_block->bl_from_loclist;
50749d3bc91SRichard Lowe     locdesc->ld_section_offset = loc_block->bl_section_offset;
50849d3bc91SRichard Lowe     locdesc->ld_lopc = lowpc;
50949d3bc91SRichard Lowe     locdesc->ld_hipc = highpc;
51049d3bc91SRichard Lowe 
51149d3bc91SRichard Lowe     return (locdesc);
51249d3bc91SRichard Lowe }
51349d3bc91SRichard Lowe 
51449d3bc91SRichard Lowe /* Using a loclist offset to get the in-memory
51549d3bc91SRichard Lowe    address of .debug_loc data to read, returns the loclist
51649d3bc91SRichard Lowe    'header' info in return_block.
51749d3bc91SRichard Lowe */
51849d3bc91SRichard Lowe 
51949d3bc91SRichard Lowe #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
52049d3bc91SRichard Lowe 
52149d3bc91SRichard Lowe static int
_dwarf_read_loc_section(Dwarf_Debug dbg,Dwarf_Block * return_block,Dwarf_Addr * lowpc,Dwarf_Addr * hipc,Dwarf_Off sec_offset,Dwarf_Half address_size,Dwarf_Error * error)52249d3bc91SRichard Lowe _dwarf_read_loc_section(Dwarf_Debug dbg,
52349d3bc91SRichard Lowe                         Dwarf_Block * return_block,
52449d3bc91SRichard Lowe                         Dwarf_Addr * lowpc, Dwarf_Addr * hipc,
525*07dc1947SRichard Lowe                         Dwarf_Off sec_offset,
526*07dc1947SRichard Lowe                         Dwarf_Half address_size,
527*07dc1947SRichard Lowe                         Dwarf_Error * error)
52849d3bc91SRichard Lowe {
529*07dc1947SRichard Lowe     Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset;
53049d3bc91SRichard Lowe 
53149d3bc91SRichard Lowe     Dwarf_Addr start_addr = 0;
53249d3bc91SRichard Lowe     Dwarf_Addr end_addr = 0;
53349d3bc91SRichard Lowe     Dwarf_Half exprblock_size = 0;
53449d3bc91SRichard Lowe     Dwarf_Unsigned exprblock_off =
53549d3bc91SRichard Lowe         2 * address_size + sizeof(Dwarf_Half);
53649d3bc91SRichard Lowe 
537*07dc1947SRichard Lowe     if (sec_offset >= dbg->de_debug_loc.dss_size) {
53849d3bc91SRichard Lowe         /* We're at the end. No more present. */
53949d3bc91SRichard Lowe         return DW_DLV_NO_ENTRY;
54049d3bc91SRichard Lowe     }
54149d3bc91SRichard Lowe 
54249d3bc91SRichard Lowe     /* If it goes past end, error */
543*07dc1947SRichard Lowe     if (exprblock_off > dbg->de_debug_loc.dss_size) {
54449d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
54549d3bc91SRichard Lowe         return DW_DLV_ERROR;
54649d3bc91SRichard Lowe     }
54749d3bc91SRichard Lowe 
54849d3bc91SRichard Lowe     READ_UNALIGNED(dbg, start_addr, Dwarf_Addr, beg, address_size);
54949d3bc91SRichard Lowe     READ_UNALIGNED(dbg, end_addr, Dwarf_Addr,
55049d3bc91SRichard Lowe                    beg + address_size, address_size);
55149d3bc91SRichard Lowe     if (start_addr == 0 && end_addr == 0) {
55249d3bc91SRichard Lowe         /* If start_addr and end_addr are 0, it's the end and no
55349d3bc91SRichard Lowe            exprblock_size field follows. */
55449d3bc91SRichard Lowe         exprblock_size = 0;
55549d3bc91SRichard Lowe         exprblock_off -= sizeof(Dwarf_Half);
55649d3bc91SRichard Lowe     } else if (start_addr == MAX_ADDR) {
55749d3bc91SRichard Lowe         /* end address is a base address, no exprblock_size field here
55849d3bc91SRichard Lowe            either */
55949d3bc91SRichard Lowe         exprblock_size = 0;
56049d3bc91SRichard Lowe         exprblock_off -= sizeof(Dwarf_Half);
56149d3bc91SRichard Lowe     } else {
56249d3bc91SRichard Lowe 
56349d3bc91SRichard Lowe         READ_UNALIGNED(dbg, exprblock_size, Dwarf_Half,
56449d3bc91SRichard Lowe                        beg + 2 * address_size, sizeof(Dwarf_Half));
56549d3bc91SRichard Lowe         /* exprblock_size can be zero, means no expression */
566*07dc1947SRichard Lowe         if ((exprblock_off + exprblock_size) > dbg->de_debug_loc.dss_size) {
56749d3bc91SRichard Lowe             _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
56849d3bc91SRichard Lowe             return DW_DLV_ERROR;
56949d3bc91SRichard Lowe         }
57049d3bc91SRichard Lowe     }
57149d3bc91SRichard Lowe #undef MAX_ADDR
57249d3bc91SRichard Lowe     *lowpc = start_addr;
57349d3bc91SRichard Lowe     *hipc = end_addr;
57449d3bc91SRichard Lowe 
57549d3bc91SRichard Lowe     return_block->bl_len = exprblock_size;
57649d3bc91SRichard Lowe     return_block->bl_from_loclist = 1;
57749d3bc91SRichard Lowe     return_block->bl_data = beg + exprblock_off;
57849d3bc91SRichard Lowe     return_block->bl_section_offset =
579*07dc1947SRichard Lowe         ((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc.dss_data;
58049d3bc91SRichard Lowe 
58149d3bc91SRichard Lowe     return DW_DLV_OK;
58249d3bc91SRichard Lowe 
58349d3bc91SRichard Lowe }
58449d3bc91SRichard Lowe static int
_dwarf_get_loclist_count(Dwarf_Debug dbg,Dwarf_Off loclist_offset,Dwarf_Half address_size,int * loclist_count,Dwarf_Error * error)58549d3bc91SRichard Lowe _dwarf_get_loclist_count(Dwarf_Debug dbg,
58649d3bc91SRichard Lowe                          Dwarf_Off loclist_offset,
587*07dc1947SRichard Lowe                          Dwarf_Half address_size,
58849d3bc91SRichard Lowe                          int *loclist_count, Dwarf_Error * error)
58949d3bc91SRichard Lowe {
59049d3bc91SRichard Lowe     int count = 0;
59149d3bc91SRichard Lowe     Dwarf_Off offset = loclist_offset;
59249d3bc91SRichard Lowe 
59349d3bc91SRichard Lowe 
59449d3bc91SRichard Lowe     for (;;) {
59549d3bc91SRichard Lowe         Dwarf_Block b;
59649d3bc91SRichard Lowe         Dwarf_Addr lowpc;
59749d3bc91SRichard Lowe         Dwarf_Addr highpc;
59849d3bc91SRichard Lowe         int res = _dwarf_read_loc_section(dbg, &b,
59949d3bc91SRichard Lowe                   &lowpc, &highpc,
600*07dc1947SRichard Lowe                   offset, address_size,error);
60149d3bc91SRichard Lowe 
60249d3bc91SRichard Lowe         if (res != DW_DLV_OK) {
60349d3bc91SRichard Lowe             return res;
60449d3bc91SRichard Lowe         }
60549d3bc91SRichard Lowe         offset = b.bl_len + b.bl_section_offset;
60649d3bc91SRichard Lowe         if (lowpc == 0 && highpc == 0) {
60749d3bc91SRichard Lowe             break;
60849d3bc91SRichard Lowe         }
60949d3bc91SRichard Lowe         count++;
61049d3bc91SRichard Lowe     }
61149d3bc91SRichard Lowe     *loclist_count = count;
61249d3bc91SRichard Lowe     return DW_DLV_OK;
61349d3bc91SRichard Lowe }
61449d3bc91SRichard Lowe 
61549d3bc91SRichard Lowe /* Helper routine to avoid code duplication.
61649d3bc91SRichard Lowe */
61749d3bc91SRichard Lowe static int
_dwarf_setup_loc(Dwarf_Attribute attr,Dwarf_Debug * dbg_ret,Dwarf_CU_Context * cucontext_ret,Dwarf_Half * form_ret,Dwarf_Error * error)61849d3bc91SRichard Lowe _dwarf_setup_loc(Dwarf_Attribute attr,
61949d3bc91SRichard Lowe                  Dwarf_Debug * dbg_ret,
620*07dc1947SRichard Lowe                  Dwarf_CU_Context *cucontext_ret,
62149d3bc91SRichard Lowe                  Dwarf_Half * form_ret, Dwarf_Error * error)
62249d3bc91SRichard Lowe {
62349d3bc91SRichard Lowe     Dwarf_Debug dbg = 0;
62449d3bc91SRichard Lowe     Dwarf_Half form = 0;
625*07dc1947SRichard Lowe     int blkres = DW_DLV_ERROR;
62649d3bc91SRichard Lowe 
62749d3bc91SRichard Lowe     if (attr == NULL) {
62849d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
62949d3bc91SRichard Lowe         return (DW_DLV_ERROR);
63049d3bc91SRichard Lowe     }
63149d3bc91SRichard Lowe     if (attr->ar_cu_context == NULL) {
63249d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
63349d3bc91SRichard Lowe         return (DW_DLV_ERROR);
63449d3bc91SRichard Lowe     }
635*07dc1947SRichard Lowe     *cucontext_ret = attr->ar_cu_context;
63649d3bc91SRichard Lowe 
63749d3bc91SRichard Lowe     dbg = attr->ar_cu_context->cc_dbg;
63849d3bc91SRichard Lowe     if (dbg == NULL) {
63949d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
64049d3bc91SRichard Lowe         return (DW_DLV_ERROR);
64149d3bc91SRichard Lowe     }
64249d3bc91SRichard Lowe     *dbg_ret = dbg;
64349d3bc91SRichard Lowe     blkres = dwarf_whatform(attr, &form, error);
64449d3bc91SRichard Lowe     if (blkres != DW_DLV_OK) {
64549d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
64649d3bc91SRichard Lowe         return blkres;
64749d3bc91SRichard Lowe     }
64849d3bc91SRichard Lowe     *form_ret = form;
64949d3bc91SRichard Lowe     return DW_DLV_OK;
65049d3bc91SRichard Lowe }
65149d3bc91SRichard Lowe 
65249d3bc91SRichard Lowe /* Helper routine  to avoid code duplication.
65349d3bc91SRichard Lowe */
65449d3bc91SRichard Lowe static int
_dwarf_get_loclist_header_start(Dwarf_Debug dbg,Dwarf_Attribute attr,Dwarf_Unsigned * loclist_offset,Dwarf_Error * error)65549d3bc91SRichard Lowe _dwarf_get_loclist_header_start(Dwarf_Debug dbg,
65649d3bc91SRichard Lowe                                 Dwarf_Attribute attr,
65749d3bc91SRichard Lowe                                 Dwarf_Unsigned * loclist_offset,
65849d3bc91SRichard Lowe                                 Dwarf_Error * error)
65949d3bc91SRichard Lowe {
66049d3bc91SRichard Lowe     int blkres = dwarf_formudata(attr, loclist_offset, error);
66149d3bc91SRichard Lowe     if (blkres != DW_DLV_OK) {
66249d3bc91SRichard Lowe         return (blkres);
66349d3bc91SRichard Lowe     }
66449d3bc91SRichard Lowe 
665*07dc1947SRichard Lowe     if (!dbg->de_debug_loc.dss_data) {
666*07dc1947SRichard Lowe         int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
66749d3bc91SRichard Lowe         if (secload != DW_DLV_OK) {
66849d3bc91SRichard Lowe             return secload;
66949d3bc91SRichard Lowe         }
67049d3bc91SRichard Lowe     }
67149d3bc91SRichard Lowe     return DW_DLV_OK;
67249d3bc91SRichard Lowe }
67349d3bc91SRichard Lowe 
67449d3bc91SRichard Lowe /* When llbuf (see dwarf_loclist_n) is partially set up
67549d3bc91SRichard Lowe    and an error is encountered, tear it down as it
67649d3bc91SRichard Lowe    won't be used.
67749d3bc91SRichard Lowe */
67849d3bc91SRichard Lowe static void
_dwarf_cleanup_llbuf(Dwarf_Debug dbg,Dwarf_Locdesc ** llbuf,int count)67949d3bc91SRichard Lowe _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count)
68049d3bc91SRichard Lowe {
68149d3bc91SRichard Lowe     int i;
68249d3bc91SRichard Lowe     for (i = 0; i < count; ++i) {
68349d3bc91SRichard Lowe         dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
68449d3bc91SRichard Lowe         dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC);
68549d3bc91SRichard Lowe     }
68649d3bc91SRichard Lowe     dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
68749d3bc91SRichard Lowe }
68849d3bc91SRichard Lowe 
68949d3bc91SRichard Lowe /*
69049d3bc91SRichard Lowe         Handles simple location entries and loclists.
69149d3bc91SRichard Lowe         Returns all the Locdesc's thru llbuf.
69249d3bc91SRichard Lowe 
69349d3bc91SRichard Lowe */
69449d3bc91SRichard Lowe int
dwarf_loclist_n(Dwarf_Attribute attr,Dwarf_Locdesc *** llbuf_out,Dwarf_Signed * listlen_out,Dwarf_Error * error)69549d3bc91SRichard Lowe dwarf_loclist_n(Dwarf_Attribute attr,
69649d3bc91SRichard Lowe                 Dwarf_Locdesc *** llbuf_out,
69749d3bc91SRichard Lowe                 Dwarf_Signed * listlen_out, Dwarf_Error * error)
69849d3bc91SRichard Lowe {
69949d3bc91SRichard Lowe     Dwarf_Debug dbg;
70049d3bc91SRichard Lowe 
70149d3bc91SRichard Lowe     /*
70249d3bc91SRichard Lowe        Dwarf_Attribute that describes the DW_AT_location in die, if
70349d3bc91SRichard Lowe        present. */
70449d3bc91SRichard Lowe     Dwarf_Attribute loc_attr = attr;
70549d3bc91SRichard Lowe 
70649d3bc91SRichard Lowe     /* Dwarf_Block that describes a single location expression. */
70749d3bc91SRichard Lowe     Dwarf_Block loc_block;
70849d3bc91SRichard Lowe 
70949d3bc91SRichard Lowe     /* A pointer to the current Dwarf_Locdesc read. */
71049d3bc91SRichard Lowe     Dwarf_Locdesc *locdesc = 0;
71149d3bc91SRichard Lowe 
71249d3bc91SRichard Lowe     Dwarf_Half form = 0;
71349d3bc91SRichard Lowe     Dwarf_Addr lowpc = 0;
71449d3bc91SRichard Lowe     Dwarf_Addr highpc = 0;
71549d3bc91SRichard Lowe     Dwarf_Signed listlen = 0;
71649d3bc91SRichard Lowe     Dwarf_Locdesc **llbuf = 0;
717*07dc1947SRichard Lowe     Dwarf_CU_Context cucontext = 0;
718*07dc1947SRichard Lowe     unsigned address_size = 0;
71949d3bc91SRichard Lowe 
720*07dc1947SRichard Lowe     int blkres = DW_DLV_ERROR;
721*07dc1947SRichard Lowe     int setup_res = DW_DLV_ERROR;
72249d3bc91SRichard Lowe 
72349d3bc91SRichard Lowe     /* ***** BEGIN CODE ***** */
724*07dc1947SRichard Lowe     setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
72549d3bc91SRichard Lowe     if (setup_res != DW_DLV_OK) {
72649d3bc91SRichard Lowe         return setup_res;
72749d3bc91SRichard Lowe     }
728*07dc1947SRichard Lowe     address_size = cucontext->cc_address_size;
72949d3bc91SRichard Lowe     /* If this is a form_block then it's a location expression. If it's
73049d3bc91SRichard Lowe        DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
731*07dc1947SRichard Lowe     if (((cucontext->cc_version_stamp == CURRENT_VERSION_STAMP ||
732*07dc1947SRichard Lowe           cucontext->cc_version_stamp == CURRENT_VERSION_STAMP3) &&
733*07dc1947SRichard Lowe           (form == DW_FORM_data4 || form == DW_FORM_data8)) ||
734*07dc1947SRichard Lowe          (cucontext->cc_version_stamp == CURRENT_VERSION_STAMP4 &&
735*07dc1947SRichard Lowe             form == DW_FORM_sec_offset))
736*07dc1947SRichard Lowe         {
737*07dc1947SRichard Lowe 
73849d3bc91SRichard Lowe 
73949d3bc91SRichard Lowe         /* A reference to .debug_loc, with an offset in .debug_loc of a
74049d3bc91SRichard Lowe            loclist */
74149d3bc91SRichard Lowe         Dwarf_Unsigned loclist_offset = 0;
742*07dc1947SRichard Lowe         int off_res  = DW_DLV_ERROR;
743*07dc1947SRichard Lowe         int count_res = DW_DLV_ERROR;
74449d3bc91SRichard Lowe         int loclist_count;
74549d3bc91SRichard Lowe         int lli;
74649d3bc91SRichard Lowe 
74749d3bc91SRichard Lowe         off_res = _dwarf_get_loclist_header_start(dbg,
74849d3bc91SRichard Lowe                                                   attr, &loclist_offset,
74949d3bc91SRichard Lowe                                                   error);
75049d3bc91SRichard Lowe         if (off_res != DW_DLV_OK) {
75149d3bc91SRichard Lowe             return off_res;
75249d3bc91SRichard Lowe         }
75349d3bc91SRichard Lowe         count_res = _dwarf_get_loclist_count(dbg, loclist_offset,
754*07dc1947SRichard Lowe                                              address_size,
75549d3bc91SRichard Lowe                                              &loclist_count, error);
75649d3bc91SRichard Lowe         listlen = loclist_count;
75749d3bc91SRichard Lowe         if (count_res != DW_DLV_OK) {
75849d3bc91SRichard Lowe             return count_res;
75949d3bc91SRichard Lowe         }
76049d3bc91SRichard Lowe         if (loclist_count == 0) {
76149d3bc91SRichard Lowe             return DW_DLV_NO_ENTRY;
76249d3bc91SRichard Lowe         }
76349d3bc91SRichard Lowe 
76449d3bc91SRichard Lowe         llbuf = (Dwarf_Locdesc **)
76549d3bc91SRichard Lowe             _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count);
76649d3bc91SRichard Lowe         if (!llbuf) {
76749d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
76849d3bc91SRichard Lowe             return (DW_DLV_ERROR);
76949d3bc91SRichard Lowe         }
77049d3bc91SRichard Lowe 
77149d3bc91SRichard Lowe         for (lli = 0; lli < loclist_count; ++lli) {
77249d3bc91SRichard Lowe             blkres = _dwarf_read_loc_section(dbg, &loc_block,
77349d3bc91SRichard Lowe                 &lowpc,
77449d3bc91SRichard Lowe                 &highpc,
775*07dc1947SRichard Lowe                 loclist_offset,
776*07dc1947SRichard Lowe                 address_size,
777*07dc1947SRichard Lowe                 error);
77849d3bc91SRichard Lowe             if (blkres != DW_DLV_OK) {
77949d3bc91SRichard Lowe                 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
78049d3bc91SRichard Lowe                 return (blkres);
78149d3bc91SRichard Lowe             }
78249d3bc91SRichard Lowe             locdesc = _dwarf_get_locdesc(dbg, &loc_block,
783*07dc1947SRichard Lowe                 address_size,
78449d3bc91SRichard Lowe                 lowpc, highpc, error);
78549d3bc91SRichard Lowe             if (locdesc == NULL) {
78649d3bc91SRichard Lowe                 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
78749d3bc91SRichard Lowe                 /* low level error already set: let it be passed back */
78849d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
78949d3bc91SRichard Lowe             }
79049d3bc91SRichard Lowe             llbuf[lli] = locdesc;
79149d3bc91SRichard Lowe 
79249d3bc91SRichard Lowe             /* Now get to next loclist entry offset. */
79349d3bc91SRichard Lowe             loclist_offset = loc_block.bl_section_offset +
79449d3bc91SRichard Lowe                 loc_block.bl_len;
79549d3bc91SRichard Lowe         }
79649d3bc91SRichard Lowe 
79749d3bc91SRichard Lowe 
79849d3bc91SRichard Lowe     } else {
79949d3bc91SRichard Lowe         Dwarf_Block *tblock = 0;
80049d3bc91SRichard Lowe 
80149d3bc91SRichard Lowe         blkres = dwarf_formblock(loc_attr, &tblock, error);
80249d3bc91SRichard Lowe         if (blkres != DW_DLV_OK) {
80349d3bc91SRichard Lowe             return (blkres);
80449d3bc91SRichard Lowe         }
80549d3bc91SRichard Lowe         loc_block = *tblock;
80649d3bc91SRichard Lowe         /* We copied tblock contents to the stack var, so can dealloc
80749d3bc91SRichard Lowe            tblock now.  Avoids leaks. */
80849d3bc91SRichard Lowe         dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
809*07dc1947SRichard Lowe         listlen = 1; /* One by definition of a location entry. */
81049d3bc91SRichard Lowe         lowpc = 0;   /* HACK */
81149d3bc91SRichard Lowe         highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
81249d3bc91SRichard Lowe 
81349d3bc91SRichard Lowe         /* An empty location description (block length 0) means the
81449d3bc91SRichard Lowe            code generator emitted no variable, the variable was not
81549d3bc91SRichard Lowe            generated, it was unused or perhaps never tested after being
81649d3bc91SRichard Lowe            set. Dwarf2, section 2.4.1 In other words, it is not an
81749d3bc91SRichard Lowe            error, and we don't test for block length 0 specially here. */
81849d3bc91SRichard Lowe         locdesc = _dwarf_get_locdesc(dbg, &loc_block,
819*07dc1947SRichard Lowe             address_size,
82049d3bc91SRichard Lowe             lowpc, highpc, error);
82149d3bc91SRichard Lowe         if (locdesc == NULL) {
82249d3bc91SRichard Lowe             /* low level error already set: let it be passed back */
82349d3bc91SRichard Lowe             return (DW_DLV_ERROR);
82449d3bc91SRichard Lowe         }
82549d3bc91SRichard Lowe         llbuf = (Dwarf_Locdesc **)
82649d3bc91SRichard Lowe             _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen);
82749d3bc91SRichard Lowe         if (!llbuf) {
82849d3bc91SRichard Lowe             /* Free the locdesc we allocated but won't use. */
82949d3bc91SRichard Lowe             dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC);
83049d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
83149d3bc91SRichard Lowe             return (DW_DLV_ERROR);
83249d3bc91SRichard Lowe         }
83349d3bc91SRichard Lowe         llbuf[0] = locdesc;
83449d3bc91SRichard Lowe     }
83549d3bc91SRichard Lowe 
83649d3bc91SRichard Lowe     *llbuf_out = llbuf;
83749d3bc91SRichard Lowe     *listlen_out = listlen;
83849d3bc91SRichard Lowe     return (DW_DLV_OK);
83949d3bc91SRichard Lowe }
84049d3bc91SRichard Lowe 
841*07dc1947SRichard Lowe 
84249d3bc91SRichard Lowe /*
84349d3bc91SRichard Lowe         Handles only a location expression.
84449d3bc91SRichard Lowe         If called on a loclist, just returns one of those.
84549d3bc91SRichard Lowe         Cannot not handle a real loclist.
84649d3bc91SRichard Lowe         It returns the location expression as a loclist with
84749d3bc91SRichard Lowe         a single entry.
84849d3bc91SRichard Lowe         See dwarf_loclist_n() which handles any number
84949d3bc91SRichard Lowe         of location list entries.
85049d3bc91SRichard Lowe 
85149d3bc91SRichard Lowe         This is the original definition, and it simply
85249d3bc91SRichard Lowe         does not work for loclists. Kept for compatibility.
85349d3bc91SRichard Lowe */
85449d3bc91SRichard Lowe int
dwarf_loclist(Dwarf_Attribute attr,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)85549d3bc91SRichard Lowe dwarf_loclist(Dwarf_Attribute attr,
85649d3bc91SRichard Lowe     Dwarf_Locdesc ** llbuf,
85749d3bc91SRichard Lowe     Dwarf_Signed * listlen, Dwarf_Error * error)
85849d3bc91SRichard Lowe {
85949d3bc91SRichard Lowe     Dwarf_Debug dbg;
86049d3bc91SRichard Lowe 
861*07dc1947SRichard Lowe     /* Dwarf_Attribute that describes the DW_AT_location in die, if
86249d3bc91SRichard Lowe        present. */
86349d3bc91SRichard Lowe     Dwarf_Attribute loc_attr = attr;
86449d3bc91SRichard Lowe 
86549d3bc91SRichard Lowe     /* Dwarf_Block that describes a single location expression. */
86649d3bc91SRichard Lowe     Dwarf_Block loc_block;
86749d3bc91SRichard Lowe 
86849d3bc91SRichard Lowe     /* A pointer to the current Dwarf_Locdesc read. */
86949d3bc91SRichard Lowe     Dwarf_Locdesc *locdesc = 0;
87049d3bc91SRichard Lowe 
87149d3bc91SRichard Lowe     Dwarf_Half form = 0;
87249d3bc91SRichard Lowe     Dwarf_Addr lowpc = 0;
87349d3bc91SRichard Lowe     Dwarf_Addr highpc = 0;
874*07dc1947SRichard Lowe     Dwarf_CU_Context cucontext = 0;
875*07dc1947SRichard Lowe     unsigned address_size = 0;
87649d3bc91SRichard Lowe 
877*07dc1947SRichard Lowe     int blkres = DW_DLV_ERROR;
878*07dc1947SRichard Lowe     int setup_res = DW_DLV_ERROR;
87949d3bc91SRichard Lowe 
88049d3bc91SRichard Lowe     /* ***** BEGIN CODE ***** */
881*07dc1947SRichard Lowe     setup_res = _dwarf_setup_loc(attr, &dbg, &cucontext, &form, error);
88249d3bc91SRichard Lowe     if (setup_res != DW_DLV_OK) {
88349d3bc91SRichard Lowe         return setup_res;
88449d3bc91SRichard Lowe     }
885*07dc1947SRichard Lowe     address_size = cucontext->cc_address_size;
88649d3bc91SRichard Lowe     /* If this is a form_block then it's a location expression. If it's
88749d3bc91SRichard Lowe        DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
888*07dc1947SRichard Lowe     if (((cucontext->cc_version_stamp == CURRENT_VERSION_STAMP ||
889*07dc1947SRichard Lowe           cucontext->cc_version_stamp == CURRENT_VERSION_STAMP3) &&
890*07dc1947SRichard Lowe           (form == DW_FORM_data4 || form == DW_FORM_data8)) ||
891*07dc1947SRichard Lowe          (cucontext->cc_version_stamp == CURRENT_VERSION_STAMP4 &&
892*07dc1947SRichard Lowe             form == DW_FORM_sec_offset))
893*07dc1947SRichard Lowe         {
89449d3bc91SRichard Lowe 
89549d3bc91SRichard Lowe         /* A reference to .debug_loc, with an offset in .debug_loc of a
89649d3bc91SRichard Lowe            loclist */
89749d3bc91SRichard Lowe         Dwarf_Unsigned loclist_offset = 0;
898*07dc1947SRichard Lowe         int off_res = DW_DLV_ERROR;
89949d3bc91SRichard Lowe 
90049d3bc91SRichard Lowe         off_res = _dwarf_get_loclist_header_start(dbg,
90149d3bc91SRichard Lowe             attr, &loclist_offset,
90249d3bc91SRichard Lowe             error);
90349d3bc91SRichard Lowe         if (off_res != DW_DLV_OK) {
90449d3bc91SRichard Lowe             return off_res;
90549d3bc91SRichard Lowe         }
90649d3bc91SRichard Lowe 
90749d3bc91SRichard Lowe         /* With dwarf_loclist, just read a single entry */
90849d3bc91SRichard Lowe         blkres = _dwarf_read_loc_section(dbg, &loc_block,
90949d3bc91SRichard Lowe             &lowpc,
91049d3bc91SRichard Lowe             &highpc,
911*07dc1947SRichard Lowe             loclist_offset,
912*07dc1947SRichard Lowe             address_size,
913*07dc1947SRichard Lowe             error);
91449d3bc91SRichard Lowe         if (blkres != DW_DLV_OK) {
91549d3bc91SRichard Lowe             return (blkres);
91649d3bc91SRichard Lowe         }
91749d3bc91SRichard Lowe     } else {
91849d3bc91SRichard Lowe         Dwarf_Block *tblock = 0;
91949d3bc91SRichard Lowe 
92049d3bc91SRichard Lowe         blkres = dwarf_formblock(loc_attr, &tblock, error);
92149d3bc91SRichard Lowe         if (blkres != DW_DLV_OK) {
92249d3bc91SRichard Lowe             return (blkres);
92349d3bc91SRichard Lowe         }
92449d3bc91SRichard Lowe         loc_block = *tblock;
92549d3bc91SRichard Lowe         /* We copied tblock contents to the stack var, so can dealloc
92649d3bc91SRichard Lowe            tblock now.  Avoids leaks. */
92749d3bc91SRichard Lowe         dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
92849d3bc91SRichard Lowe         lowpc = 0;              /* HACK */
92949d3bc91SRichard Lowe         highpc = (Dwarf_Unsigned) (-1LL);       /* HACK */
93049d3bc91SRichard Lowe     }
93149d3bc91SRichard Lowe 
93249d3bc91SRichard Lowe     /* An empty location description (block length 0) means the code
93349d3bc91SRichard Lowe        generator emitted no variable, the variable was not generated,
93449d3bc91SRichard Lowe        it was unused or perhaps never tested after being set. Dwarf2,
93549d3bc91SRichard Lowe        section 2.4.1 In other words, it is not an error, and we don't
936*07dc1947SRichard Lowe        test for block length 0 specially here.
937*07dc1947SRichard Lowe        See *dwarf_loclist_n() which handles the general case, this case
938*07dc1947SRichard Lowe        handles only a single location expression.  */
939*07dc1947SRichard Lowe     locdesc = _dwarf_get_locdesc(dbg, &loc_block,
940*07dc1947SRichard Lowe         address_size,
941*07dc1947SRichard Lowe         lowpc, highpc, error);
942*07dc1947SRichard Lowe     if (locdesc == NULL) {
943*07dc1947SRichard Lowe         /* low level error already set: let it be passed back */
944*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
945*07dc1947SRichard Lowe     }
946*07dc1947SRichard Lowe 
947*07dc1947SRichard Lowe     *llbuf = locdesc;
948*07dc1947SRichard Lowe     *listlen = 1;
949*07dc1947SRichard Lowe     return (DW_DLV_OK);
950*07dc1947SRichard Lowe }
951*07dc1947SRichard Lowe 
952*07dc1947SRichard Lowe 
953*07dc1947SRichard Lowe 
954*07dc1947SRichard Lowe /*
955*07dc1947SRichard Lowe         Handles only a location expression.
956*07dc1947SRichard Lowe         It returns the location expression as a loclist with
957*07dc1947SRichard Lowe         a single entry.
958*07dc1947SRichard Lowe 
959*07dc1947SRichard Lowe         Usable to access dwarf expressions from any source, but
960*07dc1947SRichard Lowe         specifically from
961*07dc1947SRichard Lowe             DW_CFA_def_cfa_expression
962*07dc1947SRichard Lowe             DW_CFA_expression
963*07dc1947SRichard Lowe             DW_CFA_val_expression
964*07dc1947SRichard Lowe 
965*07dc1947SRichard Lowe         expression_in must point to a valid dwarf expression
966*07dc1947SRichard Lowe         set of bytes of length expression_length. Not
967*07dc1947SRichard Lowe         a DW_FORM_block*, just the expression bytes.
968*07dc1947SRichard Lowe 
969*07dc1947SRichard Lowe         If the address_size != de_pointer_size this will not work
970*07dc1947SRichard Lowe         right. FIXME.
971*07dc1947SRichard Lowe */
972*07dc1947SRichard Lowe int
dwarf_loclist_from_expr(Dwarf_Debug dbg,Dwarf_Ptr expression_in,Dwarf_Unsigned expression_length,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)973*07dc1947SRichard Lowe dwarf_loclist_from_expr(Dwarf_Debug dbg,
974*07dc1947SRichard Lowe     Dwarf_Ptr expression_in,
975*07dc1947SRichard Lowe     Dwarf_Unsigned expression_length,
976*07dc1947SRichard Lowe     Dwarf_Locdesc ** llbuf,
977*07dc1947SRichard Lowe     Dwarf_Signed * listlen, Dwarf_Error * error)
978*07dc1947SRichard Lowe {
979*07dc1947SRichard Lowe     int res = 0;
980*07dc1947SRichard Lowe     Dwarf_Half addr_size =  dbg->de_pointer_size;
981*07dc1947SRichard Lowe     res = dwarf_loclist_from_expr_a(dbg,expression_in,
982*07dc1947SRichard Lowe         expression_length, addr_size,llbuf,listlen,error);
983*07dc1947SRichard Lowe     return res;
984*07dc1947SRichard Lowe }
985*07dc1947SRichard Lowe /* New April 27 2009. Adding addr_size argument for the rare
986*07dc1947SRichard Lowe  * cases where an object has CUs with a different address_size. */
987*07dc1947SRichard Lowe int
dwarf_loclist_from_expr_a(Dwarf_Debug dbg,Dwarf_Ptr expression_in,Dwarf_Unsigned expression_length,Dwarf_Half addr_size,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)988*07dc1947SRichard Lowe dwarf_loclist_from_expr_a(Dwarf_Debug dbg,
989*07dc1947SRichard Lowe     Dwarf_Ptr expression_in,
990*07dc1947SRichard Lowe     Dwarf_Unsigned expression_length,
991*07dc1947SRichard Lowe     Dwarf_Half addr_size,
992*07dc1947SRichard Lowe     Dwarf_Locdesc ** llbuf,
993*07dc1947SRichard Lowe     Dwarf_Signed * listlen, Dwarf_Error * error)
994*07dc1947SRichard Lowe {
995*07dc1947SRichard Lowe     /* Dwarf_Block that describes a single location expression. */
996*07dc1947SRichard Lowe     Dwarf_Block loc_block;
997*07dc1947SRichard Lowe 
998*07dc1947SRichard Lowe     /* A pointer to the current Dwarf_Locdesc read. */
999*07dc1947SRichard Lowe     Dwarf_Locdesc *locdesc = 0;
1000*07dc1947SRichard Lowe     Dwarf_Addr lowpc = 0;
1001*07dc1947SRichard Lowe     Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL);
1002*07dc1947SRichard Lowe 
1003*07dc1947SRichard Lowe     memset(&loc_block,0,sizeof(loc_block));
1004*07dc1947SRichard Lowe     loc_block.bl_len = expression_length;
1005*07dc1947SRichard Lowe     loc_block.bl_data = expression_in;
1006*07dc1947SRichard Lowe     loc_block.bl_from_loclist = 0; /* Not from loclist. */
1007*07dc1947SRichard Lowe     loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
1008*07dc1947SRichard Lowe 
1009*07dc1947SRichard Lowe     /* An empty location description (block length 0) means the code
1010*07dc1947SRichard Lowe     generator emitted no variable, the variable was not generated,
1011*07dc1947SRichard Lowe     it was unused or perhaps never tested after being set. Dwarf2,
1012*07dc1947SRichard Lowe     section 2.4.1 In other words, it is not an error, and we don't
1013*07dc1947SRichard Lowe     test for block length 0 specially here.  */
1014*07dc1947SRichard Lowe     locdesc = _dwarf_get_locdesc(dbg, &loc_block,
1015*07dc1947SRichard Lowe         addr_size,lowpc, highpc, error);
101649d3bc91SRichard Lowe     if (locdesc == NULL) {
101749d3bc91SRichard Lowe         /* low level error already set: let it be passed back */
101849d3bc91SRichard Lowe         return (DW_DLV_ERROR);
101949d3bc91SRichard Lowe     }
102049d3bc91SRichard Lowe 
102149d3bc91SRichard Lowe     *llbuf = locdesc;
102249d3bc91SRichard Lowe     *listlen = 1;
102349d3bc91SRichard Lowe     return (DW_DLV_OK);
102449d3bc91SRichard Lowe }
102549d3bc91SRichard Lowe 
102649d3bc91SRichard Lowe /* Usable to read a single loclist or to read a block of them
102749d3bc91SRichard Lowe    or to read an entire section's loclists.
102849d3bc91SRichard Lowe 
1029*07dc1947SRichard Lowe    It's broken because it's not safe to read a loclist entry
1030*07dc1947SRichard Lowe    when we do not know the address size (in any object where
1031*07dc1947SRichard Lowe    address size can vary by compilation unit).
103249d3bc91SRichard Lowe */
103349d3bc91SRichard Lowe 
103449d3bc91SRichard Lowe  /*ARGSUSED*/ int
dwarf_get_loclist_entry(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Addr * hipc_offset,Dwarf_Addr * lopc_offset,Dwarf_Ptr * data,Dwarf_Unsigned * entry_len,Dwarf_Unsigned * next_entry,Dwarf_Error * error)103549d3bc91SRichard Lowe dwarf_get_loclist_entry(Dwarf_Debug dbg,
103649d3bc91SRichard Lowe     Dwarf_Unsigned offset,
103749d3bc91SRichard Lowe     Dwarf_Addr * hipc_offset,
103849d3bc91SRichard Lowe     Dwarf_Addr * lopc_offset,
103949d3bc91SRichard Lowe     Dwarf_Ptr * data,
104049d3bc91SRichard Lowe     Dwarf_Unsigned * entry_len,
104149d3bc91SRichard Lowe     Dwarf_Unsigned * next_entry,
104249d3bc91SRichard Lowe     Dwarf_Error * error)
104349d3bc91SRichard Lowe {
104449d3bc91SRichard Lowe     Dwarf_Block b;
1045*07dc1947SRichard Lowe     Dwarf_Addr lowpc = 0;
1046*07dc1947SRichard Lowe     Dwarf_Addr highpc = 0;
1047*07dc1947SRichard Lowe     Dwarf_Half address_size = 0;
1048*07dc1947SRichard Lowe     int res = DW_DLV_ERROR;
104949d3bc91SRichard Lowe 
1050*07dc1947SRichard Lowe     if (!dbg->de_debug_loc.dss_data) {
1051*07dc1947SRichard Lowe         int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
105249d3bc91SRichard Lowe         if (secload != DW_DLV_OK) {
105349d3bc91SRichard Lowe             return secload;
105449d3bc91SRichard Lowe         }
105549d3bc91SRichard Lowe     }
105649d3bc91SRichard Lowe 
1057*07dc1947SRichard Lowe     /* FIXME: address_size is not necessarily the same in every frame. */
1058*07dc1947SRichard Lowe     address_size = dbg->de_pointer_size;
105949d3bc91SRichard Lowe     res = _dwarf_read_loc_section(dbg,
1060*07dc1947SRichard Lowe          &b, &lowpc, &highpc, offset,
1061*07dc1947SRichard Lowe          address_size,error);
106249d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
106349d3bc91SRichard Lowe         return res;
106449d3bc91SRichard Lowe     }
106549d3bc91SRichard Lowe     *hipc_offset = highpc;
106649d3bc91SRichard Lowe     *lopc_offset = lowpc;
106749d3bc91SRichard Lowe     *entry_len = b.bl_len;
106849d3bc91SRichard Lowe     *data = b.bl_data;
106949d3bc91SRichard Lowe     *next_entry = b.bl_len + b.bl_section_offset;
107049d3bc91SRichard Lowe     return DW_DLV_OK;
107149d3bc91SRichard Lowe }
1072*07dc1947SRichard Lowe 
1073*07dc1947SRichard Lowe 
1074