1 /*	$NetBSD: libdwarf_elf_access.c,v 1.2 2014/03/09 16:58:04 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 2009 Kai Wang
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include "_libdwarf.h"
30 
31 __RCSID("$NetBSD: libdwarf_elf_access.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
32 ELFTC_VCSID("Id: libdwarf_elf_access.c 2070 2011-10-27 03:05:32Z jkoshy ");
33 
34 int
_dwarf_elf_get_section_info(void * obj,Dwarf_Half ndx,Dwarf_Obj_Access_Section * ret_section,int * error)35 _dwarf_elf_get_section_info(void *obj, Dwarf_Half ndx,
36     Dwarf_Obj_Access_Section *ret_section, int *error)
37 {
38 	Dwarf_Elf_Object *e;
39 	GElf_Shdr *sh;
40 
41 	e = obj;
42 	assert(e != NULL);
43 
44 	if (ret_section == NULL) {
45 		if (error)
46 			*error = DW_DLE_ARGUMENT;
47 		return (DW_DLV_ERROR);
48 	}
49 
50 	if (ndx >= e->eo_seccnt) {
51 		if (error)
52 			*error = DW_DLE_NO_ENTRY;
53 		return (DW_DLV_NO_ENTRY);
54 	}
55 
56 	sh = &e->eo_shdr[ndx];
57 
58 	ret_section->addr = sh->sh_addr;
59 	ret_section->size = sh->sh_size;
60 
61 	ret_section->name = elf_strptr(e->eo_elf, e->eo_strndx, sh->sh_name);
62 	if (ret_section->name == NULL) {
63 		if (error)
64 			*error = DW_DLE_ELF;
65 		return (DW_DLV_ERROR);
66 	}
67 
68 	return (DW_DLV_OK);
69 }
70 
71 Dwarf_Endianness
_dwarf_elf_get_byte_order(void * obj)72 _dwarf_elf_get_byte_order(void *obj)
73 {
74 	Dwarf_Elf_Object *e;
75 
76 	e = obj;
77 	assert(e != NULL);
78 
79 	switch (e->eo_ehdr.e_ident[EI_DATA]) {
80 	case ELFDATA2MSB:
81 		return (DW_OBJECT_MSB);
82 
83 	case ELFDATA2LSB:
84 	case ELFDATANONE:
85 	default:
86 		return (DW_OBJECT_LSB);
87 	}
88 }
89 
90 Dwarf_Small
_dwarf_elf_get_length_size(void * obj)91 _dwarf_elf_get_length_size(void *obj)
92 {
93 	Dwarf_Elf_Object *e;
94 
95 	e = obj;
96 	assert(e != NULL);
97 
98 	if (gelf_getclass(e->eo_elf) == ELFCLASS32)
99 		return (4);
100 	else if (e->eo_ehdr.e_machine == EM_MIPS)
101 		return (8);
102 	else
103 		return (4);
104 }
105 
106 Dwarf_Small
_dwarf_elf_get_pointer_size(void * obj)107 _dwarf_elf_get_pointer_size(void *obj)
108 {
109 	Dwarf_Elf_Object *e;
110 
111 	e = obj;
112 	assert(e != NULL);
113 
114 	if (gelf_getclass(e->eo_elf) == ELFCLASS32)
115 		return (4);
116 	else
117 		return (8);
118 }
119 
120 Dwarf_Unsigned
_dwarf_elf_get_section_count(void * obj)121 _dwarf_elf_get_section_count(void *obj)
122 {
123 	Dwarf_Elf_Object *e;
124 
125 	e = obj;
126 	assert(e != NULL);
127 
128 	return (e->eo_seccnt);
129 }
130 
131 int
_dwarf_elf_load_section(void * obj,Dwarf_Half ndx,Dwarf_Small ** ret_data,int * error)132 _dwarf_elf_load_section(void *obj, Dwarf_Half ndx, Dwarf_Small** ret_data,
133     int *error)
134 {
135 	Dwarf_Elf_Object *e;
136 	Dwarf_Elf_Data *ed;
137 
138 	e = obj;
139 	assert(e != NULL);
140 
141 	if (ret_data == NULL) {
142 		if (error)
143 			*error = DW_DLE_ARGUMENT;
144 		return (DW_DLV_ERROR);
145 	}
146 
147 	if (ndx >= e->eo_seccnt) {
148 		if (error)
149 			*error = DW_DLE_NO_ENTRY;
150 		return (DW_DLV_NO_ENTRY);
151 	}
152 
153 	ed = &e->eo_data[ndx];
154 
155 	if (ed->ed_alloc != NULL)
156 		*ret_data = ed->ed_alloc;
157 	else {
158 		if (ed->ed_data == NULL) {
159 			if (error)
160 				*error = DW_DLE_NO_ENTRY;
161 			return (DW_DLV_NO_ENTRY);
162 		}
163 		*ret_data = ed->ed_data->d_buf;
164 	}
165 
166 	return (DW_DLV_OK);
167 }
168