16429Svs195195/*- 26429Svs195195 * Copyright (c) 2009,2011 Kai Wang 36429Svs195195 * All rights reserved. 46429Svs195195 * 56429Svs195195 * Redistribution and use in source and binary forms, with or without 66429Svs195195 * modification, are permitted provided that the following conditions 76429Svs195195 * are met: 86429Svs195195 * 1. Redistributions of source code must retain the above copyright 96429Svs195195 * notice, this list of conditions and the following disclaimer. 106429Svs195195 * 2. Redistributions in binary form must reproduce the above copyright 116429Svs195195 * notice, this list of conditions and the following disclaimer in the 126429Svs195195 * documentation and/or other materials provided with the distribution. 136429Svs195195 * 146429Svs195195 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 156429Svs195195 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 166429Svs195195 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 176429Svs195195 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 186429Svs195195 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 196429Svs195195 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 206429Svs195195 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 216429Svs195195 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 226429Svs195195 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 236491Sia112686 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 246429Svs195195 * SUCH DAMAGE. 256429Svs195195 */ 266429Svs195195 276429Svs195195#include "_libdwarf.h" 286429Svs195195 296429Svs195195ELFTC_VCSID("$Id: dwarf_arange.c 2072 2011-10-27 03:26:49Z jkoshy $"); 306429Svs195195 316429Svs195195int 326429Svs195195dwarf_get_aranges(Dwarf_Debug dbg, Dwarf_Arange **arlist, 336429Svs195195 Dwarf_Signed *ret_arange_cnt, Dwarf_Error *error) 346429Svs195195{ 356429Svs195195 366429Svs195195 if (dbg == NULL || arlist == NULL || ret_arange_cnt == NULL) { 376429Svs195195 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 386429Svs195195 return (DW_DLV_ERROR); 396429Svs195195 } 406429Svs195195 416429Svs195195 if (dbg->dbg_arange_cnt == 0) { 426429Svs195195 if (_dwarf_arange_init(dbg, error) != DW_DLE_NONE) 436429Svs195195 return (DW_DLV_ERROR); 446429Svs195195 if (dbg->dbg_arange_cnt == 0) { 456429Svs195195 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 466429Svs195195 return (DW_DLV_NO_ENTRY); 476429Svs195195 } 486429Svs195195 } 496429Svs195195 506429Svs195195 assert(dbg->dbg_arange_array != NULL); 516429Svs195195 526429Svs195195 *arlist = dbg->dbg_arange_array; 536429Svs195195 *ret_arange_cnt = dbg->dbg_arange_cnt; 546429Svs195195 556429Svs195195 return (DW_DLV_OK); 566429Svs195195} 576429Svs195195 586429Svs195195int 596429Svs195195dwarf_get_arange(Dwarf_Arange *arlist, Dwarf_Unsigned arange_cnt, 606429Svs195195 Dwarf_Addr addr, Dwarf_Arange *ret_arange, Dwarf_Error *error) 616429Svs195195{ 626429Svs195195 Dwarf_Arange ar; 636429Svs195195 Dwarf_Debug dbg; 646429Svs195195 int i; 656429Svs195195 666429Svs195195 if (arlist == NULL) { 676429Svs195195 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 686429Svs195195 return (DW_DLV_ERROR); 696429Svs195195 } 706429Svs195195 716429Svs195195 dbg = (*arlist)->ar_as->as_cu->cu_dbg; 726429Svs195195 736429Svs195195 if (ret_arange == NULL || arange_cnt == 0) { 746429Svs195195 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 756429Svs195195 return (DW_DLV_ERROR); 766429Svs195195 } 776429Svs195195 786429Svs195195 for (i = 0; (Dwarf_Unsigned)i < arange_cnt; i++) { 796429Svs195195 ar = arlist[i]; 806429Svs195195 if (addr >= ar->ar_address && addr < ar->ar_address + 816429Svs195195 ar->ar_range) { 826429Svs195195 *ret_arange = ar; 836429Svs195195 return (DW_DLV_OK); 846429Svs195195 } 856429Svs195195 } 866429Svs195195 876429Svs195195 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 886429Svs195195 896429Svs195195 return (DW_DLV_NO_ENTRY); 906429Svs195195} 916429Svs195195 926429Svs195195int 936429Svs195195dwarf_get_cu_die_offset(Dwarf_Arange ar, Dwarf_Off *ret_offset, 946429Svs195195 Dwarf_Error *error) 956429Svs195195{ 966429Svs195195 Dwarf_CU cu; 976429Svs195195 Dwarf_ArangeSet as; 986429Svs195195 996429Svs195195 if (ar == NULL) { 1006429Svs195195 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 1016429Svs195195 return (DW_DLV_ERROR); 1026429Svs195195 } 1036429Svs195195 1046429Svs195195 as = ar->ar_as; 1056429Svs195195 assert(as != NULL); 1066429Svs195195 cu = as->as_cu; 1076429Svs195195 assert(cu != NULL); 1086429Svs195195 1096429Svs195195 if (ret_offset == NULL) { 1106429Svs195195 DWARF_SET_ERROR(cu->cu_dbg, error, DW_DLE_ARGUMENT); 1116429Svs195195 return (DW_DLV_ERROR); 1126429Svs195195 } 1136429Svs195195 1146429Svs195195 *ret_offset = cu->cu_1st_offset; 1156429Svs195195 1166429Svs195195 return (DW_DLV_OK); 1176429Svs195195} 1187186Skk158166 1196429Svs195195int 1206429Svs195195dwarf_get_arange_cu_header_offset(Dwarf_Arange ar, Dwarf_Off *ret_offset, 1216429Svs195195 Dwarf_Error *error) 1226429Svs195195{ 1236429Svs195195 Dwarf_ArangeSet as; 1246429Svs195195 1256429Svs195195 if (ar == NULL) { 1267186Skk158166 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 1276429Svs195195 return (DW_DLV_ERROR); 1286429Svs195195 } 1296429Svs195195 1306429Svs195195 as = ar->ar_as; 1316429Svs195195 assert(as != NULL); 1326429Svs195195 1336429Svs195195 if (ret_offset == NULL) { 1346429Svs195195 DWARF_SET_ERROR(as->as_cu->cu_dbg, error, DW_DLE_ARGUMENT); 1356429Svs195195 return (DW_DLV_ERROR); 1366429Svs195195 } 1376429Svs195195 1386429Svs195195 *ret_offset = as->as_cu_offset; 1396429Svs195195 1406429Svs195195 return (DW_DLV_OK); 1416429Svs195195} 1426429Svs195195 1436429Svs195195int 1446429Svs195195dwarf_get_arange_info(Dwarf_Arange ar, Dwarf_Addr *start, 1456429Svs195195 Dwarf_Unsigned *length, Dwarf_Off *cu_die_offset, Dwarf_Error *error) 1466429Svs195195{ 1476429Svs195195 Dwarf_CU cu; 1486429Svs195195 Dwarf_ArangeSet as; 1496429Svs195195 1506429Svs195195 if (ar == NULL) { 1516429Svs195195 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 1526429Svs195195 return (DW_DLV_ERROR); 1536429Svs195195 } 154 155 as = ar->ar_as; 156 assert(as != NULL); 157 cu = as->as_cu; 158 assert(cu != NULL); 159 160 if (start == NULL || length == NULL || 161 cu_die_offset == NULL) { 162 DWARF_SET_ERROR(cu->cu_dbg, error, DW_DLE_ARGUMENT); 163 return (DW_DLV_ERROR); 164 } 165 166 *start = ar->ar_address; 167 *length = ar->ar_range; 168 *cu_die_offset = cu->cu_1st_offset; 169 170 return (DW_DLV_OK); 171} 172