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