07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Copyright (C) 2000,2001,2002,2005,2006 Silicon Graphics, Inc. All Rights Reserved.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This program is free software; you can redistribute it and/or modify it
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe under the terms of version 2.1 of the GNU Lesser General Public License
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe as published by the Free Software Foundation.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This program is distributed in the hope that it would be useful, but
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe WITHOUT ANY WARRANTY; without even the implied warranty of
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Further, this software is distributed without any warranty that it is
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free of the rightful claim of any third person regarding infringement
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe or the like. Any license provided herein, whether implied or
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe otherwise, applies only to this software file. Patent licenses, if
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe any, provided herein do not apply to combinations of this program with
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe other software, or any other product whatsoever.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe You should have received a copy of the GNU Lesser General Public
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe License along with this program; if not, write the Free Software
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe USA.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Mountain View, CA 94043, or:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe http://www.sgi.com
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe For further information regarding this notice, see:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe http://oss.sgi.com/projects/GenInfo/NoticeExplan
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include "config.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include "dwarf_incl.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include "dwarf_elf_access.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF_H
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <elf.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_LIBELF_H
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <libelf.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#else
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_LIBELF_LIBELF_H
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <libelf/libelf.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <stdio.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <sys/stat.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <sys/types.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <string.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <stdlib.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define DWARF_DBG_ERROR(dbg,errval,retval) \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_error(dbg, error, errval); return(retval);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define FALSE 0
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define TRUE 1
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic int
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int libdwarf_owns_elf,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned access,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Handler errhand,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Ptr errarg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Debug * ret_dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Error * error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe The basic dwarf initializer function for consumers using
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe libelf.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Return a libdwarf error code on error, return DW_DLV_OK
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if this succeeds.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweint
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_init(int fd,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned access,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Handler errhand,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct stat fstat_buf;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_handle elf_file_pointer = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* ELF_C_READ is a portable value */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf_Cmd what_kind_of_elf_read = ELF_C_READ;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if !defined(S_ISREG)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (fstat(fd, &fstat_buf) != 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe DWARF_DBG_ERROR(NULL, DW_DLE_FSTAT_ERROR, DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (!S_ISREG(fstat_buf.st_mode)) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe DWARF_DBG_ERROR(NULL, DW_DLE_FSTAT_MODE_ERROR, DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (access != DW_DLC_READ) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe elf_version(EV_CURRENT);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* changed to mmap request per bug 281217. 6/95 */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF_C_READ_MMAP
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* ELF_C_READ_MMAP is an SGI IRIX specific enum value from IRIX
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe libelf.h meaning read but use mmap */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe what_kind_of_elf_read = ELF_C_READ_MMAP;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif /* !HAVE_ELF_C_READ_MMAP */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (elf_file_pointer == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return dwarf_elf_init_file_ownership(elf_file_pointer,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe TRUE,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe access,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe errhand,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe errarg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe An alternate dwarf setup call for consumers using
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe libelf.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe When the caller has opened libelf already, so the
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe caller must free libelf.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweint
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_init(dwarf_elf_handle elf_file_pointer,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned access,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Handler errhand,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Ptr errarg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Debug * ret_dbg, Dwarf_Error * error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return dwarf_elf_init_file_ownership(elf_file_pointer,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe FALSE,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe access,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe errhand,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe errarg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Initialize the ELF object access for libdwarf.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic int
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int libdwarf_owns_elf,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned access,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Handler errhand,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Ptr errarg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Debug * ret_dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Error * error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* ELF is no longer tied to libdwarf. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Obj_Access_Interface *binary_interface = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int res = DW_DLV_OK;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int err = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (access != DW_DLC_READ) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* This allocates and fills in *binary_interface. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe res = dwarf_elf_object_access_init(
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe elf_file_pointer,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe libdwarf_owns_elf,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe &binary_interface,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe &err);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(res != DW_DLV_OK){
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe DWARF_DBG_ERROR(NULL, err, DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* This mallocs space and returns pointer thru ret_dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe saving the binary interface in 'ret-dbg' */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe res = dwarf_object_init(binary_interface, errhand, errarg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_dbg, error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(res != DW_DLV_OK){
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_finish(binary_interface);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return res;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Frees all memory that was not previously freed
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe by dwarf_dealloc.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Aside from certain categories.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This is only applicable when dwarf_init() or dwarf_elf_init()
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe was used to init 'dbg'.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweint
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_finish(dbg->de_obj_file);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return dwarf_object_finish(dbg, error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe