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