07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Copyright (C) 2000-2005 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 Portions Copyright 2009-2010 David Anderson. All rights reserved.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Portions Copyright 2009-2010 Novell 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#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 FALSE 0
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define TRUE 1
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifndef EM_MIPS
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/* This is the standard elf value EM_MIPS. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define EM_MIPS 8
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF64_GETEHDR
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweextern Elf64_Ehdr *elf64_getehdr(Elf *);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF64_GETSHDR
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweextern Elf64_Shdr *elf64_getshdr(Elf_Scn *);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef WORDS_BIGENDIAN
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe { \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dbg->de_copy_word(dest, \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ((char *)source) +srclength-len_out, \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe len_out) ; \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#else /* LITTLE ENDIAN */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe { \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dbg->de_copy_word( (dest) , \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ((char *)source) , \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe len_out) ; \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowetypedef struct {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_handle elf;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int is_64bit;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small length_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small pointer_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned section_count;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Endianness endianness;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small machine;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int libdwarf_owns_elf;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf32_Ehdr *ehdr32;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF64_GETEHDR
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf64_Ehdr *ehdr64;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Elf symtab and its strtab. Initialized at first
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe call to do relocations, the actual data is in the Dwarf_Debug
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct, not allocated locally here. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Section_s *symtab;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Section_s *strtab;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe} dwarf_elf_object_access_internals_t;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestruct Dwarf_Elf_Rela {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_ufixed64 r_offset;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /*Dwarf_ufixed64 r_info; */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_ufixed64 r_type;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_ufixed64 r_symidx;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_ufixed64 r_addend;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe};
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic int dwarf_elf_object_access_load_section(void* obj_in,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Half section_index,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small** section_data,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int* error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_init()
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic int
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_object_access_internals_init(void* obj_in,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_handle elf,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int* error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t*obj =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe (dwarf_elf_object_access_internals_t*)obj_in;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe char *ehdr_ident = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Half machine = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->elf = elf;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_ELF_GETIDENT_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(ehdr_ident[EI_DATA] == ELFDATA2LSB){
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->endianness = DW_OBJECT_LSB;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe else if(ehdr_ident[EI_DATA] == ELFDATA2MSB){
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->endianness = DW_OBJECT_MSB;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (obj->is_64bit) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF64_GETEHDR
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->ehdr64 = elf64_getehdr(elf);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (obj->ehdr64 == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_ELF_GETEHDR_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->section_count = obj->ehdr64->e_shnum;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe machine = obj->ehdr64->e_machine;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->machine = machine;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#else
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_NO_ELF64_SUPPORT;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe else {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->ehdr32 = elf32_getehdr(elf);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (obj->ehdr32 == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_ELF_GETEHDR_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->section_count = obj->ehdr32->e_shnum;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe machine = obj->ehdr32->e_machine;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->machine = machine;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* The following length_size is Not Too Significant. Only used
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe one calculation, and an approximate one at that. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->length_size = obj->is_64bit ? 8 : 4;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->pointer_size = obj->is_64bit ? 8 : 4;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (obj->is_64bit && machine != EM_MIPS) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* MIPS/IRIX makes pointer size and length size 8 for -64.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Other platforms make length 4 always. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe tools, and the dwarfv2.1 64bit extension setting.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This is not the same as the size-of-an-offset, which
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe is 4 in 32bit dwarf and 8 in 64bit dwarf. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->length_size = 4;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_OK;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_get_byte_order
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic
07dc1947c362e187fb955d283b692f8769dd5defRichard LoweDwarf_Endianness
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_object_access_get_byte_order(void* obj_in)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t*obj =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe (dwarf_elf_object_access_internals_t*)obj_in;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return obj->endianness;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_get_section_count()
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic
07dc1947c362e187fb955d283b692f8769dd5defRichard LoweDwarf_Unsigned
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_object_access_get_section_count(void * obj_in)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t*obj =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe (dwarf_elf_object_access_internals_t*)obj_in;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return obj->section_count;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_get_section()
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweint
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_object_access_get_section_info(
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe void* obj_in,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Half section_index,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Obj_Access_Section* ret_scn,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int* error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t*obj =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe (dwarf_elf_object_access_internals_t*)obj_in;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf32_Shdr *shdr32 = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF64_GETSHDR
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf64_Shdr *shdr64 = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf_Scn *scn = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe scn = elf_getscn(obj->elf, section_index);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (scn == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_MDE;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (obj->is_64bit) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF64_GETSHDR
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe shdr64 = elf64_getshdr(scn);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (shdr64 == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_ELF_GETSHDR_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_scn->size = shdr64->sh_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_scn->addr = shdr64->sh_addr;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_scn->link = shdr64->sh_link;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_scn->name = elf_strptr(obj->elf, obj->ehdr64->e_shstrndx,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe shdr64->sh_name);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(ret_scn->name == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_ELF_STRPTR_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_OK;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#else
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_MISSING_ELF64_SUPPORT;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif /* HAVE_ELF64_GETSHDR */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if ((shdr32 = elf32_getshdr(scn)) == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_ELF_GETSHDR_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_scn->size = shdr32->sh_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_scn->addr = shdr32->sh_addr;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_scn->link = shdr32->sh_link;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret_scn->name = elf_strptr(obj->elf, obj->ehdr32->e_shstrndx,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe shdr32->sh_name);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (ret_scn->name == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_ELF_STRPTR_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_OK;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_get_length_size
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic
07dc1947c362e187fb955d283b692f8769dd5defRichard LoweDwarf_Small
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_object_access_get_length_size(void* obj_in)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t*obj =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe (dwarf_elf_object_access_internals_t*)obj_in;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return obj->length_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_get_pointer_size
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic
07dc1947c362e187fb955d283b692f8769dd5defRichard LoweDwarf_Small
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_object_access_get_pointer_size(void* obj_in)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t*obj =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe (dwarf_elf_object_access_internals_t*)obj_in;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return obj->pointer_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define MATCH_REL_SEC(i_,s_,r_) \
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweif(i_ == s_.dss_index) { \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *r_ = &s_; \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_OK; \
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic int
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowefind_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Section_s **relocatablesec, int *error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* dbg-> de_debug_str,syms); */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* de_elf_symtab,syms); */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* de_elf_strtab,syms); */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_RELOC_SECTION_MISMATCH;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#undef MATCH_REL_SEC
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic void
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweget_rela_elf32(Dwarf_Small *data, unsigned int i,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int endianness,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int machine, struct Dwarf_Elf_Rela *relap)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf32_Rela *relp = (Elf32_Rela*)(data + (i * sizeof(Elf32_Rela)));
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_offset = relp->r_offset;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_info = relp->r_info;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_type = ELF32_R_TYPE(relp->r_info);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_symidx = ELF32_R_SYM(relp->r_info);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_addend = relp->r_addend;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic void
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweget_rela_elf64(Dwarf_Small *data, unsigned int i,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int endianness,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int machine,struct Dwarf_Elf_Rela *relap)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF64_RELA
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf64_Rela * relp = (Elf64_Rela*)(data + (i * sizeof(Elf64_Rela)));
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_offset = relp->r_offset;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_info = relp->r_info;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(machine == EM_MIPS && endianness == DW_OBJECT_LSB ) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* This is really wierd. Treat this very specially.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe The Elf64 LE MIPS object used for
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe testing (that has rela) wants the
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe values as sym ssym type3 type2 type, treating
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe each value as independent value. But libelf xlate
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe treats it as something else so we fudge here.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe It is unclear
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe how to precisely characterize where these relocations
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe were used.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe SGI MIPS on IRIX never used .rela relocations.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe The BE 64bit elf MIPS test object with rela uses traditional
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe elf relocation layouts, not this special case. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* We ignore the special TYPE2 and TYPE3, they should be
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe value R_MIPS_NONE in rela. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_type = ELF64MIPS_REL_TYPE(relp->r_info);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_symidx = ELF64MIPS_REL_SYM(relp->r_info);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#undef MIPS64SYM
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#undef MIPS64TYPE
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe } else
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_type = ELF64_R_TYPE(relp->r_info);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_symidx = ELF64_R_SYM(relp->r_info);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relap->r_addend = relp->r_addend;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic void
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweget_relocations_array(Dwarf_Bool is_64bit,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int endianness,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int machine,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *data,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned int num_relocations,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Elf_Rela *relap)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned int i = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe void (*get_relocations)(Dwarf_Small *data, unsigned int i,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int endianness,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int machine,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Elf_Rela *relap);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Handle 32/64 bit issue
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (is_64bit) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe get_relocations = get_rela_elf64;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe } else {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe get_relocations = get_rela_elf32;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe for (i=0; i < num_relocations; i++) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe get_relocations(data, i,endianness,machine, &(relap[i]));
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic int
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweget_relocation_entries(Dwarf_Bool is_64bit,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int endianness,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int machine,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *relocation_section,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned relocation_section_size,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Elf_Rela **relas,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned int *nrelas,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int *error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned int relocation_size = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (is_64bit) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF64_RELA
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relocation_size = sizeof(Elf64_Rela);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#else
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_MISSING_ELF64_SUPPORT;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe } else {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relocation_size = sizeof(Elf32_Rela);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (relocation_section == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_RELOC_SECTION_PTR_NULL;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return(DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if ((relocation_section_size != 0)) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe size_t bytescount = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(relocation_section_size%relocation_size) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_RELOC_SECTION_LENGTH_ODD;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *nrelas = relocation_section_size/relocation_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe bytescount = (*nrelas) * sizeof(struct Dwarf_Elf_Rela);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *relas = malloc(bytescount);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (!*relas) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_MAF;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return(DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe memset(*relas,0,bytescount);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe get_relocations_array(is_64bit,endianness,machine, relocation_section,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *nrelas, *relas);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return(DW_DLV_OK);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic Dwarf_Bool
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweis_32bit_abs_reloc(unsigned int type, Dwarf_Half machine)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Bool r = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe switch (machine) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_MIPS) && defined (R_MIPS_32)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_MIPS:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_MIPS_32);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA32)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_SPARC32PLUS:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_SPARC_UA32);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_SPARCV9) && defined (R_SPARC_UA32)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_SPARCV9:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_SPARC_UA32);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_SPARC) && defined (R_SPARC_UA32)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_SPARC:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_SPARC_UA32);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_386) && defined (R_386_32)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_386:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_386_32);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_IA_64:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_IA64_SECREL32LSB);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_PPC64) && defined (R_PPC64_ADDR32)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_PPC64:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_PPC64_ADDR32);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_PPC) && defined (R_PPC_ADDR32)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_PPC:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_PPC_ADDR32);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_S390) && defined (R_390_32)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_S390:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_390_32);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_X86_64) && defined (R_X86_64_32)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_X86_64:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_X86_64_32);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return r;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic Dwarf_Bool
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweis_64bit_abs_reloc(unsigned int type, Dwarf_Half machine)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Bool r = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe switch (machine) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_MIPS) && defined (R_MIPS_64)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_MIPS:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_MIPS_64);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_SPARC32PLUS:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_SPARC_UA64);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_SPARCV9) && defined (R_SPARC_UA64)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_SPARCV9:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_SPARC_UA64);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_SPARC) && defined (R_SPARC_UA64)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_SPARC:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_SPARC_UA64);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_IA_64:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_IA64_DIR64LSB);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_PPC64) && defined (R_PPC64_ADDR64)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_PPC64:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_PPC64_ADDR64);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_S390) && defined (R_390_64)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_S390:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_390_64);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#if defined(EM_X86_64) && defined (R_X86_64_64)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case EM_X86_64:
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe r = (type == R_X86_64_64);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return r;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic void
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweupdate_entry(Dwarf_Debug dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Bool is_64bit, Dwarf_Endianness endianess,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Half machine, struct Dwarf_Elf_Rela *rela,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *target_section, Dwarf_Small *section_data)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned int type = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned int sym_idx = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF64_SYM
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf64_Sym sym_buf;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf64_Sym *sym = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#else
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf32_Sym sym_buf;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf32_Sym *sym = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf32_Sym *sym32 = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_ufixed64 offset = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_sfixed64 addend = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned reloc_size = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Dwarf_Elf_Rela dereferencing */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe offset = rela->r_offset;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe addend = rela->r_addend;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe type = rela->r_type;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sym_idx = rela->r_symidx;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (is_64bit) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_ELF64_SYM
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sym = &((Elf64_Sym*)section_data)[sym_idx];
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe } else {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sym32 = &((Elf32_Sym*)section_data)[sym_idx];
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Convert Elf32_Sym struct to Elf64_Sym struct. We point at
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe * an Elf64_Sym local variable (sym_buf) to allow us to use the
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe * same pointer (sym) for both 32-bit and 64-bit instances.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sym = &sym_buf;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sym->st_name = sym32->st_name;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sym->st_info = sym32->st_info;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sym->st_other = sym32->st_other;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sym->st_shndx = sym32->st_shndx;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sym->st_value = sym32->st_value;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sym->st_size = sym32->st_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Determine relocation size */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (is_32bit_abs_reloc(type, machine)) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe reloc_size = 4;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe } else if (is_64bit_abs_reloc(type, machine)) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe reloc_size = 8;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe } else {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Assuming we do not need to do a READ_UNALIGNED here
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe at target_section + offset and add its value to
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe outval. Some ABIs say no read (for example MIPS),
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe but if some do then which ones? */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned outval = sym->st_value + addend;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe WRITE_UNALIGNED(dbg,target_section + offset,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe &outval,sizeof(outval),reloc_size);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic int
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweapply_rela_entries(Dwarf_Debug dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Bool is_64bit,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Endianness endianess,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Half machine,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *target_section,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *symtab_section,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Elf_Rela *relas, unsigned int nrelas,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int *error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if ((target_section != NULL) && (relas != NULL)) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned int i;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe for (i = 0; i < nrelas; i++) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe update_entry(dbg, is_64bit,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe endianess,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe machine,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe &(relas)[i],
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe target_section,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe symtab_section);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_OK;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic int
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweloop_through_relocations(
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Debug dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t* obj,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Section_s *relocatablesec,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int *error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *target_section = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *symtab_section = obj->symtab->dss_data;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *relocation_section = relocatablesec->dss_reloc_data;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Unsigned relocation_section_size =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relocatablesec->dss_reloc_size;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int ret = DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Elf_Rela *relas = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned int nrelas = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small *mspace = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret = get_relocation_entries(obj->is_64bit,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->endianness,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->machine,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relocation_section,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relocation_section_size,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe &relas, &nrelas, error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(ret != DW_DLV_OK) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free(relas);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return ret;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Some systems read Elf in read-only memory via mmap or the like.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe So the only safe thing is to copy the current data into
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe malloc space and refer to the malloc space instead of the
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe space returned by the elf library */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe mspace = malloc(relocatablesec->dss_size);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!mspace) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_RELOC_SECTION_MALLOC_FAIL;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe memcpy(mspace,relocatablesec->dss_data,relocatablesec->dss_size);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relocatablesec->dss_data = mspace;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe target_section = relocatablesec->dss_data;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relocatablesec->dss_data_was_malloc = 1;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ret = apply_rela_entries(
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->is_64bit,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->endianness, obj->machine,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe target_section,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe symtab_section,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relas, nrelas, error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free(relas);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return ret;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Find the section data in dbg and find all the relevant
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sections. Then do relocations.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic int
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_object_relocate_a_section(void* obj_in,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Half section_index,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Debug dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int* error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int res = DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t*obj = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Section_s * relocatablesec = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (section_index == 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_NO_ENTRY;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj = (dwarf_elf_object_access_internals_t*)obj_in;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* The section to relocate must already be loaded into memory. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe res = find_section_to_relocate(dbg, section_index,&relocatablesec,error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(res != DW_DLV_OK) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return res;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Sun and possibly others do not always set sh_link in .debug_* sections.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe So we cannot do full consistency checks. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(relocatablesec->dss_reloc_index == 0 ) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Something is wrong. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_RELOC_SECTION_MISSING_INDEX;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Now load the relocations themselves. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe res = dwarf_elf_object_access_load_section(obj_in,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe relocatablesec->dss_reloc_index,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe &relocatablesec->dss_reloc_data, error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(res != DW_DLV_OK) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return res;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Now get the symtab. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (!obj->symtab) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->symtab = &dbg->de_elf_symtab;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->strtab = &dbg->de_elf_strtab;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if( obj->symtab->dss_index != relocatablesec->dss_reloc_link) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Something is wrong. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if( obj->strtab->dss_index != obj->symtab->dss_link) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Something is wrong. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_RELOC_MISMATCH_STRTAB_INDEX;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!obj->symtab->dss_data) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Now load the symtab */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe res = dwarf_elf_object_access_load_section(obj_in,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->symtab->dss_index,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe &obj->symtab->dss_data, error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(res != DW_DLV_OK) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return res;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(! obj->strtab->dss_data) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Now load the strtab */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe res = dwarf_elf_object_access_load_section(obj_in,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj->strtab->dss_index,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe &obj->strtab->dss_data,error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(res != DW_DLV_OK){
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return res;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* We have all the data we need in memory. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe res = loop_through_relocations(dbg,obj,relocatablesec,error);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return res;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_load_section
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic int
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_object_access_load_section(void* obj_in,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Half section_index,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Small** section_data,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int* error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t*obj =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe (dwarf_elf_object_access_internals_t*)obj_in;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (section_index == 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_NO_ENTRY;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf_Scn *scn = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Elf_Data *data = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe scn = elf_getscn(obj->elf, section_index);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (scn == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_MDE;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe When using libelf as a producer, section data may be stored
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe in multiple buffers. In libdwarf however, we only use libelf
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe as a consumer (there is a dwarf producer API, but it doesn't
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe use libelf). Because of this, this single call to elf_getdata
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe will retrieve the entire section in a single contiguous
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe buffer. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe data = elf_getdata(scn, NULL);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (data == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *error = DW_DLE_MDE;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *section_data = data->d_buf;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_OK;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/* dwarf_elf_access method table. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic const struct Dwarf_Obj_Access_Methods_s dwarf_elf_object_access_methods =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_get_section_info,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_get_byte_order,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_get_length_size,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_get_pointer_size,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_get_section_count,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_load_section,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_relocate_a_section
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe};
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Interface for the ELF object file implementation.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweint
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_object_access_init(dwarf_elf_handle elf,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int libdwarf_owns_elf,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Obj_Access_Interface** ret_obj,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int *err)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe int res = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t *internals = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Obj_Access_Interface *intfc = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe internals = malloc(sizeof(dwarf_elf_object_access_internals_t));
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!internals) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Impossible case, we hope. Give up. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe memset(internals,0,sizeof(*internals));
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe res = dwarf_elf_object_access_internals_init(internals, elf, err);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(res != DW_DLV_OK){
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free(internals);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe internals->libdwarf_owns_elf = libdwarf_owns_elf;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe intfc = malloc(sizeof(Dwarf_Obj_Access_Interface));
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!intfc) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Impossible case, we hope. Give up. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free(internals);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Initialize the interface struct */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe intfc->object = internals;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe intfc->methods = &dwarf_elf_object_access_methods;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *ret_obj = intfc;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_OK;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Clean up the Dwarf_Obj_Access_Interface returned by elf_access_init.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowevoid
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!obj) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(obj->object) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t *internals =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe (dwarf_elf_object_access_internals_t *)obj->object;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(internals->libdwarf_owns_elf){
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe elf_end(internals->elf);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free(obj->object);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free(obj);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This function returns the Elf * pointer
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe associated with a Dwarf_Debug.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This function only makes sense if ELF is implied.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweint
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Dwarf_Error * error)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Obj_Access_Interface_s * obj = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (dbg == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe obj = dbg->de_obj_file;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(obj) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_elf_object_access_internals_t *internals =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe (dwarf_elf_object_access_internals_t*)obj->object;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(internals->elf == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_error(dbg, error, DW_DLE_FNO);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (DW_DLV_ERROR);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *elf = internals->elf;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_OK;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_error(dbg, error, DW_DLE_FNO);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_ERROR;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe