1*4d9fdb46SRobert Mustacchi /*
2*4d9fdb46SRobert Mustacchi   Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
3*4d9fdb46SRobert Mustacchi   Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
4*4d9fdb46SRobert Mustacchi   Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved.
5*4d9fdb46SRobert Mustacchi   Portions Copyright 2011-2019 David Anderson. All rights reserved.
6*4d9fdb46SRobert Mustacchi   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
7*4d9fdb46SRobert Mustacchi 
8*4d9fdb46SRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
9*4d9fdb46SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
10*4d9fdb46SRobert Mustacchi   as published by the Free Software Foundation.
11*4d9fdb46SRobert Mustacchi 
12*4d9fdb46SRobert Mustacchi   This program is distributed in the hope that it would be useful, but
13*4d9fdb46SRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
14*4d9fdb46SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15*4d9fdb46SRobert Mustacchi 
16*4d9fdb46SRobert Mustacchi   Further, this software is distributed without any warranty that it is
17*4d9fdb46SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
18*4d9fdb46SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
19*4d9fdb46SRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
20*4d9fdb46SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
21*4d9fdb46SRobert Mustacchi   other software, or any other product whatsoever.
22*4d9fdb46SRobert Mustacchi 
23*4d9fdb46SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
24*4d9fdb46SRobert Mustacchi   License along with this program; if not, write the Free Software
25*4d9fdb46SRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
26*4d9fdb46SRobert Mustacchi   USA.
27*4d9fdb46SRobert Mustacchi 
28*4d9fdb46SRobert Mustacchi */
29*4d9fdb46SRobert Mustacchi 
30*4d9fdb46SRobert Mustacchi #include "config.h"
31*4d9fdb46SRobert Mustacchi #ifdef HAVE_LIBELF_H
32*4d9fdb46SRobert Mustacchi #include <libelf.h>
33*4d9fdb46SRobert Mustacchi #else
34*4d9fdb46SRobert Mustacchi #ifdef HAVE_LIBELF_LIBELF_H
35*4d9fdb46SRobert Mustacchi #include <libelf/libelf.h>
36*4d9fdb46SRobert Mustacchi #endif
37*4d9fdb46SRobert Mustacchi #endif
38*4d9fdb46SRobert Mustacchi #include <stdio.h>
39*4d9fdb46SRobert Mustacchi #include <sys/types.h>
40*4d9fdb46SRobert Mustacchi #include <sys/stat.h>
41*4d9fdb46SRobert Mustacchi #include <fcntl.h>
42*4d9fdb46SRobert Mustacchi #include <string.h>
43*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
44*4d9fdb46SRobert Mustacchi #include <stdlib.h>
45*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
46*4d9fdb46SRobert Mustacchi #ifdef HAVE_MALLOC_H
47*4d9fdb46SRobert Mustacchi /* Useful include for some Windows compilers. */
48*4d9fdb46SRobert Mustacchi #include <malloc.h>
49*4d9fdb46SRobert Mustacchi #endif /* HAVE_MALLOC_H */
50*4d9fdb46SRobert Mustacchi #ifdef HAVE_UNISTD_H
51*4d9fdb46SRobert Mustacchi #include <unistd.h>
52*4d9fdb46SRobert Mustacchi #elif defined(_WIN32) && defined(_MSC_VER)
53*4d9fdb46SRobert Mustacchi #include <io.h>
54*4d9fdb46SRobert Mustacchi #endif /* HAVE_UNISTD_H */
55*4d9fdb46SRobert Mustacchi 
56*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
57*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
58*4d9fdb46SRobert Mustacchi #include "dwarf_object_detector.h"
59*4d9fdb46SRobert Mustacchi #include "dwarf_elf_access.h" /* Needed while libelf in use */
60*4d9fdb46SRobert Mustacchi 
61*4d9fdb46SRobert Mustacchi #ifndef O_BINARY
62*4d9fdb46SRobert Mustacchi #define O_BINARY 0
63*4d9fdb46SRobert Mustacchi #endif /* O_BINARY */
64*4d9fdb46SRobert Mustacchi 
65*4d9fdb46SRobert Mustacchi /*  This is the initialization set intended to
66*4d9fdb46SRobert Mustacchi     handle multiple object formats.
67*4d9fdb46SRobert Mustacchi     Created September 2018
68*4d9fdb46SRobert Mustacchi 
69*4d9fdb46SRobert Mustacchi     The init functions here cannot process archives.
70*4d9fdb46SRobert Mustacchi     For archives the libelf-only dwarf_elf_init*()
71*4d9fdb46SRobert Mustacchi     functions are used if present, else archives
72*4d9fdb46SRobert Mustacchi     cannot be read.
73*4d9fdb46SRobert Mustacchi */
74*4d9fdb46SRobert Mustacchi 
75*4d9fdb46SRobert Mustacchi 
76*4d9fdb46SRobert Mustacchi #define DWARF_DBG_ERROR(dbg,errval,retval) \
77*4d9fdb46SRobert Mustacchi     _dwarf_error(dbg, error, errval); return(retval);
78*4d9fdb46SRobert Mustacchi 
79*4d9fdb46SRobert Mustacchi 
80*4d9fdb46SRobert Mustacchi #define FALSE  0
81*4d9fdb46SRobert Mustacchi #define TRUE   1
82*4d9fdb46SRobert Mustacchi /*  An original basic dwarf initializer function for consumers.
83*4d9fdb46SRobert Mustacchi     Return a libdwarf error code on error, return DW_DLV_OK
84*4d9fdb46SRobert Mustacchi     if this succeeds.
85*4d9fdb46SRobert Mustacchi     dwarf_init_b() is a better choice where there
86*4d9fdb46SRobert Mustacchi     are section groups in an object file. */
87*4d9fdb46SRobert Mustacchi int
dwarf_init(int fd,Dwarf_Unsigned access,Dwarf_Handler errhand,Dwarf_Ptr errarg,Dwarf_Debug * ret_dbg,Dwarf_Error * error)88*4d9fdb46SRobert Mustacchi dwarf_init(int fd,
89*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned access,
90*4d9fdb46SRobert Mustacchi     Dwarf_Handler errhand,
91*4d9fdb46SRobert Mustacchi     Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error)
92*4d9fdb46SRobert Mustacchi {
93*4d9fdb46SRobert Mustacchi     return dwarf_init_b(fd,access, DW_GROUPNUMBER_ANY,
94*4d9fdb46SRobert Mustacchi         errhand,errarg,ret_dbg,error);
95*4d9fdb46SRobert Mustacchi }
96*4d9fdb46SRobert Mustacchi 
97*4d9fdb46SRobert Mustacchi static int
open_a_file(const char * name)98*4d9fdb46SRobert Mustacchi open_a_file(const char * name)
99*4d9fdb46SRobert Mustacchi {
100*4d9fdb46SRobert Mustacchi     /* Set to a file number that cannot be legal. */
101*4d9fdb46SRobert Mustacchi     int fd = -1;
102*4d9fdb46SRobert Mustacchi 
103*4d9fdb46SRobert Mustacchi #if HAVE_ELF_OPEN
104*4d9fdb46SRobert Mustacchi     /*  It is not possible to share file handles
105*4d9fdb46SRobert Mustacchi         between applications or DLLs. Each application has its own
106*4d9fdb46SRobert Mustacchi         file-handle table. For two applications to use the same file
107*4d9fdb46SRobert Mustacchi         using a DLL, they must both open the file individually.
108*4d9fdb46SRobert Mustacchi         Let the 'libelf' dll open and close the file.  */
109*4d9fdb46SRobert Mustacchi     fd = elf_open(name, O_RDONLY | O_BINARY);
110*4d9fdb46SRobert Mustacchi #else
111*4d9fdb46SRobert Mustacchi     fd = open(name, O_RDONLY | O_BINARY);
112*4d9fdb46SRobert Mustacchi #endif
113*4d9fdb46SRobert Mustacchi     return fd;
114*4d9fdb46SRobert Mustacchi }
115*4d9fdb46SRobert Mustacchi 
116*4d9fdb46SRobert Mustacchi static int
set_global_paths_init(Dwarf_Debug dbg,Dwarf_Error * error)117*4d9fdb46SRobert Mustacchi set_global_paths_init(Dwarf_Debug dbg, Dwarf_Error* error)
118*4d9fdb46SRobert Mustacchi {
119*4d9fdb46SRobert Mustacchi     int res = 0;
120*4d9fdb46SRobert Mustacchi 
121*4d9fdb46SRobert Mustacchi     res = dwarf_add_debuglink_global_path(dbg,
122*4d9fdb46SRobert Mustacchi         "/usr/lib/debug",error);
123*4d9fdb46SRobert Mustacchi     return res;
124*4d9fdb46SRobert Mustacchi }
125*4d9fdb46SRobert Mustacchi 
126*4d9fdb46SRobert Mustacchi /* New in December 2018. */
dwarf_init_path(const char * path,char * true_path_out_buffer,unsigned true_path_bufferlen,Dwarf_Unsigned access,unsigned groupnumber,Dwarf_Handler errhand,Dwarf_Ptr errarg,Dwarf_Debug * ret_dbg,UNUSEDARG const char * reserved1,UNUSEDARG Dwarf_Unsigned reserved2,UNUSEDARG Dwarf_Unsigned * reserved3,Dwarf_Error * error)127*4d9fdb46SRobert Mustacchi int dwarf_init_path(const char *path,
128*4d9fdb46SRobert Mustacchi     char *true_path_out_buffer,
129*4d9fdb46SRobert Mustacchi     unsigned true_path_bufferlen,
130*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned    access,
131*4d9fdb46SRobert Mustacchi     unsigned          groupnumber,
132*4d9fdb46SRobert Mustacchi     Dwarf_Handler     errhand,
133*4d9fdb46SRobert Mustacchi     Dwarf_Ptr         errarg,
134*4d9fdb46SRobert Mustacchi     Dwarf_Debug*      ret_dbg,
135*4d9fdb46SRobert Mustacchi     UNUSEDARG const char *       reserved1,
136*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Unsigned     reserved2,
137*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Unsigned  *  reserved3,
138*4d9fdb46SRobert Mustacchi     Dwarf_Error*      error)
139*4d9fdb46SRobert Mustacchi {
140*4d9fdb46SRobert Mustacchi     unsigned       ftype = 0;
141*4d9fdb46SRobert Mustacchi     unsigned       endian = 0;
142*4d9fdb46SRobert Mustacchi     unsigned       offsetsize = 0;
143*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned filesize = 0;
144*4d9fdb46SRobert Mustacchi     int res = 0;
145*4d9fdb46SRobert Mustacchi     int errcode = 0;
146*4d9fdb46SRobert Mustacchi     int fd = -1;
147*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
148*4d9fdb46SRobert Mustacchi     char *file_path = 0;
149*4d9fdb46SRobert Mustacchi 
150*4d9fdb46SRobert Mustacchi     if (!ret_dbg) {
151*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL,DW_DLV_ERROR);
152*4d9fdb46SRobert Mustacchi     }
153*4d9fdb46SRobert Mustacchi     res = dwarf_object_detector_path(path,
154*4d9fdb46SRobert Mustacchi         true_path_out_buffer,
155*4d9fdb46SRobert Mustacchi         true_path_bufferlen,
156*4d9fdb46SRobert Mustacchi         &ftype,&endian,&offsetsize,&filesize,&errcode);
157*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_NO_ENTRY) {
158*4d9fdb46SRobert Mustacchi         return res;
159*4d9fdb46SRobert Mustacchi     }
160*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_ERROR) {
161*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL, errcode, DW_DLV_ERROR);
162*4d9fdb46SRobert Mustacchi     }
163*4d9fdb46SRobert Mustacchi     if (true_path_out_buffer) {
164*4d9fdb46SRobert Mustacchi         file_path = true_path_out_buffer;
165*4d9fdb46SRobert Mustacchi         fd = open_a_file(true_path_out_buffer);
166*4d9fdb46SRobert Mustacchi     } else {
167*4d9fdb46SRobert Mustacchi         file_path = (char *)path;
168*4d9fdb46SRobert Mustacchi         fd = open_a_file(path);
169*4d9fdb46SRobert Mustacchi     }
170*4d9fdb46SRobert Mustacchi     if(fd == -1) {
171*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL, DW_DLE_FILE_UNAVAILABLE,
172*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
173*4d9fdb46SRobert Mustacchi     }
174*4d9fdb46SRobert Mustacchi     switch(ftype) {
175*4d9fdb46SRobert Mustacchi     case DW_FTYPE_ELF: {
176*4d9fdb46SRobert Mustacchi         res = _dwarf_elf_nlsetup(fd,
177*4d9fdb46SRobert Mustacchi             file_path,
178*4d9fdb46SRobert Mustacchi             ftype,endian,offsetsize,filesize,
179*4d9fdb46SRobert Mustacchi             access,groupnumber,errhand,errarg,&dbg,error);
180*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
181*4d9fdb46SRobert Mustacchi             *ret_dbg = dbg;
182*4d9fdb46SRobert Mustacchi             close(fd);
183*4d9fdb46SRobert Mustacchi             return res;
184*4d9fdb46SRobert Mustacchi         }
185*4d9fdb46SRobert Mustacchi         dbg->de_path = strdup(file_path);
186*4d9fdb46SRobert Mustacchi         dbg->de_fd = fd;
187*4d9fdb46SRobert Mustacchi         dbg->de_owns_fd = TRUE;
188*4d9fdb46SRobert Mustacchi         res = set_global_paths_init(dbg,error);
189*4d9fdb46SRobert Mustacchi         *ret_dbg = dbg;
190*4d9fdb46SRobert Mustacchi         return res;
191*4d9fdb46SRobert Mustacchi     }
192*4d9fdb46SRobert Mustacchi     case DW_FTYPE_MACH_O: {
193*4d9fdb46SRobert Mustacchi         res = _dwarf_macho_setup(fd,
194*4d9fdb46SRobert Mustacchi             file_path,
195*4d9fdb46SRobert Mustacchi             ftype,endian,offsetsize,filesize,
196*4d9fdb46SRobert Mustacchi             access,groupnumber,errhand,errarg,&dbg,error);
197*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
198*4d9fdb46SRobert Mustacchi             close(fd);
199*4d9fdb46SRobert Mustacchi             *ret_dbg = dbg;
200*4d9fdb46SRobert Mustacchi             return res;
201*4d9fdb46SRobert Mustacchi         }
202*4d9fdb46SRobert Mustacchi         dbg->de_path = strdup(file_path);
203*4d9fdb46SRobert Mustacchi         dbg->de_fd = fd;
204*4d9fdb46SRobert Mustacchi         dbg->de_owns_fd = TRUE;
205*4d9fdb46SRobert Mustacchi         set_global_paths_init(dbg,error);
206*4d9fdb46SRobert Mustacchi         *ret_dbg = dbg;
207*4d9fdb46SRobert Mustacchi         return res;
208*4d9fdb46SRobert Mustacchi     }
209*4d9fdb46SRobert Mustacchi     case DW_FTYPE_PE: {
210*4d9fdb46SRobert Mustacchi         res = _dwarf_pe_setup(fd,
211*4d9fdb46SRobert Mustacchi             file_path,
212*4d9fdb46SRobert Mustacchi             ftype,endian,offsetsize,filesize,
213*4d9fdb46SRobert Mustacchi             access,groupnumber,errhand,errarg,&dbg,error);
214*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
215*4d9fdb46SRobert Mustacchi             close(fd);
216*4d9fdb46SRobert Mustacchi             *ret_dbg = dbg;
217*4d9fdb46SRobert Mustacchi         }
218*4d9fdb46SRobert Mustacchi         dbg->de_path = strdup(file_path);
219*4d9fdb46SRobert Mustacchi         dbg->de_fd = fd;
220*4d9fdb46SRobert Mustacchi         dbg->de_owns_fd = TRUE;
221*4d9fdb46SRobert Mustacchi         set_global_paths_init(dbg,error);
222*4d9fdb46SRobert Mustacchi         *ret_dbg = dbg;
223*4d9fdb46SRobert Mustacchi         return res;
224*4d9fdb46SRobert Mustacchi     }
225*4d9fdb46SRobert Mustacchi     default:
226*4d9fdb46SRobert Mustacchi         close(fd);
227*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR);
228*4d9fdb46SRobert Mustacchi     }
229*4d9fdb46SRobert Mustacchi     return DW_DLV_NO_ENTRY; /* placeholder for now */
230*4d9fdb46SRobert Mustacchi }
231*4d9fdb46SRobert Mustacchi 
232*4d9fdb46SRobert Mustacchi 
233*4d9fdb46SRobert Mustacchi /*  New March 2017, this provides for reading
234*4d9fdb46SRobert Mustacchi     object files with multiple elf section groups.  */
235*4d9fdb46SRobert Mustacchi int
dwarf_init_b(int fd,Dwarf_Unsigned access,unsigned group_number,Dwarf_Handler errhand,Dwarf_Ptr errarg,Dwarf_Debug * ret_dbg,Dwarf_Error * error)236*4d9fdb46SRobert Mustacchi dwarf_init_b(int fd,
237*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned access,
238*4d9fdb46SRobert Mustacchi     unsigned  group_number,
239*4d9fdb46SRobert Mustacchi     Dwarf_Handler errhand,
240*4d9fdb46SRobert Mustacchi     Dwarf_Ptr errarg,
241*4d9fdb46SRobert Mustacchi     Dwarf_Debug * ret_dbg,
242*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
243*4d9fdb46SRobert Mustacchi {
244*4d9fdb46SRobert Mustacchi     unsigned ftype = 0;
245*4d9fdb46SRobert Mustacchi     unsigned endian = 0;
246*4d9fdb46SRobert Mustacchi     unsigned offsetsize = 0;
247*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned   filesize = 0;
248*4d9fdb46SRobert Mustacchi     int res = 0;
249*4d9fdb46SRobert Mustacchi     int errcode = 0;
250*4d9fdb46SRobert Mustacchi 
251*4d9fdb46SRobert Mustacchi     if (!ret_dbg) {
252*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL,DW_DLV_ERROR);
253*4d9fdb46SRobert Mustacchi     }
254*4d9fdb46SRobert Mustacchi     res = dwarf_object_detector_fd(fd, &ftype,
255*4d9fdb46SRobert Mustacchi         &endian,&offsetsize,&filesize,&errcode);
256*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_NO_ENTRY) {
257*4d9fdb46SRobert Mustacchi         return res;
258*4d9fdb46SRobert Mustacchi     } else if (res == DW_DLV_ERROR) {
259*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR);
260*4d9fdb46SRobert Mustacchi     }
261*4d9fdb46SRobert Mustacchi 
262*4d9fdb46SRobert Mustacchi     switch(ftype) {
263*4d9fdb46SRobert Mustacchi     case DW_FTYPE_ELF: {
264*4d9fdb46SRobert Mustacchi         int res2 = 0;
265*4d9fdb46SRobert Mustacchi 
266*4d9fdb46SRobert Mustacchi         res2 = _dwarf_elf_nlsetup(fd,"",
267*4d9fdb46SRobert Mustacchi             ftype,endian,offsetsize,filesize,
268*4d9fdb46SRobert Mustacchi             access,group_number,errhand,errarg,ret_dbg,error);
269*4d9fdb46SRobert Mustacchi         if (res2 != DW_DLV_OK) {
270*4d9fdb46SRobert Mustacchi             return res2;
271*4d9fdb46SRobert Mustacchi         }
272*4d9fdb46SRobert Mustacchi         set_global_paths_init(*ret_dbg,error);
273*4d9fdb46SRobert Mustacchi         return res2;
274*4d9fdb46SRobert Mustacchi         }
275*4d9fdb46SRobert Mustacchi     case DW_FTYPE_MACH_O: {
276*4d9fdb46SRobert Mustacchi         int resm = 0;
277*4d9fdb46SRobert Mustacchi 
278*4d9fdb46SRobert Mustacchi         resm = _dwarf_macho_setup(fd,"",
279*4d9fdb46SRobert Mustacchi             ftype,endian,offsetsize,filesize,
280*4d9fdb46SRobert Mustacchi             access,group_number,errhand,errarg,ret_dbg,error);
281*4d9fdb46SRobert Mustacchi         if (resm != DW_DLV_OK) {
282*4d9fdb46SRobert Mustacchi             return resm;
283*4d9fdb46SRobert Mustacchi         }
284*4d9fdb46SRobert Mustacchi         set_global_paths_init(*ret_dbg,error);
285*4d9fdb46SRobert Mustacchi         return resm;
286*4d9fdb46SRobert Mustacchi         }
287*4d9fdb46SRobert Mustacchi 
288*4d9fdb46SRobert Mustacchi     case DW_FTYPE_PE: {
289*4d9fdb46SRobert Mustacchi         int resp = 0;
290*4d9fdb46SRobert Mustacchi 
291*4d9fdb46SRobert Mustacchi         resp = _dwarf_pe_setup(fd,
292*4d9fdb46SRobert Mustacchi             "",
293*4d9fdb46SRobert Mustacchi             ftype,endian,offsetsize,filesize,
294*4d9fdb46SRobert Mustacchi             access,group_number,errhand,errarg,ret_dbg,error);
295*4d9fdb46SRobert Mustacchi         if (resp != DW_DLV_OK) {
296*4d9fdb46SRobert Mustacchi             return resp;
297*4d9fdb46SRobert Mustacchi         }
298*4d9fdb46SRobert Mustacchi         set_global_paths_init(*ret_dbg,error);
299*4d9fdb46SRobert Mustacchi         return resp;
300*4d9fdb46SRobert Mustacchi         }
301*4d9fdb46SRobert Mustacchi     }
302*4d9fdb46SRobert Mustacchi     DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR);
303*4d9fdb46SRobert Mustacchi     return res;
304*4d9fdb46SRobert Mustacchi }
305*4d9fdb46SRobert Mustacchi 
306*4d9fdb46SRobert Mustacchi /*
307*4d9fdb46SRobert Mustacchi     Frees all memory that was not previously freed
308*4d9fdb46SRobert Mustacchi     by dwarf_dealloc.
309*4d9fdb46SRobert Mustacchi     Aside from certain categories.
310*4d9fdb46SRobert Mustacchi 
311*4d9fdb46SRobert Mustacchi     Applicable when dwarf_init() or dwarf_elf_init()
312*4d9fdb46SRobert Mustacchi     or the -b() form was used to init 'dbg'.
313*4d9fdb46SRobert Mustacchi */
314*4d9fdb46SRobert Mustacchi int
dwarf_finish(Dwarf_Debug dbg,Dwarf_Error * error)315*4d9fdb46SRobert Mustacchi dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error)
316*4d9fdb46SRobert Mustacchi {
317*4d9fdb46SRobert Mustacchi     if(!dbg) {
318*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL, DW_DLE_DBG_NULL, DW_DLV_ERROR);
319*4d9fdb46SRobert Mustacchi     }
320*4d9fdb46SRobert Mustacchi     if (dbg->de_obj_file) {
321*4d9fdb46SRobert Mustacchi         /*  The initial character of a valid
322*4d9fdb46SRobert Mustacchi             dbg->de_obj_file->object struct is a letter:
323*4d9fdb46SRobert Mustacchi             E, F, M, or P */
324*4d9fdb46SRobert Mustacchi         char otype  = *(char *)(dbg->de_obj_file->object);
325*4d9fdb46SRobert Mustacchi 
326*4d9fdb46SRobert Mustacchi         switch(otype) {
327*4d9fdb46SRobert Mustacchi         case 'E':
328*4d9fdb46SRobert Mustacchi #ifdef DWARF_WITH_LIBELF
329*4d9fdb46SRobert Mustacchi             dwarf_elf_object_access_finish(dbg->de_obj_file);
330*4d9fdb46SRobert Mustacchi #endif /* DWARF_WITH_LIBELF */
331*4d9fdb46SRobert Mustacchi             break;
332*4d9fdb46SRobert Mustacchi         case 'F':
333*4d9fdb46SRobert Mustacchi             /* Non-libelf elf access */
334*4d9fdb46SRobert Mustacchi             _dwarf_destruct_elf_nlaccess(dbg->de_obj_file);
335*4d9fdb46SRobert Mustacchi             break;
336*4d9fdb46SRobert Mustacchi         case 'M':
337*4d9fdb46SRobert Mustacchi             _dwarf_destruct_macho_access(dbg->de_obj_file);
338*4d9fdb46SRobert Mustacchi             break;
339*4d9fdb46SRobert Mustacchi         case 'P':
340*4d9fdb46SRobert Mustacchi             _dwarf_destruct_pe_access(dbg->de_obj_file);
341*4d9fdb46SRobert Mustacchi             break;
342*4d9fdb46SRobert Mustacchi         default:
343*4d9fdb46SRobert Mustacchi             /*  Do nothing. A serious internal error */
344*4d9fdb46SRobert Mustacchi             break;
345*4d9fdb46SRobert Mustacchi         }
346*4d9fdb46SRobert Mustacchi     }
347*4d9fdb46SRobert Mustacchi     if (dbg->de_owns_fd) {
348*4d9fdb46SRobert Mustacchi         close(dbg->de_fd);
349*4d9fdb46SRobert Mustacchi         dbg->de_owns_fd = FALSE;
350*4d9fdb46SRobert Mustacchi     }
351*4d9fdb46SRobert Mustacchi     free((void *)dbg->de_path);
352*4d9fdb46SRobert Mustacchi     dbg->de_path = 0;
353*4d9fdb46SRobert Mustacchi     /*  dwarf_object_finish() also frees de_path,
354*4d9fdb46SRobert Mustacchi         but that is safe because we set it to zero
355*4d9fdb46SRobert Mustacchi         here so no duplicate free will occur.
356*4d9fdb46SRobert Mustacchi         Not all code uses libdwarf exactly as we do
357*4d9fdb46SRobert Mustacchi         hence the free() there. */
358*4d9fdb46SRobert Mustacchi     return dwarf_object_finish(dbg, error);
359*4d9fdb46SRobert Mustacchi }
360*4d9fdb46SRobert Mustacchi 
361*4d9fdb46SRobert Mustacchi /*
362*4d9fdb46SRobert Mustacchi     tieddbg should be the executable or .o
363*4d9fdb46SRobert Mustacchi     that has the .debug_addr section that
364*4d9fdb46SRobert Mustacchi     the base dbg refers to. See Split Objects in DWARF5.
365*4d9fdb46SRobert Mustacchi 
366*4d9fdb46SRobert Mustacchi     Allows setting to NULL (NULL is the default
367*4d9fdb46SRobert Mustacchi     of  de_tied_data.td_tied_object).
368*4d9fdb46SRobert Mustacchi     New September 2015.
369*4d9fdb46SRobert Mustacchi */
370*4d9fdb46SRobert Mustacchi int
dwarf_set_tied_dbg(Dwarf_Debug dbg,Dwarf_Debug tieddbg,Dwarf_Error * error)371*4d9fdb46SRobert Mustacchi dwarf_set_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug tieddbg,Dwarf_Error*error)
372*4d9fdb46SRobert Mustacchi {
373*4d9fdb46SRobert Mustacchi     if(!dbg) {
374*4d9fdb46SRobert Mustacchi         DWARF_DBG_ERROR(NULL, DW_DLE_DBG_NULL, DW_DLV_ERROR);
375*4d9fdb46SRobert Mustacchi     }
376*4d9fdb46SRobert Mustacchi     dbg->de_tied_data.td_tied_object = tieddbg;
377*4d9fdb46SRobert Mustacchi     if (tieddbg) {
378*4d9fdb46SRobert Mustacchi         tieddbg->de_tied_data.td_is_tied_object = TRUE;
379*4d9fdb46SRobert Mustacchi     }
380*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
381*4d9fdb46SRobert Mustacchi }
382*4d9fdb46SRobert Mustacchi 
383*4d9fdb46SRobert Mustacchi /*  Unsure of the use-case of this.
384*4d9fdb46SRobert Mustacchi     New September 2015. */
385*4d9fdb46SRobert Mustacchi int
dwarf_get_tied_dbg(Dwarf_Debug dbg,Dwarf_Debug * tieddbg_out,UNUSEDARG Dwarf_Error * error)386*4d9fdb46SRobert Mustacchi dwarf_get_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug *tieddbg_out,
387*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Error*error)
388*4d9fdb46SRobert Mustacchi {
389*4d9fdb46SRobert Mustacchi     *tieddbg_out = dbg->de_tied_data.td_tied_object;
390*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
391*4d9fdb46SRobert Mustacchi }
392