1/*
2
3  Copyright (C) 2000,2002,2003,2004,2005 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., 1500 Crittenden Lane,
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#ifdef HAVE_ELF_H
41#include <elf.h>
42#endif
43#ifdef __SGI_FAST_LIBELF
44#include <libelf_sgi.h>
45#else
46#ifdef HAVE_LIBELF_H
47#include <libelf.h>
48#else
49#ifdef HAVE_LIBELF_LIBELF_H
50#include <libelf/libelf.h>
51#endif
52#endif
53#endif /* !defined(__SGI_FAST_LIBELF) */
54
55#include <stdio.h>
56#include <sys/stat.h>
57#include <sys/types.h>
58#include <string.h>
59#include <stdlib.h>
60
61#include "dwarf_incl.h"
62#include "malloc_check.h"
63
64#define DWARF_DBG_ERROR(dbg,errval,retval) \
65     _dwarf_error(dbg, error, errval); return(retval);
66
67#define FALSE	0
68#define TRUE	1
69
70#ifdef __SGI_FAST_LIBELF
71#else
72#ifdef HAVE_ELF64_GETEHDR
73extern Elf64_Ehdr *elf64_getehdr(Elf *);
74#endif
75#ifdef HAVE_ELF64_GETSHDR
76extern Elf64_Shdr *elf64_getshdr(Elf_Scn *);
77#endif
78#endif /* !defined(__SGI_FAST_LIBELF) */
79
80
81/* This static is copied to the dbg on dbg init
82   so that the static need not be referenced at
83   run time, preserving better locality of
84   reference.
85   Value is 0 means do the string check.
86   Value non-zero means do not do the check.
87*/
88static Dwarf_Small _dwarf_assume_string_bad;
89
90
91int
92dwarf_set_stringcheck(int newval)
93{
94    int oldval = _dwarf_assume_string_bad;
95
96    _dwarf_assume_string_bad = newval;
97    return oldval;
98}
99
100#ifdef __SGI_FAST_LIBELF
101/*
102	This function translates an elf_sgi error code into a libdwarf
103	code.
104 */
105static int
106_dwarf_error_code_from_elf_sgi_error_code(enum elf_sgi_error_type val)
107{
108    switch (val) {
109    case ELF_SGI_ERROR_OK:
110	return DW_DLE_NE;
111    case ELF_SGI_ERROR_BAD_ALLOC:
112	return DW_DLE_MAF;
113    case ELF_SGI_ERROR_FORMAT:
114	return DW_DLE_MDE;
115    case ELF_SGI_ERROR_ERRNO:
116	return DW_DLE_IOF;
117    case ELF_SGI_ERROR_TOO_BIG:
118	return DW_DLE_MOF;
119    default:
120	return DW_DLE_LEE;
121    }
122}
123#endif
124
125/*
126    Given an Elf ptr, set up dbg with pointers
127    to all the Dwarf data sections.
128    Return NULL on error.
129
130    This function is also responsible for determining
131    whether the given object contains Dwarf information
132    or not.  The test currently used is that it contains
133    either a .debug_info or a .debug_frame section.  If
134    not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to
135    return DW_DLV_NO_ENTRY.  Earlier, we had thought of using only
136    the presence/absence of .debug_info to test, but we
137    added .debug_frame since there could be stripped objects
138    that have only a .debug_frame section for exception
139    processing.
140    DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR
141*/
142static int
143_dwarf_setup(Dwarf_Debug dbg, dwarf_elf_handle elf, Dwarf_Error * error)
144{
145#ifdef __SGI_FAST_LIBELF
146    Elf64_Ehdr ehdr;
147    Elf64_Shdr shdr;
148    enum elf_sgi_error_type sres;
149    unsigned char const *ehdr_ident;
150#else
151    Elf32_Ehdr *ehdr32;
152
153#ifdef HAVE_ELF64_GETEHDR
154    Elf64_Ehdr *ehdr64;
155#endif
156    Elf32_Shdr *shdr32;
157
158#ifdef HAVE_ELF64_GETSHDR
159    Elf64_Shdr *shdr64;
160#endif
161    Elf_Scn *scn;
162    char *ehdr_ident;
163#endif /* !defined(__SGI_FAST_LIBELF) */
164    Dwarf_Half machine;
165    char *scn_name;
166    int is_64bit;
167    int foundDwarf;
168
169    Dwarf_Unsigned section_size;
170    Dwarf_Unsigned section_count;
171    Dwarf_Half section_index;
172
173    foundDwarf = FALSE;
174    dbg->de_elf = elf;
175
176    dbg->de_assume_string_in_bounds = _dwarf_assume_string_bad;
177
178#ifdef __SGI_FAST_LIBELF
179    sres = elf_sgi_ehdr(elf, &ehdr);
180    if (sres != ELF_SGI_ERROR_OK) {
181	DWARF_DBG_ERROR(dbg,
182			_dwarf_error_code_from_elf_sgi_error_code(sres),
183			DW_DLV_ERROR);
184    }
185    ehdr_ident = ehdr.e_ident;
186    section_count = ehdr.e_shnum;
187    machine = ehdr.e_machine;
188#else
189    if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {
190	DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETIDENT_ERROR, DW_DLV_ERROR);
191    }
192#endif
193
194    is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);
195
196
197    dbg->de_same_endian = 1;
198    dbg->de_copy_word = memcpy;
199#ifdef WORDS_BIGENDIAN
200    dbg->de_big_endian_object = 1;
201    if (ehdr_ident[EI_DATA] == ELFDATA2LSB) {
202	dbg->de_same_endian = 0;
203	dbg->de_big_endian_object = 0;
204	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
205    }
206#else /* little endian */
207    dbg->de_big_endian_object = 0;
208    if (ehdr_ident[EI_DATA] == ELFDATA2MSB) {
209	dbg->de_same_endian = 0;
210	dbg->de_big_endian_object = 1;
211	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
212    }
213#endif /* !WORDS_BIGENDIAN */
214
215    /* The following de_length_size is Not Too Significant. Only used
216       one calculation, and an approximate one at that. */
217    dbg->de_length_size = is_64bit ? 8 : 4;
218    dbg->de_pointer_size = is_64bit ? 8 : 4;
219
220
221#ifdef __SGI_FAST_LIBELF
222    /* We've already loaded the ELF header, so there's nothing to do
223       here */
224#else
225#ifdef HAVE_ELF64_GETEHDR
226    if (is_64bit) {
227	ehdr64 = elf64_getehdr(elf);
228	if (ehdr64 == NULL) {
229	    DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR,
230			    DW_DLV_ERROR);
231	}
232	section_count = ehdr64->e_shnum;
233	machine = ehdr64->e_machine;
234    } else
235#endif
236    {
237	ehdr32 = elf32_getehdr(elf);
238	if (ehdr32 == NULL) {
239	    DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR,
240			    DW_DLV_ERROR);
241	}
242	section_count = ehdr32->e_shnum;
243	machine = ehdr32->e_machine;
244    }
245#endif /* !defined(__SGI_FAST_LIBELF) */
246
247    if (is_64bit && machine != EM_MIPS) {
248	/* MIPS/IRIX makes pointer size and length size 8 for -64.
249	   Other platforms make length 4 always. */
250	/* 4 here supports 32bit-offset dwarf2, as emitted by cygnus
251	   tools, and the dwarfv2.1 64bit extension setting. */
252	dbg->de_length_size = 4;
253    }
254
255    /* We start at index 1 to skip the initial empty section. */
256    for (section_index = 1; section_index < section_count;
257	 ++section_index) {
258
259#ifdef __SGI_FAST_LIBELF
260	sres = elf_sgi_shdr(elf, section_index, &shdr);
261	if (sres != ELF_SGI_ERROR_OK) {
262	    DWARF_DBG_ERROR(dbg,
263			    _dwarf_error_code_from_elf_sgi_error_code
264			    (sres), DW_DLV_ERROR);
265	}
266
267	section_size = shdr.sh_size;
268
269	sres =
270	    elf_sgi_string(elf, ehdr.e_shstrndx, shdr.sh_name,
271			   (char const **) &scn_name);
272	if (sres != ELF_SGI_ERROR_OK) {
273	    DWARF_DBG_ERROR(dbg,
274			    _dwarf_error_code_from_elf_sgi_error_code
275			    (sres), DW_DLV_ERROR);
276	}
277#else /* !defined(__SGI_FAST_LIBELF) */
278	scn = elf_getscn(elf, section_index);
279	if (scn == NULL) {
280	    DWARF_DBG_ERROR(dbg, DW_DLE_MDE, DW_DLV_ERROR);
281	}
282#ifdef HAVE_ELF64_GETSHDR
283	if (is_64bit) {
284	    shdr64 = elf64_getshdr(scn);
285	    if (shdr64 == NULL) {
286		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR,
287				DW_DLV_ERROR);
288	    }
289
290	    section_size = shdr64->sh_size;
291
292	    if ((scn_name = elf_strptr(elf, ehdr64->e_shstrndx,
293				       shdr64->sh_name))
294		== NULL) {
295		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR,
296				DW_DLV_ERROR);
297	    }
298	} else
299#endif /* HAVE_ELF64_GETSHDR */
300	{
301	    if ((shdr32 = elf32_getshdr(scn)) == NULL) {
302		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR, 0);
303	    }
304
305	    section_size = shdr32->sh_size;
306
307	    if ((scn_name = elf_strptr(elf, ehdr32->e_shstrndx,
308				       shdr32->sh_name)) == NULL) {
309		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR,
310				DW_DLV_ERROR);
311	    }
312	}
313#endif /* !defined(__SGI_FAST_LIBELF) */
314
315	if (strncmp(scn_name, ".debug_", 7)
316	    && strcmp(scn_name, ".eh_frame")
317	    )
318	    continue;
319
320	else if (strcmp(scn_name, ".debug_info") == 0) {
321	    if (dbg->de_debug_info != NULL) {
322		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_DUPLICATE,
323				DW_DLV_ERROR);
324	    }
325	    if (section_size == 0) {
326		/* Know no reason to allow empty debug_info section */
327		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_NULL,
328				DW_DLV_ERROR);
329	    }
330	    foundDwarf = TRUE;
331	    dbg->de_debug_info_index = section_index;
332	    dbg->de_debug_info_size = section_size;
333	}
334
335	else if (strcmp(scn_name, ".debug_abbrev") == 0) {
336	    if (dbg->de_debug_abbrev != NULL) {
337		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_DUPLICATE,
338				DW_DLV_ERROR);
339	    }
340	    if (section_size == 0) {
341		/* Know no reason to allow empty debug_abbrev section */
342		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_NULL,
343				DW_DLV_ERROR);
344	    }
345	    dbg->de_debug_abbrev_index = section_index;
346	    dbg->de_debug_abbrev_size = section_size;
347	}
348
349	else if (strcmp(scn_name, ".debug_aranges") == 0) {
350	    if (dbg->de_debug_aranges_index != 0) {
351		DWARF_DBG_ERROR(dbg,
352				DW_DLE_DEBUG_ARANGES_DUPLICATE,
353				DW_DLV_ERROR);
354	    }
355	    if (section_size == 0) {
356		/* a zero size section is just empty. Ok, no error */
357		continue;
358	    }
359	    dbg->de_debug_aranges_index = section_index;
360	    dbg->de_debug_aranges_size = section_size;
361	}
362
363	else if (strcmp(scn_name, ".debug_line") == 0) {
364	    if (dbg->de_debug_line_index != 0) {
365		DWARF_DBG_ERROR(dbg,
366				DW_DLE_DEBUG_LINE_DUPLICATE,
367				DW_DLV_ERROR);
368	    }
369	    if (section_size == 0) {
370		/* a zero size section is just empty. Ok, no error */
371		continue;
372	    }
373	    dbg->de_debug_line_index = section_index;
374	    dbg->de_debug_line_size = section_size;
375	}
376
377	else if (strcmp(scn_name, ".debug_frame") == 0) {
378	    if (dbg->de_debug_frame_index != 0) {
379		DWARF_DBG_ERROR(dbg,
380				DW_DLE_DEBUG_FRAME_DUPLICATE,
381				DW_DLV_ERROR);
382	    }
383	    if (section_size == 0) {
384		/* a zero size section is just empty. Ok, no error */
385		continue;
386	    }
387	    dbg->de_debug_frame_index = section_index;
388	    dbg->de_debug_frame_size = section_size;
389	    foundDwarf = TRUE;
390	} else if (strcmp(scn_name, ".eh_frame") == 0) {
391	    /* gnu egcs-1.1.2 data */
392	    if (dbg->de_debug_frame_eh_gnu_index != 0) {
393		DWARF_DBG_ERROR(dbg,
394				DW_DLE_DEBUG_FRAME_DUPLICATE,
395				DW_DLV_ERROR);
396	    }
397	    if (section_size == 0) {
398		/* a zero size section is just empty. Ok, no error */
399		continue;
400	    }
401	    dbg->de_debug_frame_eh_gnu_index = section_index;
402	    dbg->de_debug_frame_size_eh_gnu = section_size;
403	    foundDwarf = TRUE;
404	}
405
406	else if (strcmp(scn_name, ".debug_loc") == 0) {
407	    if (dbg->de_debug_loc_index != 0) {
408		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_LOC_DUPLICATE,
409				DW_DLV_ERROR);
410	    }
411	    if (section_size == 0) {
412		/* a zero size section is just empty. Ok, no error */
413		continue;
414	    }
415	    dbg->de_debug_loc_index = section_index;
416	    dbg->de_debug_loc_size = section_size;
417	}
418
419
420	else if (strcmp(scn_name, ".debug_pubnames") == 0) {
421	    if (dbg->de_debug_pubnames_index != 0) {
422		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_PUBNAMES_DUPLICATE,
423				DW_DLV_ERROR);
424	    }
425	    if (section_size == 0) {
426		/* a zero size section is just empty. Ok, no error */
427		continue;
428	    }
429	    dbg->de_debug_pubnames_index = section_index;
430	    dbg->de_debug_pubnames_size = section_size;
431	}
432
433	else if (strcmp(scn_name, ".debug_str") == 0) {
434	    if (dbg->de_debug_str_index != 0) {
435		DWARF_DBG_ERROR(dbg,
436				DW_DLE_DEBUG_STR_DUPLICATE,
437				DW_DLV_ERROR);
438	    }
439	    if (section_size == 0) {
440		/* a zero size section is just empty. Ok, no error */
441		continue;
442	    }
443	    dbg->de_debug_str_index = section_index;
444	    dbg->de_debug_str_size = section_size;
445	}
446
447	else if (strcmp(scn_name, ".debug_funcnames") == 0) {
448	    if (dbg->de_debug_funcnames_index != 0) {
449		DWARF_DBG_ERROR(dbg,
450				DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,
451				DW_DLV_ERROR);
452	    }
453	    if (section_size == 0) {
454		/* a zero size section is just empty. Ok, no error */
455		continue;
456	    }
457	    dbg->de_debug_funcnames_index = section_index;
458	    dbg->de_debug_funcnames_size = section_size;
459	}
460
461	else if (strcmp(scn_name, ".debug_typenames") == 0) {
462	    /* SGI IRIX-only, created years before DWARF3. Content
463	       essentially identical to .debug_pubtypes.  */
464	    if (dbg->de_debug_typenames_index != 0) {
465		DWARF_DBG_ERROR(dbg,
466				DW_DLE_DEBUG_TYPENAMES_DUPLICATE,
467				DW_DLV_ERROR);
468	    }
469	    if (section_size == 0) {
470		/* a zero size section is just empty. Ok, no error */
471		continue;
472	    }
473	    dbg->de_debug_typenames_index = section_index;
474	    dbg->de_debug_typenames_size = section_size;
475	} else if (strcmp(scn_name, ".debug_pubtypes") == 0) {
476	    /* Section new in DWARF3.  */
477	    if (dbg->de_debug_pubtypes_index != 0) {
478		DWARF_DBG_ERROR(dbg,
479				DW_DLE_DEBUG_PUBTYPES_DUPLICATE,
480				DW_DLV_ERROR);
481	    }
482	    if (section_size == 0) {
483		/* a zero size section is just empty. Ok, no error */
484		continue;
485	    }
486	    dbg->de_debug_pubtypes_index = section_index;
487	    dbg->de_debug_pubtypes_size = section_size;
488	}
489
490	else if (strcmp(scn_name, ".debug_varnames") == 0) {
491	    if (dbg->de_debug_varnames_index != 0) {
492		DWARF_DBG_ERROR(dbg,
493				DW_DLE_DEBUG_VARNAMES_DUPLICATE,
494				DW_DLV_ERROR);
495	    }
496	    if (section_size == 0) {
497		/* a zero size section is just empty. Ok, no error */
498		continue;
499	    }
500	    dbg->de_debug_varnames_index = section_index;
501	    dbg->de_debug_varnames_size = section_size;
502	}
503
504	else if (strcmp(scn_name, ".debug_weaknames") == 0) {
505	    if (dbg->de_debug_weaknames_index != 0) {
506		DWARF_DBG_ERROR(dbg,
507				DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,
508				DW_DLV_ERROR);
509	    }
510	    if (section_size == 0) {
511		/* a zero size section is just empty. Ok, no error */
512		continue;
513	    }
514	    dbg->de_debug_weaknames_index = section_index;
515	    dbg->de_debug_weaknames_size = section_size;
516	} else if (strcmp(scn_name, ".debug_macinfo") == 0) {
517	    if (dbg->de_debug_macinfo_index != 0) {
518		DWARF_DBG_ERROR(dbg,
519				DW_DLE_DEBUG_MACINFO_DUPLICATE,
520				DW_DLV_ERROR);
521	    }
522	    if (section_size == 0) {
523		/* a zero size section is just empty. Ok, no error */
524		continue;
525	    }
526	    dbg->de_debug_macinfo_index = section_index;
527	    dbg->de_debug_macinfo_size = section_size;
528	}
529    }
530    if (foundDwarf) {
531	return DW_DLV_OK;
532    }
533
534    return (DW_DLV_NO_ENTRY);
535}
536
537
538/*
539    The basic dwarf initializer function for consumers.
540    Return NULL on error.
541*/
542int
543dwarf_init(int fd,
544	   Dwarf_Unsigned access,
545	   Dwarf_Handler errhand,
546	   Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error)
547{
548    Dwarf_Debug dbg;
549    struct stat fstat_buf;
550    dwarf_elf_handle elf;
551    int res;
552
553#ifdef __SGI_FAST_LIBELF
554    enum elf_sgi_error_type sres;
555#else
556    Elf_Cmd what_kind_of_elf_read;
557#endif
558
559    dbg = _dwarf_get_debug();
560    if (dbg == NULL) {
561	DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
562    }
563    dbg->de_errhand = errhand;
564    dbg->de_errarg = errarg;
565    dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE;
566    dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM;
567
568
569    if (fstat(fd, &fstat_buf) != 0) {
570	DWARF_DBG_ERROR(dbg, DW_DLE_FSTAT_ERROR, DW_DLV_ERROR);
571    }
572    if (!S_ISREG(fstat_buf.st_mode)) {
573	DWARF_DBG_ERROR(dbg, DW_DLE_FSTAT_MODE_ERROR, DW_DLV_ERROR);
574    }
575
576    if (access != DW_DLC_READ) {
577	DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
578    }
579    dbg->de_access = access;
580
581#ifdef __SGI_FAST_LIBELF
582    elf = elf_sgi_new();
583    if (elf == NULL) {
584	DWARF_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR);
585    }
586
587    sres = elf_sgi_begin_fd(elf, fd, 0);
588    if (sres != ELF_SGI_ERROR_OK) {
589	elf_sgi_free(elf);
590	DWARF_DBG_ERROR(dbg,
591			_dwarf_error_code_from_elf_sgi_error_code(sres),
592			DW_DLV_ERROR);
593    }
594#else /* ! __SGI_FAST_LIBELF */
595    elf_version(EV_CURRENT);
596    /* changed to mmap request per bug 281217. 6/95 */
597#ifdef HAVE_ELF_C_READ_MMAP
598    /* ELF_C_READ_MMAP is an SGI IRIX specific enum value from IRIX
599       libelf.h meaning read but use mmap */
600    what_kind_of_elf_read = ELF_C_READ_MMAP;
601#else /* !HAVE_ELF_C_READ_MMAP */
602    /* ELF_C_READ is a portable value */
603    what_kind_of_elf_read = ELF_C_READ;
604#endif /* HAVE_ELF_C_READ_MMAP */
605
606    if ((elf = elf_begin(fd, what_kind_of_elf_read, 0)) == NULL) {
607	DWARF_DBG_ERROR(dbg, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR);
608    }
609#endif /* !defined(__SGI_FAST_LIBELF) */
610
611    dbg->de_elf_must_close = 1;
612    if ((res = _dwarf_setup(dbg, elf, error)) != DW_DLV_OK) {
613#ifdef __SGI_FAST_LIBELF
614	elf_sgi_free(elf);
615#else
616	elf_end(elf);
617#endif
618	free(dbg);
619	return (res);
620    }
621
622    /* call cannot fail: no malloc or free involved */
623    _dwarf_setup_debug(dbg);
624
625    *ret_dbg = dbg;
626    return (DW_DLV_OK);
627}
628
629
630/*
631    The alternate dwarf setup call for consumers
632*/
633int
634dwarf_elf_init(dwarf_elf_handle elf_file_pointer,
635	       Dwarf_Unsigned access,
636	       Dwarf_Handler errhand,
637	       Dwarf_Ptr errarg,
638	       Dwarf_Debug * ret_dbg, Dwarf_Error * error)
639{
640    Dwarf_Debug dbg;
641    int res;
642
643    dbg = _dwarf_get_debug();
644    if (dbg == NULL) {
645	DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
646    }
647    dbg->de_errhand = errhand;
648    dbg->de_errarg = errarg;
649    dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE;
650    dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM;
651
652    if (access != DW_DLC_READ) {
653	DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
654    }
655    dbg->de_access = access;
656
657    dbg->de_elf_must_close = 0;
658    if ((res = _dwarf_setup(dbg, elf_file_pointer, error)) != DW_DLV_OK) {
659	free(dbg);
660	return (res);
661    }
662
663    /* this call cannot fail: allocates nothing, releases nothing */
664    _dwarf_setup_debug(dbg);
665
666    *ret_dbg = dbg;
667    return (DW_DLV_OK);
668}
669
670
671/*
672	Frees all memory that was not previously freed
673	by dwarf_dealloc.
674	Aside from certain categories.
675*/
676int
677dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error)
678{
679    int res = DW_DLV_OK;
680
681    if (dbg->de_elf_must_close) {
682	/* Must do this *before* _dwarf_free_all_of_one_debug() as that
683	   zeroes out dbg contents */
684#ifdef __SGI_FAST_LIBELF
685	elf_sgi_free(dbg->de_elf);
686#else
687	elf_end(dbg->de_elf);
688#endif
689    }
690
691    res = _dwarf_free_all_of_one_debug(dbg);
692    if (res == DW_DLV_ERROR) {
693	DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
694    }
695    dwarf_malloc_check_complete("After Final free");
696
697    return res;
698
699
700}
701
702
703/*
704    This function returns the Elf * pointer
705    associated with a Dwarf_Debug.
706*/
707int
708dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf,
709	      Dwarf_Error * error)
710{
711    if (dbg == NULL) {
712	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
713	return (DW_DLV_ERROR);
714    }
715
716    *elf = dbg->de_elf;
717    return (DW_DLV_OK);
718}
719
720
721/*
722	Load the ELF section with the specified index and set the
723	pointer pointed to by section_data to the memory where it
724	was loaded.
725 */
726int
727_dwarf_load_section(Dwarf_Debug dbg,
728		    Dwarf_Half section_index,
729		    Dwarf_Small ** section_data, Dwarf_Error * error)
730{
731    if (section_index == 0) {
732	return DW_DLV_NO_ENTRY;
733    }
734
735    /* check to see if the section is already loaded */
736    if (*section_data != NULL) {
737	return DW_DLV_OK;
738    }
739
740    {
741#ifdef __SGI_FAST_LIBELF
742	enum elf_sgi_error_type sres;
743
744	sres = elf_sgi_section(dbg->de_elf,
745			       section_index, (void **) section_data);
746	if (sres != ELF_SGI_ERROR_OK) {
747	    DWARF_DBG_ERROR(dbg,
748			    _dwarf_error_code_from_elf_sgi_error_code
749			    (sres), DW_DLV_ERROR);
750	}
751#else
752	Elf_Scn *scn;
753	Elf_Data *data;
754
755	scn = elf_getscn(dbg->de_elf, section_index);
756	if (scn == NULL) {
757	    _dwarf_error(dbg, error, DW_DLE_MDE);
758	    return DW_DLV_ERROR;
759	}
760
761	/*
762	   When using libelf as a producer, section data may be stored
763	   in multiple buffers. In libdwarf however, we only use libelf
764	   as a consumer (there is a dwarf producer API, but it doesn't
765	   use libelf). Because of this, this single call to elf_getdata
766	   will retrieve the entire section in a single contiguous
767	   buffer. */
768	data = elf_getdata(scn, NULL);
769	if (data == NULL) {
770	    _dwarf_error(dbg, error, DW_DLE_MDE);
771	    return DW_DLV_ERROR;
772	}
773
774	*section_data = data->d_buf;
775#endif /* !defined(__SGI_FAST_LIBELF) */
776    }
777
778    return DW_DLV_OK;
779}
780
781/* This is a hack so clients can verify offsets.
782   Added April 2005 so that debugger can detect broken offsets
783   (which happened in an IRIX  -64 executable larger than 2GB
784    using MIPSpro 7.3.1.3 compilers. A couple .debug_pubnames
785    offsets were wrong.).
786*/
787int
788dwarf_get_section_max_offsets(Dwarf_Debug dbg,
789			      Dwarf_Unsigned * debug_info_size,
790			      Dwarf_Unsigned * debug_abbrev_size,
791			      Dwarf_Unsigned * debug_line_size,
792			      Dwarf_Unsigned * debug_loc_size,
793			      Dwarf_Unsigned * debug_aranges_size,
794			      Dwarf_Unsigned * debug_macinfo_size,
795			      Dwarf_Unsigned * debug_pubnames_size,
796			      Dwarf_Unsigned * debug_str_size,
797			      Dwarf_Unsigned * debug_frame_size,
798			      Dwarf_Unsigned * debug_ranges_size,
799			      Dwarf_Unsigned * debug_typenames_size)
800{
801    *debug_info_size = dbg->de_debug_info_size;
802    *debug_abbrev_size = dbg->de_debug_abbrev_size;
803    *debug_line_size = dbg->de_debug_line_size;
804    *debug_loc_size = dbg->de_debug_loc_size;
805    *debug_aranges_size = dbg->de_debug_aranges_size;
806    *debug_macinfo_size = dbg->de_debug_macinfo_size;
807    *debug_pubnames_size = dbg->de_debug_pubnames_size;
808    *debug_str_size = dbg->de_debug_str_size;
809    *debug_frame_size = dbg->de_debug_frame_size;
810    *debug_ranges_size = 0;	/* Not yet supported. */
811    *debug_typenames_size = dbg->de_debug_typenames_size;
812
813
814    return DW_DLV_OK;
815}
816