Branch data Line data Source code
1 : : /* Iterate through the CU units for a given Dwarf. 2 : : Copyright (C) 2016, 2017 Red Hat, Inc. 3 : : This file is part of elfutils. 4 : : 5 : : This file is free software; you can redistribute it and/or modify 6 : : it under the terms of either 7 : : 8 : : * the GNU Lesser General Public License as published by the Free 9 : : Software Foundation; either version 3 of the License, or (at 10 : : your option) any later version 11 : : 12 : : or 13 : : 14 : : * the GNU General Public License as published by the Free 15 : : Software Foundation; either version 2 of the License, or (at 16 : : your option) any later version 17 : : 18 : : or both in parallel, as here. 19 : : 20 : : elfutils is distributed in the hope that it will be useful, but 21 : : WITHOUT ANY WARRANTY; without even the implied warranty of 22 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 : : General Public License for more details. 24 : : 25 : : You should have received copies of the GNU General Public License and 26 : : the GNU Lesser General Public License along with this program. If 27 : : not, see <http://www.gnu.org/licenses/>. */ 28 : : 29 : : 30 : : #ifdef HAVE_CONFIG_H 31 : : # include <config.h> 32 : : #endif 33 : : 34 : : #include <string.h> 35 : : 36 : : #include "libdwP.h" 37 : : 38 : : int 39 : 19856 : dwarf_get_units (Dwarf *dwarf, Dwarf_CU *cu, Dwarf_CU **next_cu, 40 : : Dwarf_Half *version, uint8_t *unit_type, 41 : : Dwarf_Die *cudie, Dwarf_Die *subdie) 42 : : { 43 : : /* Handle existing error. */ 44 [ + - ]: 19856 : if (dwarf == NULL) 45 : : return -1; 46 : : 47 : 19856 : Dwarf_Off off; 48 : 19856 : bool v4type; 49 [ + + ]: 19856 : if (cu == NULL) 50 : : { 51 : : off = 0; 52 : : v4type = false; 53 : : } 54 : : else 55 : : { 56 : 15116 : off = cu->end; 57 : 15116 : v4type = cu->sec_idx != IDX_debug_info; 58 : : 59 : : /* Make sure we got a real (not fake) CU. */ 60 [ - + ]: 15116 : if (cu->sec_idx != IDX_debug_info && cu->sec_idx != IDX_debug_types) 61 : : { 62 : 0 : __libdw_seterrno (DWARF_E_INVALID_OFFSET); 63 : 0 : return -1; 64 : : } 65 : : 66 : : /* Do we have to switch to the other section, or are we at the end? */ 67 [ + + ]: 15116 : if (! v4type) 68 : : { 69 [ + + ]: 15092 : if (off >= cu->dbg->sectiondata[IDX_debug_info]->d_size) 70 : : { 71 [ + + ]: 356 : if (cu->dbg->sectiondata[IDX_debug_types] == NULL) 72 : : return 1; 73 : : 74 : : off = 0; 75 : : v4type = true; 76 : : } 77 : : } 78 : : else 79 [ + + ]: 24 : if (off >= cu->dbg->sectiondata[IDX_debug_types]->d_size) 80 : : return 1; 81 : : } 82 : : 83 : 19502 : *next_cu = __libdw_findcu (dwarf, off, v4type); 84 [ + + ]: 19502 : if (*next_cu == NULL) 85 : : return -1; 86 : : 87 : 19484 : Dwarf_CU *next = (*next_cu); 88 : : 89 [ + + ]: 19484 : if (version != NULL) 90 : 5858 : *version = next->version; 91 : : 92 [ + + ]: 19484 : if (unit_type != NULL) 93 : 12784 : *unit_type = next->unit_type; 94 : : 95 [ + + ]: 19484 : if (cudie != NULL) 96 : : { 97 [ + - ]: 10584 : if (next->version >= 2 && next->version <= 5 98 [ + - ]: 10584 : && next->unit_type >= DW_UT_compile 99 [ + - ]: 10584 : && next->unit_type <= DW_UT_split_type) 100 : 10584 : *cudie = CUDIE (next); 101 : : else 102 : 0 : memset (cudie, '\0', sizeof (Dwarf_Die)); 103 : : } 104 : : 105 [ + + ]: 19484 : if (subdie != NULL) 106 : : { 107 [ + - ]: 9226 : if (next->version >= 2 && next->version <= 5) 108 : : { 109 : : /* For types, return the actual type DIE. For skeletons, 110 : : find the associated split compile unit and return its 111 : : DIE. */ 112 : 9226 : if (next->unit_type == DW_UT_type 113 [ + + ]: 9226 : || next->unit_type == DW_UT_split_type) 114 : 16 : *subdie = SUBDIE(next); 115 [ + + ]: 9210 : else if (next->unit_type == DW_UT_skeleton) 116 : : { 117 : 40 : Dwarf_CU *split_cu = __libdw_find_split_unit (next); 118 [ + - ]: 40 : if (split_cu != NULL) 119 : 40 : *subdie = CUDIE(split_cu); 120 : : else 121 : 0 : memset (subdie, '\0', sizeof (Dwarf_Die)); 122 : : } 123 : : else 124 : 9170 : memset (subdie, '\0', sizeof (Dwarf_Die)); 125 : : } 126 : : else 127 : 0 : memset (subdie, '\0', sizeof (Dwarf_Die)); 128 : : } 129 : : 130 : : return 0; 131 : : }