summaryrefslogtreecommitdiff
path: root/usr/src/tools/ctf/dwarf/common/dwarf_arange.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/tools/ctf/dwarf/common/dwarf_arange.c')
-rw-r--r--usr/src/tools/ctf/dwarf/common/dwarf_arange.c593
1 files changed, 0 insertions, 593 deletions
diff --git a/usr/src/tools/ctf/dwarf/common/dwarf_arange.c b/usr/src/tools/ctf/dwarf/common/dwarf_arange.c
deleted file mode 100644
index e7ad8acc5e..0000000000
--- a/usr/src/tools/ctf/dwarf/common/dwarf_arange.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
-
- Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
- Portions Copyright (C) 2007-2010 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.
-
- 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
-
-*/
-/* The address of the Free Software Foundation is
- Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- Boston, MA 02110-1301, USA.
- SGI has moved from the Crittenden Lane address.
-*/
-
-
-
-
-
-
-#include "config.h"
-#include "dwarf_incl.h"
-#include <stdio.h>
-#include "dwarf_arange.h"
-#include "dwarf_global.h" /* for _dwarf_fixup_* */
-
-
-/* Common code for two user-visible routines to share.
- Errors here result in memory leaks, but errors here
- are serious (making aranges unusable) so we assume
- callers will not repeat the error often or mind the leaks.
-*/
-static int
-dwarf_get_aranges_list(Dwarf_Debug dbg,
- Dwarf_Chain * chain_out,
- Dwarf_Signed * chain_count_out,
- Dwarf_Error * error)
-{
- /* Sweeps through the arange. */
- Dwarf_Small *arange_ptr = 0;
- Dwarf_Small *arange_ptr_start = 0;
-
- /* Start of arange header. Used for rounding offset of arange_ptr
- to twice the tuple size. Libdwarf requirement. */
- Dwarf_Small *header_ptr = 0;
-
- /* Version of .debug_aranges header. */
- Dwarf_Half version = 0;
-
- /* Offset of current set of aranges into .debug_info. */
- Dwarf_Off info_offset = 0;
-
- /* Size in bytes of addresses in target. */
- Dwarf_Small address_size = 0;
-
- /* Size in bytes of segment offsets in target. */
- Dwarf_Small segment_size = 0;
-
- /* Count of total number of aranges. */
- Dwarf_Unsigned arange_count = 0;
-
- Dwarf_Arange arange = 0;
-
- /* Used to chain Dwarf_Aranges structs. */
- Dwarf_Chain curr_chain = NULL;
- Dwarf_Chain prev_chain = NULL;
- Dwarf_Chain head_chain = NULL;
-
- arange_ptr = dbg->de_debug_aranges.dss_data;
- arange_ptr_start = arange_ptr;
- do {
- /* Length of current set of aranges. */
- Dwarf_Unsigned length = 0;
- Dwarf_Small remainder = 0;
- Dwarf_Small *arange_ptr_past_end = 0;
- Dwarf_Unsigned range_entry_size = 0;
-
- int local_length_size;
-
- /*REFERENCED*/ /* Not used in this instance of the macro */
- int local_extension_size = 0;
-
- header_ptr = arange_ptr;
-
- /* READ_AREA_LENGTH updates arange_ptr for consumed bytes */
- READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
- arange_ptr, local_length_size,
- local_extension_size);
- arange_ptr_past_end = arange_ptr + length;
-
-
- READ_UNALIGNED(dbg, version, Dwarf_Half,
- arange_ptr, sizeof(Dwarf_Half));
- arange_ptr += sizeof(Dwarf_Half);
- length = length - sizeof(Dwarf_Half);
- if (version != CURRENT_VERSION_STAMP) {
- _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
- return (DW_DLV_ERROR);
- }
-
- READ_UNALIGNED(dbg, info_offset, Dwarf_Off,
- arange_ptr, local_length_size);
- arange_ptr += local_length_size;
- length = length - local_length_size;
- if (info_offset >= dbg->de_debug_info.dss_size) {
- FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset,
- "arange info offset.a");
- if (info_offset >= dbg->de_debug_info.dss_size) {
- _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
- return (DW_DLV_ERROR);
- }
- }
-
- address_size = *(Dwarf_Small *) arange_ptr;
- /* It is not an error if the sizes differ.
- Unusual, but not an error. */
- arange_ptr = arange_ptr + sizeof(Dwarf_Small);
- length = length - sizeof(Dwarf_Small);
-
- segment_size = *(Dwarf_Small *) arange_ptr;
- arange_ptr = arange_ptr + sizeof(Dwarf_Small);
- length = length - sizeof(Dwarf_Small);
- if (segment_size != 0) {
- _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
- return (DW_DLV_ERROR);
- }
-
- range_entry_size = 2*address_size + segment_size;
- /* Round arange_ptr offset to next multiple of address_size. */
- remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) %
- (range_entry_size);
- if (remainder != 0) {
- arange_ptr = arange_ptr + (2 * address_size) - remainder;
- length = length - ((2 * address_size) - remainder);
- }
- do {
- Dwarf_Addr range_address = 0;
- Dwarf_Unsigned segment_selector = 0;
- Dwarf_Unsigned range_length = 0;
- /* For segmented address spaces, the first field to
- read is a segment selector (new in DWARF4) */
- if(version == 4 && segment_size != 0) {
- READ_UNALIGNED(dbg, segment_selector, Dwarf_Unsigned,
- arange_ptr, segment_size);
- arange_ptr += address_size;
- length = length - address_size;
- }
-
- READ_UNALIGNED(dbg, range_address, Dwarf_Addr,
- arange_ptr, address_size);
- arange_ptr += address_size;
- length = length - address_size;
-
- READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned,
- arange_ptr, address_size);
- arange_ptr += address_size;
- length = length - address_size;
-
- { /* We used to suppress all-zero entries, but
- now we return all aranges entries so we show
- the entire content. March 31, 2010. */
-
- arange = (Dwarf_Arange)
- _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
- if (arange == NULL) {
- _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
- return (DW_DLV_ERROR);
- }
-
- arange->ar_segment_selector = segment_selector;
- arange->ar_segment_selector_size = segment_size;
- arange->ar_address = range_address;
- arange->ar_length = range_length;
- arange->ar_info_offset = info_offset;
- arange->ar_dbg = dbg;
- arange_count++;
-
- curr_chain = (Dwarf_Chain)
- _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
- if (curr_chain == NULL) {
- _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
- return (DW_DLV_ERROR);
- }
-
- curr_chain->ch_item = arange;
- if (head_chain == NULL)
- head_chain = prev_chain = curr_chain;
- else {
- prev_chain->ch_next = curr_chain;
- prev_chain = curr_chain;
- }
- }
- /* The current set of ranges is terminated by
- range_address 0 and range_length 0, but that
- does not necessarily terminate the ranges for this CU!
- There can be multiple sets in that DWARF
- does not explicitly forbid multiple sets.
- DWARF2,3,4 section 7.20
- We stop short to avoid overrun of the end of the CU.
- */
-
- } while (arange_ptr_past_end >= (arange_ptr + range_entry_size));
-
- /* A compiler could emit some padding bytes here. dwarf2/3
- (dwarf4 sec 7.20) does not clearly make extra padding
- bytes illegal. */
- if (arange_ptr_past_end < arange_ptr) {
- char buf[200];
- Dwarf_Unsigned pad_count = arange_ptr - arange_ptr_past_end;
- Dwarf_Unsigned offset = arange_ptr - arange_ptr_start;
- snprintf(buf,sizeof(buf),"DW_DLE_ARANGE_LENGTH_BAD."
- " 0x%" DW_PR_DUx
- " pad bytes at offset 0x%" DW_PR_DUx
- " in .debug_aranges",
- pad_count, offset);
- dwarf_insert_harmless_error(dbg,buf);
- }
- /* For most compilers, arange_ptr == arange_ptr_past_end at
- this point. But not if there were padding bytes */
- arange_ptr = arange_ptr_past_end;
- } while (arange_ptr <
- dbg->de_debug_aranges.dss_data + dbg->de_debug_aranges.dss_size);
-
- if (arange_ptr !=
- dbg->de_debug_aranges.dss_data + dbg->de_debug_aranges.dss_size) {
- _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
- return (DW_DLV_ERROR);
- }
- *chain_out = head_chain;
- *chain_count_out = arange_count;
- return DW_DLV_OK;
-}
-
-/*
- This function returns the count of the number of
- aranges in the .debug_aranges section. It sets
- aranges to point to a block of Dwarf_Arange's
- describing the arange's. It returns DW_DLV_ERROR
- on error.
-
- Must be identical in most aspects to
- dwarf_get_aranges_addr_offsets!
-
-*/
-int
-dwarf_get_aranges(Dwarf_Debug dbg,
- Dwarf_Arange ** aranges,
- Dwarf_Signed * returned_count, Dwarf_Error * error)
-{
- /* Count of total number of aranges. */
- Dwarf_Signed arange_count = 0;
-
- Dwarf_Arange *arange_block = 0;
-
- /* Used to chain Dwarf_Aranges structs. */
- Dwarf_Chain curr_chain = NULL;
- Dwarf_Chain prev_chain = NULL;
- Dwarf_Chain head_chain = NULL;
- Dwarf_Unsigned i = 0;
- int res = DW_DLV_ERROR;
-
- /* ***** BEGIN CODE ***** */
-
- if (dbg == NULL) {
- _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
- return (DW_DLV_ERROR);
- }
-
- res = _dwarf_load_section(dbg, &dbg->de_debug_aranges, error);
- if (res != DW_DLV_OK) {
- return res;
- }
-
- res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error);
- if(res != DW_DLV_OK) {
- return res;
- }
-
- arange_block = (Dwarf_Arange *)
- _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count);
- if (arange_block == NULL) {
- _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
- return (DW_DLV_ERROR);
- }
-
- curr_chain = head_chain;
- for (i = 0; i < arange_count; i++) {
- *(arange_block + i) = curr_chain->ch_item;
- prev_chain = curr_chain;
- curr_chain = curr_chain->ch_next;
- dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
- }
-
- *aranges = arange_block;
- *returned_count = (arange_count);
- return DW_DLV_OK;
-}
-
-/*
- This function returns DW_DLV_OK if it succeeds
- and DW_DLV_ERR or DW_DLV_OK otherwise.
- count is set to the number of addresses in the
- .debug_aranges section.
- For each address, the corresponding element in
- an array is set to the address itself(aranges) and
- the section offset (offsets).
- Must be identical in most aspects to
- dwarf_get_aranges!
-*/
-int
-_dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,
- Dwarf_Addr ** addrs,
- Dwarf_Off ** offsets,
- Dwarf_Signed * count,
- Dwarf_Error * error)
-{
- Dwarf_Unsigned i = 0;
-
- /* Used to chain Dwarf_Aranges structs. */
- Dwarf_Chain curr_chain = NULL;
- Dwarf_Chain prev_chain = NULL;
- Dwarf_Chain head_chain = NULL;
-
- Dwarf_Signed arange_count = 0;
- Dwarf_Addr *arange_addrs = 0;
- Dwarf_Off *arange_offsets = 0;
-
- int res = DW_DLV_ERROR;
-
- /* ***** BEGIN CODE ***** */
-
- if (error != NULL)
- *error = NULL;
-
- if (dbg == NULL) {
- _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
- return (DW_DLV_ERROR);
- }
-
- res = _dwarf_load_section(dbg, &dbg->de_debug_aranges,error);
- if (res != DW_DLV_OK) {
- return res;
- }
-
- res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error);
- if(res != DW_DLV_OK) {
- return res;
- }
-
- arange_addrs = (Dwarf_Addr *)
- _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
- if (arange_addrs == NULL) {
- _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
- return (DW_DLV_ERROR);
- }
- arange_offsets = (Dwarf_Off *)
- _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
- if (arange_offsets == NULL) {
- _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
- return (DW_DLV_ERROR);
- }
-
- curr_chain = head_chain;
- for (i = 0; i < arange_count; i++) {
- Dwarf_Arange ar = curr_chain->ch_item;
-
- arange_addrs[i] = ar->ar_address;
- arange_offsets[i] = ar->ar_info_offset;
- prev_chain = curr_chain;
- curr_chain = curr_chain->ch_next;
- dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
- dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
- }
- *count = arange_count;
- *offsets = arange_offsets;
- *addrs = arange_addrs;
- return (DW_DLV_OK);
-}
-
-
-/*
- This function takes a pointer to a block
- of Dwarf_Arange's, and a count of the
- length of the block. It checks if the
- given address is within the range of an
- address range in the block. If yes, it
- returns the appropriate Dwarf_Arange.
- Otherwise, it returns DW_DLV_ERROR.
-*/
-int
-dwarf_get_arange(Dwarf_Arange * aranges,
- Dwarf_Unsigned arange_count,
- Dwarf_Addr address,
- Dwarf_Arange * returned_arange, Dwarf_Error * error)
-{
- Dwarf_Arange curr_arange = 0;
- Dwarf_Unsigned i = 0;
-
- if (aranges == NULL) {
- _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL);
- return (DW_DLV_ERROR);
- }
- for (i = 0; i < arange_count; i++) {
- curr_arange = *(aranges + i);
- if (address >= curr_arange->ar_address &&
- address <
- curr_arange->ar_address + curr_arange->ar_length) {
- *returned_arange = curr_arange;
- return (DW_DLV_OK);
- }
- }
-
- return (DW_DLV_NO_ENTRY);
-}
-
-
-/*
- This function takes an Dwarf_Arange,
- and returns the offset of the first
- die in the compilation-unit that the
- arange belongs to. Returns DW_DLV_ERROR
- on error.
-*/
-int
-dwarf_get_cu_die_offset(Dwarf_Arange arange,
- Dwarf_Off * returned_offset,
- Dwarf_Error * error)
-{
- Dwarf_Debug dbg = 0;
- Dwarf_Off offset = 0;
-
- if (arange == NULL) {
- _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
- return (DW_DLV_ERROR);
- }
- dbg = arange->ar_dbg;
- offset = arange->ar_info_offset;
- if (!dbg->de_debug_info.dss_data) {
- int res = _dwarf_load_debug_info(dbg, error);
-
- if (res != DW_DLV_OK) {
- return res;
- }
- }
- *returned_offset = offset + _dwarf_length_of_cu_header(dbg, offset);
- return DW_DLV_OK;
-}
-
-/*
- This function takes an Dwarf_Arange,
- and returns the offset of the CU header
- in the compilation-unit that the
- arange belongs to. Returns DW_DLV_ERROR
- on error.
- Ensures .debug_info loaded so
- the cu_offset is meaningful.
-*/
-int
-dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,
- Dwarf_Off * cu_header_offset_returned,
- Dwarf_Error * error)
-{
- Dwarf_Debug dbg = 0;
- if (arange == NULL) {
- _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
- return (DW_DLV_ERROR);
- }
- dbg = arange->ar_dbg;
- /* Like dwarf_get_arange_info this ensures debug_info loaded:
- the cu_header is in debug_info and will be used else
- we would not call dwarf_get_arange_cu_header_offset. */
- if (!dbg->de_debug_info.dss_data) {
- int res = _dwarf_load_debug_info(dbg, error);
- if (res != DW_DLV_OK) {
- return res;
- }
- }
- *cu_header_offset_returned = arange->ar_info_offset;
- return DW_DLV_OK;
-}
-
-
-
-
-/*
- This function takes a Dwarf_Arange, and returns
- true if it is not NULL. It also stores the start
- address of the range in *start, the length of the
- range in *length, and the offset of the first die
- in the compilation-unit in *cu_die_offset. It
- returns false on error.
- If cu_die_offset returned ensures .debug_info loaded so
- the cu_die_offset is meaningful.
-*/
-int
-dwarf_get_arange_info(Dwarf_Arange arange,
- Dwarf_Addr * start,
- Dwarf_Unsigned * length,
- Dwarf_Off * cu_die_offset, Dwarf_Error * error)
-{
- if (arange == NULL) {
- _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
- return (DW_DLV_ERROR);
- }
-
- if (start != NULL)
- *start = arange->ar_address;
- if (length != NULL)
- *length = arange->ar_length;
- if (cu_die_offset != NULL) {
- Dwarf_Debug dbg = arange->ar_dbg;
- Dwarf_Off offset = arange->ar_info_offset;
-
- if (!dbg->de_debug_info.dss_data) {
- int res = _dwarf_load_debug_info(dbg, error);
- if (res != DW_DLV_OK) {
- return res;
- }
- }
- *cu_die_offset =
- offset + _dwarf_length_of_cu_header(dbg, offset);
- }
- return (DW_DLV_OK);
-}
-
-
-/* New for DWARF4, entries may have segment information.
- *segment is only meaningful if *segment_entry_size is non-zero. */
-int
-dwarf_get_arange_info_b(Dwarf_Arange arange,
- Dwarf_Unsigned* segment,
- Dwarf_Unsigned* segment_entry_size,
- Dwarf_Addr * start,
- Dwarf_Unsigned* length,
- Dwarf_Off * cu_die_offset,
- Dwarf_Error * error)
-{
- if (arange == NULL) {
- _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
- return (DW_DLV_ERROR);
- }
-
- if(segment != NULL) {
- *segment = arange->ar_segment_selector;
- }
- if(segment_entry_size != NULL) {
- *segment_entry_size = arange->ar_segment_selector_size;
- }
- if (start != NULL)
- *start = arange->ar_address;
- if (length != NULL)
- *length = arange->ar_length;
- if (cu_die_offset != NULL) {
- Dwarf_Debug dbg = arange->ar_dbg;
- Dwarf_Off offset = arange->ar_info_offset;
-
- if (!dbg->de_debug_info.dss_data) {
- int res = _dwarf_load_debug_info(dbg, error);
- if (res != DW_DLV_OK) {
- return res;
- }
- }
- *cu_die_offset =
- offset + _dwarf_length_of_cu_header(dbg, offset);
- }
- return (DW_DLV_OK);
-}