summaryrefslogtreecommitdiff
path: root/usr/src/tools/ctf/dwarf/common/dwarf_global.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/tools/ctf/dwarf/common/dwarf_global.c')
-rw-r--r--usr/src/tools/ctf/dwarf/common/dwarf_global.c607
1 files changed, 0 insertions, 607 deletions
diff --git a/usr/src/tools/ctf/dwarf/common/dwarf_global.c b/usr/src/tools/ctf/dwarf/common/dwarf_global.c
deleted file mode 100644
index d1c090fa43..0000000000
--- a/usr/src/tools/ctf/dwarf/common/dwarf_global.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
-
- Copyright (C) 2000-2005 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_global.h"
-
-
-#ifdef __sgi /* __sgi should only be defined for IRIX/MIPS. */
-/* The 'fixup' here intended for IRIX targets only.
- With a 2+GB Elf64 IRIX executable (under 4GB in size),
- some DIE offsets wrongly
- got the 32bit upper bit sign extended. For the cu-header
- offset in the .debug_pubnames section and in the
- .debug_aranges section.
- the 'varp' here is a pointer to an offset into .debug_info.
- We fix up the offset here if it seems advisable..
-
- As of June 2005 we have identified a series of mistakes
- in ldx64 that can cause this (64 bit values getting passed
- thru 32-bit signed knothole).
-*/
-void
-_dwarf_fix_up_offset_irix(Dwarf_Debug dbg,
- Dwarf_Unsigned * varp, char *caller_site_name)
-{
-
- Dwarf_Unsigned var = *varp;
-
-#define UPPER33 0xffffffff80000000LL
-#define LOWER32 0xffffffffLL
- /* Restrict the hack to the known case. Upper 32 bits erroneously
- sign extended from lower 32 upper bit. */
- if ((var & UPPER33) == UPPER33) {
- var &= LOWER32;
- /* Apply the fix. Dreadful hack. */
- *varp = var;
- }
-#undef UPPER33
-#undef LOWER32
- return;
-}
-#endif
-
-
-int
-dwarf_get_globals(Dwarf_Debug dbg,
- Dwarf_Global ** globals,
- Dwarf_Signed * return_count, Dwarf_Error * error)
-{
- int res = _dwarf_load_section(dbg, &dbg->de_debug_pubnames,error);
- if (res != DW_DLV_OK) {
- return res;
- }
-
- return _dwarf_internal_get_pubnames_like_data(dbg,
- dbg->de_debug_pubnames.dss_data,
- dbg->de_debug_pubnames.dss_size,
- globals,
- return_count,
- error,
- DW_DLA_GLOBAL_CONTEXT,
- DW_DLA_GLOBAL,
- DW_DLE_PUBNAMES_LENGTH_BAD,
- DW_DLE_PUBNAMES_VERSION_ERROR);
-
-}
-
-/* Deallocating fully requires deallocating the list
- and all entries. But some internal data is
- not exposed, so we need a function with internal knowledge.
-*/
-
-void
-dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
- Dwarf_Signed count)
-{
- _dwarf_internal_globals_dealloc(dbg, dwgl,
- count,
- DW_DLA_GLOBAL_CONTEXT,
- DW_DLA_GLOBAL, DW_DLA_LIST);
- return;
-}
-
-void
-_dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
- Dwarf_Signed count,
- int context_code,
- int global_code, int list_code)
-{
- Dwarf_Signed i;
- struct Dwarf_Global_Context_s *gcp = 0;
- struct Dwarf_Global_Context_s *lastgcp = 0;
-
- for (i = 0; i < count; i++) {
- Dwarf_Global dgb = dwgl[i];
-
- gcp = dgb->gl_context;
-
- if (lastgcp != gcp) {
- lastgcp = gcp;
- dwarf_dealloc(dbg, gcp, context_code);
- }
- dwarf_dealloc(dbg, dgb, global_code);
- }
- dwarf_dealloc(dbg, dwgl, list_code);
- return;
-}
-
-
-/* Sweeps the complete section.
-*/
-int
-_dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg,
- Dwarf_Small * section_data_ptr,
- Dwarf_Unsigned section_length,
- Dwarf_Global ** globals,
- Dwarf_Signed * return_count,
- Dwarf_Error * error,
- int context_code,
- int global_code,
- int length_err_num,
- int version_err_num)
-{
-
-
- Dwarf_Small *pubnames_like_ptr = 0;
-
-
-
- /* Points to the context for the current set of global names, and
- contains information to identify the compilation-unit that the
- set refers to. */
- Dwarf_Global_Context pubnames_context = 0;
-
- Dwarf_Half version = 0;
-
- /*
- Offset from the start of compilation-unit for the current
- global. */
- Dwarf_Off die_offset_in_cu = 0;
-
- Dwarf_Unsigned global_count = 0;
-
- /* Points to the current global read. */
- Dwarf_Global global = 0;
-
- /* Used to chain the Dwarf_Global_s structs for creating contiguous
- list of pointers to the structs. */
- Dwarf_Chain curr_chain = 0;
- Dwarf_Chain prev_chain = 0;
- Dwarf_Chain head_chain = 0;
-
- /* Points to contiguous block of Dwarf_Global's to be returned. */
- Dwarf_Global *ret_globals = 0;
-
- /* Temporary counter. */
- Dwarf_Unsigned i = 0;
-
-
-
-
- if (dbg == NULL) {
- _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
- return (DW_DLV_ERROR);
- }
- /* We will eventually need the .debug_info data. Load it now. */
- if (!dbg->de_debug_info.dss_data) {
- int res = _dwarf_load_debug_info(dbg, error);
-
- if (res != DW_DLV_OK) {
- return res;
- }
- }
-
- if (section_data_ptr == NULL) {
- return (DW_DLV_NO_ENTRY);
- }
-
- pubnames_like_ptr = section_data_ptr;
- do {
- Dwarf_Unsigned length = 0;
- int local_extension_size = 0;
- int local_length_size = 0;
-
- /* Some compilers emit padding at the end of each cu's area.
- pubnames_ptr_past_end_cu records the true area end for this
- cu's data. Essentially the length in the header and the 0
- terminator of the data are redundant information. The
- dwarf2/3 spec does not mention what to do if the length is
- past the 0 terminator. So we take any bytes left after the 0
- as padding and ignore them. */
- Dwarf_Small *pubnames_ptr_past_end_cu = 0;
-
-
- pubnames_context = (Dwarf_Global_Context)
- _dwarf_get_alloc(dbg, context_code, 1);
- if (pubnames_context == NULL) {
- _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
- return (DW_DLV_ERROR);
- }
- /* READ_AREA_LENGTH updates pubnames_like_ptr for consumed
- bytes. */
- READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
- pubnames_like_ptr, local_length_size,
- local_extension_size);
- pubnames_context->pu_length_size = local_length_size;
- pubnames_context->pu_extension_size = local_extension_size;
- pubnames_context->pu_dbg = dbg;
-
- pubnames_ptr_past_end_cu = pubnames_like_ptr + length;
-
- READ_UNALIGNED(dbg, version, Dwarf_Half,
- pubnames_like_ptr, sizeof(Dwarf_Half));
- pubnames_like_ptr += sizeof(Dwarf_Half);
- if (version != CURRENT_VERSION_STAMP) {
- _dwarf_error(dbg, error, version_err_num);
- return (DW_DLV_ERROR);
- }
-
- /* Offset of CU header in debug section. */
- READ_UNALIGNED(dbg, pubnames_context->pu_offset_of_cu_header,
- Dwarf_Off, pubnames_like_ptr,
- pubnames_context->pu_length_size);
- pubnames_like_ptr += pubnames_context->pu_length_size;
-
- FIX_UP_OFFSET_IRIX_BUG(dbg,
- pubnames_context->pu_offset_of_cu_header,
- "pubnames cu header offset");
-
-
- READ_UNALIGNED(dbg, pubnames_context->pu_info_length,
- Dwarf_Unsigned, pubnames_like_ptr,
- pubnames_context->pu_length_size);
- pubnames_like_ptr += pubnames_context->pu_length_size;
-
- if (pubnames_like_ptr > (section_data_ptr + section_length)) {
- _dwarf_error(dbg, error, length_err_num);
- return (DW_DLV_ERROR);
- }
-
- /* Read initial offset (of DIE within CU) of a pubname, final
- entry is not a pair, just a zero offset. */
- READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
- pubnames_like_ptr,
- pubnames_context->pu_length_size);
- pubnames_like_ptr += pubnames_context->pu_length_size;
- FIX_UP_OFFSET_IRIX_BUG(dbg,
- die_offset_in_cu, "offset of die in cu");
-
- /* Loop thru pairs. DIE off with CU followed by string. */
- while (die_offset_in_cu != 0) {
-
- /* Already read offset, pubnames_like_ptr now points to the
- string. */
- global =
- (Dwarf_Global) _dwarf_get_alloc(dbg, global_code, 1);
- if (global == NULL) {
- _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
- return (DW_DLV_ERROR);
- }
- global_count++;
-
- global->gl_context = pubnames_context;
-
- global->gl_named_die_offset_within_cu = die_offset_in_cu;
-
- global->gl_name = pubnames_like_ptr;
-
- pubnames_like_ptr = pubnames_like_ptr +
- strlen((char *) pubnames_like_ptr) + 1;
-
-
- /* finish off current entry chain */
- 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);
- }
-
- /* Put current global on singly_linked list. */
- curr_chain->ch_item = (Dwarf_Global) global;
-
- if (head_chain == NULL)
- head_chain = prev_chain = curr_chain;
- else {
- prev_chain->ch_next = curr_chain;
- prev_chain = curr_chain;
- }
-
- /* read offset for the *next* entry */
- READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
- pubnames_like_ptr,
- pubnames_context->pu_length_size);
-
- pubnames_like_ptr += pubnames_context->pu_length_size;
- FIX_UP_OFFSET_IRIX_BUG(dbg,
- die_offset_in_cu,
- "offset of next die in cu");
-
- if (pubnames_like_ptr > (section_data_ptr + section_length)) {
- _dwarf_error(dbg, error, length_err_num);
- return (DW_DLV_ERROR);
- }
- }
- /* ASSERT: die_offset_in_cu == 0 */
- if (pubnames_like_ptr > pubnames_ptr_past_end_cu) {
- /* This is some kind of error. This simply cannot happen.
- The encoding is wrong or the length in the header for
- this cu's contribution is wrong. */
- _dwarf_error(dbg, error, length_err_num);
- return (DW_DLV_ERROR);
- }
- /* If there is some kind of padding at the end of the section,
- as emitted by some compilers, skip over that padding and
- simply ignore the bytes thus passed-over. With most
- compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at
- this point */
- pubnames_like_ptr = pubnames_ptr_past_end_cu;
-
- } while (pubnames_like_ptr < (section_data_ptr + section_length));
-
- /* Points to contiguous block of Dwarf_Global's. */
- ret_globals = (Dwarf_Global *)
- _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count);
- if (ret_globals == NULL) {
- _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
- return (DW_DLV_ERROR);
- }
-
- /*
- Store pointers to Dwarf_Global_s structs in contiguous block,
- and deallocate the chain. */
- curr_chain = head_chain;
- for (i = 0; i < global_count; i++) {
- *(ret_globals + i) = curr_chain->ch_item;
- prev_chain = curr_chain;
- curr_chain = curr_chain->ch_next;
- dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
- }
-
- *globals = ret_globals;
- *return_count = (Dwarf_Signed) global_count;
- return DW_DLV_OK;
-}
-
-
-/*
- Given a pubnames entry (or other like section entry)
- return thru the ret_name pointer
- a pointer to the string which is the entry name.
-
-*/
-int
-dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error)
-{
- if (glob == NULL) {
- _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
- return (DW_DLV_ERROR);
- }
-
- *ret_name = (char *) (glob->gl_name);
- return DW_DLV_OK;
-}
-
-
-/*
- Given a pubnames entry (or other like section entry)
- return thru the ret_off pointer the
- global offset of the DIE for this entry.
- The global offset is the offset within the .debug_info
- section as a whole.
-*/
-int
-dwarf_global_die_offset(Dwarf_Global global,
- Dwarf_Off * ret_off, Dwarf_Error * error)
-{
- if (global == NULL) {
- _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
- return (DW_DLV_ERROR);
- }
-
- if (global->gl_context == NULL) {
- _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
- return (DW_DLV_ERROR);
- }
-
- *ret_off = (global->gl_named_die_offset_within_cu +
- global->gl_context->pu_offset_of_cu_header);
- return DW_DLV_OK;
-}
-
-/*
- Given a pubnames entry (or other like section entry)
- return thru the ret_off pointer the
- offset of the compilation unit header of the
- compilation unit the global is part of.
-
- In early versions of this, the value returned was
- the offset of the compilation unit die, and
- other cu-local die offsets were faked so adding this to
- such a cu-local offset got a true section offset.
- Now things do as they say (adding *cu_header_offset to
- a cu-local offset gets the section offset).
-
-*/
-int
-dwarf_global_cu_offset(Dwarf_Global global,
- Dwarf_Off * cu_header_offset,
- Dwarf_Error * error)
-{
- Dwarf_Global_Context con = 0;
-
- if (global == NULL) {
- _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
- return (DW_DLV_ERROR);
- }
-
- con = global->gl_context;
-
- if (con == NULL) {
- _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
- return (DW_DLV_ERROR);
- }
-
- /* In early libdwarf, this incorrectly returned the offset of the
- CU DIE. Now correctly returns the header offset. */
- *cu_header_offset = con->pu_offset_of_cu_header;
-
- return DW_DLV_OK;
-}
-
-/*
- Give back the pubnames entry (or any other like section)
- name, symbol DIE offset, and the cu-DIE offset.
-
- Various errors are possible.
-
- The string pointer returned thru ret_name is not
- dwarf_get_alloc()ed, so no dwarf_dealloc()
- DW_DLA_STRING should be applied to it.
-
-*/
-int
-dwarf_global_name_offsets(Dwarf_Global global,
- char **ret_name,
- Dwarf_Off * die_offset,
- Dwarf_Off * cu_die_offset,
- Dwarf_Error * error)
-{
- Dwarf_Global_Context con = 0;
- Dwarf_Debug dbg = 0;
- Dwarf_Off off = 0;
-
- if (global == NULL) {
- _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
- return (DW_DLV_ERROR);
- }
-
- con = global->gl_context;
-
- if (con == NULL) {
- _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
- return (DW_DLV_ERROR);
- }
-
- off = con->pu_offset_of_cu_header;
- /* The offset had better not be too close to the end. If it is,
- _dwarf_length_of_cu_header() will step off the end and therefore
- must not be used. 10 is a meaningless heuristic, but no CU
- header is that small so it is safe. An erroneous offset is due
- to a bug in the tool chain. A bug like this has been seen on
- IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and
- with 2 million pubnames entries. */
-#define MIN_CU_HDR_SIZE 10
- dbg = con->pu_dbg;
- if (dbg == NULL) {
- _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
- return (DW_DLV_ERROR);
- }
- if (dbg->de_debug_info.dss_size &&
- ((off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info.dss_size)) {
- _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD);
- return (DW_DLV_ERROR);
- }
-#undef MIN_CU_HDR_SIZE
- if (die_offset != NULL) {
- *die_offset = global->gl_named_die_offset_within_cu + off;
- }
-
- *ret_name = (char *) global->gl_name;
-
- if (cu_die_offset != NULL) {
- int res = _dwarf_load_debug_info(dbg, error);
-
- if (res != DW_DLV_OK) {
- return res;
- }
- /* The offset had better not be too close to the end. If it is,
- _dwarf_length_of_cu_header() will step off the end and
- therefore must not be used. 10 is a meaningless heuristic,
- but no CU header is that small so it is safe. */
- if ((off + 10) >= dbg->de_debug_info.dss_size) {
- _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD);
- return (DW_DLV_ERROR);
- }
- *cu_die_offset = off + _dwarf_length_of_cu_header(dbg, off);
- }
-
-
- return DW_DLV_OK;
-}
-
-/*
- We have the offset to a CU header.
- Return thru outFileOffset the offset of the CU DIE.
-
- New June, 2001.
- Used by SGI debuggers.
- No error is possible.
-
- See also dwarf_CU_dieoffset_given_die().
-*/
-
-/* ARGSUSED */
-int
-dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
- Dwarf_Off in_cu_header_offset,
- Dwarf_Off * out_cu_die_offset,
- Dwarf_Error * err)
-{
- Dwarf_Off len =
- _dwarf_length_of_cu_header(dbg, in_cu_header_offset);
-
- Dwarf_Off newoff = in_cu_header_offset + len;
-
- *out_cu_die_offset = newoff;
- return DW_DLV_OK;
-}
-/* dwarf_CU_dieoffset_given_die returns
- the global debug_info section offset of the CU die
- that is the CU containing the given (passed-in) die.
- This information makes it possible for a consumer to
- find and print context information for any die.
-
- Use dwarf_offdie() passing in the offset this returns
- to get a die pointer to the CU die.
- */
-int
-dwarf_CU_dieoffset_given_die(Dwarf_Die die,
- Dwarf_Off* return_offset,
- Dwarf_Error* error)
-{
- Dwarf_Off dieoff = 0;
- Dwarf_CU_Context cucontext = 0;
-
- CHECK_DIE(die, DW_DLV_ERROR);
- cucontext = die->di_cu_context;
- dieoff = cucontext->cc_debug_info_offset;
- /* The following call cannot fail, so no error check. */
- dwarf_get_cu_die_offset_given_cu_header_offset(
- cucontext->cc_dbg, dieoff, return_offset,error);
- return DW_DLV_OK;
-}