#include "config.h"
#ifdef HAVE_LIBELF_H
#include <libelf.h>
#else
#ifdef HAVE_LIBELF_LIBELF_H
#include <libelf/libelf.h>
#endif
#endif
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "dwarf_incl.h"
#include "dwarf_error.h"
#include "dwarf_elf_access.h"
#include "dwarf_object_detector.h"
#define DWARF_DBG_ERROR(dbg,errval,retval) \
_dwarf_error(dbg, error, errval); return(retval);
#define FALSE 0
#define TRUE 1
int
dwarf_elf_init_b(
#ifndef DWARF_WITH_LIBELF
UNUSEDARG dwarf_elf_handle elf_file_pointer,
UNUSEDARG Dwarf_Unsigned access,
UNUSEDARG unsigned group_number,
UNUSEDARG Dwarf_Handler errhand,
UNUSEDARG Dwarf_Ptr errarg,
UNUSEDARG Dwarf_Debug * ret_dbg,
#else
dwarf_elf_handle elf_file_pointer,
Dwarf_Unsigned access,
unsigned group_number,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
Dwarf_Debug * ret_dbg,
#endif
Dwarf_Error * error)
{
#ifndef DWARF_WITH_LIBELF
DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR);
#else
Dwarf_Obj_Access_Interface *binary_interface = 0;
int res = DW_DLV_OK;
int localerrnum = 0;
int libdwarf_owns_elf = FALSE;
if (!ret_dbg) {
DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL,DW_DLV_ERROR);
}
if (access != DW_DLC_READ) {
DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
}
res = dwarf_elf_object_access_init(
elf_file_pointer,
libdwarf_owns_elf,
&binary_interface,
&localerrnum);
if (res != DW_DLV_OK) {
if (res == DW_DLV_NO_ENTRY) {
return res;
}
DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR);
}
res = dwarf_object_init_b(binary_interface, errhand, errarg,
group_number,
ret_dbg, error);
if (res != DW_DLV_OK){
dwarf_elf_object_access_finish(binary_interface);
return res;
}
res = dwarf_add_debuglink_global_path(*ret_dbg,
"/usr/lib/debug",error);
if (res != DW_DLV_OK){
dwarf_elf_object_access_finish(binary_interface);
return res;
}
return res;
#endif
}
int
dwarf_elf_init(
#ifndef DWARF_WITH_LIBELF
UNUSEDARG dwarf_elf_handle elf_file_pointer,
UNUSEDARG Dwarf_Unsigned access,
UNUSEDARG Dwarf_Handler errhand,
UNUSEDARG Dwarf_Ptr errarg,
UNUSEDARG Dwarf_Debug * ret_dbg,
#else
dwarf_elf_handle elf_file_pointer,
Dwarf_Unsigned access,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
Dwarf_Debug * ret_dbg,
#endif
Dwarf_Error * error)
{
#ifndef DWARF_WITH_LIBELF
DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR);
#else
int res = 0;
res = dwarf_elf_init_b(elf_file_pointer,
DW_GROUPNUMBER_ANY,
access,errhand,errarg,ret_dbg,error);
return res;
#endif
}
int
_dwarf_elf_setup(
#ifndef DWARF_WITH_LIBELF
UNUSEDARG int fd,
UNUSEDARG char *path,
UNUSEDARG unsigned ftype,
UNUSEDARG unsigned endian,
UNUSEDARG unsigned offsetsize,
UNUSEDARG size_t filesize,
UNUSEDARG Dwarf_Unsigned access,
UNUSEDARG unsigned groupnumber,
UNUSEDARG Dwarf_Handler errhand,
UNUSEDARG Dwarf_Ptr errarg,
UNUSEDARG Dwarf_Debug *dbg,
#else
int fd,
UNUSEDARG char *path,
UNUSEDARG unsigned ftype,
UNUSEDARG unsigned endian,
UNUSEDARG unsigned offsetsize,
size_t filesize,
UNUSEDARG Dwarf_Unsigned access,
unsigned groupnumber,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
Dwarf_Debug *dbg,
#endif
Dwarf_Error *error)
{
#ifndef DWARF_WITH_LIBELF
DWARF_DBG_ERROR(NULL, DW_DLE_PRODUCER_CODE_NOT_AVAILABLE, DW_DLV_ERROR);
#else
Elf_Cmd what_kind_of_elf_read = ELF_C_READ;
Dwarf_Obj_Access_Interface *binary_interface = 0;
int res = DW_DLV_OK;
int localerrnum = 0;
int libdwarf_owns_elf = TRUE;
dwarf_elf_handle elf_file_pointer = 0;
elf_version(EV_CURRENT);
elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0);
if (elf_file_pointer == NULL) {
DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR);
}
res = dwarf_elf_object_access_init(
elf_file_pointer,
libdwarf_owns_elf,
&binary_interface,
&localerrnum);
if (res != DW_DLV_OK) {
if (res == DW_DLV_NO_ENTRY) {
return res;
}
DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR);
}
res = dwarf_object_init_b(binary_interface, errhand, errarg,
groupnumber,
dbg, error);
if (res != DW_DLV_OK){
dwarf_elf_object_access_finish(binary_interface);
return res;
}
(*dbg)->de_filesize = filesize;
res = dwarf_add_debuglink_global_path(*dbg,
"/usr/lib/debug",error);
if (res != DW_DLV_OK){
dwarf_elf_object_access_finish(binary_interface);
}
return res;
#endif
}