xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_original_elf_init.c (revision f52943a93040563107b95bccb9db87d9971ef47d)
1 /*
2 
3   Copyright (C) 2000,2001,2002,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
4   Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
5   Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved.
6 
7   This program is free software; you can redistribute it and/or modify it
8   under the terms of version 2.1 of the GNU Lesser General Public License
9   as published by the Free Software Foundation.
10 
11   This program is distributed in the hope that it would be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15   Further, this software is distributed without any warranty that it is
16   free of the rightful claim of any third person regarding infringement
17   or the like.  Any license provided herein, whether implied or
18   otherwise, applies only to this software file.  Patent licenses, if
19   any, provided herein do not apply to combinations of this program with
20   other software, or any other product whatsoever.
21 
22   You should have received a copy of the GNU Lesser General Public
23   License along with this program; if not, write the Free Software
24   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25   USA.
26 
27   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
28   Mountain View, CA 94043, or:
29 
30   http://www.sgi.com
31 
32   For further information regarding this notice, see:
33 
34   http://oss.sgi.com/projects/GenInfo/NoticeExplan
35 
36 */
37 
38 
39 #include "config.h"
40 #include "dwarf_incl.h"
41 #include "dwarf_elf_access.h"
42 
43 #ifdef HAVE_ELF_H
44 #include <elf.h>
45 #endif
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 
54 #include <stdio.h>
55 #include <sys/stat.h>
56 #include <sys/types.h>
57 #include <string.h>
58 #include <stdlib.h>
59 
60 #define DWARF_DBG_ERROR(dbg,errval,retval) \
61      _dwarf_error(dbg, error, errval); return(retval);
62 
63 #define FALSE  0
64 #define TRUE   1
65 
66 static int
67 dwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer,
68                               int libdwarf_owns_elf,
69                               Dwarf_Unsigned access,
70                               Dwarf_Handler errhand,
71                               Dwarf_Ptr errarg,
72                               Dwarf_Debug * ret_dbg,
73                               Dwarf_Error * error);
74 
75 
76 /*
77     The basic dwarf initializer function for consumers using
78     libelf.
79     Return a libdwarf error code on error, return DW_DLV_OK
80     if this succeeds.
81 */
82 int
83 dwarf_init(int fd,
84     Dwarf_Unsigned access,
85     Dwarf_Handler errhand,
86     Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error)
87 {
88     struct stat fstat_buf;
89     dwarf_elf_handle elf_file_pointer = 0;
90     /* ELF_C_READ is a portable value */
91     Elf_Cmd what_kind_of_elf_read = ELF_C_READ;
92 
93 #if !defined(S_ISREG)
94 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
95 #endif
96     if (fstat(fd, &fstat_buf) != 0) {
97         DWARF_DBG_ERROR(NULL, DW_DLE_FSTAT_ERROR, DW_DLV_ERROR);
98     }
99     if (!S_ISREG(fstat_buf.st_mode)) {
100         DWARF_DBG_ERROR(NULL, DW_DLE_FSTAT_MODE_ERROR, DW_DLV_ERROR);
101     }
102 
103     if (access != DW_DLC_READ) {
104         DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
105     }
106 
107     elf_version(EV_CURRENT);
108     /* changed to mmap request per bug 281217. 6/95 */
109 #ifdef HAVE_ELF_C_READ_MMAP
110     /* ELF_C_READ_MMAP is an SGI IRIX specific enum value from IRIX
111        libelf.h meaning read but use mmap */
112     what_kind_of_elf_read = ELF_C_READ_MMAP;
113 #endif /* !HAVE_ELF_C_READ_MMAP */
114 
115     elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0);
116     if (elf_file_pointer == NULL) {
117         DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR);
118     }
119 
120     return dwarf_elf_init_file_ownership(elf_file_pointer,
121                                          TRUE,
122                                          access,
123                                          errhand,
124                                          errarg,
125                                          ret_dbg,
126                                          error);
127 }
128 
129 /*
130     An alternate dwarf setup call for consumers using
131     libelf.
132     When the caller has opened libelf already, so the
133     caller must free libelf.
134 */
135 int
136 dwarf_elf_init(dwarf_elf_handle elf_file_pointer,
137     Dwarf_Unsigned access,
138     Dwarf_Handler errhand,
139     Dwarf_Ptr errarg,
140     Dwarf_Debug * ret_dbg, Dwarf_Error * error)
141 {
142   return dwarf_elf_init_file_ownership(elf_file_pointer,
143                                        FALSE,
144                                        access,
145                                        errhand,
146                                        errarg,
147                                        ret_dbg,
148                                        error);
149 }
150 
151 
152 /*
153     Initialize the ELF object access for libdwarf.
154  */
155 static int
156 dwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer,
157                               int libdwarf_owns_elf,
158                               Dwarf_Unsigned access,
159                               Dwarf_Handler errhand,
160                               Dwarf_Ptr errarg,
161                               Dwarf_Debug * ret_dbg,
162                               Dwarf_Error * error)
163 {
164     /* ELF is no longer tied to libdwarf. */
165     Dwarf_Obj_Access_Interface *binary_interface = 0;
166     int res = DW_DLV_OK;
167     int err = 0;
168 
169     if (access != DW_DLC_READ) {
170         DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
171     }
172 
173     /* This allocates and fills in *binary_interface. */
174     res = dwarf_elf_object_access_init(
175         elf_file_pointer,
176         libdwarf_owns_elf,
177         &binary_interface,
178         &err);
179     if(res != DW_DLV_OK){
180         DWARF_DBG_ERROR(NULL, err, DW_DLV_ERROR);
181     }
182 
183     /* This mallocs space and returns pointer thru ret_dbg,
184        saving  the binary interface in 'ret-dbg' */
185     res = dwarf_object_init(binary_interface, errhand, errarg,
186                          ret_dbg, error);
187     if(res != DW_DLV_OK){
188         dwarf_elf_object_access_finish(binary_interface);
189     }
190     return res;
191 }
192 
193 
194 /*
195     Frees all memory that was not previously freed
196     by dwarf_dealloc.
197     Aside from certain categories.
198 
199     This is only applicable when dwarf_init() or dwarf_elf_init()
200     was used to init 'dbg'.
201 */
202 int
203 dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error)
204 {
205     dwarf_elf_object_access_finish(dbg->de_obj_file);
206 
207     return dwarf_object_finish(dbg, error);
208 }
209 
210