1 /*- 2 * Copyright (c) 2009,2011 Kai Wang 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include "_libdwarf.h" 28 29 ELFTC_VCSID("$Id: dwarf_arange.c 2072 2011-10-27 03:26:49Z jkoshy $"); 30 31 int 32 dwarf_get_aranges(Dwarf_Debug dbg, Dwarf_Arange **arlist, 33 Dwarf_Signed *ret_arange_cnt, Dwarf_Error *error) 34 { 35 36 if (dbg == NULL || arlist == NULL || ret_arange_cnt == NULL) { 37 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 38 return (DW_DLV_ERROR); 39 } 40 41 if (dbg->dbg_arange_cnt == 0) { 42 if (_dwarf_arange_init(dbg, error) != DW_DLE_NONE) 43 return (DW_DLV_ERROR); 44 if (dbg->dbg_arange_cnt == 0) { 45 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 46 return (DW_DLV_NO_ENTRY); 47 } 48 } 49 50 assert(dbg->dbg_arange_array != NULL); 51 52 *arlist = dbg->dbg_arange_array; 53 *ret_arange_cnt = dbg->dbg_arange_cnt; 54 55 return (DW_DLV_OK); 56 } 57 58 int 59 dwarf_get_arange(Dwarf_Arange *arlist, Dwarf_Unsigned arange_cnt, 60 Dwarf_Addr addr, Dwarf_Arange *ret_arange, Dwarf_Error *error) 61 { 62 Dwarf_Arange ar; 63 Dwarf_Debug dbg; 64 int i; 65 66 if (arlist == NULL) { 67 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 68 return (DW_DLV_ERROR); 69 } 70 71 dbg = (*arlist)->ar_as->as_cu->cu_dbg; 72 73 if (ret_arange == NULL || arange_cnt == 0) { 74 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 75 return (DW_DLV_ERROR); 76 } 77 78 for (i = 0; (Dwarf_Unsigned)i < arange_cnt; i++) { 79 ar = arlist[i]; 80 if (addr >= ar->ar_address && addr < ar->ar_address + 81 ar->ar_range) { 82 *ret_arange = ar; 83 return (DW_DLV_OK); 84 } 85 } 86 87 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 88 89 return (DW_DLV_NO_ENTRY); 90 } 91 92 int 93 dwarf_get_cu_die_offset(Dwarf_Arange ar, Dwarf_Off *ret_offset, 94 Dwarf_Error *error) 95 { 96 Dwarf_CU cu; 97 Dwarf_ArangeSet as; 98 99 if (ar == NULL) { 100 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 101 return (DW_DLV_ERROR); 102 } 103 104 as = ar->ar_as; 105 assert(as != NULL); 106 cu = as->as_cu; 107 assert(cu != NULL); 108 109 if (ret_offset == NULL) { 110 DWARF_SET_ERROR(cu->cu_dbg, error, DW_DLE_ARGUMENT); 111 return (DW_DLV_ERROR); 112 } 113 114 *ret_offset = cu->cu_1st_offset; 115 116 return (DW_DLV_OK); 117 } 118 119 int 120 dwarf_get_arange_cu_header_offset(Dwarf_Arange ar, Dwarf_Off *ret_offset, 121 Dwarf_Error *error) 122 { 123 Dwarf_ArangeSet as; 124 125 if (ar == NULL) { 126 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 127 return (DW_DLV_ERROR); 128 } 129 130 as = ar->ar_as; 131 assert(as != NULL); 132 133 if (ret_offset == NULL) { 134 DWARF_SET_ERROR(as->as_cu->cu_dbg, error, DW_DLE_ARGUMENT); 135 return (DW_DLV_ERROR); 136 } 137 138 *ret_offset = as->as_cu_offset; 139 140 return (DW_DLV_OK); 141 } 142 143 int 144 dwarf_get_arange_info(Dwarf_Arange ar, Dwarf_Addr *start, 145 Dwarf_Unsigned *length, Dwarf_Off *cu_die_offset, Dwarf_Error *error) 146 { 147 Dwarf_CU cu; 148 Dwarf_ArangeSet as; 149 150 if (ar == NULL) { 151 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 152 return (DW_DLV_ERROR); 153 } 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