Home | History | Annotate | Line # | Download | only in libdwarf
      1 /*	$NetBSD: dwarf_pro_lineno.c,v 1.5 2024/03/03 17:37:32 christos Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2010 Kai Wang
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include "_libdwarf.h"
     30 
     31 __RCSID("$NetBSD: dwarf_pro_lineno.c,v 1.5 2024/03/03 17:37:32 christos Exp $");
     32 ELFTC_VCSID("Id: dwarf_pro_lineno.c 2973 2013-12-23 06:46:16Z kaiwang27");
     33 
     34 Dwarf_Unsigned
     35 dwarf_add_line_entry(Dwarf_P_Debug dbg, Dwarf_Unsigned file,
     36     Dwarf_Addr off, Dwarf_Unsigned lineno, Dwarf_Signed column,
     37     Dwarf_Bool is_stmt, Dwarf_Bool basic_block, Dwarf_Error *error)
     38 {
     39 	Dwarf_LineInfo li;
     40 	Dwarf_Line ln;
     41 
     42 	if (dbg == NULL) {
     43 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
     44 		return (DW_DLV_NOCOUNT);
     45 	}
     46 
     47 	li = dbg->dbgp_lineinfo;
     48 
     49 	ln = STAILQ_LAST(&li->li_lnlist, _Dwarf_Line, ln_next);
     50 
     51 	if (ln == NULL || ln->ln_addr > off) {
     52 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
     53 		return (DW_DLV_NOCOUNT);
     54 	}
     55 
     56 	if ((ln = calloc(1, sizeof(struct _Dwarf_Line))) == NULL) {
     57 		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
     58 		return (DW_DLV_NOCOUNT);
     59 	}
     60 	ln->ln_li     = li;
     61 	ln->ln_addr   = off;
     62 	ln->ln_symndx = 0;
     63 	ln->ln_fileno = file;
     64 	ln->ln_lineno = lineno;
     65 	ln->ln_column = column;
     66 	ln->ln_bblock = basic_block != 0;
     67 	ln->ln_stmt   = is_stmt != 0;
     68 	ln->ln_endseq = 0;
     69 	STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next);
     70 	li->li_lnlen++;
     71 
     72 	return (DW_DLV_OK);
     73 }
     74 
     75 Dwarf_Unsigned
     76 dwarf_lne_set_address(Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symndx,
     77     Dwarf_Error *error)
     78 {
     79 	Dwarf_LineInfo li;
     80 	Dwarf_Line ln;
     81 
     82 	if (dbg == NULL || symndx == 0) {
     83 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
     84 		return (DW_DLV_NOCOUNT);
     85 	}
     86 
     87 	li = dbg->dbgp_lineinfo;
     88 
     89 	if ((ln = calloc(1, sizeof(struct _Dwarf_Line))) == NULL) {
     90 		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
     91 		return (DW_DLV_NOCOUNT);
     92 	}
     93 	ln->ln_li = li;
     94 	ln->ln_addr = offs;
     95 	ln->ln_symndx = symndx;
     96 	STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next);
     97 	li->li_lnlen++;
     98 
     99 	return (DW_DLV_OK);
    100 }
    101 
    102 Dwarf_Unsigned
    103 dwarf_lne_end_sequence(Dwarf_P_Debug dbg, Dwarf_Addr addr, Dwarf_Error *error)
    104 {
    105 	Dwarf_LineInfo li;
    106 	Dwarf_Line ln;
    107 
    108 	if (dbg == NULL) {
    109 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
    110 		return (DW_DLV_NOCOUNT);
    111 	}
    112 
    113 	li = dbg->dbgp_lineinfo;
    114 
    115 	ln = STAILQ_LAST(&li->li_lnlist, _Dwarf_Line, ln_next);
    116 	if (ln && ln->ln_addr >= addr) {
    117 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
    118 		return (DW_DLV_NOCOUNT);
    119 	}
    120 
    121 	if ((ln = calloc(1, sizeof(struct _Dwarf_Line))) == NULL) {
    122 		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
    123 		return (DW_DLV_NOCOUNT);
    124 	}
    125 	ln->ln_li = li;
    126 	ln->ln_addr = addr;
    127 	ln->ln_endseq = 1;
    128 	STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next);
    129 	li->li_lnlen++;
    130 
    131 	return (DW_DLV_OK);
    132 }
    133 
    134 Dwarf_Unsigned
    135 dwarf_add_directory_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Error *error)
    136 {
    137 	Dwarf_LineInfo li;
    138 
    139 	if (dbg == NULL || name == NULL || strlen(name) == 0) {
    140 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
    141 		return (DW_DLV_NOCOUNT);
    142 	}
    143 
    144 	li = dbg->dbgp_lineinfo;
    145 
    146 	li->li_incdirs = realloc(li->li_incdirs, (li->li_inclen + 1) *
    147 	    sizeof(char *));
    148 	if (li->li_incdirs == NULL) {
    149 		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
    150 		return (DW_DLV_NOCOUNT);
    151 	}
    152 	if ((li->li_incdirs[li->li_inclen] = strdup(name)) == NULL) {
    153 		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
    154 		return (DW_DLV_NOCOUNT);
    155 	}
    156 
    157 	return (++li->li_inclen);
    158 }
    159 
    160 Dwarf_Unsigned
    161 dwarf_add_file_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dirndx,
    162     Dwarf_Unsigned mtime, Dwarf_Unsigned size, Dwarf_Error *error)
    163 {
    164 	Dwarf_LineInfo li;
    165 	Dwarf_LineFile lf;
    166 
    167 	if (dbg == NULL || name == NULL || strlen(name) == 0) {
    168 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
    169 		return (DW_DLV_NOCOUNT);
    170 	}
    171 
    172 	li = dbg->dbgp_lineinfo;
    173 
    174 	if ((lf = malloc(sizeof(struct _Dwarf_LineFile))) == NULL) {
    175 		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
    176 		return (DW_DLE_MEMORY);
    177 	}
    178 
    179 	if ((lf->lf_fname = strdup(name)) == NULL) {
    180 		free(lf);
    181 		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
    182 		return (DW_DLE_MEMORY);
    183 	}
    184 	lf->lf_dirndx = dirndx;
    185 	lf->lf_mtime = mtime;
    186 	lf->lf_size = size;
    187 	STAILQ_INSERT_TAIL(&li->li_lflist, lf, lf_next);
    188 
    189 	return (++li->li_lflen);
    190 }
    191