1 /* 2 3 Copyright (C) 2000,2001,2002,2005,2006 Silicon Graphics, Inc. All Rights Reserved. 4 Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. 5 Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. 6 7 This program is free software; you can redistribute it and/or modify it 8 under the terms of version 2.1 of the GNU Lesser General Public License 9 as published by the Free Software Foundation. 10 11 This program is distributed in the hope that it would be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 15 Further, this software is distributed without any warranty that it is 16 free of the rightful claim of any third person regarding infringement 17 or the like. Any license provided herein, whether implied or 18 otherwise, applies only to this software file. Patent licenses, if 19 any, provided herein do not apply to combinations of this program with 20 other software, or any other product whatsoever. 21 22 You should have received a copy of the GNU Lesser General Public 23 License along with this program; if not, write the Free Software 24 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 25 USA. 26 27 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 28 Mountain View, CA 94043, or: 29 30 http://www.sgi.com 31 32 For further information regarding this notice, see: 33 34 http://oss.sgi.com/projects/GenInfo/NoticeExplan 35 36 */ 37 38 39 #include "config.h" 40 #include "dwarf_incl.h" 41 #include "dwarf_elf_access.h" 42 43 #ifdef HAVE_ELF_H 44 #include <elf.h> 45 #endif 46 #ifdef HAVE_LIBELF_H 47 #include <libelf.h> 48 #else 49 #ifdef HAVE_LIBELF_LIBELF_H 50 #include <libelf/libelf.h> 51 #endif 52 #endif 53 54 #include <stdio.h> 55 #include <sys/stat.h> 56 #include <sys/types.h> 57 #include <string.h> 58 #include <stdlib.h> 59 60 #define DWARF_DBG_ERROR(dbg,errval,retval) \ 61 _dwarf_error(dbg, error, errval); return(retval); 62 63 #define FALSE 0 64 #define TRUE 1 65 66 static int 67 dwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer, 68 int libdwarf_owns_elf, 69 Dwarf_Unsigned access, 70 Dwarf_Handler errhand, 71 Dwarf_Ptr errarg, 72 Dwarf_Debug * ret_dbg, 73 Dwarf_Error * error); 74 75 76 /* 77 The basic dwarf initializer function for consumers using 78 libelf. 79 Return a libdwarf error code on error, return DW_DLV_OK 80 if this succeeds. 81 */ 82 int 83 dwarf_init(int fd, 84 Dwarf_Unsigned access, 85 Dwarf_Handler errhand, 86 Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error) 87 { 88 struct stat fstat_buf; 89 dwarf_elf_handle elf_file_pointer = 0; 90 /* ELF_C_READ is a portable value */ 91 Elf_Cmd what_kind_of_elf_read = ELF_C_READ; 92 93 #if !defined(S_ISREG) 94 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) 95 #endif 96 if (fstat(fd, &fstat_buf) != 0) { 97 DWARF_DBG_ERROR(NULL, DW_DLE_FSTAT_ERROR, DW_DLV_ERROR); 98 } 99 if (!S_ISREG(fstat_buf.st_mode)) { 100 DWARF_DBG_ERROR(NULL, DW_DLE_FSTAT_MODE_ERROR, DW_DLV_ERROR); 101 } 102 103 if (access != DW_DLC_READ) { 104 DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); 105 } 106 107 elf_version(EV_CURRENT); 108 /* changed to mmap request per bug 281217. 6/95 */ 109 #ifdef HAVE_ELF_C_READ_MMAP 110 /* ELF_C_READ_MMAP is an SGI IRIX specific enum value from IRIX 111 libelf.h meaning read but use mmap */ 112 what_kind_of_elf_read = ELF_C_READ_MMAP; 113 #endif /* !HAVE_ELF_C_READ_MMAP */ 114 115 elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0); 116 if (elf_file_pointer == NULL) { 117 DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR); 118 } 119 120 return dwarf_elf_init_file_ownership(elf_file_pointer, 121 TRUE, 122 access, 123 errhand, 124 errarg, 125 ret_dbg, 126 error); 127 } 128 129 /* 130 An alternate dwarf setup call for consumers using 131 libelf. 132 When the caller has opened libelf already, so the 133 caller must free libelf. 134 */ 135 int 136 dwarf_elf_init(dwarf_elf_handle elf_file_pointer, 137 Dwarf_Unsigned access, 138 Dwarf_Handler errhand, 139 Dwarf_Ptr errarg, 140 Dwarf_Debug * ret_dbg, Dwarf_Error * error) 141 { 142 return dwarf_elf_init_file_ownership(elf_file_pointer, 143 FALSE, 144 access, 145 errhand, 146 errarg, 147 ret_dbg, 148 error); 149 } 150 151 152 /* 153 Initialize the ELF object access for libdwarf. 154 */ 155 static int 156 dwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer, 157 int libdwarf_owns_elf, 158 Dwarf_Unsigned access, 159 Dwarf_Handler errhand, 160 Dwarf_Ptr errarg, 161 Dwarf_Debug * ret_dbg, 162 Dwarf_Error * error) 163 { 164 /* ELF is no longer tied to libdwarf. */ 165 Dwarf_Obj_Access_Interface *binary_interface = 0; 166 int res = DW_DLV_OK; 167 int err = 0; 168 169 if (access != DW_DLC_READ) { 170 DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); 171 } 172 173 /* This allocates and fills in *binary_interface. */ 174 res = dwarf_elf_object_access_init( 175 elf_file_pointer, 176 libdwarf_owns_elf, 177 &binary_interface, 178 &err); 179 if(res != DW_DLV_OK){ 180 DWARF_DBG_ERROR(NULL, err, DW_DLV_ERROR); 181 } 182 183 /* This mallocs space and returns pointer thru ret_dbg, 184 saving the binary interface in 'ret-dbg' */ 185 res = dwarf_object_init(binary_interface, errhand, errarg, 186 ret_dbg, error); 187 if(res != DW_DLV_OK){ 188 dwarf_elf_object_access_finish(binary_interface); 189 } 190 return res; 191 } 192 193 194 /* 195 Frees all memory that was not previously freed 196 by dwarf_dealloc. 197 Aside from certain categories. 198 199 This is only applicable when dwarf_init() or dwarf_elf_init() 200 was used to init 'dbg'. 201 */ 202 int 203 dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error) 204 { 205 dwarf_elf_object_access_finish(dbg->de_obj_file); 206 207 return dwarf_object_finish(dbg, error); 208 } 209 210