07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Copyright (C) 2008-2010 David Anderson. All Rights Reserved.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This program is free software; you can redistribute it and/or modify it
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe under the terms of version 2.1 of the GNU Lesser General Public License
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe as published by the Free Software Foundation.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This program is distributed in the hope that it would be useful, but
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe WITHOUT ANY WARRANTY; without even the implied warranty of
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Further, this software is distributed without any warranty that it is
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free of the rightful claim of any third person regarding infringement
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe or the like. Any license provided herein, whether implied or
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe otherwise, applies only to this software file. Patent licenses, if
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe any, provided herein do not apply to combinations of this program with
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe other software, or any other product whatsoever.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe You should have received a copy of the GNU Lesser General Public
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe License along with this program; if not, write the Free Software
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe USA.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Mountain View, CA 94043, or:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe http://www.sgi.com
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe For further information regarding this notice, see:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe http://oss.sgi.com/projects/GenInfo/NoticeExplan
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/* The address of the Free Software Foundation is
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Boston, MA 02110-1301, USA.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe SGI has moved from the Crittenden Lane address.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include "config.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <stdlib.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include "dwarf_incl.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestruct ranges_entry {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct ranges_entry *next;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Ranges cur;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe};
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweint dwarf_get_ranges_a(Dwarf_Debug dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Off rangesoffset,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Die die,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Ranges ** rangesbuf,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Signed * listlen,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned * bytecount,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Error * error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *rangeptr = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *beginrangeptr = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *section_end = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned entry_count = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct ranges_entry *base = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct ranges_entry *last = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct ranges_entry *curre = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Ranges * ranges_data_out = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned copyindex = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Half address_size = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int res = DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe res = _dwarf_load_section(dbg, &dbg->de_debug_ranges,error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (res != DW_DLV_OK) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return res;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(rangesoffset >= dbg->de_debug_ranges.dss_size) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe address_size = _dwarf_get_address_size(dbg, die);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe section_end = dbg->de_debug_ranges.dss_data +
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dbg->de_debug_ranges.dss_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe rangeptr = dbg->de_debug_ranges.dss_data + rangesoffset;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe beginrangeptr = rangeptr;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe for(;;) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct ranges_entry * re = calloc(sizeof(struct ranges_entry),1);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!re) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(rangeptr >= section_end) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (DW_DLV_NO_ENTRY);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if((rangeptr + (2*address_size)) > section_end) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe entry_count++;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe READ_UNALIGNED(dbg,re->cur.dwr_addr1,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Addr, rangeptr,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe address_size);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe rangeptr += address_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe READ_UNALIGNED(dbg,re->cur.dwr_addr2 ,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Addr, rangeptr,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe address_size);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe rangeptr += address_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!base) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe base = re;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe last = re;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe } else {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe last->next = re;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe last = re;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(re->cur.dwr_addr1 == 0 && re->cur.dwr_addr2 == 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe re->cur.dwr_type = DW_RANGES_END;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe } else if ( re->cur.dwr_addr1 == MAX_ADDR) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe re->cur.dwr_type = DW_RANGES_ADDRESS_SELECTION;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe } else {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe re->cur.dwr_type = DW_RANGES_ENTRY;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ranges_data_out = (Dwarf_Ranges *)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_get_alloc(dbg,DW_DLA_RANGES,entry_count);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!ranges_data_out) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe curre = base;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *rangesbuf = ranges_data_out;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *listlen = entry_count;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe for( copyindex = 0; curre && (copyindex < entry_count);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ++copyindex,++ranges_data_out) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct ranges_entry *r = curre;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *ranges_data_out = curre->cur;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe curre = curre->next;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free(r);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Callers will often not care about the bytes used. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(bytecount) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *bytecount = rangeptr - beginrangeptr;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_OK;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweint dwarf_get_ranges(Dwarf_Debug dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Off rangesoffset,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Ranges ** rangesbuf,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Signed * listlen,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned * bytecount,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Error * error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Die die = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int res = dwarf_get_ranges_a(dbg,rangesoffset,die,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe rangesbuf,listlen,bytecount,error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return res;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowevoid
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_ranges_dealloc(Dwarf_Debug dbg, Dwarf_Ranges * rangesbuf,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Signed rangecount)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_dealloc(dbg,rangesbuf, DW_DLA_RANGES);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe