1 /*
2   Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
4   Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved.
5   Portions Copyright 2011-2015 David Anderson. All rights reserved.
6   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
7 
8   This program is free software; you can redistribute it and/or modify it
9   under the terms of version 2.1 of the GNU Lesser General Public License
10   as published by the Free Software Foundation.
11 
12   This program is distributed in the hope that it would be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 
16   Further, this software is distributed without any warranty that it is
17   free of the rightful claim of any third person regarding infringement
18   or the like.  Any license provided herein, whether implied or
19   otherwise, applies only to this software file.  Patent licenses, if
20   any, provided herein do not apply to combinations of this program with
21   other software, or any other product whatsoever.
22 
23   You should have received a copy of the GNU Lesser General Public
24   License along with this program; if not, write the Free Software
25   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
26   USA.
27 
28 */
29 
30 #include "config.h"
31 #ifdef HAVE_LIBELF_H
32 #include <libelf.h>
33 #else
34 #ifdef HAVE_LIBELF_LIBELF_H
35 #include <libelf/libelf.h>
36 #endif
37 #endif
38 #include <stdio.h>
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 #include <string.h>
42 #ifdef HAVE_STDLIB_H
43 #include <stdlib.h>
44 #endif /* HAVE_STDLIB_H */
45 
46 #include "dwarf_incl.h"
47 #include "dwarf_error.h"
48 #include "dwarf_elf_access.h"
49 #include "dwarf_object_detector.h"
50 
51 
52 #define DWARF_DBG_ERROR(dbg,errval,retval) \
53     _dwarf_error(dbg, error, errval); return(retval);
54 
55 #define FALSE  0
56 #define TRUE   1
57 
58 /* New March 2017 */
59 int
dwarf_elf_init_b(UNUSEDARG dwarf_elf_handle elf_file_pointer,UNUSEDARG Dwarf_Unsigned access,UNUSEDARG unsigned group_number,UNUSEDARG Dwarf_Handler errhand,UNUSEDARG Dwarf_Ptr errarg,UNUSEDARG Dwarf_Debug * ret_dbg,Dwarf_Error * error)60 dwarf_elf_init_b(
61 #ifndef DWARF_WITH_LIBELF
62     UNUSEDARG dwarf_elf_handle elf_file_pointer,
63     UNUSEDARG Dwarf_Unsigned access,
64     UNUSEDARG unsigned group_number,
65     UNUSEDARG Dwarf_Handler errhand,
66     UNUSEDARG Dwarf_Ptr errarg,
67     UNUSEDARG Dwarf_Debug * ret_dbg,
68 #else
69     dwarf_elf_handle elf_file_pointer,
70     Dwarf_Unsigned access,
71     unsigned group_number,
72     Dwarf_Handler errhand,
73     Dwarf_Ptr errarg,
74     Dwarf_Debug * ret_dbg,
75 #endif /* DWARF_WITH_LIBELF */
76     Dwarf_Error * error)
77 {
78 #ifndef DWARF_WITH_LIBELF
79     DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR);
80 #else /* DWARF_WITH_LIBELF */
81     Dwarf_Obj_Access_Interface *binary_interface = 0;
82     int res = DW_DLV_OK;
83     int localerrnum = 0;
84     int libdwarf_owns_elf = FALSE;
85 
86     if (!ret_dbg) {
87         DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL,DW_DLV_ERROR);
88     }
89     if (access != DW_DLC_READ) {
90         DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
91     }
92 
93     /* This allocates and fills in *binary_interface. */
94     res = dwarf_elf_object_access_init(
95         elf_file_pointer,
96         libdwarf_owns_elf,
97         &binary_interface,
98         &localerrnum);
99     if (res != DW_DLV_OK) {
100         if (res == DW_DLV_NO_ENTRY) {
101             return res;
102         }
103         DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR);
104     }
105     /* allocates and initializes Dwarf_Debug */
106     res = dwarf_object_init_b(binary_interface, errhand, errarg,
107         group_number,
108         ret_dbg, error);
109     if (res != DW_DLV_OK){
110         dwarf_elf_object_access_finish(binary_interface);
111         return res;
112     }
113     res = dwarf_add_debuglink_global_path(*ret_dbg,
114         "/usr/lib/debug",error);
115     if (res != DW_DLV_OK){
116         dwarf_elf_object_access_finish(binary_interface);
117         return res;
118     }
119     /* DBG known */
120     return res;
121 #endif /* DWARF_WITH_LIBELF */
122 }
123 
124 int
dwarf_elf_init(UNUSEDARG dwarf_elf_handle elf_file_pointer,UNUSEDARG Dwarf_Unsigned access,UNUSEDARG Dwarf_Handler errhand,UNUSEDARG Dwarf_Ptr errarg,UNUSEDARG Dwarf_Debug * ret_dbg,Dwarf_Error * error)125 dwarf_elf_init(
126 #ifndef DWARF_WITH_LIBELF
127     UNUSEDARG dwarf_elf_handle elf_file_pointer,
128     UNUSEDARG Dwarf_Unsigned access,
129     UNUSEDARG Dwarf_Handler errhand,
130     UNUSEDARG Dwarf_Ptr errarg,
131     UNUSEDARG Dwarf_Debug * ret_dbg,
132 #else
133     dwarf_elf_handle elf_file_pointer,
134     Dwarf_Unsigned access,
135     Dwarf_Handler errhand,
136     Dwarf_Ptr errarg,
137     Dwarf_Debug * ret_dbg,
138 #endif
139     Dwarf_Error * error)
140 {
141 #ifndef DWARF_WITH_LIBELF
142     DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR);
143 #else /* DWARF_WITH_LIBELF */
144     int res = 0;
145     res = dwarf_elf_init_b(elf_file_pointer,
146         DW_GROUPNUMBER_ANY,
147         access,errhand,errarg,ret_dbg,error);
148     return res;
149 #endif /* DWARF_WITH_LIBELF */
150 }
151 
152 int
_dwarf_elf_setup(UNUSEDARG int fd,UNUSEDARG char * path,UNUSEDARG unsigned ftype,UNUSEDARG unsigned endian,UNUSEDARG unsigned offsetsize,UNUSEDARG size_t filesize,UNUSEDARG Dwarf_Unsigned access,UNUSEDARG unsigned groupnumber,UNUSEDARG Dwarf_Handler errhand,UNUSEDARG Dwarf_Ptr errarg,UNUSEDARG Dwarf_Debug * dbg,Dwarf_Error * error)153 _dwarf_elf_setup(
154 #ifndef  DWARF_WITH_LIBELF
155     UNUSEDARG int fd,
156     UNUSEDARG char *path,
157     UNUSEDARG unsigned ftype,
158     UNUSEDARG unsigned endian,
159     UNUSEDARG unsigned offsetsize,
160     UNUSEDARG size_t filesize,
161     UNUSEDARG Dwarf_Unsigned access,
162     UNUSEDARG unsigned groupnumber,
163     UNUSEDARG Dwarf_Handler errhand,
164     UNUSEDARG Dwarf_Ptr errarg,
165     UNUSEDARG Dwarf_Debug *dbg,
166 #else
167     int fd,
168     UNUSEDARG char *path,
169     UNUSEDARG unsigned ftype,
170     UNUSEDARG unsigned endian,
171     UNUSEDARG unsigned offsetsize,
172     size_t filesize,
173     UNUSEDARG Dwarf_Unsigned access,
174     unsigned groupnumber,
175     Dwarf_Handler errhand,
176     Dwarf_Ptr errarg,
177     Dwarf_Debug *dbg,
178 #endif /* DWARF_WITH_LIBELF */
179     Dwarf_Error *error)
180 {
181 #ifndef DWARF_WITH_LIBELF
182     DWARF_DBG_ERROR(NULL, DW_DLE_PRODUCER_CODE_NOT_AVAILABLE, DW_DLV_ERROR);
183 #else /* DWARF_WITH_LIBELF */
184     Elf_Cmd what_kind_of_elf_read = ELF_C_READ;
185     Dwarf_Obj_Access_Interface *binary_interface = 0;
186     int res = DW_DLV_OK;
187     int localerrnum = 0;
188     int libdwarf_owns_elf = TRUE;
189     dwarf_elf_handle elf_file_pointer = 0;
190 
191     elf_version(EV_CURRENT);
192     elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0);
193     if (elf_file_pointer == NULL) {
194         DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR);
195     }
196     /* Sets up elf access function pointers. */
197     res = dwarf_elf_object_access_init(
198         elf_file_pointer,
199         libdwarf_owns_elf,
200         &binary_interface,
201         &localerrnum);
202     if (res != DW_DLV_OK) {
203         if (res == DW_DLV_NO_ENTRY) {
204             return res;
205         }
206         DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR);
207     }
208     /* allocates and initializes Dwarf_Debug */
209     res = dwarf_object_init_b(binary_interface, errhand, errarg,
210         groupnumber,
211         dbg, error);
212     if (res != DW_DLV_OK){
213         dwarf_elf_object_access_finish(binary_interface);
214         return res;
215     }
216     (*dbg)->de_filesize = filesize;
217     res = dwarf_add_debuglink_global_path(*dbg,
218         "/usr/lib/debug",error);
219     if (res != DW_DLV_OK){
220         dwarf_elf_object_access_finish(binary_interface);
221     }
222     return res;
223 #endif /* DWARF_WITH_LIBELF */
224 }
225