xref: /titanic_44/usr/src/tools/ctf/dwarf/common/dwarf_line.c (revision b8afd3a780ce850ff107bb3be330465bf47f84bd)
1 /*
2 
3   Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
4 
5   This program is free software; you can redistribute it and/or modify it
6   under the terms of version 2.1 of the GNU Lesser General Public License
7   as published by the Free Software Foundation.
8 
9   This program is distributed in the hope that it would be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13   Further, this software is distributed without any warranty that it is
14   free of the rightful claim of any third person regarding infringement
15   or the like.  Any license provided herein, whether implied or
16   otherwise, applies only to this software file.  Patent licenses, if
17   any, provided herein do not apply to combinations of this program with
18   other software, or any other product whatsoever.
19 
20   You should have received a copy of the GNU Lesser General Public
21   License along with this program; if not, write the Free Software
22   Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
23   USA.
24 
25   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
26   Mountain View, CA 94043, or:
27 
28   http://www.sgi.com
29 
30   For further information regarding this notice, see:
31 
32   http://oss.sgi.com/projects/GenInfo/NoticeExplan
33 
34 */
35 
36 
37 
38 #include "config.h"
39 #include "dwarf_incl.h"
40 #include <stdio.h>
41 #include "dwarf_line.h"
42 #ifdef HAVE_ALLOCA_H
43 #include <alloca.h>
44 #endif
45 
46 
47 /*
48     Although source files is supposed to return the
49     source files in the compilation-unit, it does
50     not look for any in the statement program.  In
51     other words, it ignores those defined using the
52     extended opcode DW_LNE_define_file.
53 */
54 int
55 dwarf_srcfiles(Dwarf_Die die,
56 	       char ***srcfiles,
57 	       Dwarf_Signed * srcfilecount, Dwarf_Error * error)
58 {
59     /*
60        This pointer is used to scan the portion of the .debug_line
61        section for the current cu. */
62     Dwarf_Small *line_ptr;
63 
64     /*
65        This points to the last byte of the .debug_line portion for the
66        current cu. */
67     Dwarf_Small *line_ptr_end;
68 
69     /*
70        This points to the end of the statement program prologue for the
71        current cu, and serves to check that the prologue was correctly
72        decoded. */
73     Dwarf_Small *check_line_ptr;
74 
75     /*
76        Pointer to a DW_AT_stmt_list attribute in case it exists in the
77        die. */
78     Dwarf_Attribute stmt_list_attr;
79 
80     /* Pointer to DW_AT_comp_dir attribute in die. */
81     Dwarf_Attribute comp_dir_attr;
82 
83     /* Pointer to name of compilation directory. */
84     Dwarf_Small *comp_dir = 0;
85 
86     /*
87        Offset into .debug_line specified by a DW_AT_stmt_list
88        attribute. */
89     Dwarf_Unsigned line_offset = 0;
90 
91     /* Some of the fields of the statement program header. */
92     Dwarf_Unsigned total_length = 0;
93     Dwarf_Half version = 0;
94     Dwarf_Unsigned prologue_length = 0;
95     Dwarf_Small special_opcode_base= 0;
96 
97     /* File name excluding included directory. */
98     char *file_name = 0;
99 
100     /* Name of directory that the file is in. */
101     char *dir_name = 0;
102 
103     /* Name concatenating both directory and file name. */
104     char *full_name = 0;
105 
106     /*
107        This is the directory index for the file. The compilation
108        directory is 0, and the first included directory is 1. */
109     Dwarf_Sword dir_index = 0;
110 
111     Dwarf_Small *include_directories = 0;
112 
113     Dwarf_Sword i = 0;
114     Dwarf_Sword file_count = 0;
115     Dwarf_Sword directories_count = 0;
116 
117     /*
118        This is the current opcode read from the statement program. */
119 
120     Dwarf_Word leb128_length;
121 
122     /* This is the length of an extended opcode instr.  */
123 
124     /*
125        This points to a block of char *'s, each of which points to a
126        file name. */
127     char **ret_files = 0;
128 
129     /* The Dwarf_Debug this die belongs to. */
130     Dwarf_Debug dbg;
131 
132     /* Used to chain the file names. */
133     Dwarf_Chain curr_chain, prev_chain, head_chain = NULL;
134     int resattr;
135     int lres;
136 
137     int local_length_size = 0;
138     /*REFERENCED*/ /* Not used in this instance of the macro */
139     int local_extension_size = 0;
140 
141     int res;
142 
143     /* ***** BEGIN CODE ***** */
144 
145     /* Reset error. */
146     if (error != NULL)
147 	*error = NULL;
148 
149     CHECK_DIE(die, DW_DLV_ERROR)
150 	dbg = die->di_cu_context->cc_dbg;
151 
152     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
153     if (resattr != DW_DLV_OK) {
154 	return resattr;
155     }
156 
157     if (dbg->de_debug_line_index == 0) {
158 	_dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL);
159 	return (DW_DLV_ERROR);
160     }
161 
162     res =
163        _dwarf_load_section(dbg,
164 		           dbg->de_debug_line_index,
165 			   &dbg->de_debug_line,
166 			   error);
167     if (res != DW_DLV_OK) {
168 	return res;
169     }
170 
171     lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
172     if (lres != DW_DLV_OK) {
173 	return lres;
174     }
175     if (line_offset >= dbg->de_debug_line_size) {
176 	_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
177 	return (DW_DLV_ERROR);
178     }
179     line_ptr = dbg->de_debug_line + line_offset;
180     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
181 
182     /*
183        If die has DW_AT_comp_dir attribute, get the string that names
184        the compilation directory. */
185     resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
186     if (resattr == DW_DLV_ERROR) {
187 	return resattr;
188     }
189     if (resattr == DW_DLV_OK) {
190 	int cres;
191 	char *cdir;
192 
193 	cres = dwarf_formstring(comp_dir_attr, &cdir, error);
194 	if (cres == DW_DLV_ERROR) {
195 	    return cres;
196 	} else if (cres == DW_DLV_OK) {
197 	    comp_dir = (Dwarf_Small *) cdir;
198 	}
199     }
200     if (resattr == DW_DLV_OK) {
201 	dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
202     }
203 
204     /*
205        Following is a straightforward decoding of the statement
206        program prologue information. */
207     /* READ_AREA_LENGTH updates line_ptr for consumed bytes */
208     READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
209 		     line_ptr, local_length_size, local_extension_size);
210 
211 
212     line_ptr_end = line_ptr + total_length;
213     if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) {
214 	_dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD);
215 	return (DW_DLV_ERROR);
216     }
217 
218     READ_UNALIGNED(dbg, version, Dwarf_Half,
219 		   line_ptr, sizeof(Dwarf_Half));
220     line_ptr += sizeof(Dwarf_Half);
221     if (version != CURRENT_VERSION_STAMP) {
222 	_dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
223 	return (DW_DLV_ERROR);
224     }
225 
226     READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
227 		   line_ptr, local_length_size);
228     line_ptr += local_length_size;
229     check_line_ptr = line_ptr;
230 
231     /* Skip over minimum instruction length. */
232     line_ptr = line_ptr + sizeof(Dwarf_Small);
233 
234     /* Skip over default_is_stmt. */
235     line_ptr = line_ptr + sizeof(Dwarf_Small);
236 
237     /* Skip over line_base. */
238     line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
239 
240     /* Skip over line_ptr. */
241     line_ptr = line_ptr + sizeof(Dwarf_Small);
242 
243     special_opcode_base = *(Dwarf_Small *) line_ptr;
244     line_ptr = line_ptr + sizeof(Dwarf_Small);
245 
246     for (i = 1; i < special_opcode_base; i++) {
247 	/* Skip over opcode lengths for standard opcodes. */
248 	line_ptr = line_ptr + sizeof(Dwarf_Small);
249     }
250 
251     directories_count = 0;
252     include_directories = line_ptr;
253     while ((*(char *) line_ptr) != '\0') {
254 	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
255 	directories_count++;
256     }
257     line_ptr++;
258 
259     file_count = 0;
260     while (*(char *) line_ptr != '\0') {
261 	Dwarf_Unsigned utmp;
262 
263 	file_name = (char *) line_ptr;
264 	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
265 
266 	DECODE_LEB128_UWORD(line_ptr, utmp)
267 	    dir_index = (Dwarf_Sword) utmp;
268 	if (dir_index > directories_count) {
269 	    _dwarf_error(dbg, error, DW_DLE_DIR_INDEX_BAD);
270 	    return (DW_DLV_ERROR);
271 	}
272 
273 	if (dir_index == 0)
274 	    dir_name = (char *) comp_dir;
275 	else {
276 	    dir_name = (char *) include_directories;
277 	    for (i = 1; i < dir_index; i++)
278 		/* FIX: this is probably very slow: redoing strlen!
279 		   davea 9/94 */
280 		dir_name = dir_name + strlen(dir_name) + 1;
281 	}
282 
283 	/* dir_name can be NULL if there is no DW_AT_comp_dir */
284 	if ((*file_name) == '/' || dir_name == 0)
285 	    full_name = file_name;
286 	else {
287 	    full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
288 						  strlen(dir_name) + 1 +
289 						  strlen(file_name) +
290 						  1);
291 	    if (full_name == NULL) {
292 		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
293 		return (DW_DLV_ERROR);
294 	    }
295 
296 	    strcpy(full_name, dir_name);
297 	    strcat(full_name, "/");
298 	    strcat(full_name, file_name);
299 	}
300 
301 	/* Skip over time of last modification. */
302 	_dwarf_decode_u_leb128(line_ptr, &leb128_length);
303 	line_ptr = line_ptr + leb128_length;
304 
305 	/* Skip over file length. */
306 	_dwarf_decode_u_leb128(line_ptr, &leb128_length);
307 	line_ptr = line_ptr + leb128_length;
308 
309 	curr_chain =
310 	    (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
311 	if (curr_chain == NULL) {
312 	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
313 	    return (DW_DLV_ERROR);
314 	}
315 
316 	curr_chain->ch_item = full_name;
317 
318 	if (head_chain == NULL)
319 	    head_chain = prev_chain = curr_chain;
320 	else {
321 	    prev_chain->ch_next = curr_chain;
322 	    prev_chain = curr_chain;
323 	}
324 
325 	file_count++;
326     }
327     line_ptr++;
328 
329     if (line_ptr != check_line_ptr + prologue_length) {
330 	_dwarf_error(dbg, error, DW_DLE_LINE_PROLOG_LENGTH_BAD);
331 	return (DW_DLV_ERROR);
332     }
333 
334     if (file_count == 0) {
335 	*srcfiles = NULL;
336 	*srcfilecount = 0;
337 	return (DW_DLV_NO_ENTRY);
338     }
339 
340     ret_files = (char **)
341 	_dwarf_get_alloc(dbg, DW_DLA_LIST, file_count);
342     if (ret_files == NULL) {
343 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
344 	return (DW_DLV_ERROR);
345     }
346 
347     curr_chain = head_chain;
348     for (i = 0; i < file_count; i++) {
349 	*(ret_files + i) = curr_chain->ch_item;
350 	prev_chain = curr_chain;
351 	curr_chain = curr_chain->ch_next;
352 	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
353     }
354 
355     *srcfiles = ret_files;
356     *srcfilecount = file_count;
357     return (DW_DLV_OK);
358 }
359 
360 
361 /*
362 	return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
363 */
364 int
365 _dwarf_internal_srclines(Dwarf_Die die,
366 			 Dwarf_Line ** linebuf,
367 			 Dwarf_Signed * count,
368 			 Dwarf_Bool doaddrs,
369 			 Dwarf_Bool dolines, Dwarf_Error * error)
370 {
371     /*
372        This pointer is used to scan the portion of the .debug_line
373        section for the current cu. */
374     Dwarf_Small *line_ptr;
375 
376     /*
377        This points to the last byte of the .debug_line portion for the
378        current cu. */
379     Dwarf_Small *line_ptr_end;
380 
381     /*
382        This points to the end of the statement program prologue for the
383        current cu, and serves to check that the prologue was correctly
384        decoded. */
385     Dwarf_Small *check_line_ptr;
386 
387     /*
388        Pointer to a DW_AT_stmt_list attribute in case it exists in the
389        die. */
390     Dwarf_Attribute stmt_list_attr;
391 
392     /* Pointer to DW_AT_comp_dir attribute in die. */
393     Dwarf_Attribute comp_dir_attr;
394 
395     /* Pointer to name of compilation directory. */
396     Dwarf_Small *comp_dir = NULL;
397 
398     /*
399        Offset into .debug_line specified by a DW_AT_stmt_list
400        attribute. */
401     Dwarf_Unsigned line_offset;
402 
403     /* These are the fields of the statement program header. */
404     Dwarf_Unsigned total_length;
405     Dwarf_Half version;
406     Dwarf_Unsigned prologue_length;
407     Dwarf_Small minimum_instruction_length;
408     Dwarf_Small default_is_stmt;
409     Dwarf_Sbyte line_base;
410     Dwarf_Small line_range;
411     Dwarf_Small special_opcode_base;
412 
413     Dwarf_Small *opcode_length;
414     Dwarf_Small *include_directories;
415     Dwarf_File_Entry file_entries;
416 
417     /* These are the state machine state variables. */
418     Dwarf_Addr address;
419     Dwarf_Word file;
420     Dwarf_Word line;
421     Dwarf_Word column;
422     Dwarf_Bool is_stmt;
423     Dwarf_Bool basic_block;
424     Dwarf_Bool end_sequence;
425 
426     /*
427        These pointers are used to build the list of files names by
428        this cu.  cur_file_entry points to the file name being added,
429        and prev_file_entry to the previous one. */
430     Dwarf_File_Entry cur_file_entry, prev_file_entry;
431 
432     Dwarf_Sword i, file_entry_count, include_directories_count;
433 
434     /*
435        This is the current opcode read from the statement program. */
436     Dwarf_Small opcode;
437 
438     /*
439        Pointer to a Dwarf_Line_Context_s structure that contains the
440        context such as file names and include directories for the set
441        of lines being generated. */
442     Dwarf_Line_Context line_context;
443 
444     /*
445        This is a pointer to the current line being added to the line
446        matrix. */
447     Dwarf_Line curr_line;
448 
449     /*
450        These variables are used to decode leb128 numbers. Leb128_num
451        holds the decoded number, and leb128_length is its length in
452        bytes. */
453     Dwarf_Word leb128_num;
454     Dwarf_Word leb128_length;
455     Dwarf_Sword advance_line;
456 
457     /*
458        This is the operand of the latest fixed_advance_pc extended
459        opcode. */
460     Dwarf_Half fixed_advance_pc;
461 
462     /*
463        Counts the number of lines in the line matrix. */
464     Dwarf_Sword line_count = 0;
465 
466     /* This is the length of an extended opcode instr.  */
467     Dwarf_Word instr_length;
468     Dwarf_Small ext_opcode;
469 
470     /*
471        Used to chain together pointers to line table entries that are
472        later used to create a block of Dwarf_Line entries. */
473     Dwarf_Chain chain_line, head_chain = NULL, curr_chain;
474 
475     /*
476        This points to a block of Dwarf_Lines, a pointer to which is
477        returned in linebuf. */
478     Dwarf_Line *block_line;
479 
480     /* The Dwarf_Debug this die belongs to. */
481     Dwarf_Debug dbg;
482     int resattr;
483     int lres;
484     int local_length_size = 0;
485     /*REFERENCED*/ /* Not used in this instance of the macro */
486     int local_extension_size = 0;
487 
488     int res;
489 
490     /* ***** BEGIN CODE ***** */
491 
492     if (error != NULL)
493 	*error = NULL;
494 
495     CHECK_DIE(die, DW_DLV_ERROR)
496 	dbg = die->di_cu_context->cc_dbg;
497 
498     res =
499        _dwarf_load_section(dbg,
500 		           dbg->de_debug_line_index,
501 			   &dbg->de_debug_line,
502 			   error);
503     if (res != DW_DLV_OK) {
504 	return res;
505     }
506 
507     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
508     if (resattr != DW_DLV_OK) {
509 	return resattr;
510     }
511 
512 
513 
514     lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
515     if (lres != DW_DLV_OK) {
516 	return lres;
517     }
518 
519     if (line_offset >= dbg->de_debug_line_size) {
520 	_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
521 	return (DW_DLV_ERROR);
522     }
523     line_ptr = dbg->de_debug_line + line_offset;
524     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
525 
526     /*
527        If die has DW_AT_comp_dir attribute, get the string that names
528        the compilation directory. */
529     resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
530     if (resattr == DW_DLV_ERROR) {
531 	return resattr;
532     }
533     if (resattr == DW_DLV_OK) {
534 	int cres;
535 	char *cdir;
536 
537 	cres = dwarf_formstring(comp_dir_attr, &cdir, error);
538 	if (cres == DW_DLV_ERROR) {
539 	    return cres;
540 	} else if (cres == DW_DLV_OK) {
541 	    comp_dir = (Dwarf_Small *) cdir;
542 	}
543     }
544     if (resattr == DW_DLV_OK) {
545 	dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
546     }
547 
548     /*
549        Following is a straightforward decoding of the statement
550        program prologue information. */
551     /* READ_AREA_LENGTH updates line_ptr for consumed bytes */
552     READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
553 		     line_ptr, local_length_size, local_extension_size);
554 
555     line_ptr_end = line_ptr + total_length;
556     if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) {
557 	_dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD);
558 	return (DW_DLV_ERROR);
559     }
560 
561     READ_UNALIGNED(dbg, version, Dwarf_Half,
562 		   line_ptr, sizeof(Dwarf_Half));
563     line_ptr += sizeof(Dwarf_Half);
564     if (version != CURRENT_VERSION_STAMP) {
565 	_dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
566 	return (DW_DLV_ERROR);
567     }
568 
569     READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
570 		   line_ptr, local_length_size);
571     line_ptr += local_length_size;
572     check_line_ptr = line_ptr;
573 
574     minimum_instruction_length = *(Dwarf_Small *) line_ptr;
575     line_ptr = line_ptr + sizeof(Dwarf_Small);
576 
577     default_is_stmt = *(Dwarf_Small *) line_ptr;
578     line_ptr = line_ptr + sizeof(Dwarf_Small);
579 
580     line_base = *(Dwarf_Sbyte *) line_ptr;
581     line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
582 
583     line_range = *(Dwarf_Small *) line_ptr;
584     line_ptr = line_ptr + sizeof(Dwarf_Small);
585 
586     special_opcode_base = *(Dwarf_Small *) line_ptr;
587     line_ptr = line_ptr + sizeof(Dwarf_Small);
588 
589     opcode_length = (Dwarf_Small *)
590 	alloca(sizeof(Dwarf_Small) * special_opcode_base);
591     for (i = 1; i < special_opcode_base; i++) {
592 	opcode_length[i] = *(Dwarf_Small *) line_ptr;
593 	line_ptr = line_ptr + sizeof(Dwarf_Small);
594     }
595 
596     include_directories_count = 0;
597     include_directories = line_ptr;
598     while ((*(char *) line_ptr) != '\0') {
599 	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
600 	include_directories_count++;
601     }
602     line_ptr++;
603 
604     file_entry_count = 0;
605     file_entries = prev_file_entry = NULL;
606     while (*(char *) line_ptr != '\0') {
607 
608 	cur_file_entry = (Dwarf_File_Entry)
609 	    _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
610 	if (cur_file_entry == NULL) {
611 	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
612 	    return (DW_DLV_ERROR);
613 	}
614 
615 	cur_file_entry->fi_file_name = (Dwarf_Small *) line_ptr;
616 	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
617 
618 	cur_file_entry->fi_dir_index =
619 	    (Dwarf_Sword) _dwarf_decode_u_leb128(line_ptr,
620 						 &leb128_length);
621 	line_ptr = line_ptr + leb128_length;
622 
623 	cur_file_entry->fi_time_last_mod =
624 	    _dwarf_decode_u_leb128(line_ptr, &leb128_length);
625 	line_ptr = line_ptr + leb128_length;
626 
627 	cur_file_entry->fi_file_length =
628 	    _dwarf_decode_u_leb128(line_ptr, &leb128_length);
629 	line_ptr = line_ptr + leb128_length;
630 
631 	if (file_entries == NULL)
632 	    file_entries = cur_file_entry;
633 	else
634 	    prev_file_entry->fi_next = cur_file_entry;
635 	prev_file_entry = cur_file_entry;
636 
637 	file_entry_count++;
638     }
639     line_ptr++;
640 
641     if (line_ptr != check_line_ptr + prologue_length) {
642 	_dwarf_error(dbg, error, DW_DLE_LINE_PROLOG_LENGTH_BAD);
643 	return (DW_DLV_ERROR);
644     }
645 
646     /* Set up context structure for this set of lines. */
647     line_context = (Dwarf_Line_Context)
648 	_dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
649     if (line_context == NULL) {
650 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
651 	return (DW_DLV_ERROR);
652     }
653 
654     /* Initialize the state machine.  */
655     address = 0;
656     file = 1;
657     line = 1;
658     column = 0;
659     is_stmt = default_is_stmt;
660     basic_block = false;
661     end_sequence = false;
662 
663     /* Start of statement program.  */
664     while (line_ptr < line_ptr_end) {
665 	int type;
666 
667 	opcode = *(Dwarf_Small *) line_ptr;
668 	line_ptr++;
669 
670 
671 	/* 'type' is the output */
672 	WHAT_IS_OPCODE(type, opcode, special_opcode_base,
673 		       opcode_length, line_ptr);
674 
675 
676 
677 	if (type == LOP_DISCARD) {
678 	    /* do nothing, necessary ops done */
679 	} else if (type == LOP_SPECIAL) {
680 	    /* This op code is a special op in the object, no matter
681 	       that it might fall into the standard op range in this
682 	       compile Thatis, these are special opcodes between
683 	       special_opcode_base and MAX_LINE_OP_CODE.  (including
684 	       special_opcode_base and MAX_LINE_OP_CODE) */
685 
686 	    opcode = opcode - special_opcode_base;
687 	    address = address + minimum_instruction_length *
688 		(opcode / line_range);
689 	    line = line + line_base + opcode % line_range;
690 
691 	    if (dolines) {
692 		curr_line =
693 		    (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
694 		if (curr_line == NULL) {
695 		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
696 		    return (DW_DLV_ERROR);
697 		}
698 
699 		curr_line->li_address = address;
700 		curr_line->li_addr_line.li_l_data.li_file =
701 		    (Dwarf_Sword) file;
702 		curr_line->li_addr_line.li_l_data.li_line =
703 		    (Dwarf_Sword) line;
704 		curr_line->li_addr_line.li_l_data.li_column =
705 		    (Dwarf_Half) column;
706 		curr_line->li_addr_line.li_l_data.li_is_stmt = is_stmt;
707 		curr_line->li_addr_line.li_l_data.li_basic_block =
708 		    basic_block;
709 		curr_line->li_addr_line.li_l_data.li_end_sequence =
710 		    end_sequence;
711 		curr_line->li_context = line_context;
712 		line_count++;
713 
714 		chain_line = (Dwarf_Chain)
715 		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
716 		if (chain_line == NULL) {
717 		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
718 		    return (DW_DLV_ERROR);
719 		}
720 		chain_line->ch_item = curr_line;
721 
722 		if (head_chain == NULL)
723 		    head_chain = curr_chain = chain_line;
724 		else {
725 		    curr_chain->ch_next = chain_line;
726 		    curr_chain = chain_line;
727 		}
728 	    }
729 
730 	    basic_block = false;
731 	} else if (type == LOP_STANDARD) {
732 	    switch (opcode) {
733 
734 	    case DW_LNS_copy:{
735 		    if (opcode_length[DW_LNS_copy] != 0) {
736 			_dwarf_error(dbg, error,
737 				     DW_DLE_LINE_NUM_OPERANDS_BAD);
738 			return (DW_DLV_ERROR);
739 		    }
740 
741 		    if (dolines) {
742 
743 			curr_line =
744 			    (Dwarf_Line) _dwarf_get_alloc(dbg,
745 							  DW_DLA_LINE,
746 							  1);
747 			if (curr_line == NULL) {
748 			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
749 			    return (DW_DLV_ERROR);
750 			}
751 
752 			curr_line->li_address = address;
753 			curr_line->li_addr_line.li_l_data.li_file =
754 			    (Dwarf_Sword) file;
755 			curr_line->li_addr_line.li_l_data.li_line =
756 			    (Dwarf_Sword) line;
757 			curr_line->li_addr_line.li_l_data.li_column =
758 			    (Dwarf_Half) column;
759 			curr_line->li_addr_line.li_l_data.li_is_stmt =
760 			    is_stmt;
761 			curr_line->li_addr_line.li_l_data.
762 			    li_basic_block = basic_block;
763 			curr_line->li_addr_line.li_l_data.
764 			    li_end_sequence = end_sequence;
765 			curr_line->li_context = line_context;
766 			line_count++;
767 
768 			chain_line = (Dwarf_Chain)
769 			    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
770 			if (chain_line == NULL) {
771 			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
772 			    return (DW_DLV_ERROR);
773 			}
774 			chain_line->ch_item = curr_line;
775 			if (head_chain == NULL)
776 			    head_chain = curr_chain = chain_line;
777 			else {
778 			    curr_chain->ch_next = chain_line;
779 			    curr_chain = chain_line;
780 			}
781 		    }
782 
783 		    basic_block = false;
784 		    break;
785 		}
786 
787 	    case DW_LNS_advance_pc:{
788 		    Dwarf_Unsigned utmp2;
789 
790 		    if (opcode_length[DW_LNS_advance_pc] != 1) {
791 			_dwarf_error(dbg, error,
792 				     DW_DLE_LINE_NUM_OPERANDS_BAD);
793 			return (DW_DLV_ERROR);
794 		    }
795 
796 		    DECODE_LEB128_UWORD(line_ptr, utmp2)
797 			leb128_num = (Dwarf_Word) utmp2;
798 		    address =
799 			address +
800 			minimum_instruction_length * leb128_num;
801 		    break;
802 		}
803 
804 	    case DW_LNS_advance_line:{
805 		    Dwarf_Signed stmp;
806 
807 		    if (opcode_length[DW_LNS_advance_line] != 1) {
808 			_dwarf_error(dbg, error,
809 				     DW_DLE_LINE_NUM_OPERANDS_BAD);
810 			return (DW_DLV_ERROR);
811 		    }
812 
813 		    DECODE_LEB128_SWORD(line_ptr, stmp)
814 			advance_line = (Dwarf_Sword) stmp;
815 		    line = line + advance_line;
816 		    break;
817 		}
818 
819 	    case DW_LNS_set_file:{
820 		    Dwarf_Unsigned utmp2;
821 
822 		    if (opcode_length[DW_LNS_set_file] != 1) {
823 			_dwarf_error(dbg, error,
824 				     DW_DLE_LINE_NUM_OPERANDS_BAD);
825 			return (DW_DLV_ERROR);
826 		    }
827 
828 		    DECODE_LEB128_UWORD(line_ptr, utmp2)
829 			file = (Dwarf_Word) utmp2;
830 		    break;
831 		}
832 
833 	    case DW_LNS_set_column:{
834 		    Dwarf_Unsigned utmp2;
835 
836 		    if (opcode_length[DW_LNS_set_column] != 1) {
837 			_dwarf_error(dbg, error,
838 				     DW_DLE_LINE_NUM_OPERANDS_BAD);
839 			return (DW_DLV_ERROR);
840 		    }
841 
842 		    DECODE_LEB128_UWORD(line_ptr, utmp2)
843 			column = (Dwarf_Word) utmp2;
844 		    break;
845 		}
846 
847 	    case DW_LNS_negate_stmt:{
848 		    if (opcode_length[DW_LNS_negate_stmt] != 0) {
849 			_dwarf_error(dbg, error,
850 				     DW_DLE_LINE_NUM_OPERANDS_BAD);
851 			return (DW_DLV_ERROR);
852 		    }
853 
854 		    is_stmt = !is_stmt;
855 		    break;
856 		}
857 
858 	    case DW_LNS_set_basic_block:{
859 		    if (opcode_length[DW_LNS_set_basic_block] != 0) {
860 			_dwarf_error(dbg, error,
861 				     DW_DLE_LINE_NUM_OPERANDS_BAD);
862 			return (DW_DLV_ERROR);
863 		    }
864 
865 		    basic_block = true;
866 		    break;
867 		}
868 
869 	    case DW_LNS_const_add_pc:{
870 		    opcode = MAX_LINE_OP_CODE - special_opcode_base;
871 		    address = address + minimum_instruction_length *
872 			(opcode / line_range);
873 
874 		    break;
875 		}
876 
877 	    case DW_LNS_fixed_advance_pc:{
878 		    if (opcode_length[DW_LNS_fixed_advance_pc] != 1) {
879 			_dwarf_error(dbg, error,
880 				     DW_DLE_LINE_NUM_OPERANDS_BAD);
881 			return (DW_DLV_ERROR);
882 		    }
883 
884 		    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
885 				   line_ptr, sizeof(Dwarf_Half));
886 		    line_ptr += sizeof(Dwarf_Half);
887 		    address = address + fixed_advance_pc;
888 		    break;
889 		}
890 	    }
891 
892 	} else if (type == LOP_EXTENDED) {
893 	    Dwarf_Unsigned utmp3;
894 
895 	    DECODE_LEB128_UWORD(line_ptr, utmp3)
896 		instr_length = (Dwarf_Word) utmp3;
897 	    /* Dwarf_Small is a ubyte and the extended opcode
898 	       is a ubyte, though not stated as clearly in
899 	       the 2.0.0 spec as one might hope.
900 	    */
901 	    ext_opcode = *(Dwarf_Small *) line_ptr;
902 	    line_ptr++;
903 	    switch (ext_opcode) {
904 
905 	    case DW_LNE_end_sequence:{
906 		    end_sequence = true;
907 
908 		    if (dolines) {
909 			curr_line = (Dwarf_Line)
910 			    _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
911 			if (curr_line == NULL) {
912 			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
913 			    return (DW_DLV_ERROR);
914 			}
915 
916 			curr_line->li_address = address;
917 			curr_line->li_addr_line.li_l_data.li_file =
918 			    (Dwarf_Sword) file;
919 			curr_line->li_addr_line.li_l_data.li_line =
920 			    (Dwarf_Sword) line;
921 			curr_line->li_addr_line.li_l_data.li_column =
922 			    (Dwarf_Half) column;
923 			curr_line->li_addr_line.li_l_data.li_is_stmt =
924 			    default_is_stmt;
925 			curr_line->li_addr_line.li_l_data.
926 			    li_basic_block = basic_block;
927 			curr_line->li_addr_line.li_l_data.
928 			    li_end_sequence = end_sequence;
929 			curr_line->li_context = line_context;
930 			line_count++;
931 
932 			chain_line = (Dwarf_Chain)
933 			    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
934 			if (chain_line == NULL) {
935 			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
936 			    return (DW_DLV_ERROR);
937 			}
938 			chain_line->ch_item = curr_line;
939 
940 			if (head_chain == NULL)
941 			    head_chain = curr_chain = chain_line;
942 			else {
943 			    curr_chain->ch_next = chain_line;
944 			    curr_chain = chain_line;
945 			}
946 		    }
947 
948 		    address = 0;
949 		    file = 1;
950 		    line = 1;
951 		    column = 0;
952 		    is_stmt = default_is_stmt;
953 		    basic_block = false;
954 		    end_sequence = false;
955 
956 		    break;
957 		}
958 
959 	    case DW_LNE_set_address:{
960 		    if (instr_length - 1 == dbg->de_pointer_size) {
961 			READ_UNALIGNED(dbg, address, Dwarf_Addr,
962 				       line_ptr, dbg->de_pointer_size);
963 			if (doaddrs) {
964 			    curr_line =
965 				(Dwarf_Line) _dwarf_get_alloc(dbg,
966 							      DW_DLA_LINE,
967 							      1);
968 			    if (curr_line == NULL) {
969 				_dwarf_error(dbg, error,
970 					     DW_DLE_ALLOC_FAIL);
971 				return (DW_DLV_ERROR);
972 			    }
973 
974 			    curr_line->li_address = address;
975 			    curr_line->li_addr_line.li_offset =
976 				line_ptr - dbg->de_debug_line;
977 
978 			    line_count++;
979 
980 			    chain_line = (Dwarf_Chain)
981 				_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
982 			    if (chain_line == NULL) {
983 				_dwarf_error(dbg, error,
984 					     DW_DLE_ALLOC_FAIL);
985 				return (DW_DLV_ERROR);
986 			    }
987 			    chain_line->ch_item = curr_line;
988 
989 			    if (head_chain == NULL)
990 				head_chain = curr_chain = chain_line;
991 			    else {
992 				curr_chain->ch_next = chain_line;
993 				curr_chain = chain_line;
994 			    }
995 			}
996 
997 			line_ptr += dbg->de_pointer_size;
998 		    } else {
999 			_dwarf_error(dbg, error,
1000 				     DW_DLE_LINE_SET_ADDR_ERROR);
1001 			return (DW_DLV_ERROR);
1002 		    }
1003 
1004 		    break;
1005 		}
1006 
1007 	    case DW_LNE_define_file:{
1008 
1009 		    if (dolines) {
1010 			cur_file_entry = (Dwarf_File_Entry)
1011 			    _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
1012 			if (cur_file_entry == NULL) {
1013 			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1014 			    return (DW_DLV_ERROR);
1015 			}
1016 
1017 			cur_file_entry->fi_file_name =
1018 			    (Dwarf_Small *) line_ptr;
1019 			line_ptr =
1020 			    line_ptr + strlen((char *) line_ptr) + 1;
1021 
1022 			cur_file_entry->fi_dir_index =
1023 			    (Dwarf_Sword)
1024 			    _dwarf_decode_u_leb128(line_ptr,
1025 						   &leb128_length);
1026 			line_ptr = line_ptr + leb128_length;
1027 
1028 			cur_file_entry->fi_time_last_mod =
1029 			    _dwarf_decode_u_leb128(line_ptr,
1030 						   &leb128_length);
1031 			line_ptr = line_ptr + leb128_length;
1032 
1033 			cur_file_entry->fi_file_length =
1034 			    _dwarf_decode_u_leb128(line_ptr,
1035 						   &leb128_length);
1036 			line_ptr = line_ptr + leb128_length;
1037 
1038 			if (file_entries == NULL)
1039 			    file_entries = cur_file_entry;
1040 			else
1041 			    prev_file_entry->fi_next = cur_file_entry;
1042 			prev_file_entry = cur_file_entry;
1043 
1044 			file_entry_count++;
1045 		    }
1046 		    break;
1047 		}
1048 
1049 	    default:{
1050 		    _dwarf_error(dbg, error,
1051 				 DW_DLE_LINE_EXT_OPCODE_BAD);
1052 		    return (DW_DLV_ERROR);
1053 		}
1054 	    }
1055 
1056 	}
1057     }
1058 
1059     block_line = (Dwarf_Line *)
1060 	_dwarf_get_alloc(dbg, DW_DLA_LIST, line_count);
1061     if (block_line == NULL) {
1062 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1063 	return (DW_DLV_ERROR);
1064     }
1065 
1066     curr_chain = head_chain;
1067     for (i = 0; i < line_count; i++) {
1068 	*(block_line + i) = curr_chain->ch_item;
1069 	head_chain = curr_chain;
1070 	curr_chain = curr_chain->ch_next;
1071 	dwarf_dealloc(dbg, head_chain, DW_DLA_CHAIN);
1072     }
1073 
1074     line_context->lc_file_entries = file_entries;
1075     line_context->lc_file_entry_count = file_entry_count;
1076     line_context->lc_include_directories = include_directories;
1077     line_context->lc_include_directories_count =
1078 	include_directories_count;
1079     line_context->lc_line_count = line_count;
1080     line_context->lc_compilation_directory = comp_dir;
1081     line_context->lc_dbg = dbg;
1082     *count = line_count;
1083 
1084     *linebuf = block_line;
1085     return (DW_DLV_OK);
1086 }
1087 
1088 int
1089 dwarf_srclines(Dwarf_Die die,
1090 	       Dwarf_Line ** linebuf,
1091 	       Dwarf_Signed * linecount, Dwarf_Error * error)
1092 {
1093     Dwarf_Signed count;
1094     int res;
1095 
1096     res = _dwarf_internal_srclines(die, linebuf,
1097 				   &count, /* addrlist= */ false,
1098 				   /* linelist= */ true, error);
1099     if (res != DW_DLV_OK) {
1100 	return res;
1101     }
1102     *linecount = count;
1103     return res;
1104 }
1105 
1106 
1107 
1108 
1109 
1110 int
1111 dwarf_linebeginstatement(Dwarf_Line line,
1112 			 Dwarf_Bool * return_bool, Dwarf_Error * error)
1113 {
1114     if (line == NULL || return_bool == 0) {
1115 	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1116 	return (DW_DLV_ERROR);
1117     }
1118 
1119     *return_bool = (line->li_addr_line.li_l_data.li_is_stmt);
1120     return DW_DLV_OK;
1121 }
1122 
1123 int
1124 dwarf_lineendsequence(Dwarf_Line line,
1125 		      Dwarf_Bool * return_bool, Dwarf_Error * error)
1126 {
1127     if (line == NULL) {
1128 	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1129 	return (DW_DLV_ERROR);
1130     }
1131 
1132     *return_bool = (line->li_addr_line.li_l_data.li_end_sequence);
1133     return DW_DLV_OK;
1134 }
1135 
1136 
1137 int
1138 dwarf_lineno(Dwarf_Line line,
1139 	     Dwarf_Unsigned * ret_lineno, Dwarf_Error * error)
1140 {
1141     if (line == NULL || ret_lineno == 0) {
1142 	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1143 	return (DW_DLV_ERROR);
1144     }
1145 
1146     *ret_lineno = (line->li_addr_line.li_l_data.li_line);
1147     return DW_DLV_OK;
1148 }
1149 
1150 
1151 int
1152 dwarf_lineaddr(Dwarf_Line line,
1153 	       Dwarf_Addr * ret_lineaddr, Dwarf_Error * error)
1154 {
1155     if (line == NULL || ret_lineaddr == 0) {
1156 	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1157 	return (DW_DLV_ERROR);
1158     }
1159 
1160     *ret_lineaddr = (line->li_address);
1161     return DW_DLV_OK;
1162 }
1163 
1164 
1165 int
1166 dwarf_lineoff(Dwarf_Line line,
1167 	      Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
1168 {
1169     if (line == NULL || ret_lineoff == 0) {
1170 	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1171 	return (DW_DLV_ERROR);
1172     }
1173 
1174     *ret_lineoff =
1175 	(line->li_addr_line.li_l_data.li_column ==
1176 	 0 ? -1 : line->li_addr_line.li_l_data.li_column);
1177     return DW_DLV_OK;
1178 }
1179 
1180 
1181 int
1182 dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error)
1183 {
1184     Dwarf_Signed i;
1185     Dwarf_File_Entry file_entry;
1186     Dwarf_Small *name_buffer;
1187     Dwarf_Small *include_directories;
1188     Dwarf_Debug dbg;
1189     unsigned int comp_dir_len;
1190 
1191     if (line == NULL) {
1192 	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1193 	return (DW_DLV_ERROR);
1194     }
1195 
1196     if (line->li_context == NULL) {
1197 	_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
1198 	return (DW_DLV_ERROR);
1199     }
1200     dbg = line->li_context->lc_dbg;
1201 
1202     if (line->li_addr_line.li_l_data.li_file >
1203 	line->li_context->lc_file_entry_count) {
1204 	_dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD);
1205 	return (DW_DLV_ERROR);
1206     }
1207 
1208     file_entry = line->li_context->lc_file_entries;
1209     for (i = line->li_addr_line.li_l_data.li_file - 1; i > 0; i--)
1210 	file_entry = file_entry->fi_next;
1211 
1212     if (file_entry->fi_file_name == NULL) {
1213 	_dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
1214 	return (DW_DLV_ERROR);
1215     }
1216 
1217     if (*(char *) file_entry->fi_file_name == '/') {
1218 	*ret_linesrc = ((char *) file_entry->fi_file_name);
1219 	return DW_DLV_OK;
1220     }
1221 
1222     if (file_entry->fi_dir_index == 0) {
1223 
1224 	/* dir_index of 0 means that the compilation was in the
1225 	   'current directory of compilation' */
1226 	if (line->li_context->lc_compilation_directory == NULL) {
1227 	    /* we don't actually *have* a current directory of
1228 	       compilation: DW_AT_comp_dir was not present Rather than
1229 	       emitting DW_DLE_NO_COMP_DIR lets just make an empty name
1230 	       here. In other words, do the best we can with what we do
1231 	       have instead of reporting an error. _dwarf_error(dbg,
1232 	       error, DW_DLE_NO_COMP_DIR); return(DW_DLV_ERROR); */
1233 	    comp_dir_len = 0;
1234 	} else {
1235 	    comp_dir_len = strlen((char *)
1236 				  (line->li_context->
1237 				   lc_compilation_directory));
1238 	}
1239 
1240 	name_buffer =
1241 	    _dwarf_get_alloc(line->li_context->lc_dbg, DW_DLA_STRING,
1242 			     comp_dir_len + 1 +
1243 			     strlen((char *) file_entry->fi_file_name) +
1244 			     1);
1245 	if (name_buffer == NULL) {
1246 	    _dwarf_error(line->li_context->lc_dbg, error,
1247 			 DW_DLE_ALLOC_FAIL);
1248 	    return (DW_DLV_ERROR);
1249 	}
1250 
1251 	if (comp_dir_len > 0) {
1252 	    /* if comp_dir_len is 0 we do not want to put a / in front
1253 	       of the fi_file_name as we just don't know anything. */
1254 	    strcpy((char *) name_buffer,
1255 		   (char *) (line->li_context->
1256 			     lc_compilation_directory));
1257 	    strcat((char *) name_buffer, "/");
1258 	}
1259 	strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
1260 	*ret_linesrc = ((char *) name_buffer);
1261 	return DW_DLV_OK;
1262     }
1263 
1264     if (file_entry->fi_dir_index >
1265 	line->li_context->lc_include_directories_count) {
1266 	_dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD);
1267 	return (DW_DLV_ERROR);
1268     }
1269 
1270     include_directories = line->li_context->lc_include_directories;
1271     for (i = file_entry->fi_dir_index - 1; i > 0; i--)
1272 	include_directories += strlen((char *) include_directories) + 1;
1273 
1274     if (line->li_context->lc_compilation_directory) {
1275 	comp_dir_len = strlen((char *)
1276 			      (line->li_context->
1277 			       lc_compilation_directory));
1278     } else {
1279 	/* No DW_AT_comp_dir present. Do the best we can without it. */
1280 	comp_dir_len = 0;
1281     }
1282 
1283     name_buffer = _dwarf_get_alloc(dbg, DW_DLA_STRING,
1284 				   (*include_directories == '/' ?
1285 				    0 : comp_dir_len + 1) +
1286 				   strlen((char *) include_directories)
1287 				   + 1 +
1288 				   strlen((char *) file_entry->
1289 					  fi_file_name) + 1);
1290     if (name_buffer == NULL) {
1291 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1292 	return (DW_DLV_ERROR);
1293     }
1294 
1295     if (*include_directories != '/') {
1296 	if (comp_dir_len > 0) {
1297 	    strcpy((char *) name_buffer,
1298 		   (char *) line->li_context->lc_compilation_directory);
1299 	    /* Who provides the / needed after the compilation
1300 	       directory? */
1301 	    if (name_buffer[comp_dir_len - 1] != '/') {
1302 		/* Here we provide the / separator */
1303 		name_buffer[comp_dir_len] = '/';	/* overwrite
1304 							   previous nul
1305 							   terminator
1306 							   with needed
1307 							   / */
1308 		name_buffer[comp_dir_len + 1] = 0;
1309 	    }
1310 	}
1311     } else {
1312 	strcpy((char *) name_buffer, "");
1313     }
1314     strcat((char *) name_buffer, (char *) include_directories);
1315     strcat((char *) name_buffer, "/");
1316     strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
1317     *ret_linesrc = ((char *) name_buffer);
1318     return DW_DLV_OK;
1319 }
1320 
1321 
1322 int
1323 dwarf_lineblock(Dwarf_Line line,
1324 		Dwarf_Bool * return_bool, Dwarf_Error * error)
1325 {
1326     if (line == NULL) {
1327 	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1328 	return (DW_DLV_ERROR);
1329     }
1330 
1331     *return_bool = (line->li_addr_line.li_l_data.li_basic_block);
1332     return DW_DLV_OK;
1333 }
1334 
1335 
1336 #if 0				/* Ignore this.  This needs major
1337 				   re-work. */
1338 /*
1339     This routine works by looking for exact matches between
1340     the current line address and pc, and crossovers from
1341     from less than pc value to greater than.  At each line
1342     that satisfies the above, it records a pointer to the
1343     line, and the difference between the address and pc.
1344     It then scans these pointers and picks out those with
1345     the smallest difference between pc and address.
1346 */
1347 int
1348 dwarf_pclines(Dwarf_Debug dbg,
1349 	      Dwarf_Addr pc,
1350 	      Dwarf_Line ** linebuf,
1351 	      Dwarf_Signed slide,
1352 	      Dwarf_Signed * linecount, Dwarf_Error * error)
1353 {
1354     /*
1355        Scans the line matrix for the current cu to which a pointer
1356        exists in dbg. */
1357     Dwarf_Line line;
1358     Dwarf_Line prev_line;
1359 
1360     /*
1361        These flags are for efficiency reasons. Check_line is true
1362        initially, but set false when the address of the current line
1363        is greater than pc.  It is set true only when the address of the
1364        current line falls below pc.  This assumes that addresses
1365        within the same segment increase, and we are only interested in
1366        the switch from a less than pc address to a greater than.
1367        First_line is set true initially, but set false after the first
1368        line is scanned.  This is to prevent looking at the address of
1369        previous line when slide is DW_DLS_BACKWARD, and the first line
1370        is being scanned. */
1371     Dwarf_Bool check_line, first_line;
1372 
1373     /*
1374        Diff tracks the smallest difference a line address and the
1375        input pc value. */
1376     Dwarf_Signed diff, i;
1377 
1378     /*
1379        For the slide = DW_DLS_BACKWARD case, pc_less is the value of
1380        the address of the line immediately preceding the first line
1381        that has value greater than pc. For the slide = DW_DLS_FORWARD
1382        case, pc_more is the values of address for the first line that
1383        is greater than pc. Diff is the difference between either of
1384        the these values and pc. */
1385     Dwarf_Addr pc_less, pc_more;
1386 
1387     /*
1388        Pc_line_buf points to a chain of pointers to lines of which
1389        those with a diff equal to the smallest difference will be
1390        returned. */
1391     Dwarf_Line *pc_line_buf, *pc_line;
1392 
1393     /*
1394        Chain_count counts the number of lines in the above chain for
1395        which the diff is equal to the smallest difference This is the
1396        number returned by this routine. */
1397     Dwarf_Signed chain_count;
1398 
1399     chain_head = NULL;
1400 
1401     check_line = true;
1402     first_line = true;
1403     diff = MAX_LINE_DIFF;
1404 
1405     for (i = 0; i < dbg->de_cu_line_count; i++) {
1406 
1407 	line = *(dbg->de_cu_line_ptr + i);
1408 	prev_line = first_line ? NULL : *(dbg->de_cu_line_ptr + i - 1);
1409 
1410 	if (line->li_address == pc) {
1411 	    chain_ptr = (struct chain *)
1412 		_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
1413 	    if (chain_ptr == NULL) {
1414 		_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
1415 		return (DW_DLV_ERROR);
1416 	    }
1417 
1418 	    chain_ptr->line = line;
1419 	    chain_ptr->diff = diff = 0;
1420 	    chain_ptr->next = chain_head;
1421 	    chain_head = chain_ptr;
1422 	} else
1423 	    /*
1424 	       Look for crossover from less than pc address to greater
1425 	       than. */
1426 	if (check_line && line->li_address > pc &&
1427 		(first_line ? 0 : prev_line->li_address) < pc)
1428 
1429 	    if (slide == DW_DLS_BACKWARD && !first_line) {
1430 		pc_less = prev_line->li_address;
1431 		if (pc - pc_less <= diff) {
1432 		    chain_ptr = (struct chain *)
1433 			_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
1434 		    if (chain_ptr == NULL) {
1435 			_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
1436 			return (DW_DLV_ERROR);
1437 		    }
1438 
1439 		    chain_ptr->line = prev_line;
1440 		    chain_ptr->diff = diff = pc - pc_less;
1441 		    chain_ptr->next = chain_head;
1442 		    chain_head = chain_ptr;
1443 		}
1444 		check_line = false;
1445 	    } else if (slide == DW_DLS_FORWARD) {
1446 		pc_more = line->li_address;
1447 		if (pc_more - pc <= diff) {
1448 		    chain_ptr = (struct chain *)
1449 			_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
1450 		    if (chain_ptr == NULL) {
1451 			_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
1452 			return (DW_DLV_ERROR);
1453 		    }
1454 
1455 		    chain_ptr->line = line;
1456 		    chain_ptr->diff = diff = pc_more - pc;
1457 		    chain_ptr->next = chain_head;
1458 		    chain_head = chain_ptr;
1459 		}
1460 		check_line = false;
1461 	    } else
1462 		/* Check addresses only when they go */
1463 		/* below pc.  */
1464 	    if (line->li_address < pc)
1465 		check_line = true;
1466 
1467 	first_line = false;
1468     }
1469 
1470     chain_count = 0;
1471     for (chain_ptr = chain_head; chain_ptr != NULL;
1472 	 chain_ptr = chain_ptr->next)
1473 	if (chain_ptr->diff == diff)
1474 	    chain_count++;
1475 
1476     pc_line_buf = pc_line = (Dwarf_Line)
1477 	_dwarf_get_alloc(dbg, DW_DLA_LIST, chain_count);
1478     for (chain_ptr = chain_head; chain_ptr != NULL;
1479 	 chain_ptr = chain_ptr->next)
1480 	if (chain_ptr->diff == diff) {
1481 	    *pc_line = chain_ptr->line;
1482 	    pc_line++;
1483 	}
1484 
1485     for (chain_ptr = chain_head; chain_ptr != NULL;) {
1486 	chain_head = chain_ptr;
1487 	chain_ptr = chain_ptr->next;
1488 	dwarf_dealloc(dbg, chain_head, DW_DLA_CHAIN);
1489     }
1490 
1491     *linebuf = pc_line_buf;
1492     return (chain_count);
1493 }
1494 #endif
1495 
1496 
1497 /*
1498 	Return DW_DLV_OK or, if error,
1499 	DW_DLV_ERROR.
1500 
1501 	Thru pointers, return 2 arrays and a count
1502 	for rqs.
1503 */
1504 int
1505 _dwarf_line_address_offsets(Dwarf_Debug dbg,
1506 			    Dwarf_Die die,
1507 			    Dwarf_Addr ** addrs,
1508 			    Dwarf_Off ** offs,
1509 			    Dwarf_Unsigned * returncount,
1510 			    Dwarf_Error * err)
1511 {
1512     Dwarf_Addr *laddrs;
1513     Dwarf_Off *loffsets;
1514     Dwarf_Signed lcount;
1515     Dwarf_Signed i;
1516     int res;
1517     Dwarf_Line *linebuf;
1518 
1519     res = _dwarf_internal_srclines(die, &linebuf,
1520 				   &lcount, /* addrlist= */ true,
1521 				   /* linelist= */ false, err);
1522     if (res != DW_DLV_OK) {
1523 	return res;
1524     }
1525     laddrs = (Dwarf_Addr *)
1526 	_dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount);
1527     if (laddrs == NULL) {
1528 	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
1529 	return (DW_DLV_ERROR);
1530     }
1531     loffsets = (Dwarf_Off *)
1532 	_dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount);
1533     if (loffsets == NULL) {
1534 	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
1535 	return (DW_DLV_ERROR);
1536     }
1537 
1538     for (i = 0; i < lcount; i++) {
1539 	laddrs[i] = linebuf[i]->li_address;
1540 	loffsets[i] = linebuf[i]->li_addr_line.li_offset;
1541 	dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
1542     }
1543     dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
1544     *returncount = lcount;
1545     *offs = loffsets;
1546     *addrs = laddrs;
1547     return DW_DLV_OK;
1548 }
1549