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 */
59int
60dwarf_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
124int
125dwarf_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
152int
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