summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdwarf/common/pro_expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libdwarf/common/pro_expr.c')
-rw-r--r--usr/src/lib/libdwarf/common/pro_expr.c386
1 files changed, 233 insertions, 153 deletions
diff --git a/usr/src/lib/libdwarf/common/pro_expr.c b/usr/src/lib/libdwarf/common/pro_expr.c
index ad40eb762a..6933b18e5e 100644
--- a/usr/src/lib/libdwarf/common/pro_expr.c
+++ b/usr/src/lib/libdwarf/common/pro_expr.c
@@ -1,51 +1,56 @@
/*
-
Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved.
Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of version 2.1 of the GNU Lesser General Public License
- as published by the Free Software Foundation.
-
- This program is distributed in the hope that it would be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- Further, this software is distributed without any warranty that it is
- free of the rightful claim of any third person regarding infringement
- or the like. Any license provided herein, whether implied or
- otherwise, applies only to this software file. Patent licenses, if
- any, provided herein do not apply to combinations of this program with
- other software, or any other product whatsoever.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this program; if not, write the Free Software
- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
- USA.
-
- Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
- Mountain View, CA 94043, or:
-
- http://www.sgi.com
-
- For further information regarding this notice, see:
-
- http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ Portions Copyright 2011-2019 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it
+ and/or modify it under the terms of version 2.1 of the
+ GNU Lesser General Public License as published by the Free
+ Software Foundation.
+
+ This program is distributed in the hope that it would be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ Further, this software is distributed without any warranty
+ that it is free of the rightful claim of any third person
+ regarding infringement or the like. Any license provided
+ herein, whether implied or otherwise, applies only to this
+ software file. Patent licenses, if any, provided herein
+ do not apply to combinations of this program with other
+ software, or any other product whatsoever.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this program; if not, write the
+ Free Software Foundation, Inc., 51 Franklin Street - Fifth
+ Floor, Boston MA 02110-1301, USA.
*/
-
-
#include "config.h"
#include "libdwarfdefs.h"
#include <stdio.h>
#include <string.h>
-#include <sys/types.h>
+#include <stddef.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h> /* For uintptr_t */
+#endif /* HAVE_STDINT_H */
#include "pro_incl.h"
+#include "dwarf.h"
+#include "libdwarf.h"
+#include "pro_opaque.h"
+#include "pro_error.h"
+#include "pro_encode_nm.h"
+#include "pro_alloc.h"
#include "pro_expr.h"
+#define SIZEOFT16 2
+#define SIZEOFT32 4
+#define SIZEOFT64 8
+
/*
- This function creates a new expression
+ This function creates a new expression
struct that can be used to build up a
location expression.
*/
@@ -71,55 +76,70 @@ dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error)
return (ret_expr);
}
-
Dwarf_Unsigned
dwarf_add_expr_gen(Dwarf_P_Expr expr,
- Dwarf_Small opcode,
- Dwarf_Unsigned val1,
- Dwarf_Unsigned val2, Dwarf_Error * error)
+ Dwarf_Small opcode,
+ Dwarf_Unsigned val1,
+ Dwarf_Unsigned val2, Dwarf_Error * error)
+{
+ Dwarf_Unsigned len = 0;
+ int res = 0;
+
+ res = dwarf_add_expr_gen_a(expr,opcode,
+ val1,val2,&len,error);
+ if (res != DW_DLV_OK) {
+ return DW_DLV_NOCOUNT;
+ }
+ return len;
+
+}
+
+int
+dwarf_add_expr_gen_a(Dwarf_P_Expr expr,
+ Dwarf_Small opcode,
+ Dwarf_Unsigned val1,
+ Dwarf_Unsigned val2,
+ Dwarf_Unsigned *stream_length_out,
+ Dwarf_Error * error)
{
- char encode_buffer[2 * ENCODE_SPACE_NEEDED]; /* 2* since
- used to
- concatenate
- 2 leb's
- below */
+ /* 2* since used to concatenate 2 leb's below */
+ char encode_buffer[2 * ENCODE_SPACE_NEEDED];
+
char encode_buffer2[ENCODE_SPACE_NEEDED];
- int res;
- Dwarf_P_Debug dbg = expr->ex_dbg;
+ int res = 0;
+ Dwarf_P_Debug dbg = 0;
- /*
- Give the buffer where the operands are first going to be
- assembled the largest alignment. */
+ /* Give the buffer where the operands are first going to be
+ assembled the largest alignment. */
Dwarf_Unsigned operand_buffer[10];
- /*
- Size of the byte stream buffer that needs to be memcpy-ed. */
- int operand_size;
+ /* Size of the byte stream buffer that needs to be memcpy-ed. */
+ int operand_size = 0;
- /*
- Points to the byte stream for the first operand, and finally to
- the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */
- Dwarf_Small *operand;
+ /* Points to the byte stream for the first operand, and finally to
+ the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */
+ Dwarf_Small *operand = 0;
- /* Size of the byte stream for second operand. */
- int operand2_size;
+ /* Size of the byte stream for second operand. */
+ int operand2_size = 0;
- /* Points to next byte to be written in Dwarf_P_Expr_s struct. */
- Dwarf_Small *next_byte_ptr;
+ /* Points to next byte to be written in Dwarf_P_Expr_s struct. */
+ Dwarf_Small *next_byte_ptr = 0;
- /* Offset past the last byte written into Dwarf_P_Expr_s. */
- int next_byte_offset;
+ /* Offset past the last byte written into Dwarf_P_Expr_s. */
+ int next_byte_offset = 0;
/* ***** BEGIN CODE ***** */
if (expr == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
+ dbg = expr->ex_dbg;
if (expr->ex_dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand = NULL;
@@ -193,23 +213,20 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
case DW_OP_breg30:
case DW_OP_breg31:
res = _dwarf_pro_encode_signed_leb128_nm(val1,
- &operand_size,
- encode_buffer,
- sizeof(encode_buffer));
+ &operand_size, encode_buffer, sizeof(encode_buffer));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand = (Dwarf_Small *) encode_buffer;
break;
case DW_OP_regx:
res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
- encode_buffer,
- sizeof(encode_buffer));
+ encode_buffer, sizeof(encode_buffer));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand = (Dwarf_Small *) encode_buffer;
break;
@@ -250,7 +267,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
case DW_OP_addr:
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
case DW_OP_const1u:
case DW_OP_const1s:
@@ -269,8 +286,9 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
case DW_OP_const4u:
case DW_OP_const4s:
operand = (Dwarf_Small *) & operand_buffer[0];
- WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
- operand_size = 4;
+ WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1),
+ SIZEOFT32);
+ operand_size = SIZEOFT32;
break;
case DW_OP_const8u:
@@ -282,58 +300,55 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
case DW_OP_constu:
res = _dwarf_pro_encode_leb128_nm(val1,
- &operand_size,
- encode_buffer,
- sizeof(encode_buffer));
+ &operand_size, encode_buffer, sizeof(encode_buffer));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand = (Dwarf_Small *) encode_buffer;
break;
case DW_OP_consts:
res = _dwarf_pro_encode_signed_leb128_nm(val1,
- &operand_size,
- encode_buffer,
- sizeof(encode_buffer));
+ &operand_size,
+ encode_buffer,
+ sizeof(encode_buffer));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand = (Dwarf_Small *) encode_buffer;
break;
case DW_OP_fbreg:
res = _dwarf_pro_encode_signed_leb128_nm(val1,
- &operand_size,
- encode_buffer,
- sizeof(encode_buffer));
+ &operand_size,
+ encode_buffer,
+ sizeof(encode_buffer));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand = (Dwarf_Small *) encode_buffer;
break;
case DW_OP_bregx:
res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
- encode_buffer,
- sizeof(encode_buffer));
+ encode_buffer,
+ sizeof(encode_buffer));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand = (Dwarf_Small *) encode_buffer;
/* put this one directly into 'operand' at tail of prev value */
res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size,
- ((char *) operand) +
- operand_size,
- sizeof
- (encode_buffer2));
+ ((char *) operand) +
+ operand_size,
+ sizeof(encode_buffer2));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand_size += operand2_size;
@@ -344,7 +359,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
case DW_OP_pick:
operand = (Dwarf_Small *) & operand_buffer[0];
WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
- sizeof(val1), 1);
+ sizeof(val1), 1);
operand_size = 1;
break;
@@ -359,7 +374,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
case DW_OP_xderef_size:
operand = (Dwarf_Small *) & operand_buffer[0];
WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
- sizeof(val1), 1);
+ sizeof(val1), 1);
operand_size = 1;
break;
@@ -377,11 +392,11 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
case DW_OP_plus_uconst:
res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
- encode_buffer,
- sizeof(encode_buffer));
+ encode_buffer,
+ sizeof(encode_buffer));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand = (Dwarf_Small *) encode_buffer;
break;
@@ -404,15 +419,15 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
case DW_OP_bra:
/* FIX: unhandled! OP_bra, OP_skip! */
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
case DW_OP_piece:
res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
- encode_buffer,
- sizeof(encode_buffer));
+ encode_buffer,
+ sizeof(encode_buffer));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand = (Dwarf_Small *) encode_buffer;
break;
@@ -423,21 +438,21 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
break;
case DW_OP_call2: /* DWARF3 */
operand = (Dwarf_Small *) & operand_buffer[0];
- WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
- operand_size = 2;
+ WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT16);
+ operand_size = SIZEOFT16;
break;
case DW_OP_call4: /* DWARF3 */
operand = (Dwarf_Small *) & operand_buffer[0];
- WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
- operand_size = 4;
+ WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT32);
+ operand_size = SIZEOFT32;
break;
case DW_OP_call_ref: /* DWARF3 */
operand = (Dwarf_Small *) & operand_buffer[0];
WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1),
- dbg->de_offset_size);
- operand_size = dbg->de_offset_size;
+ dbg->de_dwarf_offset_size);
+ operand_size = dbg->de_dwarf_offset_size;
break;
case DW_OP_form_tls_address: /* DWARF3f */
break;
@@ -445,35 +460,34 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
break;
case DW_OP_bit_piece: /* DWARF3f */
res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
- encode_buffer,
- sizeof(encode_buffer));
+ encode_buffer,
+ sizeof(encode_buffer));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand = (Dwarf_Small *) encode_buffer;
/* put this one directly into 'operand' at tail of prev value */
res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size,
- ((char *) operand) +
- operand_size,
- sizeof(encode_buffer2));
+ ((char *) operand) +
+ operand_size,
+ sizeof(encode_buffer2));
if (res != DW_DLV_OK) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
operand_size += operand2_size;
- break;
-
+ break;
default:
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
next_byte_offset = expr->ex_next_byte_offset + operand_size + 1;
if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
next_byte_ptr =
@@ -481,16 +495,38 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr,
*next_byte_ptr = opcode;
next_byte_ptr++;
- memcpy(next_byte_ptr, operand, operand_size);
+ if (operand) {
+ memcpy(next_byte_ptr, operand, operand_size);
+ }
expr->ex_next_byte_offset = next_byte_offset;
- return (next_byte_offset);
+ *stream_length_out = next_byte_offset;
+ return DW_DLV_OK;
}
Dwarf_Unsigned
dwarf_add_expr_addr_b(Dwarf_P_Expr expr,
- Dwarf_Unsigned addr,
- Dwarf_Unsigned sym_index, Dwarf_Error * error)
+ Dwarf_Unsigned addr,
+ Dwarf_Unsigned sym_index,
+ Dwarf_Error * error)
+{
+ Dwarf_Unsigned length = 0;
+ int res = 0;
+
+ res = dwarf_add_expr_addr_c(expr,addr,sym_index,
+ &length,error);
+ if (res != DW_DLV_OK) {
+ return DW_DLV_NOCOUNT;
+ }
+ return length;
+
+}
+int
+dwarf_add_expr_addr_c(Dwarf_P_Expr expr,
+ Dwarf_Unsigned addr,
+ Dwarf_Unsigned sym_index,
+ Dwarf_Unsigned *stream_length_out,
+ Dwarf_Error * error)
{
Dwarf_P_Debug dbg;
Dwarf_Small *next_byte_ptr;
@@ -499,20 +535,20 @@ dwarf_add_expr_addr_b(Dwarf_P_Expr expr,
if (expr == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
- return (DW_DLV_NOCOUNT);
+ return (DW_DLV_ERROR);
}
dbg = expr->ex_dbg;
if (dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
- return (DW_DLV_NOCOUNT);
+ return (DW_DLV_ERROR);
}
upointer_size = dbg->de_pointer_size;
next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1;
if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
_dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD);
- return (DW_DLV_NOCOUNT);
+ return (DW_DLV_ERROR);
}
next_byte_ptr =
@@ -521,77 +557,121 @@ dwarf_add_expr_addr_b(Dwarf_P_Expr expr,
*next_byte_ptr = DW_OP_addr;
next_byte_ptr++;
WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr,
- sizeof(addr), upointer_size);
+ sizeof(addr), upointer_size);
if (expr->ex_reloc_offset != 0) {
_dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR);
- return (DW_DLV_NOCOUNT);
+ return (DW_DLV_ERROR);
}
expr->ex_reloc_sym_index = sym_index;
expr->ex_reloc_offset = expr->ex_next_byte_offset + 1;
expr->ex_next_byte_offset = next_byte_offset;
- return (next_byte_offset);
+ *stream_length_out = next_byte_offset;
+ return DW_DLV_OK;
}
Dwarf_Unsigned
dwarf_add_expr_addr(Dwarf_P_Expr expr,
- Dwarf_Unsigned addr,
- Dwarf_Signed sym_index, Dwarf_Error * error)
+ Dwarf_Unsigned addr,
+ Dwarf_Signed sym_index,
+ Dwarf_Error * error)
{
- return
- dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index,
- error);
+ Dwarf_Unsigned length = 0;
+ int res = 0;
+ Dwarf_P_Debug dbg = 0;
+
+ if (sym_index < 0) {
+ _dwarf_p_error(dbg, error,
+ DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD);
+ return DW_DLV_NOCOUNT;
+ }
+ res = dwarf_add_expr_addr_c(expr,
+ (Dwarf_Unsigned)addr,
+ (Dwarf_Unsigned)sym_index,
+ &length,error);
+ if (res != DW_DLV_OK) {
+ return (Dwarf_Unsigned)DW_DLV_NOCOUNT;
+ }
+ return length;
}
-
Dwarf_Unsigned
dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error)
{
+ Dwarf_Unsigned l = 0;
+ int res = 0;
+
+ res = dwarf_expr_current_offset_a(expr,&l,error);
+ if (res != DW_DLV_OK) {
+ return (DW_DLV_NOCOUNT);
+ }
+ return l;
+}
+
+int
+dwarf_expr_current_offset_a(Dwarf_P_Expr expr,
+ Dwarf_Unsigned * stream_length_out,
+ Dwarf_Error * error)
+{
if (expr == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
if (expr->ex_dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
- return (DW_DLV_NOCOUNT);
+ return DW_DLV_ERROR;
}
-
- return (expr->ex_next_byte_offset);
+ *stream_length_out = expr->ex_next_byte_offset;
+ return DW_DLV_OK;
}
void
dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error)
{
- if (expr == NULL) {
- _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
- return;
- }
- expr->ex_next_byte_offset=0;
+ if (expr == NULL) {
+ _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+ return;
+ }
+ expr->ex_next_byte_offset=0;
}
-
Dwarf_Addr
dwarf_expr_into_block(Dwarf_P_Expr expr,
- Dwarf_Unsigned * length, Dwarf_Error * error)
+ Dwarf_Unsigned * length,
+ Dwarf_Error * error)
+{
+ Dwarf_Small *addr = 0;
+ int res = 0;
+
+ res = dwarf_expr_into_block_a(expr,length,&addr,error);
+ if (res != DW_DLV_OK) {
+ return (DW_DLV_BADADDR);
+ }
+ return (Dwarf_Addr)(uintptr_t)addr;
+}
+
+
+int
+dwarf_expr_into_block_a(Dwarf_P_Expr expr,
+ Dwarf_Unsigned * length,
+ Dwarf_Small ** address,
+ Dwarf_Error * error)
{
if (expr == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
- return (DW_DLV_BADADDR);
+ return DW_DLV_ERROR;
}
if (expr->ex_dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
- return (DW_DLV_BADADDR);
+ return DW_DLV_ERROR;
}
if (length != NULL)
*length = expr->ex_next_byte_offset;
- /* The following cast from pointer to integer is ok as long as
- Dwarf_Addr is at least as large as a pointer. Which is a
- requirement of libdwarf so must be satisfied (some compilers
- emit a warning about the following line). */
- return ((Dwarf_Addr)(uintptr_t) &(expr->ex_byte_stream[0]));
+ *address = &(expr->ex_byte_stream[0]);
+ return DW_DLV_OK;
}