1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return list address ranges. 23e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath Copyright (C) 2000-2010 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2000. 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of either 8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU Lesser General Public License as published by the Free 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 3 of the License, or (at 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU General Public License as published by the Free 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 2 of the License, or (at 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or both in parallel, as here. 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 21de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper General Public License for more details. 25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received copies of the GNU General Public License and 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the GNU Lesser General Public License along with this program. If 28de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard not, see <http://www.gnu.org/licenses/>. */ 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libdwP.h" 3735f08c4d52d0ffd9f8aa50f47b84de5603842b1fUlrich Drepper#include <dwarf.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstruct arangelist 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Arange arange; 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct arangelist *next; 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Compare by Dwarf_Arange.addr, given pointers into an array of pointeers. */ 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercompare_aranges (const void *a, const void *b) 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 495f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath struct arangelist *const *p1 = a, *const *p2 = b; 505f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath struct arangelist *l1 = *p1, *l2 = *p2; 514a330f62794abaa3db95a0b447f4c433e4275ce6Mark Wielaard if (l1->arange.addr != l2->arange.addr) 524a330f62794abaa3db95a0b447f4c433e4275ce6Mark Wielaard return (l1->arange.addr < l2->arange.addr) ? -1 : 1; 534a330f62794abaa3db95a0b447f4c433e4275ce6Mark Wielaard return 0; 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 571ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaarddwarf_getaranges (Dwarf *dbg, Dwarf_Aranges **aranges, size_t *naranges) 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dbg == NULL) 60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dbg->aranges != NULL) 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *aranges = dbg->aranges; 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (naranges != NULL) 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *naranges = dbg->aranges->naranges; 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 70e7a73177dfbbc650fb43e5caa3ce29143f02fabdUlrich Drepper if (dbg->sectiondata[IDX_debug_aranges] == NULL) 71e7a73177dfbbc650fb43e5caa3ce29143f02fabdUlrich Drepper { 72e7a73177dfbbc650fb43e5caa3ce29143f02fabdUlrich Drepper /* No such section. */ 73e7a73177dfbbc650fb43e5caa3ce29143f02fabdUlrich Drepper *aranges = NULL; 74e7a73177dfbbc650fb43e5caa3ce29143f02fabdUlrich Drepper if (naranges != NULL) 75e7a73177dfbbc650fb43e5caa3ce29143f02fabdUlrich Drepper *naranges = 0; 76e7a73177dfbbc650fb43e5caa3ce29143f02fabdUlrich Drepper return 0; 77e7a73177dfbbc650fb43e5caa3ce29143f02fabdUlrich Drepper } 78e7a73177dfbbc650fb43e5caa3ce29143f02fabdUlrich Drepper 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dbg->sectiondata[IDX_debug_aranges]->d_buf == NULL) 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct arangelist *arangelist = NULL; 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int narangelist = 0; 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 8505c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath const unsigned char *readp = dbg->sectiondata[IDX_debug_aranges]->d_buf; 8605c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath const unsigned char *readendp 8705c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath = readp + dbg->sectiondata[IDX_debug_aranges]->d_size; 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (readp < readendp) 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 9105c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath const unsigned char *hdrstart = readp; 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Each entry starts with a header: 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1. A 4-byte or 12-byte length containing the length of the 96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper set of entries for this compilation unit, not including the 97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper length field itself. [...] 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2. A 2-byte version identifier containing the value 2 for 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper DWARF Version 2.1. 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3. A 4-byte or 8-byte offset into the .debug_info section. [...] 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4. A 1-byte unsigned integer containing the size in bytes of 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper an address (or the offset portion of an address for segmented 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper addressing) on the target system. 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 5. A 1-byte unsigned integer containing the size in bytes of 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper a segment descriptor on the target system. */ 110ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard if (unlikely (readp + 4 > readendp)) 111ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard goto invalid; 112ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp); 114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int length_bytes = 4; 11535f08c4d52d0ffd9f8aa50f47b84de5603842b1fUlrich Drepper if (length == DWARF3_LENGTH_64_BIT) 116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 117ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard if (unlikely (readp + 8 > readendp)) 118ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard goto invalid; 119ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard 120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper length = read_8ubyte_unaligned_inc (dbg, readp); 121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper length_bytes = 8; 122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 12335f08c4d52d0ffd9f8aa50f47b84de5603842b1fUlrich Drepper else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE 12435f08c4d52d0ffd9f8aa50f47b84de5603842b1fUlrich Drepper && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE)) 12535f08c4d52d0ffd9f8aa50f47b84de5603842b1fUlrich Drepper goto invalid; 126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 127ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard if (unlikely (readp + 2 > readendp)) 128ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard goto invalid; 129ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int version = read_2ubyte_unaligned_inc (dbg, readp); 131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (version != 2) 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper invalid: 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdw_seterrno (DWARF_E_INVALID_DWARF); 1355f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath fail: 1365f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath while (arangelist != NULL) 1375f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath { 1385f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath struct arangelist *next = arangelist->next; 1395f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath free (arangelist); 1405f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath arangelist = next; 1415f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath } 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 145ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard Dwarf_Word offset = 0; 14699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (__libdw_read_offset_inc (dbg, 14705c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath IDX_debug_aranges, &readp, 14899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper length_bytes, &offset, IDX_debug_info, 4)) 1495f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath goto fail; 150a5a89687681ca81e82681b56612495c0d087829eRoland McGrath 151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int address_size = *readp++; 152ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard if (unlikely (address_size != 4 && address_size != 8)) 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 15503d76f4aec5e750b81198c7a24571e119e754b40Mark Wielaard /* We don't actually support segment selectors. */ 15603d76f4aec5e750b81198c7a24571e119e754b40Mark Wielaard unsigned int segment_size = *readp++; 15703d76f4aec5e750b81198c7a24571e119e754b40Mark Wielaard if (segment_size != 0) 15803d76f4aec5e750b81198c7a24571e119e754b40Mark Wielaard goto invalid; 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Round the address to the next multiple of 2*address_size. */ 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size))) 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper % (2 * address_size)); 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (1) 165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word range_address; 167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word range_length; 168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 16905c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath if (__libdw_read_address_inc (dbg, IDX_debug_aranges, &readp, 17099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper address_size, &range_address)) 1715f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath goto fail; 17299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper 173ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard if (readp + address_size > readendp) 174ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard goto invalid; 175ae02916ba11547418c749ab0bebeb59c6094b96cMark Wielaard 176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (address_size == 4) 17799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper range_length = read_4ubyte_unaligned_inc (dbg, readp); 178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 17999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper range_length = read_8ubyte_unaligned_inc (dbg, readp); 180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Two zero values mark the end. */ 182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (range_address == 0 && range_length == 0) 183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1855f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath /* We don't use alloca for these temporary structures because 1865f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath the total number of them can be quite large. */ 1875f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath struct arangelist *new_arange = malloc (sizeof *new_arange); 1885f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath if (unlikely (new_arange == NULL)) 1895f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath { 1905f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath __libdw_seterrno (DWARF_E_NOMEM); 1915f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath goto fail; 1925f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath } 193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper new_arange->arange.addr = range_address; 195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper new_arange->arange.length = range_length; 196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We store the actual CU DIE offset, not the CU header offset. */ 198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *cu_header = (dbg->sectiondata[IDX_debug_info]->d_buf 199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + offset); 200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int offset_size; 20135f08c4d52d0ffd9f8aa50f47b84de5603842b1fUlrich Drepper if (read_4ubyte_unaligned_noncvt (cu_header) == DWARF3_LENGTH_64_BIT) 202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper offset_size = 8; 203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper offset_size = 4; 205c57b65cf3b1a7a19b25fdac91e83c514fd93e565Ulrich Drepper new_arange->arange.offset = DIE_OFFSET_FROM_CU_OFFSET (offset, 2063e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath offset_size, 2073e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath false); 208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper new_arange->next = arangelist; 210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper arangelist = new_arange; 211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++narangelist; 2125f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath 2135f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath /* Sanity-check the data. */ 2145f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath if (unlikely (new_arange->arange.offset 2155f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath >= dbg->sectiondata[IDX_debug_info]->d_size)) 2165f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath goto invalid; 217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (narangelist == 0) 221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2225f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath assert (arangelist == NULL); 223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (naranges != NULL) 224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *naranges = 0; 225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *aranges = NULL; 226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Allocate the array for the result. */ 230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper void *buf = libdw_alloc (dbg, Dwarf_Aranges, 231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sizeof (Dwarf_Aranges) 232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + narangelist * sizeof (Dwarf_Arange), 1); 233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* First use the buffer for the pointers, and sort the entries. 235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper We'll write the pointers in the end of the buffer, and then 236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper copy into the buffer from the beginning so the overlap works. */ 237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (sizeof (Dwarf_Arange) >= sizeof (Dwarf_Arange *)); 2385f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath struct arangelist **sortaranges 2395f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath = (buf + sizeof (Dwarf_Aranges) 2405f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath + ((sizeof (Dwarf_Arange) - sizeof sortaranges[0]) * narangelist)); 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The list is in LIFO order and usually they come in clumps with 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ascending addresses. So fill from the back to probably start with 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper runs already in order before we sort. */ 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int i = narangelist; 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (i-- > 0) 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2485f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath sortaranges[i] = arangelist; 249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper arangelist = arangelist->next; 250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (arangelist == NULL); 252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Sort by ascending address. */ 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper qsort (sortaranges, narangelist, sizeof sortaranges[0], &compare_aranges); 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now that they are sorted, put them in the final array. 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper The buffers overlap, so we've clobbered the early elements 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper of SORTARANGES by the time we're reading the later ones. */ 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *aranges = buf; 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (*aranges)->dbg = dbg; 261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (*aranges)->naranges = narangelist; 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper dbg->aranges = *aranges; 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (naranges != NULL) 264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *naranges = narangelist; 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (i = 0; i < narangelist; ++i) 2665f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath { 2675f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath struct arangelist *elt = sortaranges[i]; 2685f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath (*aranges)->info[i] = elt->arange; 2695f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath free (elt); 2705f95e2b093cdeb4610cbb049dd5e7dac5dd7c3efRoland McGrath } 271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 274b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperINTDEF(dwarf_getaranges) 275