107dc1947SRichard Lowe /*
2*4d9fdb46SRobert Mustacchi   Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
307dc1947SRichard Lowe   Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
407dc1947SRichard Lowe   Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved.
5*4d9fdb46SRobert Mustacchi   Portions Copyright 2011-2015 David Anderson. All rights reserved.
6*4d9fdb46SRobert Mustacchi   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
707dc1947SRichard Lowe 
807dc1947SRichard Lowe   This program is free software; you can redistribute it and/or modify it
907dc1947SRichard Lowe   under the terms of version 2.1 of the GNU Lesser General Public License
1007dc1947SRichard Lowe   as published by the Free Software Foundation.
1107dc1947SRichard Lowe 
1207dc1947SRichard Lowe   This program is distributed in the hope that it would be useful, but
1307dc1947SRichard Lowe   WITHOUT ANY WARRANTY; without even the implied warranty of
1407dc1947SRichard Lowe   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1507dc1947SRichard Lowe 
1607dc1947SRichard Lowe   Further, this software is distributed without any warranty that it is
1707dc1947SRichard Lowe   free of the rightful claim of any third person regarding infringement
1807dc1947SRichard Lowe   or the like.  Any license provided herein, whether implied or
1907dc1947SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
2007dc1947SRichard Lowe   any, provided herein do not apply to combinations of this program with
2107dc1947SRichard Lowe   other software, or any other product whatsoever.
2207dc1947SRichard Lowe 
2307dc1947SRichard Lowe   You should have received a copy of the GNU Lesser General Public
2407dc1947SRichard Lowe   License along with this program; if not, write the Free Software
2507dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2607dc1947SRichard Lowe   USA.
2707dc1947SRichard Lowe 
2807dc1947SRichard Lowe */
2907dc1947SRichard Lowe 
3007dc1947SRichard Lowe #include "config.h"
3107dc1947SRichard Lowe #ifdef HAVE_LIBELF_H
3207dc1947SRichard Lowe #include <libelf.h>
3307dc1947SRichard Lowe #else
3407dc1947SRichard Lowe #ifdef HAVE_LIBELF_LIBELF_H
3507dc1947SRichard Lowe #include <libelf/libelf.h>
3607dc1947SRichard Lowe #endif
3707dc1947SRichard Lowe #endif
3807dc1947SRichard Lowe #include <stdio.h>
3907dc1947SRichard Lowe #include <sys/stat.h>
4007dc1947SRichard Lowe #include <sys/types.h>
4107dc1947SRichard Lowe #include <string.h>
42*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
4307dc1947SRichard Lowe #include <stdlib.h>
44*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
45*4d9fdb46SRobert Mustacchi 
46*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
47*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
48*4d9fdb46SRobert Mustacchi #include "dwarf_elf_access.h"
49*4d9fdb46SRobert Mustacchi #include "dwarf_object_detector.h"
50*4d9fdb46SRobert Mustacchi 
5107dc1947SRichard Lowe 
5207dc1947SRichard Lowe #define DWARF_DBG_ERROR(dbg,errval,retval) \
53*4d9fdb46SRobert Mustacchi     _dwarf_error(dbg, error, errval); return(retval);
5407dc1947SRichard Lowe 
5507dc1947SRichard Lowe #define FALSE  0
5607dc1947SRichard Lowe #define TRUE   1
5707dc1947SRichard Lowe 
58*4d9fdb46SRobert Mustacchi /* New March 2017 */
5907dc1947SRichard Lowe 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*4d9fdb46SRobert Mustacchi dwarf_elf_init_b(
61*4d9fdb46SRobert Mustacchi #ifndef DWARF_WITH_LIBELF
62*4d9fdb46SRobert Mustacchi     UNUSEDARG dwarf_elf_handle elf_file_pointer,
63*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Unsigned access,
64*4d9fdb46SRobert Mustacchi     UNUSEDARG unsigned group_number,
65*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Handler errhand,
66*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Ptr errarg,
67*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Debug * ret_dbg,
68*4d9fdb46SRobert Mustacchi #else
69*4d9fdb46SRobert Mustacchi     dwarf_elf_handle elf_file_pointer,
7007dc1947SRichard Lowe     Dwarf_Unsigned access,
71*4d9fdb46SRobert Mustacchi     unsigned group_number,
7207dc1947SRichard Lowe     Dwarf_Handler errhand,
73*4d9fdb46SRobert Mustacchi     Dwarf_Ptr errarg,
74*4d9fdb46SRobert Mustacchi     Dwarf_Debug * ret_dbg,
75*4d9fdb46SRobert Mustacchi #endif /* DWARF_WITH_LIBELF */
76*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
7707dc1947SRichard Lowe {
78*4d9fdb46SRobert Mustacchi #ifndef DWARF_WITH_LIBELF
79*4d9fdb46SRobert Mustacchi     DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR);
80*4d9fdb46SRobert Mustacchi #else /* DWARF_WITH_LIBELF */
81*4d9fdb46SRobert Mustacchi     Dwarf_Obj_Access_Interface *binary_interface = 0;
82*4d9fdb46SRobert Mustacchi     int res = DW_DLV_OK;
83*4d9fdb46SRobert Mustacchi     int localerrnum = 0;
84*4d9fdb46SRobert Mustacchi     int libdwarf_owns_elf = FALSE;
8507dc1947SRichard Lowe 
86*4d9fdb46SRobert Mustacchi     if (!ret_dbg) {
87*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL,DW_DLV_ERROR);
8807dc1947SRichard Lowe     }
8907dc1947SRichard Lowe     if (access != DW_DLC_READ) {
9007dc1947SRichard Lowe         DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
9107dc1947SRichard Lowe     }
9207dc1947SRichard Lowe 
93*4d9fdb46SRobert Mustacchi     /* This allocates and fills in *binary_interface. */
94*4d9fdb46SRobert Mustacchi     res = dwarf_elf_object_access_init(
95*4d9fdb46SRobert Mustacchi         elf_file_pointer,
96*4d9fdb46SRobert Mustacchi         libdwarf_owns_elf,
97*4d9fdb46SRobert Mustacchi         &binary_interface,
98*4d9fdb46SRobert Mustacchi         &localerrnum);
99*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
100*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_NO_ENTRY) {
101*4d9fdb46SRobert Mustacchi             return res;
102*4d9fdb46SRobert Mustacchi         }
103*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR);
10407dc1947SRichard Lowe     }
105*4d9fdb46SRobert Mustacchi     /* allocates and initializes Dwarf_Debug */
106*4d9fdb46SRobert Mustacchi     res = dwarf_object_init_b(binary_interface, errhand, errarg,
107*4d9fdb46SRobert Mustacchi         group_number,
108*4d9fdb46SRobert Mustacchi         ret_dbg, error);
109*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK){
110*4d9fdb46SRobert Mustacchi         dwarf_elf_object_access_finish(binary_interface);
111*4d9fdb46SRobert Mustacchi         return res;
112*4d9fdb46SRobert Mustacchi     }
113*4d9fdb46SRobert Mustacchi     res = dwarf_add_debuglink_global_path(*ret_dbg,
114*4d9fdb46SRobert Mustacchi         "/usr/lib/debug",error);
115*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK){
116*4d9fdb46SRobert Mustacchi         dwarf_elf_object_access_finish(binary_interface);
117*4d9fdb46SRobert Mustacchi         return res;
118*4d9fdb46SRobert Mustacchi     }
119*4d9fdb46SRobert Mustacchi     /* DBG known */
120*4d9fdb46SRobert Mustacchi     return res;
121*4d9fdb46SRobert Mustacchi #endif /* DWARF_WITH_LIBELF */
12207dc1947SRichard Lowe }
12307dc1947SRichard Lowe 
12407dc1947SRichard Lowe 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*4d9fdb46SRobert Mustacchi dwarf_elf_init(
126*4d9fdb46SRobert Mustacchi #ifndef DWARF_WITH_LIBELF
127*4d9fdb46SRobert Mustacchi     UNUSEDARG dwarf_elf_handle elf_file_pointer,
128*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Unsigned access,
129*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Handler errhand,
130*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Ptr errarg,
131*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Debug * ret_dbg,
132*4d9fdb46SRobert Mustacchi #else
133*4d9fdb46SRobert Mustacchi     dwarf_elf_handle elf_file_pointer,
13407dc1947SRichard Lowe     Dwarf_Unsigned access,
13507dc1947SRichard Lowe     Dwarf_Handler errhand,
13607dc1947SRichard Lowe     Dwarf_Ptr errarg,
137*4d9fdb46SRobert Mustacchi     Dwarf_Debug * ret_dbg,
138*4d9fdb46SRobert Mustacchi #endif
139*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
14007dc1947SRichard Lowe {
141*4d9fdb46SRobert Mustacchi #ifndef DWARF_WITH_LIBELF
142*4d9fdb46SRobert Mustacchi     DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR);
143*4d9fdb46SRobert Mustacchi #else /* DWARF_WITH_LIBELF */
144*4d9fdb46SRobert Mustacchi     int res = 0;
145*4d9fdb46SRobert Mustacchi     res = dwarf_elf_init_b(elf_file_pointer,
146*4d9fdb46SRobert Mustacchi         DW_GROUPNUMBER_ANY,
147*4d9fdb46SRobert Mustacchi         access,errhand,errarg,ret_dbg,error);
148*4d9fdb46SRobert Mustacchi     return res;
149*4d9fdb46SRobert Mustacchi #endif /* DWARF_WITH_LIBELF */
15007dc1947SRichard Lowe }
15107dc1947SRichard Lowe 
152*4d9fdb46SRobert Mustacchi 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*4d9fdb46SRobert Mustacchi _dwarf_elf_setup(
154*4d9fdb46SRobert Mustacchi #ifndef  DWARF_WITH_LIBELF
155*4d9fdb46SRobert Mustacchi     UNUSEDARG int fd,
156*4d9fdb46SRobert Mustacchi     UNUSEDARG char *path,
157*4d9fdb46SRobert Mustacchi     UNUSEDARG unsigned ftype,
158*4d9fdb46SRobert Mustacchi     UNUSEDARG unsigned endian,
159*4d9fdb46SRobert Mustacchi     UNUSEDARG unsigned offsetsize,
160*4d9fdb46SRobert Mustacchi     UNUSEDARG size_t filesize,
161*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Unsigned access,
162*4d9fdb46SRobert Mustacchi     UNUSEDARG unsigned groupnumber,
163*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Handler errhand,
164*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Ptr errarg,
165*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Debug *dbg,
166*4d9fdb46SRobert Mustacchi #else
167*4d9fdb46SRobert Mustacchi     int fd,
168*4d9fdb46SRobert Mustacchi     UNUSEDARG char *path,
169*4d9fdb46SRobert Mustacchi     UNUSEDARG unsigned ftype,
170*4d9fdb46SRobert Mustacchi     UNUSEDARG unsigned endian,
171*4d9fdb46SRobert Mustacchi     UNUSEDARG unsigned offsetsize,
172*4d9fdb46SRobert Mustacchi     size_t filesize,
173*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Unsigned access,
174*4d9fdb46SRobert Mustacchi     unsigned groupnumber,
175*4d9fdb46SRobert Mustacchi     Dwarf_Handler errhand,
176*4d9fdb46SRobert Mustacchi     Dwarf_Ptr errarg,
177*4d9fdb46SRobert Mustacchi     Dwarf_Debug *dbg,
178*4d9fdb46SRobert Mustacchi #endif /* DWARF_WITH_LIBELF */
179*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
18007dc1947SRichard Lowe {
181*4d9fdb46SRobert Mustacchi #ifndef DWARF_WITH_LIBELF
182*4d9fdb46SRobert Mustacchi     DWARF_DBG_ERROR(NULL, DW_DLE_PRODUCER_CODE_NOT_AVAILABLE, DW_DLV_ERROR);
183*4d9fdb46SRobert Mustacchi #else /* DWARF_WITH_LIBELF */
184*4d9fdb46SRobert Mustacchi     Elf_Cmd what_kind_of_elf_read = ELF_C_READ;
18507dc1947SRichard Lowe     Dwarf_Obj_Access_Interface *binary_interface = 0;
18607dc1947SRichard Lowe     int res = DW_DLV_OK;
187*4d9fdb46SRobert Mustacchi     int localerrnum = 0;
188*4d9fdb46SRobert Mustacchi     int libdwarf_owns_elf = TRUE;
189*4d9fdb46SRobert Mustacchi     dwarf_elf_handle elf_file_pointer = 0;
19007dc1947SRichard Lowe 
191*4d9fdb46SRobert Mustacchi     elf_version(EV_CURRENT);
192*4d9fdb46SRobert Mustacchi     elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0);
193*4d9fdb46SRobert Mustacchi     if (elf_file_pointer == NULL) {
194*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR);
19507dc1947SRichard Lowe     }
196*4d9fdb46SRobert Mustacchi     /* Sets up elf access function pointers. */
19707dc1947SRichard Lowe     res = dwarf_elf_object_access_init(
198*4d9fdb46SRobert Mustacchi         elf_file_pointer,
19907dc1947SRichard Lowe         libdwarf_owns_elf,
20007dc1947SRichard Lowe         &binary_interface,
201*4d9fdb46SRobert Mustacchi         &localerrnum);
202*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
203*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_NO_ENTRY) {
204*4d9fdb46SRobert Mustacchi             return res;
205*4d9fdb46SRobert Mustacchi         }
206*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR);
20707dc1947SRichard Lowe     }
208*4d9fdb46SRobert Mustacchi     /* allocates and initializes Dwarf_Debug */
209*4d9fdb46SRobert Mustacchi     res = dwarf_object_init_b(binary_interface, errhand, errarg,
210*4d9fdb46SRobert Mustacchi         groupnumber,
211*4d9fdb46SRobert Mustacchi         dbg, error);
212*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK){
213*4d9fdb46SRobert Mustacchi         dwarf_elf_object_access_finish(binary_interface);
214*4d9fdb46SRobert Mustacchi         return res;
215*4d9fdb46SRobert Mustacchi     }
216*4d9fdb46SRobert Mustacchi     (*dbg)->de_filesize = filesize;
217*4d9fdb46SRobert Mustacchi     res = dwarf_add_debuglink_global_path(*dbg,
218*4d9fdb46SRobert Mustacchi         "/usr/lib/debug",error);
219*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK){
22007dc1947SRichard Lowe         dwarf_elf_object_access_finish(binary_interface);
22107dc1947SRichard Lowe     }
22207dc1947SRichard Lowe     return res;
223*4d9fdb46SRobert Mustacchi #endif /* DWARF_WITH_LIBELF */
22407dc1947SRichard Lowe }
225