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 $"); 32ELFTC_VCSID("Id: dwarf_pro_lineno.c 2973 2013-12-23 06:46:16Z kaiwang27"); 33 34Dwarf_Unsigned 35dwarf_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 75Dwarf_Unsigned 76dwarf_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 102Dwarf_Unsigned 103dwarf_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 134Dwarf_Unsigned 135dwarf_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 160Dwarf_Unsigned 161dwarf_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