Home | History | Annotate | Line # | Download | only in libdwarf
      1 /*	$NetBSD: dwarf_cu.c,v 1.5 2024/03/03 17:37:30 christos Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2007 John Birrell (jb (at) freebsd.org)
      5  * Copyright (c) 2014,2023 Kai Wang
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 
     30 #include "_libdwarf.h"
     31 
     32 __RCSID("$NetBSD: dwarf_cu.c,v 1.5 2024/03/03 17:37:30 christos Exp $");
     33 ELFTC_VCSID("Id: dwarf_cu.c 4013 2023-10-14 22:40:50Z kaiwang27");
     34 
     35 int
     36 dwarf_next_cu_header_d(Dwarf_Debug dbg, Dwarf_Bool is_info,
     37     Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version,
     38     Dwarf_Off *cu_abbrev_offset, Dwarf_Half *cu_pointer_size,
     39     Dwarf_Half *cu_offset_size, Dwarf_Half *cu_extension_size,
     40     Dwarf_Sig8 *type_signature, Dwarf_Unsigned *type_offset,
     41     Dwarf_Unsigned *cu_next_offset, Dwarf_Half *cu_type,
     42     Dwarf_Error *error)
     43 {
     44 	Dwarf_CU cu;
     45 	int ret;
     46 
     47 	if (dbg == NULL) {
     48 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
     49 		return (DW_DLV_ERROR);
     50 	}
     51 
     52 	if (is_info) {
     53 		if (dbg->dbg_cu_current == NULL)
     54 			ret = _dwarf_info_first_cu(dbg, error);
     55 		else
     56 			ret = _dwarf_info_next_cu(dbg, error);
     57 	} else {
     58 		if (dbg->dbg_tu_current == NULL)
     59 			ret = _dwarf_info_first_tu(dbg, error);
     60 		else
     61 			ret = _dwarf_info_next_tu(dbg, error);
     62 	}
     63 
     64 	if (ret == DW_DLE_NO_ENTRY) {
     65 		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
     66 		return (DW_DLV_NO_ENTRY);
     67 	} else if (ret != DW_DLE_NONE)
     68 		return (DW_DLV_ERROR);
     69 
     70 	if (is_info) {
     71 		if (dbg->dbg_cu_current == NULL) {
     72 			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
     73 			return (DW_DLV_NO_ENTRY);
     74 		}
     75 		cu = dbg->dbg_cu_current;
     76 	} else {
     77 		if (dbg->dbg_tu_current == NULL) {
     78 			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
     79 			return (DW_DLV_NO_ENTRY);
     80 		}
     81 		cu = dbg->dbg_tu_current;
     82 	}
     83 
     84 	if (cu_length)
     85 		*cu_length = cu->cu_length;
     86 	if (cu_version)
     87 		*cu_version = cu->cu_version;
     88 	if (cu_abbrev_offset)
     89 		*cu_abbrev_offset = (Dwarf_Off) cu->cu_abbrev_offset;
     90 	if (cu_pointer_size)
     91 		*cu_pointer_size = cu->cu_pointer_size;
     92 	if (cu_offset_size) {
     93 		if (cu->cu_length_size == 4)
     94 			*cu_offset_size = 4;
     95 		else
     96 			*cu_offset_size = 8;
     97 	}
     98 	if (cu_extension_size) {
     99 		if (cu->cu_length_size == 4)
    100 			*cu_extension_size = 0;
    101 		else
    102 			*cu_extension_size = 4;
    103 	}
    104 	if (cu_next_offset)
    105 		*cu_next_offset	= cu->cu_next_offset;
    106 
    107 	if (!is_info) {
    108 		if (type_signature)
    109 			*type_signature = cu->cu_type_sig;
    110 		if (type_offset)
    111 			*type_offset = cu->cu_type_offset;
    112 	}
    113 
    114 	if (cu_type)
    115 		*cu_type = cu->cu_unit_type;
    116 
    117 	return (DW_DLV_OK);
    118 }
    119 
    120 int
    121 dwarf_next_cu_header_c(Dwarf_Debug dbg, Dwarf_Bool is_info,
    122     Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version,
    123     Dwarf_Off *cu_abbrev_offset, Dwarf_Half *cu_pointer_size,
    124     Dwarf_Half *cu_offset_size, Dwarf_Half *cu_extension_size,
    125     Dwarf_Sig8 *type_signature, Dwarf_Unsigned *type_offset,
    126     Dwarf_Unsigned *cu_next_offset, Dwarf_Error *error)
    127 {
    128 
    129 	return (dwarf_next_cu_header_d(dbg, 1, cu_length, cu_version,
    130 	    cu_abbrev_offset, cu_pointer_size, cu_offset_size,
    131 	    cu_extension_size, NULL, NULL, cu_next_offset, NULL, error));
    132 }
    133 
    134 
    135 int
    136 dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
    137     Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset,
    138     Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size,
    139     Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset,
    140     Dwarf_Error *error)
    141 {
    142 
    143 	return (dwarf_next_cu_header_c(dbg, 1, cu_length, cu_version,
    144 	    cu_abbrev_offset, cu_pointer_size, cu_offset_size,
    145 	    cu_extension_size, NULL, NULL, cu_next_offset, error));
    146 }
    147 
    148 int
    149 dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
    150     Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset,
    151     Dwarf_Half *cu_pointer_size, Dwarf_Unsigned *cu_next_offset,
    152     Dwarf_Error *error)
    153 {
    154 
    155 	return (dwarf_next_cu_header_b(dbg, cu_length, cu_version,
    156 	    cu_abbrev_offset, cu_pointer_size, NULL, NULL, cu_next_offset,
    157 	    error));
    158 }
    159 
    160 int
    161 dwarf_next_types_section(Dwarf_Debug dbg, Dwarf_Error *error)
    162 {
    163 
    164 	/* Free resource allocated for current .debug_types section. */
    165 	_dwarf_type_unit_cleanup(dbg);
    166 	dbg->dbg_types_loaded = 0;
    167 	dbg->dbg_types_off = 0;
    168 
    169 	/* Reset type unit pointer. */
    170 	dbg->dbg_tu_current = NULL;
    171 
    172 	/* Search for the next .debug_types section. */
    173 	dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg,
    174 	    dbg->dbg_types_sec);
    175 
    176 	if (dbg->dbg_types_sec == NULL) {
    177 		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
    178 		return (DW_DLV_NO_ENTRY);
    179 	}
    180 
    181 	return (DW_DLV_OK);
    182 }
    183