xref: /aosp_15_r20/external/elfutils/libdw/dwarf_begin.c (revision 7304104da70ce23c86437a01be71edd1a2d7f37e)
1*7304104dSAndroid Build Coastguard Worker /* Create descriptor from file descriptor for processing file.
2*7304104dSAndroid Build Coastguard Worker    Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
3*7304104dSAndroid Build Coastguard Worker    This file is part of elfutils.
4*7304104dSAndroid Build Coastguard Worker    Written by Ulrich Drepper <[email protected]>, 2002.
5*7304104dSAndroid Build Coastguard Worker 
6*7304104dSAndroid Build Coastguard Worker    This file is free software; you can redistribute it and/or modify
7*7304104dSAndroid Build Coastguard Worker    it under the terms of either
8*7304104dSAndroid Build Coastguard Worker 
9*7304104dSAndroid Build Coastguard Worker      * the GNU Lesser General Public License as published by the Free
10*7304104dSAndroid Build Coastguard Worker        Software Foundation; either version 3 of the License, or (at
11*7304104dSAndroid Build Coastguard Worker        your option) any later version
12*7304104dSAndroid Build Coastguard Worker 
13*7304104dSAndroid Build Coastguard Worker    or
14*7304104dSAndroid Build Coastguard Worker 
15*7304104dSAndroid Build Coastguard Worker      * the GNU General Public License as published by the Free
16*7304104dSAndroid Build Coastguard Worker        Software Foundation; either version 2 of the License, or (at
17*7304104dSAndroid Build Coastguard Worker        your option) any later version
18*7304104dSAndroid Build Coastguard Worker 
19*7304104dSAndroid Build Coastguard Worker    or both in parallel, as here.
20*7304104dSAndroid Build Coastguard Worker 
21*7304104dSAndroid Build Coastguard Worker    elfutils is distributed in the hope that it will be useful, but
22*7304104dSAndroid Build Coastguard Worker    WITHOUT ANY WARRANTY; without even the implied warranty of
23*7304104dSAndroid Build Coastguard Worker    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24*7304104dSAndroid Build Coastguard Worker    General Public License for more details.
25*7304104dSAndroid Build Coastguard Worker 
26*7304104dSAndroid Build Coastguard Worker    You should have received copies of the GNU General Public License and
27*7304104dSAndroid Build Coastguard Worker    the GNU Lesser General Public License along with this program.  If
28*7304104dSAndroid Build Coastguard Worker    not, see <http://www.gnu.org/licenses/>.  */
29*7304104dSAndroid Build Coastguard Worker 
30*7304104dSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
31*7304104dSAndroid Build Coastguard Worker # include <config.h>
32*7304104dSAndroid Build Coastguard Worker #endif
33*7304104dSAndroid Build Coastguard Worker 
34*7304104dSAndroid Build Coastguard Worker #include <errno.h>
35*7304104dSAndroid Build Coastguard Worker #include <stddef.h>
36*7304104dSAndroid Build Coastguard Worker #include <sys/stat.h>
37*7304104dSAndroid Build Coastguard Worker 
38*7304104dSAndroid Build Coastguard Worker #include <libdwP.h>
39*7304104dSAndroid Build Coastguard Worker 
40*7304104dSAndroid Build Coastguard Worker 
41*7304104dSAndroid Build Coastguard Worker Dwarf *
dwarf_begin(int fd,Dwarf_Cmd cmd)42*7304104dSAndroid Build Coastguard Worker dwarf_begin (int fd, Dwarf_Cmd cmd)
43*7304104dSAndroid Build Coastguard Worker {
44*7304104dSAndroid Build Coastguard Worker   Elf *elf;
45*7304104dSAndroid Build Coastguard Worker   Elf_Cmd elfcmd;
46*7304104dSAndroid Build Coastguard Worker   Dwarf *result = NULL;
47*7304104dSAndroid Build Coastguard Worker 
48*7304104dSAndroid Build Coastguard Worker   switch (cmd)
49*7304104dSAndroid Build Coastguard Worker     {
50*7304104dSAndroid Build Coastguard Worker     case DWARF_C_READ:
51*7304104dSAndroid Build Coastguard Worker       elfcmd = ELF_C_READ_MMAP;
52*7304104dSAndroid Build Coastguard Worker       break;
53*7304104dSAndroid Build Coastguard Worker     case DWARF_C_WRITE:
54*7304104dSAndroid Build Coastguard Worker       elfcmd = ELF_C_WRITE;
55*7304104dSAndroid Build Coastguard Worker       break;
56*7304104dSAndroid Build Coastguard Worker     case DWARF_C_RDWR:
57*7304104dSAndroid Build Coastguard Worker       elfcmd = ELF_C_RDWR;
58*7304104dSAndroid Build Coastguard Worker       break;
59*7304104dSAndroid Build Coastguard Worker     default:
60*7304104dSAndroid Build Coastguard Worker       /* No valid mode.  */
61*7304104dSAndroid Build Coastguard Worker       __libdw_seterrno (DWARF_E_INVALID_CMD);
62*7304104dSAndroid Build Coastguard Worker       return NULL;
63*7304104dSAndroid Build Coastguard Worker     }
64*7304104dSAndroid Build Coastguard Worker 
65*7304104dSAndroid Build Coastguard Worker   /* We have to call `elf_version' here since the user might have not
66*7304104dSAndroid Build Coastguard Worker      done it or initialized libelf with a different version.  This
67*7304104dSAndroid Build Coastguard Worker      would break libdwarf since we are using the ELF data structures
68*7304104dSAndroid Build Coastguard Worker      in a certain way.  */
69*7304104dSAndroid Build Coastguard Worker   elf_version (EV_CURRENT);
70*7304104dSAndroid Build Coastguard Worker 
71*7304104dSAndroid Build Coastguard Worker   /* Get an ELF descriptor.  */
72*7304104dSAndroid Build Coastguard Worker   elf = elf_begin (fd, elfcmd, NULL);
73*7304104dSAndroid Build Coastguard Worker   if (elf == NULL)
74*7304104dSAndroid Build Coastguard Worker     {
75*7304104dSAndroid Build Coastguard Worker       /* Test why the `elf_begin" call failed.  */
76*7304104dSAndroid Build Coastguard Worker       struct stat st;
77*7304104dSAndroid Build Coastguard Worker 
78*7304104dSAndroid Build Coastguard Worker       if (fstat (fd, &st) == 0 && ! S_ISREG (st.st_mode))
79*7304104dSAndroid Build Coastguard Worker 	__libdw_seterrno (DWARF_E_NO_REGFILE);
80*7304104dSAndroid Build Coastguard Worker       else if (errno == EBADF)
81*7304104dSAndroid Build Coastguard Worker 	__libdw_seterrno (DWARF_E_INVALID_FILE);
82*7304104dSAndroid Build Coastguard Worker       else
83*7304104dSAndroid Build Coastguard Worker 	__libdw_seterrno (DWARF_E_IO_ERROR);
84*7304104dSAndroid Build Coastguard Worker     }
85*7304104dSAndroid Build Coastguard Worker   else
86*7304104dSAndroid Build Coastguard Worker     {
87*7304104dSAndroid Build Coastguard Worker       /* Do the real work now that we have an ELF descriptor.  */
88*7304104dSAndroid Build Coastguard Worker       result = INTUSE(dwarf_begin_elf) (elf, cmd, NULL);
89*7304104dSAndroid Build Coastguard Worker 
90*7304104dSAndroid Build Coastguard Worker       /* If this failed, free the resources.  */
91*7304104dSAndroid Build Coastguard Worker       if (result == NULL)
92*7304104dSAndroid Build Coastguard Worker 	elf_end (elf);
93*7304104dSAndroid Build Coastguard Worker       else
94*7304104dSAndroid Build Coastguard Worker 	result->free_elf = true;
95*7304104dSAndroid Build Coastguard Worker     }
96*7304104dSAndroid Build Coastguard Worker 
97*7304104dSAndroid Build Coastguard Worker   return result;
98*7304104dSAndroid Build Coastguard Worker }
99*7304104dSAndroid Build Coastguard Worker INTDEF(dwarf_begin)
100