1 /*-
2  * Copyright (c) 2006,2008-2010 Joseph Koshy
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #ifndef _PRIVATE_LIBELF_H_
28 #define	_PRIVATE_LIBELF_H_
29 
30 #include <sys/param.h>
31 #include <sys/endian.h>
32 #include <sys/queue.h>
33 #include <sys/mman.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <assert.h>
37 #include <errno.h>
38 #include <limits.h>
39 #include <stddef.h>
40 #include <stdint.h>
41 #include <unistd.h>
42 
43 /* _libelf_config.h */
44 #if defined(__DragonFly__)
45 #define	LIBELF_ARCH		EM_X86_64
46 #define	LIBELF_BYTEORDER	ELFDATA2LSB
47 #define	LIBELF_CLASS		ELFCLASS64
48 #endif	/* __DragonFly__ */
49 
50 /* _elftc.h */
51 #if defined(__DragonFly__)
52 #define	ELFTC_BYTE_ORDER			_BYTE_ORDER
53 #define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
54 #define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
55 #define	ELFTC_HAVE_MMAP				1
56 #define	STAILQ_FOREACH_SAFE			STAILQ_FOREACH_MUTABLE
57 #endif
58 
59 #if 1
60 #define	_libelf_allocate_data		__ei_libelf_allocate_data
61 #define	_libelf_allocate_elf		__ei_libelf_allocate_elf
62 #define	_libelf_allocate_scn		__ei_libelf_allocate_scn
63 #define	_libelf_cvt_ADDR64_tom		__ei_libelf_cvt_ADDR64_tom
64 #define	_libelf_cvt_BYTE_tox		__ei_libelf_cvt_BYTE_tox
65 #define	_libelf_cvt_CAP64_tom		__ei_libelf_cvt_CAP64_tom
66 #define	_libelf_cvt_DYN64_tom		__ei_libelf_cvt_DYN64_tom
67 #define	_libelf_cvt_EHDR64_tom		__ei_libelf_cvt_EHDR64_tom
68 #define	_libelf_cvt_GNUHASH64_tom	__ei_libelf_cvt_GNUHASH64_tom
69 #define	_libelf_cvt_HALF_tom		__ei_libelf_cvt_HALF_tom
70 #define	_libelf_cvt_LWORD_tom		__ei_libelf_cvt_LWORD_tom
71 #define	_libelf_cvt_MOVE64_tom		__ei_libelf_cvt_MOVE64_tom
72 #define	_libelf_cvt_NOTE_tom		__ei_libelf_cvt_NOTE_tom
73 #define	_libelf_cvt_OFF64_tom		__ei_libelf_cvt_OFF64_tom
74 #define	_libelf_cvt_PHDR64_tom		__ei_libelf_cvt_PHDR64_tom
75 #define	_libelf_cvt_REL64_tom		__ei_libelf_cvt_REL64_tom
76 #define	_libelf_cvt_RELA64_tom		__ei_libelf_cvt_RELA64_tom
77 #define	_libelf_cvt_SHDR64_tom		__ei_libelf_cvt_SHDR64_tom
78 #define	_libelf_cvt_SWORD_tom		__ei_libelf_cvt_SWORD_tom
79 #define	_libelf_cvt_SXWORD_tom		__ei_libelf_cvt_SXWORD_tom
80 #define	_libelf_cvt_SYM64_tom		__ei_libelf_cvt_SYM64_tom
81 #define	_libelf_cvt_SYMINFO64_tom	__ei_libelf_cvt_SYMINFO64_tom
82 #define	_libelf_cvt_VDEF64_tom		__ei_libelf_cvt_VDEF64_tom
83 #define	_libelf_cvt_VNEED64_tom		__ei_libelf_cvt_VNEED64_tom
84 #define	_libelf_cvt_WORD_tom		__ei_libelf_cvt_WORD_tom
85 #define	_libelf_cvt_XWORD_tom		__ei_libelf_cvt_XWORD_tom
86 #define	_libelf_ehdr			__ei_libelf_ehdr
87 #define	_libelf_fsize			__ei_libelf_fsize
88 #define	_libelf_get_translator		__ei_libelf_get_translator
89 #define	_libelf_getshdr			__ei_libelf_getshdr
90 #define	_libelf_init_elf		__ei_libelf_init_elf
91 #define	_libelf_load_extended		__ei_libelf_load_extended
92 #define	_libelf_load_section_headers	__ei_libelf_load_section_headers
93 #define	_libelf_memory			__ei_libelf_memory
94 #define	_libelf_msize			__ei_libelf_msize
95 #define	_libelf_open_object		__ei_libelf_open_object
96 #define	_libelf_read_special_file	__ei_libelf_read_special_file
97 #define	_libelf_release_data		__ei_libelf_release_data
98 #define	_libelf_release_elf		__ei_libelf_release_elf
99 #define	_libelf_release_scn		__ei_libelf_release_scn
100 #define	_libelf_xlate_shtype		__ei_libelf_xlate_shtype
101 #define	_libelf		__ei_libelf
102 
103 #define	elf64_fsize	__ei_elf64_fsize
104 #define	elf_getscn	__ei_elf_getscn
105 
106 #define	elf_begin	_ei_elf_begin
107 #define	elf_end		_ei_elf_end
108 #define	elf_errmsg	_ei_elf_errmsg
109 #define	elf_errno	_ei_elf_errno
110 #define	elf_getdata	_ei_elf_getdata
111 #define	elf_nextscn	_ei_elf_nextscn
112 #define	elf_strptr	_ei_elf_strptr
113 #define	elf_version	_ei_elf_version
114 #define	gelf_getshdr	_ei_gelf_getshdr
115 #define	gelf_getsym	_ei_gelf_getsym
116 #endif
117 
118 /* elfdefinitions.h */
119 /*
120  * Offsets in the `ei_ident[]` field of an ELF executable header.
121  */
122 #define	_ELF_DEFINE_EI_OFFSETS()			\
123 _ELF_DEFINE_EI(EI_MAG0,     0, "magic number")		\
124 _ELF_DEFINE_EI(EI_MAG1,     1, "magic number")		\
125 _ELF_DEFINE_EI(EI_MAG2,     2, "magic number")		\
126 _ELF_DEFINE_EI(EI_MAG3,     3, "magic number")		\
127 _ELF_DEFINE_EI(EI_CLASS,    4, "file class")		\
128 _ELF_DEFINE_EI(EI_DATA,     5, "data encoding")		\
129 _ELF_DEFINE_EI(EI_VERSION,  6, "file version")		\
130 _ELF_DEFINE_EI(EI_OSABI,    7, "OS ABI kind")		\
131 _ELF_DEFINE_EI(EI_ABIVERSION, 8, "OS ABI version")	\
132 _ELF_DEFINE_EI(EI_PAD,	    9, "padding start")		\
133 _ELF_DEFINE_EI(EI_NIDENT,  16, "total size")
134 
135 #undef	_ELF_DEFINE_EI
136 #define	_ELF_DEFINE_EI(N, V, DESCR)	N = V ,
137 enum {
138 	_ELF_DEFINE_EI_OFFSETS()
139 	EI__LAST__
140 };
141 
142 /*
143  * The ELF class of an object.
144  */
145 #define	_ELF_DEFINE_ELFCLASS()				\
146 _ELF_DEFINE_EC(ELFCLASSNONE, 0, "Unknown ELF class")	\
147 _ELF_DEFINE_EC(ELFCLASS32,   1, "32 bit objects")	\
148 _ELF_DEFINE_EC(ELFCLASS64,   2, "64 bit objects")
149 
150 #undef	_ELF_DEFINE_EC
151 #define	_ELF_DEFINE_EC(N, V, DESCR)	N = V ,
152 enum {
153 	_ELF_DEFINE_ELFCLASS()
154 	EC__LAST__
155 };
156 
157 /*
158  * Endianness of data in an ELF object.
159  */
160 
161 #define	_ELF_DEFINE_ELF_DATA_ENDIANNESS()			\
162 _ELF_DEFINE_ED(ELFDATANONE, 0, "Unknown data endianness")	\
163 _ELF_DEFINE_ED(ELFDATA2LSB, 1, "little endian")			\
164 _ELF_DEFINE_ED(ELFDATA2MSB, 2, "big endian")
165 
166 #undef	_ELF_DEFINE_ED
167 #define	_ELF_DEFINE_ED(N, V, DESCR)	N = V ,
168 enum {
169 	_ELF_DEFINE_ELF_DATA_ENDIANNESS()
170 	ED__LAST__
171 };
172 
173 /*
174  * Values of the magic numbers used in identification array.
175  */
176 #define	_ELF_DEFINE_ELF_MAGIC()			\
177 _ELF_DEFINE_EMAG(ELFMAG0, 0x7FU)		\
178 _ELF_DEFINE_EMAG(ELFMAG1, 'E')			\
179 _ELF_DEFINE_EMAG(ELFMAG2, 'L')			\
180 _ELF_DEFINE_EMAG(ELFMAG3, 'F')
181 
182 #undef	_ELF_DEFINE_EMAG
183 #define	_ELF_DEFINE_EMAG(N, V)		N = V ,
184 enum {
185 	_ELF_DEFINE_ELF_MAGIC()
186 	ELFMAG__LAST__
187 };
188 
189 /*
190  * ELF Machine types: (EM_*).
191  */
192 #define	_ELF_DEFINE_ELF_MACHINES()					\
193 _ELF_DEFINE_EM(EM_NONE,             0, "No machine")			\
194 _ELF_DEFINE_EM(EM_386,              3, "Intel 80386")			\
195 _ELF_DEFINE_EM(EM_X86_64,           62, "AMD x86-64 architecture")
196 
197 #undef	_ELF_DEFINE_EM
198 #define	_ELF_DEFINE_EM(N, V, DESCR)	N = V ,
199 enum {
200 	_ELF_DEFINE_ELF_MACHINES()
201 	EM__LAST__
202 };
203 
204 /* ELF file format version numbers. */
205 #define	EV_NONE		0
206 #define	EV_CURRENT	1
207 
208 /*
209  * Special section indices.
210  */
211 #define _ELF_DEFINE_SECTION_INDICES()					\
212 _ELF_DEFINE_SHN(SHN_UNDEF,	0,	 "undefined section")		\
213 _ELF_DEFINE_SHN(SHN_LORESERVE,	0xFF00U, "start of reserved area")	\
214 _ELF_DEFINE_SHN(SHN_LOPROC,	0xFF00U,				\
215 	"start of processor-specific range")				\
216 _ELF_DEFINE_SHN(SHN_BEFORE,	0xFF00U, "used for section ordering")	\
217 _ELF_DEFINE_SHN(SHN_AFTER,	0xFF01U, "used for section ordering")	\
218 _ELF_DEFINE_SHN(SHN_AMD64_LCOMMON, 0xFF02U, "large common block label") \
219 _ELF_DEFINE_SHN(SHN_MIPS_ACOMMON, 0xFF00U,				\
220 	"allocated common symbols in a DSO")				\
221 _ELF_DEFINE_SHN(SHN_MIPS_TEXT,	0xFF01U, "Reserved (obsolete)")		\
222 _ELF_DEFINE_SHN(SHN_MIPS_DATA,	0xFF02U, "Reserved (obsolete)")		\
223 _ELF_DEFINE_SHN(SHN_MIPS_SCOMMON, 0xFF03U,				\
224 	"gp-addressable common symbols")				\
225 _ELF_DEFINE_SHN(SHN_MIPS_SUNDEFINED, 0xFF04U,				\
226 	"gp-addressable undefined symbols")				\
227 _ELF_DEFINE_SHN(SHN_MIPS_LCOMMON, 0xFF05U, "local common symbols")	\
228 _ELF_DEFINE_SHN(SHN_MIPS_LUNDEFINED, 0xFF06U,				\
229 	"local undefined symbols")					\
230 _ELF_DEFINE_SHN(SHN_HIPROC,	0xFF1FU,				\
231 	"end of processor-specific range")				\
232 _ELF_DEFINE_SHN(SHN_LOOS,	0xFF20U,				\
233 	"start of OS-specific range")					\
234 _ELF_DEFINE_SHN(SHN_SUNW_IGNORE, 0xFF3FU, "used by dtrace")		\
235 _ELF_DEFINE_SHN(SHN_HIOS,	0xFF3FU,				\
236 	"end of OS-specific range")					\
237 _ELF_DEFINE_SHN(SHN_ABS,	0xFFF1U, "absolute references")		\
238 _ELF_DEFINE_SHN(SHN_COMMON,	0xFFF2U, "references to COMMON areas")	\
239 _ELF_DEFINE_SHN(SHN_XINDEX,	0xFFFFU, "extended index")		\
240 _ELF_DEFINE_SHN(SHN_HIRESERVE,	0xFFFFU, "end of reserved area")
241 
242 #undef	_ELF_DEFINE_SHN
243 #define	_ELF_DEFINE_SHN(N, V, DESCR)	N = V ,
244 enum {
245 	_ELF_DEFINE_SECTION_INDICES()
246 	SHN__LAST__
247 };
248 
249 /*
250  * Section types.
251  */
252 
253 #define	_ELF_DEFINE_SECTION_TYPES()					\
254 _ELF_DEFINE_SHT(SHT_NULL,            0, "inactive header")		\
255 _ELF_DEFINE_SHT(SHT_PROGBITS,        1, "program defined information")	\
256 _ELF_DEFINE_SHT(SHT_SYMTAB,          2, "symbol table")			\
257 _ELF_DEFINE_SHT(SHT_STRTAB,          3, "string table")			\
258 _ELF_DEFINE_SHT(SHT_RELA,            4,					\
259 	"relocation entries with addends")				\
260 _ELF_DEFINE_SHT(SHT_HASH,            5, "symbol hash table")		\
261 _ELF_DEFINE_SHT(SHT_DYNAMIC,         6,					\
262 	"information for dynamic linking")				\
263 _ELF_DEFINE_SHT(SHT_NOTE,            7, "additional notes")		\
264 _ELF_DEFINE_SHT(SHT_NOBITS,          8, "section occupying no space")	\
265 _ELF_DEFINE_SHT(SHT_REL,             9,					\
266 	"relocation entries without addends")				\
267 _ELF_DEFINE_SHT(SHT_SHLIB,           10, "reserved")			\
268 _ELF_DEFINE_SHT(SHT_DYNSYM,          11, "symbol table")		\
269 _ELF_DEFINE_SHT(SHT_INIT_ARRAY,      14,				\
270 	"pointers to initialization functions")				\
271 _ELF_DEFINE_SHT(SHT_FINI_ARRAY,      15,				\
272 	"pointers to termination functions")				\
273 _ELF_DEFINE_SHT(SHT_PREINIT_ARRAY,   16,				\
274 	"pointers to functions called before initialization")		\
275 _ELF_DEFINE_SHT(SHT_GROUP,           17, "defines a section group")	\
276 _ELF_DEFINE_SHT(SHT_SYMTAB_SHNDX,    18,				\
277 	"used for extended section numbering")				\
278 _ELF_DEFINE_SHT(SHT_LOOS,            0x60000000UL,			\
279 	"start of OS-specific range")					\
280 _ELF_DEFINE_SHT(SHT_SUNW_dof,	     0x6FFFFFF4UL,			\
281 	"used by dtrace")						\
282 _ELF_DEFINE_SHT(SHT_SUNW_cap,	     0x6FFFFFF5UL,			\
283 	"capability requirements")					\
284 _ELF_DEFINE_SHT(SHT_GNU_ATTRIBUTES,  0x6FFFFFF5UL,			\
285 	"object attributes")						\
286 _ELF_DEFINE_SHT(SHT_SUNW_SIGNATURE,  0x6FFFFFF6UL,			\
287 	"module verification signature")				\
288 _ELF_DEFINE_SHT(SHT_GNU_HASH,	     0x6FFFFFF6UL,			\
289 	"GNU Hash sections")						\
290 _ELF_DEFINE_SHT(SHT_GNU_LIBLIST,     0x6FFFFFF7UL,			\
291 	"List of libraries to be prelinked")				\
292 _ELF_DEFINE_SHT(SHT_SUNW_ANNOTATE,   0x6FFFFFF7UL,			\
293 	"special section where unresolved references are allowed")	\
294 _ELF_DEFINE_SHT(SHT_SUNW_DEBUGSTR,   0x6FFFFFF8UL,			\
295 	"debugging information")					\
296 _ELF_DEFINE_SHT(SHT_CHECKSUM,	     0x6FFFFFF8UL,			\
297 	"checksum for dynamic shared objects")				\
298 _ELF_DEFINE_SHT(SHT_SUNW_DEBUG,      0x6FFFFFF9UL,			\
299 	"debugging information")					\
300 _ELF_DEFINE_SHT(SHT_SUNW_move,       0x6FFFFFFAUL,			\
301 	"information to handle partially initialized symbols")		\
302 _ELF_DEFINE_SHT(SHT_SUNW_COMDAT,     0x6FFFFFFBUL,			\
303 	"section supporting merging of multiple copies of data")	\
304 _ELF_DEFINE_SHT(SHT_SUNW_syminfo,    0x6FFFFFFCUL,			\
305 	"additional symbol information")				\
306 _ELF_DEFINE_SHT(SHT_SUNW_verdef,     0x6FFFFFFDUL,			\
307 	"symbol versioning information")				\
308 _ELF_DEFINE_SHT(SHT_SUNW_verneed,    0x6FFFFFFEUL,			\
309 	"symbol versioning requirements")				\
310 _ELF_DEFINE_SHT(SHT_SUNW_versym,     0x6FFFFFFFUL,			\
311 	"symbol versioning table")					\
312 _ELF_DEFINE_SHT(SHT_HIOS,            0x6FFFFFFFUL,			\
313 	"end of OS-specific range")					\
314 _ELF_DEFINE_SHT(SHT_LOPROC,          0x70000000UL,			\
315 	"start of processor-specific range")				\
316 _ELF_DEFINE_SHT(SHT_ARM_EXIDX,       0x70000001UL,			\
317 	"exception index table")					\
318 _ELF_DEFINE_SHT(SHT_ARM_PREEMPTMAP,  0x70000002UL,			\
319 	"BPABI DLL dynamic linking preemption map")			\
320 _ELF_DEFINE_SHT(SHT_ARM_ATTRIBUTES,  0x70000003UL,			\
321 	"object file compatibility attributes")				\
322 _ELF_DEFINE_SHT(SHT_ARM_DEBUGOVERLAY, 0x70000004UL,			\
323 	"overlay debug information")					\
324 _ELF_DEFINE_SHT(SHT_ARM_OVERLAYSECTION, 0x70000005UL,			\
325 	"overlay debug information")					\
326 _ELF_DEFINE_SHT(SHT_MIPS_LIBLIST,    0x70000000UL,			\
327 	"DSO library information used in link")				\
328 _ELF_DEFINE_SHT(SHT_MIPS_MSYM,       0x70000001UL,			\
329 	"MIPS symbol table extension")					\
330 _ELF_DEFINE_SHT(SHT_MIPS_CONFLICT,   0x70000002UL,			\
331 	"symbol conflicting with DSO-defined symbols ")			\
332 _ELF_DEFINE_SHT(SHT_MIPS_GPTAB,      0x70000003UL,			\
333 	"global pointer table")						\
334 _ELF_DEFINE_SHT(SHT_MIPS_UCODE,      0x70000004UL,			\
335 	"reserved")							\
336 _ELF_DEFINE_SHT(SHT_MIPS_DEBUG,      0x70000005UL,			\
337 	"reserved (obsolete debug information)")			\
338 _ELF_DEFINE_SHT(SHT_MIPS_REGINFO,    0x70000006UL,			\
339 	"register usage information")					\
340 _ELF_DEFINE_SHT(SHT_MIPS_PACKAGE,    0x70000007UL,			\
341 	"OSF reserved")							\
342 _ELF_DEFINE_SHT(SHT_MIPS_PACKSYM,    0x70000008UL,			\
343 	"OSF reserved")							\
344 _ELF_DEFINE_SHT(SHT_MIPS_RELD,       0x70000009UL,			\
345 	"dynamic relocation")						\
346 _ELF_DEFINE_SHT(SHT_MIPS_IFACE,      0x7000000BUL,			\
347 	"subprogram interface information")				\
348 _ELF_DEFINE_SHT(SHT_MIPS_CONTENT,    0x7000000CUL,			\
349 	"section content classification")				\
350 _ELF_DEFINE_SHT(SHT_MIPS_OPTIONS,     0x7000000DUL,			\
351 	"general options")						\
352 _ELF_DEFINE_SHT(SHT_MIPS_DELTASYM,   0x7000001BUL,			\
353 	"Delta C++: symbol table")					\
354 _ELF_DEFINE_SHT(SHT_MIPS_DELTAINST,  0x7000001CUL,			\
355 	"Delta C++: instance table")					\
356 _ELF_DEFINE_SHT(SHT_MIPS_DELTACLASS, 0x7000001DUL,			\
357 	"Delta C++: class table")					\
358 _ELF_DEFINE_SHT(SHT_MIPS_DWARF,      0x7000001EUL,			\
359 	"DWARF debug information")					\
360 _ELF_DEFINE_SHT(SHT_MIPS_DELTADECL,  0x7000001FUL,			\
361 	"Delta C++: declarations")					\
362 _ELF_DEFINE_SHT(SHT_MIPS_SYMBOL_LIB, 0x70000020UL,			\
363 	"symbol-to-library mapping")					\
364 _ELF_DEFINE_SHT(SHT_MIPS_EVENTS,     0x70000021UL,			\
365 	"event locations")						\
366 _ELF_DEFINE_SHT(SHT_MIPS_TRANSLATE,  0x70000022UL,			\
367 	"???")								\
368 _ELF_DEFINE_SHT(SHT_MIPS_PIXIE,      0x70000023UL,			\
369 	"special pixie sections")					\
370 _ELF_DEFINE_SHT(SHT_MIPS_XLATE,      0x70000024UL,			\
371 	"address translation table")					\
372 _ELF_DEFINE_SHT(SHT_MIPS_XLATE_DEBUG, 0x70000025UL,			\
373 	"SGI internal address translation table")			\
374 _ELF_DEFINE_SHT(SHT_MIPS_WHIRL,      0x70000026UL,			\
375 	"intermediate code")						\
376 _ELF_DEFINE_SHT(SHT_MIPS_EH_REGION,  0x70000027UL,			\
377 	"C++ exception handling region info")				\
378 _ELF_DEFINE_SHT(SHT_MIPS_XLATE_OLD,  0x70000028UL,			\
379 	"obsolete")							\
380 _ELF_DEFINE_SHT(SHT_MIPS_PDR_EXCEPTION, 0x70000029UL,			\
381 	"runtime procedure descriptor table exception information")	\
382 _ELF_DEFINE_SHT(SHT_MIPS_ABIFLAGS,   0x7000002AUL,			\
383 	"ABI flags")							\
384 _ELF_DEFINE_SHT(SHT_SPARC_GOTDATA,   0x70000000UL,			\
385 	"SPARC-specific data")						\
386 _ELF_DEFINE_SHT(SHT_AMD64_UNWIND,    0x70000001UL,			\
387 	"unwind tables for the AMD64")					\
388 _ELF_DEFINE_SHT(SHT_ORDERED,         0x7FFFFFFFUL,			\
389 	"sort entries in the section")					\
390 _ELF_DEFINE_SHT(SHT_HIPROC,          0x7FFFFFFFUL,			\
391 	"end of processor-specific range")				\
392 _ELF_DEFINE_SHT(SHT_LOUSER,          0x80000000UL,			\
393 	"start of application-specific range")				\
394 _ELF_DEFINE_SHT(SHT_HIUSER,          0xFFFFFFFFUL,			\
395 	"end of application-specific range")
396 
397 #undef	_ELF_DEFINE_SHT
398 #define	_ELF_DEFINE_SHT(N, V, DESCR)	N = V ,
399 enum {
400 	_ELF_DEFINE_SECTION_TYPES()
401 	SHT__LAST__ = SHT_HIUSER
402 };
403 
404 #define	PN_XNUM			0xFFFFU /* Use extended section numbering. */
405 
406 /**
407  ** ELF Types.
408  **/
409 
410 typedef uint64_t	Elf64_Addr;	/* Program address. */
411 typedef uint16_t	Elf64_Half;	/* Unsigned medium integer. */
412 typedef uint64_t	Elf64_Off;	/* File offset. */
413 typedef int32_t		Elf64_Sword;	/* Signed integer. */
414 typedef uint32_t	Elf64_Word;	/* Unsigned integer. */
415 typedef uint64_t	Elf64_Lword;	/* Unsigned long integer. */
416 typedef uint64_t	Elf64_Xword;	/* Unsigned long integer. */
417 typedef int64_t		Elf64_Sxword;	/* Signed long integer. */
418 
419 /*
420  * Capability descriptors.
421  */
422 typedef struct {
423 	Elf64_Xword	c_tag;	     /* Type of entry. */
424 	union {
425 		Elf64_Xword	c_val; /* Integer value. */
426 		Elf64_Addr	c_ptr; /* Pointer value. */
427 	} c_un;
428 } Elf64_Cap;
429 
430 /*
431  * Dynamic section entries.
432  */
433 typedef struct {
434 	Elf64_Sxword	d_tag;	     /* Type of entry. */
435 	union {
436 		Elf64_Xword	d_val; /* Integer value. */
437 		Elf64_Addr	d_ptr; /* Pointer value; */
438 	} d_un;
439 } Elf64_Dyn;
440 
441 /*
442  * The executable header (EHDR).
443  */
444 typedef struct {
445 	unsigned char   e_ident[EI_NIDENT]; /* ELF identification. */
446 	Elf64_Half      e_type;	     /* Object file type (ET_*). */
447 	Elf64_Half      e_machine;   /* Machine type (EM_*). */
448 	Elf64_Word      e_version;   /* File format version (EV_*). */
449 	Elf64_Addr      e_entry;     /* Start address. */
450 	Elf64_Off       e_phoff;     /* File offset to the PHDR table. */
451 	Elf64_Off       e_shoff;     /* File offset to the SHDRheader. */
452 	Elf64_Word      e_flags;     /* Flags (EF_*). */
453 	Elf64_Half      e_ehsize;    /* Elf header size in bytes. */
454 	Elf64_Half      e_phentsize; /* PHDR table entry size in bytes. */
455 	Elf64_Half      e_phnum;     /* Number of PHDR entries. */
456 	Elf64_Half      e_shentsize; /* SHDR table entry size in bytes. */
457 	Elf64_Half      e_shnum;     /* Number of SHDR entries. */
458 	Elf64_Half      e_shstrndx;  /* Index of section name string table. */
459 } Elf64_Ehdr;
460 
461 /*
462  * Note descriptors.
463  */
464 
465 typedef	struct {
466 	uint32_t	n_namesz;    /* Length of note's name. */
467 	uint32_t	n_descsz;    /* Length of note's value. */
468 	uint32_t	n_type;	     /* Type of note. */
469 } Elf_Note;
470 
471 /*
472  * Program Header Table (PHDR) entries.
473  */
474 typedef struct {
475 	Elf64_Word	p_type;	     /* Type of segment. */
476 	Elf64_Word	p_flags;     /* Segment flags. */
477 	Elf64_Off	p_offset;    /* File offset to segment. */
478 	Elf64_Addr	p_vaddr;     /* Virtual address in memory. */
479 	Elf64_Addr	p_paddr;     /* Physical address (if relevant). */
480 	Elf64_Xword	p_filesz;    /* Size of segment in file. */
481 	Elf64_Xword	p_memsz;     /* Size of segment in memory. */
482 	Elf64_Xword	p_align;     /* Alignment constraints. */
483 } Elf64_Phdr;
484 
485 /*
486  * Move entries, for describing data in COMMON blocks in a compact
487  * manner.
488  */
489 typedef struct {
490 	Elf64_Lword	m_value;     /* Initialization value. */
491 	Elf64_Xword	m_info;	     /* Encoded size and index. */
492 	Elf64_Xword	m_poffset;   /* Offset relative to symbol. */
493 	Elf64_Half	m_repeat;    /* Repeat count. */
494 	Elf64_Half	m_stride;    /* Number of units to skip. */
495 } Elf64_Move;
496 
497 /*
498  * Section Header Table (SHDR) entries.
499  */
500 typedef struct {
501 	Elf64_Word	sh_name;     /* index of section name */
502 	Elf64_Word	sh_type;     /* section type */
503 	Elf64_Xword	sh_flags;    /* section flags */
504 	Elf64_Addr	sh_addr;     /* in-memory address of section */
505 	Elf64_Off	sh_offset;   /* file offset of section */
506 	Elf64_Xword	sh_size;     /* section size in bytes */
507 	Elf64_Word	sh_link;     /* section header table link */
508 	Elf64_Word	sh_info;     /* extra information */
509 	Elf64_Xword	sh_addralign; /* alignment constraint */
510 	Elf64_Xword	sh_entsize;  /* size for fixed-size entries */
511 } Elf64_Shdr;
512 
513 /*
514  * Symbol table entries.
515  */
516 typedef struct {
517 	Elf64_Word	st_name;     /* index of symbol's name */
518 	unsigned char	st_info;     /* type and binding attributes */
519 	unsigned char	st_other;    /* visibility */
520 	Elf64_Half	st_shndx;    /* index of related section */
521 	Elf64_Addr	st_value;    /* value for the symbol */
522 	Elf64_Xword	st_size;     /* size of associated data */
523 } Elf64_Sym;
524 
525 /*
526  * Syminfo descriptors, containing additional symbol information.
527  */
528 typedef struct {
529 	Elf64_Half	si_boundto;  /* Entry index with additional flags. */
530 	Elf64_Half	si_flags;    /* Flags. */
531 } Elf64_Syminfo;
532 
533 /*
534  * Relocation descriptors.
535  */
536 typedef struct {
537 	Elf64_Addr	r_offset;    /* location to apply relocation to */
538 	Elf64_Xword	r_info;      /* type+section for relocation */
539 } Elf64_Rel;
540 
541 typedef struct {
542 	Elf64_Addr	r_offset;    /* location to apply relocation to */
543 	Elf64_Xword	r_info;      /* type+section for relocation */
544 	Elf64_Sxword	r_addend;    /* constant addend */
545 } Elf64_Rela;
546 
547 /*
548  * Symbol versioning structures.
549  */
550 typedef struct {
551 	Elf64_Word	vda_name;    /* Index to name. */
552 	Elf64_Word	vda_next;    /* Offset to next entry. */
553 } Elf64_Verdaux;
554 
555 typedef struct {
556 	Elf64_Word	vna_hash;    /* Hash value of dependency name. */
557 	Elf64_Half	vna_flags;   /* Flags. */
558 	Elf64_Half	vna_other;   /* Unused. */
559 	Elf64_Word	vna_name;    /* Offset to dependency name. */
560 	Elf64_Word	vna_next;    /* Offset to next vernaux entry. */
561 } Elf64_Vernaux;
562 
563 typedef struct {
564 	Elf64_Half	vd_version;  /* Version information. */
565 	Elf64_Half	vd_flags;    /* Flags. */
566 	Elf64_Half	vd_ndx;	     /* Index into the versym section. */
567 	Elf64_Half	vd_cnt;	     /* Number of aux entries. */
568 	Elf64_Word	vd_hash;     /* Hash value of name. */
569 	Elf64_Word	vd_aux;	     /* Offset to aux entries. */
570 	Elf64_Word	vd_next;     /* Offset to next version definition. */
571 } Elf64_Verdef;
572 
573 typedef struct {
574 	Elf64_Half	vn_version;  /* Version number. */
575 	Elf64_Half	vn_cnt;	     /* Number of aux entries. */
576 	Elf64_Word	vn_file;     /* Offset of associated file name. */
577 	Elf64_Word	vn_aux;	     /* Offset of vernaux array. */
578 	Elf64_Word	vn_next;     /* Offset of next verneed entry. */
579 } Elf64_Verneed;
580 
581 /*
582  * The header for GNU-style hash sections.
583  */
584 
585 typedef struct {
586 	uint32_t	gh_nbuckets;	/* Number of hash buckets. */
587 	uint32_t	gh_symndx;	/* First visible symbol in .dynsym. */
588 	uint32_t	gh_maskwords;	/* #maskwords used in bloom filter. */
589 	uint32_t	gh_shift2;	/* Bloom filter shift count. */
590 } Elf_GNU_Hash_Header;
591 
592 /* libelf.h */
593 /* Library private data structures */
594 typedef struct _Elf Elf;
595 typedef struct _Elf_Scn Elf_Scn;
596 
597 /* File types */
598 typedef enum {
599 	ELF_K_NONE = 0,
600 	ELF_K_AR,	/* `ar' archives */
601 	ELF_K_COFF,	/* COFF files (unsupported) */
602 	ELF_K_ELF,	/* ELF files */
603 	ELF_K_NUM
604 } Elf_Kind;
605 
606 /* Data types */
607 typedef enum {
608 	ELF_T_ADDR,
609 	ELF_T_BYTE,
610 	ELF_T_CAP,
611 	ELF_T_DYN,
612 	ELF_T_EHDR,
613 	ELF_T_HALF,
614 	ELF_T_LWORD,
615 	ELF_T_MOVE,
616 	ELF_T_MOVEP,
617 	ELF_T_NOTE,
618 	ELF_T_OFF,
619 	ELF_T_PHDR,
620 	ELF_T_REL,
621 	ELF_T_RELA,
622 	ELF_T_SHDR,
623 	ELF_T_SWORD,
624 	ELF_T_SXWORD,
625 	ELF_T_SYMINFO,
626 	ELF_T_SYM,
627 	ELF_T_VDEF,
628 	ELF_T_VNEED,
629 	ELF_T_WORD,
630 	ELF_T_XWORD,
631 	ELF_T_GNUHASH,	/* GNU style hash tables. */
632 	ELF_T_NUM
633 } Elf_Type;
634 
635 #define	ELF_T_FIRST	ELF_T_ADDR
636 #define	ELF_T_LAST	ELF_T_GNUHASH
637 
638 /* Commands */
639 typedef enum {
640 	ELF_C_NULL = 0,
641 	ELF_C_CLR,
642 	ELF_C_FDDONE,
643 	ELF_C_FDREAD,
644 	ELF_C_RDWR,
645 	ELF_C_READ,
646 	ELF_C_SET,
647 	ELF_C_WRITE,
648 	ELF_C_NUM
649 } Elf_Cmd;
650 
651 /*
652  * An `Elf_Data' structure describes data in an
653  * ELF section.
654  */
655 typedef struct _Elf_Data {
656 	/*
657 	 * `Public' members that are part of the ELF(3) API.
658 	 */
659 	uint64_t	d_align;
660 	void		*d_buf;
661 	uint64_t	d_off;
662 	uint64_t	d_size;
663 	Elf_Type	d_type;
664 	unsigned int	d_version;
665 } Elf_Data;
666 
667 /*
668  * An `Elf_Arhdr' structure describes an archive
669  * header.
670  */
671 typedef struct {
672 	time_t		ar_date;
673 	char		*ar_name;	/* archive member name */
674 	gid_t		ar_gid;
675 	mode_t		ar_mode;
676 	char		*ar_rawname;	/* 'raw' member name */
677 	size_t		ar_size;
678 	uid_t		ar_uid;
679 
680 	/*
681 	 * Members that are not part of the public API.
682 	 */
683 	unsigned int	ar_flags;
684 } Elf_Arhdr;
685 
686 /*
687  * An `Elf_Arsym' describes an entry in the archive
688  * symbol table.
689  */
690 typedef struct {
691 	off_t		as_off;		/* byte offset to member's header */
692 	unsigned long	as_hash;	/* elf_hash() value for name */
693 	char		*as_name;	/* null terminated symbol name */
694 } Elf_Arsym;
695 
696 /*
697  * Error numbers.
698  */
699 
700 enum Elf_Error {
701 	ELF_E_NONE,	/* No error */
702 	ELF_E_ARCHIVE,	/* Malformed ar(1) archive */
703 	ELF_E_ARGUMENT,	/* Invalid argument */
704 	ELF_E_CLASS,	/* Mismatched ELF class */
705 	ELF_E_DATA,	/* Invalid data descriptor */
706 	ELF_E_HEADER,	/* Missing or malformed ELF header */
707 	ELF_E_IO,	/* I/O error */
708 	ELF_E_LAYOUT,	/* Layout constraint violation */
709 	ELF_E_MODE,	/* Wrong mode for ELF descriptor */
710 	ELF_E_RANGE,	/* Value out of range */
711 	ELF_E_RESOURCE,	/* Resource exhaustion */
712 	ELF_E_SECTION,	/* Invalid section descriptor */
713 	ELF_E_SEQUENCE,	/* API calls out of sequence */
714 	ELF_E_UNIMPL,	/* Feature is unimplemented */
715 	ELF_E_VERSION,	/* Unknown API version */
716 	ELF_E_NUM	/* Max error number */
717 };
718 
719 /*
720  * Flags defined by the API.
721  */
722 
723 #define	ELF_F_LAYOUT	0x001U	/* application will layout the file */
724 #define	ELF_F_DIRTY	0x002U	/* a section or ELF file is dirty */
725 
726 #ifdef __cplusplus
727 extern "C" {
728 #endif
729 static
730 Elf		*elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf);
731 static
732 int		elf_end(Elf *_elf);
733 static
734 const char	*elf_errmsg(int _error);
735 static
736 int		elf_errno(void);
737 static
738 Elf_Data	*elf_getdata(Elf_Scn *, Elf_Data *);
739 static
740 char		*elf_strptr(Elf *_elf, size_t _section, size_t _offset);
741 static
742 unsigned int	elf_version(unsigned int _version);
743 static
744 Elf_Scn		*elf_nextscn(Elf *_elf, Elf_Scn *_scn);
745 #ifdef __cplusplus
746 }
747 #endif
748 
749 /* gelf.h */
750 typedef Elf64_Shdr	GElf_Shdr;	/* Section header */
751 typedef Elf64_Sym	GElf_Sym;	/* Symbol table entries */
752 
753 #ifdef __cplusplus
754 extern "C" {
755 #endif
756 static
757 GElf_Shdr	*gelf_getshdr(Elf_Scn *_scn, GElf_Shdr *_dst);
758 static
759 GElf_Sym	*gelf_getsym(Elf_Data *_src, int _index, GElf_Sym *_dst);
760 #ifdef __cplusplus
761 }
762 #endif
763 
764 /* _libelf.h */
765 /*
766  * Library-private data structures.
767  */
768 
769 #define LIBELF_MSG_SIZE	256
770 
771 struct _libelf_globals {
772 	int		libelf_arch;
773 	unsigned int	libelf_byteorder;
774 	int		libelf_class;
775 	int		libelf_error;
776 	int		libelf_fillchar;
777 	unsigned int	libelf_version;
778 	unsigned char	libelf_msg[LIBELF_MSG_SIZE];
779 };
780 
781 #if 0
782 extern struct _libelf_globals _libelf;
783 #endif
784 
785 #define	LIBELF_PRIVATE(N)	(_libelf.libelf_##N)
786 
787 #define	LIBELF_ELF_ERROR_MASK			0xFF
788 #define	LIBELF_OS_ERROR_SHIFT			8
789 
790 #define	LIBELF_ERROR(E, O) (((E) & LIBELF_ELF_ERROR_MASK) |	\
791 	((O) << LIBELF_OS_ERROR_SHIFT))
792 
793 #define	LIBELF_SET_ERROR(E, O) do {					\
794 		LIBELF_PRIVATE(error) = LIBELF_ERROR(ELF_E_##E, (O));	\
795 	} while (0)
796 
797 /*
798  * Flags for library internal use.  These use the upper 16 bits of the
799  * `e_flags' field.
800  */
801 
802 #define	LIBELF_F_DATA_MALLOCED	0x040000U /* whether data was malloc'ed */
803 #define	LIBELF_F_RAWFILE_MALLOC	0x080000U /* whether e_rawfile was malloc'ed */
804 #define	LIBELF_F_RAWFILE_MMAP	0x100000U /* whether e_rawfile was mmap'ed */
805 #define	LIBELF_F_SHDRS_LOADED	0x200000U /* whether all shdrs were read in */
806 #define	LIBELF_F_SPECIAL_FILE	0x400000U /* non-regular file */
807 
808 struct _Elf {
809 	int		e_activations;	/* activation count */
810 	unsigned int	e_byteorder;	/* ELFDATA* */
811 	int		e_class;	/* ELFCLASS*  */
812 	Elf_Cmd		e_cmd;		/* ELF_C_* used at creation time */
813 	int		e_fd;		/* associated file descriptor */
814 	unsigned int	e_flags;	/* ELF_F_* & LIBELF_F_* flags */
815 	Elf_Kind	e_kind;		/* ELF_K_* */
816 	Elf		*e_parent;	/* non-NULL for archive members */
817 	unsigned char	*e_rawfile;	/* uninterpreted bytes */
818 	size_t		e_rawsize;	/* size of uninterpreted bytes */
819 	unsigned int	e_version;	/* file version */
820 
821 	/*
822 	 * Header information for archive members.  See the
823 	 * LIBELF_F_AR_HEADER flag.
824 	 */
825 	union {
826 		Elf_Arhdr	*e_arhdr;	/* translated header */
827 		unsigned char	*e_rawhdr;	/* untranslated header */
828 	} e_hdr;
829 
830 	union {
831 		struct {		/* ar(1) archives */
832 			off_t	e_next;	/* set by elf_rand()/elf_next() */
833 			int	e_nchildren;
834 			unsigned char *e_rawstrtab; /* file name strings */
835 			size_t	e_rawstrtabsz;
836 			unsigned char *e_rawsymtab;	/* symbol table */
837 			size_t	e_rawsymtabsz;
838 			Elf_Arsym *e_symtab;
839 			size_t	e_symtabsz;
840 		} e_ar;
841 		struct {		/* regular ELF files */
842 			union {
843 #if 0
844 				Elf32_Ehdr *e_ehdr32;
845 #endif
846 				Elf64_Ehdr *e_ehdr64;
847 			} e_ehdr;
848 			union {
849 #if 0
850 				Elf32_Phdr *e_phdr32;
851 #endif
852 				Elf64_Phdr *e_phdr64;
853 			} e_phdr;
854 			STAILQ_HEAD(, _Elf_Scn)	e_scn;	/* section list */
855 			size_t	e_nphdr;	/* number of Phdr entries */
856 			size_t	e_nscn;		/* number of sections */
857 			size_t	e_strndx;	/* string table section index */
858 		} e_elf;
859 	} e_u;
860 };
861 
862 /*
863  * The internal descriptor wrapping the "Elf_Data" type.
864  */
865 struct _Libelf_Data {
866 	Elf_Data	d_data;		/* The exported descriptor. */
867 	Elf_Scn		*d_scn;		/* The containing section */
868 	unsigned int	d_flags;
869 	STAILQ_ENTRY(_Libelf_Data) d_next;
870 };
871 
872 struct _Elf_Scn {
873 	union {
874 #if 0
875 		Elf32_Shdr	s_shdr32;
876 #endif
877 		Elf64_Shdr	s_shdr64;
878 	} s_shdr;
879 	STAILQ_HEAD(, _Libelf_Data) s_data;	/* translated data */
880 	STAILQ_HEAD(, _Libelf_Data) s_rawdata;	/* raw data */
881 	STAILQ_ENTRY(_Elf_Scn) s_next;
882 	struct _Elf	*s_elf;		/* parent ELF descriptor */
883 	unsigned int	s_flags;	/* flags for the section as a whole */
884 	size_t		s_ndx;		/* index# for this section */
885 	uint64_t	s_offset;	/* managed by elf_update() */
886 	uint64_t	s_rawoff;	/* original offset in the file */
887 	uint64_t	s_size;		/* managed by elf_update() */
888 };
889 
890 enum {
891 	ELF_TOFILE,
892 	ELF_TOMEMORY
893 };
894 
895 /* PRIVATE */
896 
897 /* elf.c */
898 static struct _libelf_globals _libelf = {
899 	.libelf_arch		= LIBELF_ARCH,
900 	.libelf_byteorder	= LIBELF_BYTEORDER,
901 	.libelf_class		= LIBELF_CLASS,
902 	.libelf_error		= 0,
903 	.libelf_fillchar	= 0,
904 	.libelf_version		= EV_NONE
905 };
906 
907 /* libelf_msize.c */
908 struct msize {
909 	size_t	msz64;
910 };
911 
912 static struct msize msize[ELF_T_NUM] = {
913 [ELF_T_ADDR] = { .msz64 = sizeof(Elf64_Addr) },
914 [ELF_T_BYTE] = { .msz64 = 1 },
915 [ELF_T_CAP] = { .msz64 = sizeof(Elf64_Cap) },
916 [ELF_T_DYN] = { .msz64 = sizeof(Elf64_Dyn) },
917 [ELF_T_EHDR] = { .msz64 = sizeof(Elf64_Ehdr) },
918 [ELF_T_GNUHASH] = { .msz64 = 1 },
919 [ELF_T_HALF] = { .msz64 = sizeof(Elf64_Half) },
920 [ELF_T_LWORD] = { .msz64 = sizeof(Elf64_Lword) },
921 [ELF_T_MOVE] = { .msz64 = sizeof(Elf64_Move) },
922 [ELF_T_MOVEP] = { .msz64 = 0 },
923 [ELF_T_NOTE] = { .msz64 = 1 },
924 [ELF_T_OFF] = { .msz64 = sizeof(Elf64_Off) },
925 [ELF_T_PHDR] = { .msz64 = sizeof(Elf64_Phdr) },
926 [ELF_T_REL] = { .msz64 = sizeof(Elf64_Rel) },
927 [ELF_T_RELA] = { .msz64 = sizeof(Elf64_Rela) },
928 [ELF_T_SHDR] = { .msz64 = sizeof(Elf64_Shdr) },
929 [ELF_T_SWORD] = { .msz64 = sizeof(Elf64_Sword) },
930 [ELF_T_SXWORD] = { .msz64 = sizeof(Elf64_Sxword) },
931 [ELF_T_SYMINFO] = { .msz64 = sizeof(Elf64_Syminfo) },
932 [ELF_T_SYM] = { .msz64 = sizeof(Elf64_Sym) },
933 [ELF_T_VDEF] = { .msz64 = 1 },
934 [ELF_T_VNEED] = { .msz64 = 1 },
935 [ELF_T_WORD] = { .msz64 = sizeof(Elf64_Word) },
936 [ELF_T_XWORD] = { .msz64 = sizeof(Elf64_Xword) },
937 };
938 
939 static size_t
940 _libelf_msize(Elf_Type t, int elfclass, unsigned int version)
941 {
942 	size_t sz;
943 
944 	assert(/*elfclass == ELFCLASS32 ||*/ elfclass == ELFCLASS64);
945 	assert((signed) t >= ELF_T_FIRST && t <= ELF_T_LAST);
946 
947 	if (version != EV_CURRENT) {
948 		LIBELF_SET_ERROR(VERSION, 0);
949 		return (0);
950 	}
951 
952 	sz = /* (elfclass == ELFCLASS32) ? msize[t].msz32 : */ msize[t].msz64;
953 
954 	return (sz);
955 }
956 
957 /* libelf_fsize.c */
958 struct tfsize {
959 	size_t fsz64;
960 };
961 
962 static struct tfsize tfsize[ELF_T_NUM] = {
963 [ELF_T_ADDR] =    { .fsz64 = sizeof(Elf64_Addr) },
964 [ELF_T_BYTE] =    { .fsz64 = 1 },
965 [ELF_T_CAP] =     { .fsz64 = sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 },
966 [ELF_T_DYN] =     { .fsz64 = sizeof(Elf64_Sxword)+sizeof(Elf64_Xword)+0 },
967 [ELF_T_EHDR] =    { .fsz64 = EI_NIDENT
968 			    +sizeof(Elf64_Half)+sizeof(Elf64_Half)
969 			    +sizeof(Elf64_Word)+sizeof(Elf64_Addr)
970 			    +sizeof(Elf64_Off)+ sizeof(Elf64_Off)
971 			    +sizeof(Elf64_Word)+sizeof(Elf64_Half)
972 			    +sizeof(Elf64_Half)+sizeof(Elf64_Half)
973 			    +sizeof(Elf64_Half)+sizeof(Elf64_Half)
974 			    +sizeof(Elf64_Half)+0 },
975 [ELF_T_GNUHASH] = { .fsz64 = 1 },
976 [ELF_T_HALF] =    { .fsz64 = sizeof(Elf64_Half) },
977 [ELF_T_LWORD] =   { .fsz64 = sizeof(Elf64_Lword) },
978 [ELF_T_MOVE] =    { .fsz64 = sizeof(Elf64_Lword)+sizeof(Elf64_Xword)
979 			    +sizeof(Elf64_Xword)+sizeof(Elf64_Half)
980 			    +sizeof(Elf64_Half)+0 },
981 [ELF_T_MOVEP] =   { .fsz64 = 0 },
982 [ELF_T_NOTE] =    { .fsz64 = 1 },
983 [ELF_T_OFF] =     { .fsz64 = sizeof(Elf64_Off) },
984 [ELF_T_PHDR] =    { .fsz64 = sizeof(Elf64_Word)+sizeof(Elf64_Word)
985 			    +sizeof(Elf64_Off)+ sizeof(Elf64_Addr)
986 			    +sizeof(Elf64_Addr)+sizeof(Elf64_Xword)
987 			    +sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 },
988 [ELF_T_REL] =     { .fsz64 = sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+0 },
989 [ELF_T_RELA] =    { .fsz64 = sizeof(Elf64_Addr)+sizeof(Elf64_Xword)
990 			    +sizeof(Elf64_Sxword)+0 },
991 [ELF_T_SHDR] =    { .fsz64 = sizeof(Elf64_Word)+sizeof(Elf64_Word)
992 			    +sizeof(Elf64_Xword)+sizeof(Elf64_Addr)
993 			    +sizeof(Elf64_Off)+ sizeof(Elf64_Xword)
994 			    +sizeof(Elf64_Word)+sizeof(Elf64_Word)
995 			    +sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 },
996 [ELF_T_SWORD] =   { .fsz64 = sizeof(Elf64_Sword) },
997 [ELF_T_SXWORD] =  { .fsz64 = sizeof(Elf64_Sxword) },
998 [ELF_T_SYMINFO] = { .fsz64 = sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 },
999 [ELF_T_SYM] =     { .fsz64 = sizeof(Elf64_Word)+1+1+sizeof(Elf64_Half)
1000 			    +sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+0 },
1001 [ELF_T_VDEF] =    { .fsz64 = 1 },
1002 [ELF_T_VNEED] =   { .fsz64 = 1 },
1003 [ELF_T_WORD] =    { .fsz64 = sizeof(Elf64_Word) },
1004 [ELF_T_XWORD] =   { .fsz64 = sizeof(Elf64_Xword) },
1005 };
1006 
1007 static size_t
1008 _libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c)
1009 {
1010 	size_t sz;
1011 
1012 	sz = 0;
1013 	if (v != EV_CURRENT)
1014 		LIBELF_SET_ERROR(VERSION, 0);
1015 	else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST)
1016 		LIBELF_SET_ERROR(ARGUMENT, 0);
1017 	else {
1018 		sz = ec == ELFCLASS64 ? tfsize[t].fsz64 : /* tfsize[t].fsz32 */ 0;
1019 		if (sz == 0)
1020 			LIBELF_SET_ERROR(UNIMPL, 0);
1021 	}
1022 
1023 	return (sz*c);
1024 }
1025 
1026 /* gelf_fsize.c */
1027 static size_t
1028 elf64_fsize(Elf_Type t, size_t c, unsigned int v)
1029 {
1030 	return (_libelf_fsize(t, ELFCLASS64, v, c));
1031 }
1032 
1033 /* libelf_allocate.h */
1034 static Elf *
1035 _libelf_allocate_elf(void)
1036 {
1037 	Elf *e;
1038 
1039 	if ((e = malloc(sizeof(*e))) == NULL) {
1040 		LIBELF_SET_ERROR(RESOURCE, errno);
1041 		return NULL;
1042 	}
1043 
1044 	e->e_activations = 1;
1045 	e->e_hdr.e_rawhdr = NULL;
1046 	e->e_byteorder   = ELFDATANONE;
1047 	e->e_class       = ELFCLASSNONE;
1048 	e->e_cmd         = ELF_C_NULL;
1049 	e->e_fd          = -1;
1050 	e->e_flags	 = 0;
1051 	e->e_kind        = ELF_K_NONE;
1052 	e->e_parent      = NULL;
1053 	e->e_rawfile     = NULL;
1054 	e->e_rawsize     = 0;
1055 	e->e_version     = LIBELF_PRIVATE(version);
1056 
1057 	(void) memset(&e->e_u, 0, sizeof(e->e_u));
1058 
1059 	return (e);
1060 }
1061 
1062 static void
1063 _libelf_init_elf(Elf *e, Elf_Kind kind)
1064 {
1065 	assert(e != NULL);
1066 	assert(e->e_kind == ELF_K_NONE);
1067 
1068 	e->e_kind = kind;
1069 
1070 	switch (kind) {
1071 	case ELF_K_ELF:
1072 		STAILQ_INIT(&e->e_u.e_elf.e_scn);
1073 		break;
1074 	default:
1075 		break;
1076 	}
1077 }
1078 
1079 #define	FREE(P)		do {				\
1080 		if (P)					\
1081 			free(P);			\
1082 	} while (0)
1083 
1084 static Elf *
1085 _libelf_release_elf(Elf *e)
1086 {
1087 #if 0
1088 	Elf_Arhdr *arh;
1089 #endif
1090 
1091 	switch (e->e_kind) {
1092 #if 0
1093 	case ELF_K_AR:
1094 		FREE(e->e_u.e_ar.e_symtab);
1095 		break;
1096 #endif
1097 
1098 	case ELF_K_ELF:
1099 		switch (e->e_class) {
1100 #if 0
1101 		case ELFCLASS32:
1102 			FREE(e->e_u.e_elf.e_ehdr.e_ehdr32);
1103 			FREE(e->e_u.e_elf.e_phdr.e_phdr32);
1104 			break;
1105 #endif
1106 		case ELFCLASS64:
1107 			FREE(e->e_u.e_elf.e_ehdr.e_ehdr64);
1108 			FREE(e->e_u.e_elf.e_phdr.e_phdr64);
1109 			break;
1110 		}
1111 
1112 		assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn));
1113 
1114 #if 0
1115 		if (e->e_flags & LIBELF_F_AR_HEADER) {
1116 			arh = e->e_hdr.e_arhdr;
1117 			FREE(arh->ar_name);
1118 			FREE(arh->ar_rawname);
1119 			free(arh);
1120 		}
1121 #endif
1122 
1123 		break;
1124 
1125 	default:
1126 		break;
1127 	}
1128 
1129 	free(e);
1130 
1131 	return (NULL);
1132 }
1133 
1134 #undef FREE
1135 
1136 static struct _Libelf_Data *
1137 _libelf_allocate_data(Elf_Scn *s)
1138 {
1139 	struct _Libelf_Data *d;
1140 
1141 	if ((d = calloc((size_t) 1, sizeof(*d))) == NULL) {
1142 		LIBELF_SET_ERROR(RESOURCE, 0);
1143 		return (NULL);
1144 	}
1145 
1146 	d->d_scn = s;
1147 
1148 	return (d);
1149 }
1150 
1151 static struct _Libelf_Data *
1152 _libelf_release_data(struct _Libelf_Data *d)
1153 {
1154 
1155 	if (d->d_flags & LIBELF_F_DATA_MALLOCED)
1156 		free(d->d_data.d_buf);
1157 
1158 	free(d);
1159 
1160 	return (NULL);
1161 }
1162 
1163 static Elf_Scn *
1164 _libelf_allocate_scn(Elf *e, size_t ndx)
1165 {
1166 	Elf_Scn *s;
1167 
1168 	if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) {
1169 		LIBELF_SET_ERROR(RESOURCE, errno);
1170 		return (NULL);
1171 	}
1172 
1173 	s->s_elf = e;
1174 	s->s_ndx = ndx;
1175 
1176 	STAILQ_INIT(&s->s_data);
1177 	STAILQ_INIT(&s->s_rawdata);
1178 
1179 	STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next);
1180 
1181 	return (s);
1182 }
1183 
1184 static Elf_Scn *
1185 _libelf_release_scn(Elf_Scn *s)
1186 {
1187 	Elf *e;
1188 	struct _Libelf_Data *d, *td;
1189 
1190 	assert(s != NULL);
1191 
1192 	STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) {
1193 		STAILQ_REMOVE(&s->s_data, d, _Libelf_Data, d_next);
1194 		d = _libelf_release_data(d);
1195 	}
1196 
1197 	STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) {
1198 		assert((d->d_flags & LIBELF_F_DATA_MALLOCED) == 0);
1199 		STAILQ_REMOVE(&s->s_rawdata, d, _Libelf_Data, d_next);
1200 		d = _libelf_release_data(d);
1201 	}
1202 
1203 	e = s->s_elf;
1204 
1205 	assert(e != NULL);
1206 
1207 	STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next);
1208 
1209 	free(s);
1210 
1211 	return (NULL);
1212 }
1213 
1214 /* libelf_data.c */
1215 static int
1216 _libelf_xlate_shtype(uint32_t sht)
1217 {
1218 	/*
1219 	 * Look for known section types.
1220 	 */
1221 	switch (sht) {
1222 	case SHT_DYNAMIC:
1223 		return (ELF_T_DYN);
1224 	case SHT_DYNSYM:
1225 		return (ELF_T_SYM);
1226 	case SHT_FINI_ARRAY:
1227 		return (ELF_T_ADDR);
1228 	case SHT_GNU_HASH:
1229 		return (ELF_T_GNUHASH);
1230 	case SHT_GNU_LIBLIST:
1231 		return (ELF_T_WORD);
1232 	case SHT_GROUP:
1233 		return (ELF_T_WORD);
1234 	case SHT_HASH:
1235 		return (ELF_T_WORD);
1236 	case SHT_INIT_ARRAY:
1237 		return (ELF_T_ADDR);
1238 	case SHT_NOBITS:
1239 		return (ELF_T_BYTE);
1240 	case SHT_NOTE:
1241 		return (ELF_T_NOTE);
1242 	case SHT_PREINIT_ARRAY:
1243 		return (ELF_T_ADDR);
1244 	case SHT_PROGBITS:
1245 		return (ELF_T_BYTE);
1246 	case SHT_REL:
1247 		return (ELF_T_REL);
1248 	case SHT_RELA:
1249 		return (ELF_T_RELA);
1250 	case SHT_STRTAB:
1251 		return (ELF_T_BYTE);
1252 	case SHT_SYMTAB:
1253 		return (ELF_T_SYM);
1254 	case SHT_SYMTAB_SHNDX:
1255 		return (ELF_T_WORD);
1256 	case SHT_SUNW_dof:
1257 		return (ELF_T_BYTE);
1258 	case SHT_SUNW_move:
1259 		return (ELF_T_MOVE);
1260 	case SHT_SUNW_syminfo:
1261 		return (ELF_T_SYMINFO);
1262 	case SHT_SUNW_verdef:	/* == SHT_GNU_verdef */
1263 		return (ELF_T_VDEF);
1264 	case SHT_SUNW_verneed:	/* == SHT_GNU_verneed */
1265 		return (ELF_T_VNEED);
1266 	case SHT_SUNW_versym:	/* == SHT_GNU_versym */
1267 		return (ELF_T_HALF);
1268 	default:
1269 		/*
1270 		 * Values in the range [SHT_LOOS..SHT_HIUSER] (i.e.,
1271 		 * OS, processor and user-defined section types) are
1272 		 * legal, but since we do not know anything more about
1273 		 * their semantics, we return a type of ELF_T_BYTE.
1274 		 */
1275 		if (sht >= SHT_LOOS && sht <= SHT_HIUSER)
1276 			return (ELF_T_BYTE);
1277 
1278 		/*
1279 		 * Other values are unsupported.
1280 		 */
1281 		return (-1);
1282 	}
1283 }
1284 
1285 /* libelf_convert.c */
1286 #define	SWAP_BYTE(X)	do { (void) (X); } while (0)
1287 #define	SWAP_IDENT(X)	do { (void) (X); } while (0)
1288 #define	SWAP_HALF(X)	do {						\
1289 		uint16_t _x = (uint16_t) (X);				\
1290 		uint32_t _t = _x & 0xFFU;				\
1291 		_t <<= 8U; _x >>= 8U; _t |= _x & 0xFFU;			\
1292 		(X) = (uint16_t) _t;					\
1293 	} while (0)
1294 #define	_SWAP_WORD(X, T) do {						\
1295 		uint32_t _x = (uint32_t) (X);				\
1296 		uint32_t _t = _x & 0xFF;				\
1297 		_t <<= 8; _x >>= 8; _t |= _x & 0xFF;			\
1298 		_t <<= 8; _x >>= 8; _t |= _x & 0xFF;			\
1299 		_t <<= 8; _x >>= 8; _t |= _x & 0xFF;			\
1300 		(X) = (T) _t;						\
1301 	} while (0)
1302 #define	SWAP_SWORD(X)	_SWAP_WORD(X, /* Elf32_Sword */ Elf64_Sword)
1303 #define	SWAP_WORD(X)	_SWAP_WORD(X, /* Elf32_Word */ Elf64_Word)
1304 #define	_SWAP_WORD64(X, T) do {						\
1305 		uint64_t _x = (uint64_t) (X);				\
1306 		uint64_t _t = _x & 0xFF;				\
1307 		_t <<= 8; _x >>= 8; _t |= _x & 0xFF;			\
1308 		_t <<= 8; _x >>= 8; _t |= _x & 0xFF;			\
1309 		_t <<= 8; _x >>= 8; _t |= _x & 0xFF;			\
1310 		_t <<= 8; _x >>= 8; _t |= _x & 0xFF;			\
1311 		_t <<= 8; _x >>= 8; _t |= _x & 0xFF;			\
1312 		_t <<= 8; _x >>= 8; _t |= _x & 0xFF;			\
1313 		_t <<= 8; _x >>= 8; _t |= _x & 0xFF;			\
1314 		(X) = (T) _t;						\
1315 	} while (0)
1316 #define	SWAP_ADDR64(X)	_SWAP_WORD64(X, Elf64_Addr)
1317 #define	SWAP_LWORD(X)	_SWAP_WORD64(X, Elf64_Lword)
1318 #define	SWAP_OFF64(X)	_SWAP_WORD64(X, Elf64_Off)
1319 #define	SWAP_SXWORD(X)	_SWAP_WORD64(X, Elf64_Sxword)
1320 #define	SWAP_XWORD(X)	_SWAP_WORD64(X, Elf64_Xword)
1321 
1322 #define	READ_BYTE(P,X)	do {						\
1323 		const unsigned char *const _p =				\
1324 			(const unsigned char *) (P);			\
1325 		(X)		= _p[0];				\
1326 		(P)		= (P) + 1;				\
1327 	} while (0)
1328 #define	READ_HALF(P,X)	do {						\
1329 		uint16_t _t;						\
1330 		unsigned char *const _q = (unsigned char *) &_t;	\
1331 		const unsigned char *const _p =				\
1332 			(const unsigned char *) (P);			\
1333 		_q[0]		= _p[0];				\
1334 		_q[1]		= _p[1];				\
1335 		(P)		= (P) + 2;				\
1336 		(X)		= _t;					\
1337 	} while (0)
1338 #define	_READ_WORD(P,X,T) do {						\
1339 		uint32_t _t;						\
1340 		unsigned char *const _q = (unsigned char *) &_t;	\
1341 		const unsigned char *const _p =				\
1342 			(const unsigned char *) (P);			\
1343 		_q[0]		= _p[0];				\
1344 		_q[1]		= _p[1];				\
1345 		_q[2]		= _p[2];				\
1346 		_q[3]		= _p[3];				\
1347 		(P)		= (P) + 4;				\
1348 		(X)		= (T) _t;				\
1349 	} while (0)
1350 #define	READ_SWORD(P,X)		_READ_WORD(P, X, /*Elf32_Sword*/ Elf64_Sword)
1351 #define	READ_WORD(P,X)		_READ_WORD(P, X, /*Elf32_Word*/ Elf64_Word)
1352 #define	_READ_WORD64(P,X,T)	do {					\
1353 		uint64_t _t;						\
1354 		unsigned char *const _q = (unsigned char *) &_t;	\
1355 		const unsigned char *const _p =				\
1356 			(const unsigned char *) (P);			\
1357 		_q[0]		= _p[0];				\
1358 		_q[1]		= _p[1];				\
1359 		_q[2]		= _p[2];				\
1360 		_q[3]		= _p[3];				\
1361 		_q[4]		= _p[4];				\
1362 		_q[5]		= _p[5];				\
1363 		_q[6]		= _p[6];				\
1364 		_q[7]		= _p[7];				\
1365 		(P)		= (P) + 8;				\
1366 		(X)		= (T) _t;				\
1367 	} while (0)
1368 #define	READ_ADDR64(P,X)	_READ_WORD64(P, X, Elf64_Addr)
1369 #define	READ_LWORD(P,X)		_READ_WORD64(P, X, Elf64_Lword)
1370 #define	READ_OFF64(P,X)		_READ_WORD64(P, X, Elf64_Off)
1371 #define	READ_SXWORD(P,X)	_READ_WORD64(P, X, Elf64_Sxword)
1372 #define	READ_XWORD(P,X)		_READ_WORD64(P, X, Elf64_Xword)
1373 #define	READ_IDENT(P,X)		do {					\
1374 		(void) memcpy((X), (P), sizeof((X)));			\
1375 		(P)		= (P) + EI_NIDENT;			\
1376 	} while (0)
1377 
1378 #define	ROUNDUP2(V,N)	(V) = ((((V) + (N) - 1)) & ~((N) - 1))
1379 
1380 static int
1381 _libelf_cvt_ADDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1382     size_t count, int byteswap)
1383 {
1384 	Elf64_Addr t, *d = (Elf64_Addr *) (uintptr_t) dst;
1385 	size_t c;
1386 
1387 	if (dsz < count * sizeof(Elf64_Addr))
1388 		return (0);
1389 
1390 	if (!byteswap) {
1391 		(void) memcpy(dst, src, count * sizeof(*d));
1392 		return (1);
1393 	}
1394 
1395 	for (c = 0; c < count; c++) {
1396 		READ_ADDR64(src,t);
1397 		SWAP_ADDR64(t);
1398 		*d++ = t;
1399 	}
1400 
1401 	return (1);
1402 }
1403 
1404 static int
1405 _libelf_cvt_CAP64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1406     size_t count, int byteswap)
1407 {
1408 	Elf64_Cap	t, *d;
1409 	unsigned char	*s,*s0;
1410 	size_t		fsz;
1411 
1412 	fsz = elf64_fsize(ELF_T_CAP, (size_t) 1, EV_CURRENT);
1413 	d   = ((Elf64_Cap *) (uintptr_t) dst) + (count - 1);
1414 	s0  = src + (count - 1) * fsz;
1415 
1416 	if (dsz < count * sizeof(Elf64_Cap))
1417 		return (0);
1418 
1419 	while (count--) {
1420 		s = s0;
1421 		/* Read an Elf64_Cap */
1422 		READ_XWORD(s,t.c_tag);
1423 		READ_XWORD(s,t.c_un.c_val);
1424 		/**/
1425 		if (byteswap) {
1426 			/* Swap an Elf64_Cap */
1427 			SWAP_XWORD(t.c_tag);
1428 			SWAP_XWORD(t.c_un.c_val);
1429 			/**/
1430 		}
1431 		*d-- = t; s0 -= fsz;
1432 	}
1433 
1434 	return (1);
1435 }
1436 
1437 static int
1438 _libelf_cvt_DYN64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1439     size_t count, int byteswap)
1440 {
1441 	Elf64_Dyn	t, *d;
1442 	unsigned char	*s,*s0;
1443 	size_t		fsz;
1444 
1445 	fsz = elf64_fsize(ELF_T_DYN, (size_t) 1, EV_CURRENT);
1446 	d   = ((Elf64_Dyn *) (uintptr_t) dst) + (count - 1);
1447 	s0  = src + (count - 1) * fsz;
1448 
1449 	if (dsz < count * sizeof(Elf64_Dyn))
1450 		return (0);
1451 
1452 	while (count--) {
1453 		s = s0;
1454 		/* Read an Elf64_Dyn */
1455 		READ_SXWORD(s,t.d_tag);
1456 		READ_XWORD(s,t.d_un.d_ptr);
1457 		/**/
1458 		if (byteswap) {
1459 			/* Swap an Elf64_Dyn */
1460 			SWAP_SXWORD(t.d_tag);
1461 			SWAP_XWORD(t.d_un.d_ptr);
1462 			/**/
1463 		}
1464 		*d-- = t; s0 -= fsz;
1465 	}
1466 
1467 	return (1);
1468 }
1469 
1470 static int
1471 _libelf_cvt_EHDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1472     size_t count, int byteswap)
1473 {
1474 	Elf64_Ehdr	t, *d;
1475 	unsigned char	*s,*s0;
1476 	size_t		fsz;
1477 
1478 	fsz = elf64_fsize(ELF_T_EHDR, (size_t) 1, EV_CURRENT);
1479 	d   = ((Elf64_Ehdr *) (uintptr_t) dst) + (count - 1);
1480 	s0  = src + (count - 1) * fsz;
1481 
1482 	if (dsz < count * sizeof(Elf64_Ehdr))
1483 		return (0);
1484 
1485 	while (count--) {
1486 		s = s0;
1487 		/* Read an Elf64_Ehdr */
1488 		READ_IDENT(s,t.e_ident);
1489 		READ_HALF(s,t.e_type);
1490 		READ_HALF(s,t.e_machine);
1491 		READ_WORD(s,t.e_version);
1492 		READ_ADDR64(s,t.e_entry);
1493 		READ_OFF64(s,t.e_phoff);
1494 		READ_OFF64(s,t.e_shoff);
1495 		READ_WORD(s,t.e_flags);
1496 		READ_HALF(s,t.e_ehsize);
1497 		READ_HALF(s,t.e_phentsize);
1498 		READ_HALF(s,t.e_phnum);
1499 		READ_HALF(s,t.e_shentsize);
1500 		READ_HALF(s,t.e_shnum);
1501 		READ_HALF(s,t.e_shstrndx);
1502 		/**/
1503 		if (byteswap) {
1504 			/* Swap an Elf64_Ehdr */
1505 			SWAP_IDENT(t.e_ident);
1506 			SWAP_HALF(t.e_type);
1507 			SWAP_HALF(t.e_machine);
1508 			SWAP_WORD(t.e_version);
1509 			SWAP_ADDR64(t.e_entry);
1510 			SWAP_OFF64(t.e_phoff);
1511 			SWAP_OFF64(t.e_shoff);
1512 			SWAP_WORD(t.e_flags);
1513 			SWAP_HALF(t.e_ehsize);
1514 			SWAP_HALF(t.e_phentsize);
1515 			SWAP_HALF(t.e_phnum);
1516 			SWAP_HALF(t.e_shentsize);
1517 			SWAP_HALF(t.e_shnum);
1518 			SWAP_HALF(t.e_shstrndx);
1519 			/**/
1520 		}
1521 		*d-- = t; s0 -= fsz;
1522 	}
1523 
1524 	return (1);
1525 }
1526 
1527 static int
1528 _libelf_cvt_HALF_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1529     size_t count, int byteswap)
1530 {
1531 	Elf64_Half t, *d = (Elf64_Half *) (uintptr_t) dst;
1532 	size_t c;
1533 
1534 	if (dsz < count * sizeof(Elf64_Half))
1535 		return (0);
1536 
1537 	if (!byteswap) {
1538 		(void) memcpy(dst, src, count * sizeof(*d));
1539 		return (1);
1540 	}
1541 
1542 	for (c = 0; c < count; c++) {
1543 		READ_HALF(src,t);
1544 		SWAP_HALF(t);
1545 		*d++ = t;
1546 	}
1547 
1548 	return (1);
1549 }
1550 
1551 static int
1552 _libelf_cvt_LWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1553     size_t count, int byteswap)
1554 {
1555 	Elf64_Lword t, *d = (Elf64_Lword *) (uintptr_t) dst;
1556 	size_t c;
1557 
1558 	if (dsz < count * sizeof(Elf64_Lword))
1559 		return (0);
1560 
1561 	if (!byteswap) {
1562 		(void) memcpy(dst, src, count * sizeof(*d));
1563 		return (1);
1564 	}
1565 
1566 	for (c = 0; c < count; c++) {
1567 		READ_LWORD(src,t);
1568 		SWAP_LWORD(t);
1569 		*d++ = t;
1570 	}
1571 
1572 	return (1);
1573 }
1574 
1575 static int
1576 _libelf_cvt_MOVE64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1577     size_t count, int byteswap)
1578 {
1579 	Elf64_Move	t, *d;
1580 	unsigned char	*s,*s0;
1581 	size_t		fsz;
1582 
1583 	fsz = elf64_fsize(ELF_T_MOVE, (size_t) 1, EV_CURRENT);
1584 	d   = ((Elf64_Move *) (uintptr_t) dst) + (count - 1);
1585 	s0  = src + (count - 1) * fsz;
1586 
1587 	if (dsz < count * sizeof(Elf64_Move))
1588 		return (0);
1589 
1590 	while (count--) {
1591 		s = s0;
1592 		/* Read an Elf64_Move */
1593 		READ_LWORD(s,t.m_value);
1594 		READ_XWORD(s,t.m_info);
1595 		READ_XWORD(s,t.m_poffset);
1596 		READ_HALF(s,t.m_repeat);
1597 		READ_HALF(s,t.m_stride);
1598 		/**/
1599 		if (byteswap) {
1600 			/* Swap an Elf64_Move */
1601 			SWAP_LWORD(t.m_value);
1602 			SWAP_XWORD(t.m_info);
1603 			SWAP_XWORD(t.m_poffset);
1604 			SWAP_HALF(t.m_repeat);
1605 			SWAP_HALF(t.m_stride);
1606 			/**/
1607 		}
1608 		*d-- = t; s0 -= fsz;
1609 	}
1610 
1611 	return (1);
1612 }
1613 
1614 static int
1615 _libelf_cvt_OFF64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1616     size_t count, int byteswap)
1617 {
1618 	Elf64_Off t, *d = (Elf64_Off *) (uintptr_t) dst;
1619 	size_t c;
1620 
1621 	if (dsz < count * sizeof(Elf64_Off))
1622 		return (0);
1623 
1624 	if (!byteswap) {
1625 		(void) memcpy(dst, src, count * sizeof(*d));
1626 		return (1);
1627 	}
1628 
1629 	for (c = 0; c < count; c++) {
1630 		READ_OFF64(src,t);
1631 		SWAP_OFF64(t);
1632 		*d++ = t;
1633 	}
1634 
1635 	return (1);
1636 }
1637 
1638 static int
1639 _libelf_cvt_PHDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1640     size_t count, int byteswap)
1641 {
1642 	Elf64_Phdr	t, *d;
1643 	unsigned char	*s,*s0;
1644 	size_t		fsz;
1645 
1646 	fsz = elf64_fsize(ELF_T_PHDR, (size_t) 1, EV_CURRENT);
1647 	d   = ((Elf64_Phdr *) (uintptr_t) dst) + (count - 1);
1648 	s0  = src + (count - 1) * fsz;
1649 
1650 	if (dsz < count * sizeof(Elf64_Phdr))
1651 		return (0);
1652 
1653 	while (count--) {
1654 		s = s0;
1655 		/* Read an Elf64_Phdr */
1656 		READ_WORD(s,t.p_type);
1657 		READ_WORD(s,t.p_flags);
1658 		READ_OFF64(s,t.p_offset);
1659 		READ_ADDR64(s,t.p_vaddr);
1660 		READ_ADDR64(s,t.p_paddr);
1661 		READ_XWORD(s,t.p_filesz);
1662 		READ_XWORD(s,t.p_memsz);
1663 		READ_XWORD(s,t.p_align);
1664 		/**/
1665 		if (byteswap) {
1666 			/* Swap an Elf64_Phdr */
1667 			SWAP_WORD(t.p_type);
1668 			SWAP_WORD(t.p_flags);
1669 			SWAP_OFF64(t.p_offset);
1670 			SWAP_ADDR64(t.p_vaddr);
1671 			SWAP_ADDR64(t.p_paddr);
1672 			SWAP_XWORD(t.p_filesz);
1673 			SWAP_XWORD(t.p_memsz);
1674 			SWAP_XWORD(t.p_align);
1675 			/**/
1676 		}
1677 		*d-- = t; s0 -= fsz;
1678 	}
1679 
1680 	return (1);
1681 }
1682 
1683 static int
1684 _libelf_cvt_REL64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1685     size_t count, int byteswap)
1686 {
1687 	Elf64_Rel	t, *d;
1688 	unsigned char	*s,*s0;
1689 	size_t		fsz;
1690 
1691 	fsz = elf64_fsize(ELF_T_REL, (size_t) 1, EV_CURRENT);
1692 	d   = ((Elf64_Rel *) (uintptr_t) dst) + (count - 1);
1693 	s0  = src + (count - 1) * fsz;
1694 
1695 	if (dsz < count * sizeof(Elf64_Rel))
1696 		return (0);
1697 
1698 	while (count--) {
1699 		s = s0;
1700 		/* Read an Elf64_Rel */
1701 		READ_ADDR64(s,t.r_offset);
1702 		READ_XWORD(s,t.r_info);
1703 		/**/
1704 		if (byteswap) {
1705 			/* Swap an Elf64_Rel */
1706 			SWAP_ADDR64(t.r_offset);
1707 			SWAP_XWORD(t.r_info);
1708 			/**/
1709 		}
1710 		*d-- = t; s0 -= fsz;
1711 	}
1712 
1713 	return (1);
1714 }
1715 
1716 static int
1717 _libelf_cvt_RELA64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1718     size_t count, int byteswap)
1719 {
1720 	Elf64_Rela	t, *d;
1721 	unsigned char	*s,*s0;
1722 	size_t		fsz;
1723 
1724 	fsz = elf64_fsize(ELF_T_RELA, (size_t) 1, EV_CURRENT);
1725 	d   = ((Elf64_Rela *) (uintptr_t) dst) + (count - 1);
1726 	s0  = src + (count - 1) * fsz;
1727 
1728 	if (dsz < count * sizeof(Elf64_Rela))
1729 		return (0);
1730 
1731 	while (count--) {
1732 		s = s0;
1733 		/* Read an Elf64_Rela */
1734 		READ_ADDR64(s,t.r_offset);
1735 		READ_XWORD(s,t.r_info);
1736 		READ_SXWORD(s,t.r_addend);
1737 		/**/
1738 		if (byteswap) {
1739 			/* Swap an Elf64_Rela */
1740 			SWAP_ADDR64(t.r_offset);
1741 			SWAP_XWORD(t.r_info);
1742 			SWAP_SXWORD(t.r_addend);
1743 			/**/
1744 		}
1745 		*d-- = t; s0 -= fsz;
1746 	}
1747 
1748 	return (1);
1749 }
1750 
1751 static int
1752 _libelf_cvt_SHDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1753     size_t count, int byteswap)
1754 {
1755 	Elf64_Shdr	t, *d;
1756 	unsigned char	*s,*s0;
1757 	size_t		fsz;
1758 
1759 	fsz = elf64_fsize(ELF_T_SHDR, (size_t) 1, EV_CURRENT);
1760 	d   = ((Elf64_Shdr *) (uintptr_t) dst) + (count - 1);
1761 	s0  = src + (count - 1) * fsz;
1762 
1763 	if (dsz < count * sizeof(Elf64_Shdr))
1764 		return (0);
1765 
1766 	while (count--) {
1767 		s = s0;
1768 		/* Read an Elf64_Shdr */
1769 		READ_WORD(s,t.sh_name);
1770 		READ_WORD(s,t.sh_type);
1771 		READ_XWORD(s,t.sh_flags);
1772 		READ_ADDR64(s,t.sh_addr);
1773 		READ_OFF64(s,t.sh_offset);
1774 		READ_XWORD(s,t.sh_size);
1775 		READ_WORD(s,t.sh_link);
1776 		READ_WORD(s,t.sh_info);
1777 		READ_XWORD(s,t.sh_addralign);
1778 		READ_XWORD(s,t.sh_entsize);
1779 		/**/
1780 		if (byteswap) {
1781 			/* Swap an Elf64_Shdr */
1782 			SWAP_WORD(t.sh_name);
1783 			SWAP_WORD(t.sh_type);
1784 			SWAP_XWORD(t.sh_flags);
1785 			SWAP_ADDR64(t.sh_addr);
1786 			SWAP_OFF64(t.sh_offset);
1787 			SWAP_XWORD(t.sh_size);
1788 			SWAP_WORD(t.sh_link);
1789 			SWAP_WORD(t.sh_info);
1790 			SWAP_XWORD(t.sh_addralign);
1791 			SWAP_XWORD(t.sh_entsize);
1792 			/**/
1793 		}
1794 		*d-- = t; s0 -= fsz;
1795 	}
1796 
1797 	return (1);
1798 }
1799 
1800 static int
1801 _libelf_cvt_SWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1802     size_t count, int byteswap)
1803 {
1804 	Elf64_Sword t, *d = (Elf64_Sword *) (uintptr_t) dst;
1805 	size_t c;
1806 
1807 	if (dsz < count * sizeof(Elf64_Sword))
1808 		return (0);
1809 
1810 	if (!byteswap) {
1811 		(void) memcpy(dst, src, count * sizeof(*d));
1812 		return (1);
1813 	}
1814 
1815 	for (c = 0; c < count; c++) {
1816 		READ_SWORD(src,t);
1817 		SWAP_SWORD(t);
1818 		*d++ = t;
1819 	}
1820 
1821 	return (1);
1822 }
1823 
1824 static int
1825 _libelf_cvt_SXWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1826     size_t count, int byteswap)
1827 {
1828 	Elf64_Sxword t, *d = (Elf64_Sxword *) (uintptr_t) dst;
1829 	size_t c;
1830 
1831 	if (dsz < count * sizeof(Elf64_Sxword))
1832 		return (0);
1833 
1834 	if (!byteswap) {
1835 		(void) memcpy(dst, src, count * sizeof(*d));
1836 		return (1);
1837 	}
1838 
1839 	for (c = 0; c < count; c++) {
1840 		READ_SXWORD(src,t);
1841 		SWAP_SXWORD(t);
1842 		*d++ = t;
1843 	}
1844 
1845 	return (1);
1846 }
1847 
1848 static int
1849 _libelf_cvt_SYMINFO64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1850     size_t count, int byteswap)
1851 {
1852 	Elf64_Syminfo	t, *d;
1853 	unsigned char	*s,*s0;
1854 	size_t		fsz;
1855 
1856 	fsz = elf64_fsize(ELF_T_SYMINFO, (size_t) 1, EV_CURRENT);
1857 	d   = ((Elf64_Syminfo *) (uintptr_t) dst) + (count - 1);
1858 	s0  = src + (count - 1) * fsz;
1859 
1860 	if (dsz < count * sizeof(Elf64_Syminfo))
1861 		return (0);
1862 
1863 	while (count--) {
1864 		s = s0;
1865 		/* Read an Elf64_Syminfo */
1866 		READ_HALF(s,t.si_boundto);
1867 		READ_HALF(s,t.si_flags);
1868 		/**/
1869 		if (byteswap) {
1870 			/* Swap an Elf64_Syminfo */
1871 			SWAP_HALF(t.si_boundto);
1872 			SWAP_HALF(t.si_flags);
1873 			/**/
1874 		}
1875 		*d-- = t; s0 -= fsz;
1876 	}
1877 
1878 	return (1);
1879 }
1880 
1881 static int
1882 _libelf_cvt_SYM64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1883     size_t count, int byteswap)
1884 {
1885 	Elf64_Sym	t, *d;
1886 	unsigned char	*s,*s0;
1887 	size_t		fsz;
1888 
1889 	fsz = elf64_fsize(ELF_T_SYM, (size_t) 1, EV_CURRENT);
1890 	d   = ((Elf64_Sym *) (uintptr_t) dst) + (count - 1);
1891 	s0  = src + (count - 1) * fsz;
1892 
1893 	if (dsz < count * sizeof(Elf64_Sym))
1894 		return (0);
1895 
1896 	while (count--) {
1897 		s = s0;
1898 		/* Read an Elf64_Sym */
1899 		READ_WORD(s,t.st_name);
1900 		READ_BYTE(s,t.st_info);
1901 		READ_BYTE(s,t.st_other);
1902 		READ_HALF(s,t.st_shndx);
1903 		READ_ADDR64(s,t.st_value);
1904 		READ_XWORD(s,t.st_size);
1905 		/**/
1906 		if (byteswap) {
1907 			/* Swap an Elf64_Sym */
1908 			SWAP_WORD(t.st_name);
1909 			SWAP_BYTE(t.st_info);
1910 			SWAP_BYTE(t.st_other);
1911 			SWAP_HALF(t.st_shndx);
1912 			SWAP_ADDR64(t.st_value);
1913 			SWAP_XWORD(t.st_size);
1914 			/**/
1915 		}
1916 		*d-- = t; s0 -= fsz;
1917 	}
1918 
1919 	return (1);
1920 }
1921 
1922 static int
1923 _libelf_cvt_WORD_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1924     size_t count, int byteswap)
1925 {
1926 	Elf64_Word t, *d = (Elf64_Word *) (uintptr_t) dst;
1927 	size_t c;
1928 
1929 	if (dsz < count * sizeof(Elf64_Word))
1930 		return (0);
1931 
1932 	if (!byteswap) {
1933 		(void) memcpy(dst, src, count * sizeof(*d));
1934 		return (1);
1935 	}
1936 
1937 	for (c = 0; c < count; c++) {
1938 		READ_WORD(src,t);
1939 		SWAP_WORD(t);
1940 		*d++ = t;
1941 	}
1942 
1943 	return (1);
1944 }
1945 
1946 static int
1947 _libelf_cvt_XWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1948     size_t count, int byteswap)
1949 {
1950 	Elf64_Xword t, *d = (Elf64_Xword *) (uintptr_t) dst;
1951 	size_t c;
1952 
1953 	if (dsz < count * sizeof(Elf64_Xword))
1954 		return (0);
1955 
1956 	if (!byteswap) {
1957 		(void) memcpy(dst, src, count * sizeof(*d));
1958 		return (1);
1959 	}
1960 
1961 	for (c = 0; c < count; c++) {
1962 		READ_XWORD(src,t);
1963 		SWAP_XWORD(t);
1964 		*d++ = t;
1965 	}
1966 
1967 	return (1);
1968 }
1969 
1970 static int
1971 _libelf_cvt_VDEF64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
1972     size_t count, int byteswap)
1973 {
1974 	Elf64_Verdef	t, *dp;
1975 	Elf64_Verdaux	a, *ap;
1976 	const size_t	verfsz = 20;
1977 	const size_t	auxfsz = 8;
1978 	const size_t	vermsz = sizeof(Elf64_Verdef);
1979 	const size_t	auxmsz = sizeof(Elf64_Verdaux);
1980 	unsigned char * const dstend = dst + dsz;
1981 	unsigned char * const srcend = src + count;
1982 	unsigned char	*dstaux, *s, *srcaux, *stmp;
1983 	Elf64_Word	aux, anext, cnt, vnext;
1984 
1985 	for (stmp = src, vnext = ~0U;
1986 	     vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend;
1987 	     stmp += vnext, dst += vnext) {
1988 
1989 		/* Read in a VDEF structure. */
1990 		s = stmp;
1991 		/* Read an Elf64_Verdef */
1992 		READ_HALF(s,t.vd_version);
1993 		READ_HALF(s,t.vd_flags);
1994 		READ_HALF(s,t.vd_ndx);
1995 		READ_HALF(s,t.vd_cnt);
1996 		READ_WORD(s,t.vd_hash);
1997 		READ_WORD(s,t.vd_aux);
1998 		READ_WORD(s,t.vd_next);
1999 		/**/
2000 		if (byteswap) {
2001 			/* Swap an Elf64_Verdef */
2002 			SWAP_HALF(t.vd_version);
2003 			SWAP_HALF(t.vd_flags);
2004 			SWAP_HALF(t.vd_ndx);
2005 			SWAP_HALF(t.vd_cnt);
2006 			SWAP_WORD(t.vd_hash);
2007 			SWAP_WORD(t.vd_aux);
2008 			SWAP_WORD(t.vd_next);
2009 			/**/
2010 		}
2011 
2012 		dp = (Elf64_Verdef *) (uintptr_t) dst;
2013 		*dp = t;
2014 
2015 		aux = t.vd_aux;
2016 		cnt = t.vd_cnt;
2017 		vnext = t.vd_next;
2018 
2019 		if (aux < vermsz)
2020 			return (0);
2021 
2022 		/* Process AUX entries. */
2023 		for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux;
2024 		     cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend &&
2025 			srcaux + auxfsz <= srcend;
2026 		     dstaux += anext, srcaux += anext, cnt--) {
2027 
2028 			s = srcaux;
2029 			/* Read an Elf64_Verdaux */
2030 		READ_WORD(s,a.vda_name);
2031 		READ_WORD(s,a.vda_next);
2032 		/**/
2033 
2034 			if (byteswap) {
2035 				/* Swap an Elf64_Verdaux */
2036 			SWAP_WORD(a.vda_name);
2037 			SWAP_WORD(a.vda_next);
2038 			/**/
2039 			}
2040 
2041 			anext = a.vda_next;
2042 
2043 			ap = ((Elf64_Verdaux *) (uintptr_t) dstaux);
2044 			*ap = a;
2045 		}
2046 
2047 		if (anext || cnt)
2048 			return (0);
2049 	}
2050 
2051 	if (vnext)
2052 		return (0);
2053 
2054 	return (1);
2055 }
2056 
2057 static int
2058 _libelf_cvt_VNEED64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
2059     size_t count, int byteswap)
2060 {
2061 	Elf64_Verneed	t, *dp;
2062 	Elf64_Vernaux	a, *ap;
2063 	const size_t	verfsz = 16;
2064 	const size_t	auxfsz = 16;
2065 	const size_t	vermsz = sizeof(Elf64_Verneed);
2066 	const size_t	auxmsz = sizeof(Elf64_Vernaux);
2067 	unsigned char * const dstend = dst + dsz;
2068 	unsigned char * const srcend = src + count;
2069 	unsigned char	*dstaux, *s, *srcaux, *stmp;
2070 	Elf64_Word	aux, anext, cnt, vnext;
2071 
2072 	for (stmp = src, vnext = ~0U;
2073 	     vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend;
2074 	     stmp += vnext, dst += vnext) {
2075 
2076 		/* Read in a VNEED structure. */
2077 		s = stmp;
2078 		/* Read an Elf64_Verneed */
2079 		READ_HALF(s,t.vn_version);
2080 		READ_HALF(s,t.vn_cnt);
2081 		READ_WORD(s,t.vn_file);
2082 		READ_WORD(s,t.vn_aux);
2083 		READ_WORD(s,t.vn_next);
2084 		/**/
2085 		if (byteswap) {
2086 			/* Swap an Elf64_Verneed */
2087 			SWAP_HALF(t.vn_version);
2088 			SWAP_HALF(t.vn_cnt);
2089 			SWAP_WORD(t.vn_file);
2090 			SWAP_WORD(t.vn_aux);
2091 			SWAP_WORD(t.vn_next);
2092 			/**/
2093 		}
2094 
2095 		dp = (Elf64_Verneed *) (uintptr_t) dst;
2096 		*dp = t;
2097 
2098 		aux = t.vn_aux;
2099 		cnt = t.vn_cnt;
2100 		vnext = t.vn_next;
2101 
2102 		if (aux < vermsz)
2103 			return (0);
2104 
2105 		/* Process AUX entries. */
2106 		for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux;
2107 		     cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend &&
2108 			srcaux + auxfsz <= srcend;
2109 		     dstaux += anext, srcaux += anext, cnt--) {
2110 
2111 			s = srcaux;
2112 			/* Read an Elf64_Vernaux */
2113 		READ_WORD(s,a.vna_hash);
2114 		READ_HALF(s,a.vna_flags);
2115 		READ_HALF(s,a.vna_other);
2116 		READ_WORD(s,a.vna_name);
2117 		READ_WORD(s,a.vna_next);
2118 		/**/
2119 
2120 			if (byteswap) {
2121 				/* Swap an Elf64_Vernaux */
2122 			SWAP_WORD(a.vna_hash);
2123 			SWAP_HALF(a.vna_flags);
2124 			SWAP_HALF(a.vna_other);
2125 			SWAP_WORD(a.vna_name);
2126 			SWAP_WORD(a.vna_next);
2127 			/**/
2128 			}
2129 
2130 			anext = a.vna_next;
2131 
2132 			ap = ((Elf64_Vernaux *) (uintptr_t) dstaux);
2133 			*ap = a;
2134 		}
2135 
2136 		if (anext || cnt)
2137 			return (0);
2138 	}
2139 
2140 	if (vnext)
2141 		return (0);
2142 
2143 	return (1);
2144 }
2145 
2146 static int
2147 _libelf_cvt_BYTE_tox(unsigned char *dst, size_t dsz, unsigned char *src,
2148     size_t count, int byteswap)
2149 {
2150 	(void) byteswap;
2151 	if (dsz < count)
2152 		return (0);
2153 	if (dst != src)
2154 		(void) memcpy(dst, src, count);
2155 	return (1);
2156 }
2157 
2158 static int
2159 _libelf_cvt_GNUHASH64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
2160     size_t srcsz, int byteswap)
2161 {
2162 	size_t sz;
2163 	uint64_t t64, *bloom64;
2164 	Elf_GNU_Hash_Header *gh;
2165 	uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32;
2166 	uint32_t *buckets, *chains;
2167 
2168 	sz = 4 * sizeof(uint32_t);	/* File header is 4 words long. */
2169 	if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz)
2170 		return (0);
2171 
2172 	/* Read in the section header and byteswap if needed. */
2173 	READ_WORD(src, nbuckets);
2174 	READ_WORD(src, symndx);
2175 	READ_WORD(src, maskwords);
2176 	READ_WORD(src, shift2);
2177 
2178 	srcsz -= sz;
2179 
2180 	if (byteswap) {
2181 		SWAP_WORD(nbuckets);
2182 		SWAP_WORD(symndx);
2183 		SWAP_WORD(maskwords);
2184 		SWAP_WORD(shift2);
2185 	}
2186 
2187 	/* Check source buffer and destination buffer sizes. */
2188 	sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t);
2189 	if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header))
2190 		return (0);
2191 
2192 	gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst;
2193 	gh->gh_nbuckets  = nbuckets;
2194 	gh->gh_symndx    = symndx;
2195 	gh->gh_maskwords = maskwords;
2196 	gh->gh_shift2    = shift2;
2197 
2198 	dsz -= sizeof(Elf_GNU_Hash_Header);
2199 	dst += sizeof(Elf_GNU_Hash_Header);
2200 
2201 	bloom64 = (uint64_t *) (uintptr_t) dst;
2202 
2203 	/* Copy bloom filter data. */
2204 	for (n = 0; n < maskwords; n++) {
2205 		READ_XWORD(src, t64);
2206 		if (byteswap)
2207 			SWAP_XWORD(t64);
2208 		bloom64[n] = t64;
2209 	}
2210 
2211 	/* The hash buckets follows the bloom filter. */
2212 	dst += maskwords * sizeof(uint64_t);
2213 	buckets = (uint32_t *) (uintptr_t) dst;
2214 
2215 	for (n = 0; n < nbuckets; n++) {
2216 		READ_WORD(src, t32);
2217 		if (byteswap)
2218 			SWAP_WORD(t32);
2219 		buckets[n] = t32;
2220 	}
2221 
2222 	dst += nbuckets * sizeof(uint32_t);
2223 
2224 	/* The hash chain follows the hash buckets. */
2225 	dsz -= sz;
2226 	srcsz -= sz;
2227 
2228 	if (dsz < srcsz)	/* Destination lacks space. */
2229 		return (0);
2230 
2231 	nchains = srcsz / sizeof(uint32_t);
2232 	chains = (uint32_t *) (uintptr_t) dst;
2233 
2234 	for (n = 0; n < nchains; n++) {
2235 		READ_WORD(src, t32);
2236 		if (byteswap)
2237 			SWAP_WORD(t32);
2238 		*chains++ = t32;
2239 	}
2240 
2241 	return (1);
2242 }
2243 
2244 static int
2245 _libelf_cvt_NOTE_tom(unsigned char *dst, size_t dsz, unsigned char *src,
2246     size_t count, int byteswap)
2247 {
2248 	uint32_t namesz, descsz, type;
2249 	Elf_Note *en;
2250 	size_t sz, hdrsz;
2251 
2252 	if (dsz < count)	/* Destination buffer is too small. */
2253 		return (0);
2254 
2255 	hdrsz = 3 * sizeof(uint32_t);
2256 	if (count < hdrsz)		/* Source too small. */
2257 		return (0);
2258 
2259 	if (!byteswap) {
2260 		(void) memcpy(dst, src, count);
2261 		return (1);
2262 	}
2263 
2264 	/* Process all notes in the section. */
2265 	while (count > hdrsz) {
2266 		/* Read the note header. */
2267 		READ_WORD(src, namesz);
2268 		READ_WORD(src, descsz);
2269 		READ_WORD(src, type);
2270 
2271 		/* Translate. */
2272 		SWAP_WORD(namesz);
2273 		SWAP_WORD(descsz);
2274 		SWAP_WORD(type);
2275 
2276 		/* Copy out the translated note header. */
2277 		en = (Elf_Note *) (uintptr_t) dst;
2278 		en->n_namesz = namesz;
2279 		en->n_descsz = descsz;
2280 		en->n_type = type;
2281 
2282 		dsz -= sizeof(Elf_Note);
2283 		dst += sizeof(Elf_Note);
2284 		count -= hdrsz;
2285 
2286 		ROUNDUP2(namesz, 4U);
2287 		ROUNDUP2(descsz, 4U);
2288 
2289 		sz = namesz + descsz;
2290 
2291 		if (count < sz || dsz < sz)	/* Buffers are too small. */
2292 			return (0);
2293 
2294 		(void) memcpy(dst, src, sz);
2295 
2296 		src += sz;
2297 		dst += sz;
2298 
2299 		count -= sz;
2300 		dsz -= sz;
2301 	}
2302 
2303 	return (1);
2304 }
2305 
2306 struct converters {
2307 	int	(*tof32)(unsigned char *dst, size_t dsz, unsigned char *src,
2308 		    size_t cnt, int byteswap);
2309 	int	(*tom32)(unsigned char *dst, size_t dsz, unsigned char *src,
2310 		    size_t cnt, int byteswap);
2311 	int	(*tof64)(unsigned char *dst, size_t dsz, unsigned char *src,
2312 		    size_t cnt, int byteswap);
2313 	int	(*tom64)(unsigned char *dst, size_t dsz, unsigned char *src,
2314 		    size_t cnt, int byteswap);
2315 };
2316 
2317 static struct converters cvt[ELF_T_NUM] = {
2318 	/*[*/
2319 	[ELF_T_ADDR] =    { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2320 		.tom64 = _libelf_cvt_ADDR64_tom },
2321 	[ELF_T_CAP] =     { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2322 		.tom64 = _libelf_cvt_CAP64_tom },
2323 	[ELF_T_DYN] =     { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2324 		.tom64 = _libelf_cvt_DYN64_tom },
2325 	[ELF_T_EHDR] =    { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2326 		.tom64 = _libelf_cvt_EHDR64_tom },
2327 	[ELF_T_GNUHASH] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2328 		.tom64 = _libelf_cvt_GNUHASH64_tom },
2329 	[ELF_T_HALF] =    { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2330 		.tom64 = _libelf_cvt_HALF_tom },
2331 	[ELF_T_LWORD] =   { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2332 		.tom64 = _libelf_cvt_LWORD_tom },
2333 	[ELF_T_MOVE] =    { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2334 		.tom64 = _libelf_cvt_MOVE64_tom },
2335 	[ELF_T_OFF] =     { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2336 		.tom64 = _libelf_cvt_OFF64_tom },
2337 	[ELF_T_PHDR] =    { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2338 		.tom64 = _libelf_cvt_PHDR64_tom },
2339 	[ELF_T_REL] =     { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2340 		.tom64 = _libelf_cvt_REL64_tom },
2341 	[ELF_T_RELA] =    { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2342 		.tom64 = _libelf_cvt_RELA64_tom },
2343 	[ELF_T_SHDR] =    { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2344 		.tom64 = _libelf_cvt_SHDR64_tom },
2345 	[ELF_T_SWORD] =   { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2346 		.tom64 = _libelf_cvt_SWORD_tom },
2347 	[ELF_T_SXWORD] =  { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2348 		.tom64 = _libelf_cvt_SXWORD_tom },
2349 	[ELF_T_SYMINFO] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2350 		.tom64 = _libelf_cvt_SYMINFO64_tom },
2351 	[ELF_T_SYM] =     { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2352 		.tom64 = _libelf_cvt_SYM64_tom },
2353 	[ELF_T_VDEF] =    { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2354 		.tom64 = _libelf_cvt_VDEF64_tom },
2355 	[ELF_T_VNEED] =   { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2356 		.tom64 = _libelf_cvt_VNEED64_tom },
2357 	[ELF_T_WORD] =    { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2358 		.tom64 = _libelf_cvt_WORD_tom },
2359 	[ELF_T_XWORD] =   { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2360 		.tom64 = _libelf_cvt_XWORD_tom },
2361 	/*]*/
2362 	/*
2363 	 * Types that need hand-coded converters follow.
2364 	 */
2365 	[ELF_T_BYTE] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2366 		.tom64 = _libelf_cvt_BYTE_tox },
2367 	[ELF_T_NOTE] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL,
2368 		.tom64 = _libelf_cvt_NOTE_tom }
2369 };
2370 
2371 static int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass))
2372  (unsigned char *_dst, size_t dsz, unsigned char *_src, size_t _cnt,
2373   int _byteswap)
2374 {
2375 	assert(/* elfclass == ELFCLASS32 || */ elfclass == ELFCLASS64);
2376 	assert(/* direction == ELF_TOFILE || */ direction == ELF_TOMEMORY);
2377 
2378 	if (t >= ELF_T_NUM ||
2379 	    (/* elfclass != ELFCLASS32 && */ elfclass != ELFCLASS64) ||
2380 	    (/* direction != ELF_TOFILE && */ direction != ELF_TOMEMORY))
2381 		return (NULL);
2382 
2383 #if 1
2384 	return cvt[t].tom64;
2385 #else
2386 	return ((elfclass == ELFCLASS32) ?
2387 	    (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) :
2388 	    (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64));
2389 #endif
2390 }
2391 
2392 /* libelf_ehdr.h */
2393 /*
2394  * Retrieve counts for sections, phdrs and the section string table index
2395  * from section header #0 of the ELF object.
2396  */
2397 static int
2398 _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum,
2399     uint16_t strndx)
2400 {
2401 	Elf_Scn *scn;
2402 	size_t fsz;
2403 	int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s,
2404 	    size_t _c, int _swap);
2405 	uint32_t shtype;
2406 
2407 	assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn));
2408 
2409 	fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1);
2410 	assert(fsz > 0);
2411 
2412 	if (e->e_rawsize < shoff + fsz) { /* raw file too small */
2413 		LIBELF_SET_ERROR(HEADER, 0);
2414 		return (0);
2415 	}
2416 
2417 	if ((scn = _libelf_allocate_scn(e, (size_t) 0)) == NULL)
2418 		return (0);
2419 
2420 	xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec);
2421 	(*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr),
2422 	    (unsigned char *) e->e_rawfile + shoff, (size_t) 1,
2423 	    e->e_byteorder != LIBELF_PRIVATE(byteorder));
2424 
2425 #define	GET_SHDR_MEMBER(M) (/* (ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M :*/ \
2426 		scn->s_shdr.s_shdr64.M)
2427 
2428 	if ((shtype = GET_SHDR_MEMBER(sh_type)) != SHT_NULL) {
2429 		LIBELF_SET_ERROR(SECTION, 0);
2430 		return (0);
2431 	}
2432 
2433 	e->e_u.e_elf.e_nscn = (size_t) GET_SHDR_MEMBER(sh_size);
2434 	e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum :
2435 	    GET_SHDR_MEMBER(sh_info);
2436 	e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx :
2437 	    GET_SHDR_MEMBER(sh_link);
2438 #undef	GET_SHDR_MEMBER
2439 
2440 	return (1);
2441 }
2442 
2443 #define	EHDR_INIT(E,SZ)	 do {						\
2444 		Elf##SZ##_Ehdr *eh = (E);				\
2445 		eh->e_ident[EI_MAG0] = ELFMAG0;				\
2446 		eh->e_ident[EI_MAG1] = ELFMAG1;				\
2447 		eh->e_ident[EI_MAG2] = ELFMAG2;				\
2448 		eh->e_ident[EI_MAG3] = ELFMAG3;				\
2449 		eh->e_ident[EI_CLASS] = ELFCLASS##SZ;			\
2450 		eh->e_ident[EI_DATA]  = ELFDATANONE;			\
2451 		eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version) & 0xFFU; \
2452 		eh->e_machine = EM_NONE;				\
2453 		eh->e_type    = ELF_K_NONE;				\
2454 		eh->e_version = LIBELF_PRIVATE(version);		\
2455 	} while (0)
2456 
2457 static void *
2458 _libelf_ehdr(Elf *e, int ec, int allocate)
2459 {
2460 	void *ehdr;
2461 	size_t fsz, msz;
2462 	uint16_t phnum, shnum, strndx;
2463 	uint64_t shoff;
2464 	int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s,
2465 	    size_t _c, int _swap);
2466 
2467 	assert(ec == ELFCLASS32 || ec == ELFCLASS64);
2468 
2469 	if (e == NULL || e->e_kind != ELF_K_ELF) {
2470 		LIBELF_SET_ERROR(ARGUMENT, 0);
2471 		return (NULL);
2472 	}
2473 
2474 	if (e->e_class != ELFCLASSNONE && e->e_class != ec) {
2475 		LIBELF_SET_ERROR(CLASS, 0);
2476 		return (NULL);
2477 	}
2478 
2479 	if (e->e_version != EV_CURRENT) {
2480 		LIBELF_SET_ERROR(VERSION, 0);
2481 		return (NULL);
2482 	}
2483 
2484 	if (e->e_class == ELFCLASSNONE)
2485 		e->e_class = ec;
2486 
2487 #if 0
2488 	if (ec == ELFCLASS32)
2489 		ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr32;
2490 	else
2491 #endif
2492 		ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr64;
2493 
2494 	if (ehdr != NULL)	/* already have a translated ehdr */
2495 		return (ehdr);
2496 
2497 	fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1);
2498 	assert(fsz > 0);
2499 
2500 	if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) {
2501 		LIBELF_SET_ERROR(HEADER, 0);
2502 		return (NULL);
2503 	}
2504 
2505 	msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT);
2506 
2507 	assert(msz > 0);
2508 
2509 	if ((ehdr = calloc((size_t) 1, msz)) == NULL) {
2510 		LIBELF_SET_ERROR(RESOURCE, 0);
2511 		return (NULL);
2512 	}
2513 
2514 #if 0
2515 	if (ec == ELFCLASS32) {
2516 		e->e_u.e_elf.e_ehdr.e_ehdr32 = ehdr;
2517 		EHDR_INIT(ehdr,32);
2518 	} else
2519 #endif
2520 	{
2521 		e->e_u.e_elf.e_ehdr.e_ehdr64 = ehdr;
2522 		EHDR_INIT(ehdr,64);
2523 	}
2524 
2525 	if (allocate)
2526 		e->e_flags |= ELF_F_DIRTY;
2527 
2528 	if (e->e_cmd == ELF_C_WRITE)
2529 		return (ehdr);
2530 
2531 	xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec);
2532 	(*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1,
2533 	    e->e_byteorder != LIBELF_PRIVATE(byteorder));
2534 
2535 	/*
2536 	 * If extended numbering is being used, read the correct
2537 	 * number of sections and program header entries.
2538 	 */
2539 #if 0
2540 	if (ec == ELFCLASS32) {
2541 		phnum = ((Elf32_Ehdr *) ehdr)->e_phnum;
2542 		shnum = ((Elf32_Ehdr *) ehdr)->e_shnum;
2543 		shoff = ((Elf32_Ehdr *) ehdr)->e_shoff;
2544 		strndx = ((Elf32_Ehdr *) ehdr)->e_shstrndx;
2545 	} else
2546 #endif
2547 	{
2548 		phnum = ((Elf64_Ehdr *) ehdr)->e_phnum;
2549 		shnum = ((Elf64_Ehdr *) ehdr)->e_shnum;
2550 		shoff = ((Elf64_Ehdr *) ehdr)->e_shoff;
2551 		strndx = ((Elf64_Ehdr *) ehdr)->e_shstrndx;
2552 	}
2553 
2554 	if (shnum >= SHN_LORESERVE ||
2555 	    (shoff == 0LL && (shnum != 0 || phnum == PN_XNUM ||
2556 		strndx == SHN_XINDEX))) {
2557 		LIBELF_SET_ERROR(HEADER, 0);
2558 		return (NULL);
2559 	}
2560 
2561 	if (shnum != 0 || shoff == 0LL) { /* not using extended numbering */
2562 		e->e_u.e_elf.e_nphdr = phnum;
2563 		e->e_u.e_elf.e_nscn = shnum;
2564 		e->e_u.e_elf.e_strndx = strndx;
2565 	} else if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0)
2566 		return (NULL);
2567 
2568 	return (ehdr);
2569 }
2570 
2571 /* libelf_shdr.c */
2572 static void *
2573 _libelf_getshdr(Elf_Scn *s, int ec)
2574 {
2575 	Elf *e;
2576 
2577 	if (s == NULL || (e = s->s_elf) == NULL ||
2578 	    e->e_kind != ELF_K_ELF) {
2579 		LIBELF_SET_ERROR(ARGUMENT, 0);
2580 		return (NULL);
2581 	}
2582 
2583 	if (ec == ELFCLASSNONE)
2584 		ec = e->e_class;
2585 
2586 	if (ec != e->e_class) {
2587 		LIBELF_SET_ERROR(CLASS, 0);
2588 		return (NULL);
2589 	}
2590 
2591 	return ((void *) &s->s_shdr);
2592 }
2593 
2594 /* elf_scn.c */
2595 static int
2596 _libelf_load_section_headers(Elf *e, void *ehdr)
2597 {
2598 	Elf_Scn *scn;
2599 	uint64_t shoff;
2600 #if 0
2601 	Elf32_Ehdr *eh32;
2602 #endif
2603 	Elf64_Ehdr *eh64;
2604 	int ec, swapbytes;
2605 	unsigned char *src;
2606 	size_t fsz, i, shnum;
2607 	int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s,
2608 	    size_t _c, int _swap);
2609 
2610 	assert(e != NULL);
2611 	assert(ehdr != NULL);
2612 	assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0);
2613 
2614 #define	CHECK_EHDR(E,EH)	do {				\
2615 		if (shoff > e->e_rawsize ||			\
2616 		    fsz != (EH)->e_shentsize ||			\
2617 		    shnum > SIZE_MAX / fsz ||			\
2618 		    fsz * shnum > e->e_rawsize - shoff) {	\
2619 			LIBELF_SET_ERROR(HEADER, 0);		\
2620 			return (0);				\
2621 		}						\
2622 	} while (0)
2623 
2624 	ec = e->e_class;
2625 	fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1);
2626 	assert(fsz > 0);
2627 
2628 	shnum = e->e_u.e_elf.e_nscn;
2629 
2630 #if 0
2631 	if (ec == ELFCLASS32) {
2632 		eh32 = (Elf32_Ehdr *) ehdr;
2633 		shoff = (uint64_t) eh32->e_shoff;
2634 		CHECK_EHDR(e, eh32);
2635 	} else
2636 #endif
2637 	{
2638 		eh64 = (Elf64_Ehdr *) ehdr;
2639 		shoff = eh64->e_shoff;
2640 		CHECK_EHDR(e, eh64);
2641 	}
2642 
2643 	xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec);
2644 
2645 	swapbytes = e->e_byteorder != LIBELF_PRIVATE(byteorder);
2646 	src = e->e_rawfile + shoff;
2647 
2648 	/*
2649 	 * If the file is using extended numbering then section #0
2650 	 * would have already been read in.
2651 	 */
2652 
2653 	i = 0;
2654 	if (!STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) {
2655 		assert(STAILQ_FIRST(&e->e_u.e_elf.e_scn) ==
2656 		    STAILQ_LAST(&e->e_u.e_elf.e_scn, _Elf_Scn, s_next));
2657 
2658 		i = 1;
2659 		src += fsz;
2660 	}
2661 
2662 	for (; i < shnum; i++, src += fsz) {
2663 		if ((scn = _libelf_allocate_scn(e, i)) == NULL)
2664 			return (0);
2665 
2666 		(*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr),
2667 		    src, (size_t) 1, swapbytes);
2668 
2669 #if 0
2670 		if (ec == ELFCLASS32) {
2671 			scn->s_offset = scn->s_rawoff =
2672 			    scn->s_shdr.s_shdr32.sh_offset;
2673 			scn->s_size = scn->s_shdr.s_shdr32.sh_size;
2674 		} else
2675 #endif
2676 		{
2677 			scn->s_offset = scn->s_rawoff =
2678 			    scn->s_shdr.s_shdr64.sh_offset;
2679 			scn->s_size = scn->s_shdr.s_shdr64.sh_size;
2680 		}
2681 	}
2682 
2683 	e->e_flags |= LIBELF_F_SHDRS_LOADED;
2684 
2685 	return (1);
2686 }
2687 
2688 static Elf_Scn *
2689 elf_getscn(Elf *e, size_t index)
2690 {
2691 	int ec;
2692 	void *ehdr;
2693 	Elf_Scn *s;
2694 
2695 	if (e == NULL || e->e_kind != ELF_K_ELF ||
2696 	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
2697 		LIBELF_SET_ERROR(ARGUMENT, 0);
2698 		return (NULL);
2699 	}
2700 
2701 	if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
2702 		return (NULL);
2703 
2704 	if (e->e_cmd != ELF_C_WRITE &&
2705 	    (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 &&
2706 	    _libelf_load_section_headers(e, ehdr) == 0)
2707 		return (NULL);
2708 
2709 	STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next)
2710 		if (s->s_ndx == index)
2711 			return (s);
2712 
2713 	LIBELF_SET_ERROR(ARGUMENT, 0);
2714 	return (NULL);
2715 }
2716 
2717 /* libelf_memory.c */
2718 static Elf *
2719 _libelf_memory(unsigned char *image, size_t sz, int reporterror)
2720 {
2721 	Elf *e;
2722 	int e_class;
2723 	enum Elf_Error error;
2724 	unsigned int e_byteorder, e_version;
2725 
2726 	assert(image != NULL);
2727 	assert(sz > 0);
2728 
2729 	if ((e = _libelf_allocate_elf()) == NULL)
2730 		return (NULL);
2731 
2732 	e->e_cmd = ELF_C_READ;
2733 	e->e_rawfile = image;
2734 	e->e_rawsize = sz;
2735 
2736 #undef	LIBELF_IS_ELF
2737 #define	LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 &&		\
2738 	(P)[EI_MAG1] == ELFMAG1 && (P)[EI_MAG2] == ELFMAG2 &&	\
2739 	(P)[EI_MAG3] == ELFMAG3)
2740 
2741 	if (sz > EI_NIDENT && LIBELF_IS_ELF(image)) {
2742 		e_byteorder = image[EI_DATA];
2743 		e_class     = image[EI_CLASS];
2744 		e_version   = image[EI_VERSION];
2745 
2746 		error = ELF_E_NONE;
2747 
2748 		if (e_version > EV_CURRENT)
2749 			error = ELF_E_VERSION;
2750 		else if ((e_byteorder != ELFDATA2LSB && e_byteorder !=
2751 		    ELFDATA2MSB) || (e_class != ELFCLASS32 && e_class !=
2752 		    ELFCLASS64))
2753 			error = ELF_E_HEADER;
2754 
2755 		if (error != ELF_E_NONE) {
2756 			if (reporterror) {
2757 				LIBELF_PRIVATE(error) = LIBELF_ERROR(error, 0);
2758 				(void) _libelf_release_elf(e);
2759 				return (NULL);
2760 			}
2761 		} else {
2762 			_libelf_init_elf(e, ELF_K_ELF);
2763 
2764 			e->e_byteorder = e_byteorder;
2765 			e->e_class = e_class;
2766 			e->e_version = e_version;
2767 		}
2768 	}
2769 #if 0
2770 	else if (sz >= SARMAG &&
2771 	    strncmp((const char *) image, ARMAG, (size_t) SARMAG) == 0)
2772 		return (_libelf_ar_open(e, reporterror));
2773 #endif
2774 
2775 	return (e);
2776 }
2777 
2778 /* libelf_open.c */
2779 #define	_LIBELF_INITSIZE	(64*1024)
2780 
2781 static void *
2782 _libelf_read_special_file(int fd, size_t *fsz)
2783 {
2784 	ssize_t readsz;
2785 	size_t bufsz, datasz;
2786 	unsigned char *buf, *t;
2787 
2788 	datasz = 0;
2789 	readsz = 0;
2790 	bufsz = _LIBELF_INITSIZE;
2791 	if ((buf = malloc(bufsz)) == NULL)
2792 		goto resourceerror;
2793 
2794 	/*
2795 	 * Read data from the file descriptor till we reach EOF, or
2796 	 * till an error is encountered.
2797 	 */
2798 	do {
2799 		/* Check if we need to expand the data buffer. */
2800 		if (datasz == bufsz) {
2801 			bufsz *= 2;
2802 			if ((t = realloc(buf, bufsz)) == NULL)
2803 				goto resourceerror;
2804 			buf = t;
2805 		}
2806 
2807 		do {
2808 			assert(bufsz - datasz > 0);
2809 			t = buf + datasz;
2810 			if ((readsz = read(fd, t, bufsz - datasz)) <= 0)
2811 				break;
2812 			datasz += (size_t) readsz;
2813 		} while (datasz < bufsz);
2814 
2815 	} while (readsz > 0);
2816 
2817 	if (readsz < 0) {
2818 		LIBELF_SET_ERROR(IO, errno);
2819 		goto error;
2820 	}
2821 
2822 	assert(readsz == 0);
2823 
2824 	/*
2825 	 * Free up extra buffer space.
2826 	 */
2827 	if (bufsz > datasz) {
2828 		if (datasz > 0) {
2829 			if ((t = realloc(buf, datasz)) == NULL)
2830 				goto resourceerror;
2831 			buf = t;
2832 		} else {	/* Zero bytes read. */
2833 			LIBELF_SET_ERROR(ARGUMENT, 0);
2834 			free(buf);
2835 			buf = NULL;
2836 		}
2837 	}
2838 
2839 	*fsz = datasz;
2840 	return (buf);
2841 
2842 resourceerror:
2843 	LIBELF_SET_ERROR(RESOURCE, 0);
2844 error:
2845 	if (buf != NULL)
2846 		free(buf);
2847 	return (NULL);
2848 }
2849 
2850 static Elf *
2851 _libelf_open_object(int fd, Elf_Cmd c, int reporterror)
2852 {
2853 	Elf *e;
2854 	void *m;
2855 	mode_t mode;
2856 	size_t fsize;
2857 	struct stat sb;
2858 	unsigned int flags;
2859 
2860 	assert(c == ELF_C_READ || c == ELF_C_RDWR || c == ELF_C_WRITE);
2861 
2862 	if (fstat(fd, &sb) < 0) {
2863 		LIBELF_SET_ERROR(IO, errno);
2864 		return (NULL);
2865 	}
2866 
2867 	mode = sb.st_mode;
2868 	fsize = (size_t) sb.st_size;
2869 
2870 	/*
2871 	 * Reject unsupported file types.
2872 	 */
2873 	if (!S_ISREG(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) &&
2874 	    !S_ISSOCK(mode)) {
2875 		LIBELF_SET_ERROR(ARGUMENT, 0);
2876 		return (NULL);
2877 	}
2878 
2879 	/*
2880 	 * For ELF_C_WRITE mode, allocate and return a descriptor.
2881 	 */
2882 	if (c == ELF_C_WRITE) {
2883 		if ((e = _libelf_allocate_elf()) != NULL) {
2884 			_libelf_init_elf(e, ELF_K_ELF);
2885 			e->e_byteorder = LIBELF_PRIVATE(byteorder);
2886 			e->e_fd = fd;
2887 			e->e_cmd = c;
2888 			if (!S_ISREG(mode))
2889 				e->e_flags |= LIBELF_F_SPECIAL_FILE;
2890 		}
2891 
2892 		return (e);
2893 	}
2894 
2895 
2896 	/*
2897 	 * ELF_C_READ and ELF_C_RDWR mode.
2898 	 */
2899 	m = NULL;
2900 	flags = 0;
2901 	if (S_ISREG(mode)) {
2902 
2903 		/*
2904 		 * Reject zero length files.
2905 		 */
2906 		if (fsize == 0) {
2907 			LIBELF_SET_ERROR(ARGUMENT, 0);
2908 			return (NULL);
2909 		}
2910 
2911 #if	ELFTC_HAVE_MMAP
2912 		/*
2913 		 * Always map regular files in with 'PROT_READ'
2914 		 * permissions.
2915 		 *
2916 		 * For objects opened in ELF_C_RDWR mode, when
2917 		 * elf_update(3) is called, we remove this mapping,
2918 		 * write file data out using write(2), and map the new
2919 		 * contents back.
2920 		 */
2921 		m = mmap(NULL, fsize, PROT_READ, MAP_PRIVATE, fd, (off_t) 0);
2922 
2923 		if (m == MAP_FAILED)
2924 			m = NULL;
2925 		else
2926 			flags = LIBELF_F_RAWFILE_MMAP;
2927 #endif
2928 
2929 		/*
2930 		 * Fallback to a read() if the call to mmap() failed,
2931 		 * or if mmap() is not available.
2932 		 */
2933 		if (m == NULL) {
2934 			if ((m = malloc(fsize)) == NULL) {
2935 				LIBELF_SET_ERROR(RESOURCE, 0);
2936 				return (NULL);
2937 			}
2938 
2939 			if (read(fd, m, fsize) != (ssize_t) fsize) {
2940 				LIBELF_SET_ERROR(IO, errno);
2941 				free(m);
2942 				return (NULL);
2943 			}
2944 
2945 			flags = LIBELF_F_RAWFILE_MALLOC;
2946 		}
2947 	} else if ((m = _libelf_read_special_file(fd, &fsize)) != NULL)
2948 		flags = LIBELF_F_RAWFILE_MALLOC | LIBELF_F_SPECIAL_FILE;
2949 	else
2950 		return (NULL);
2951 
2952 	if ((e = _libelf_memory(m, fsize, reporterror)) == NULL) {
2953 		assert((flags & LIBELF_F_RAWFILE_MALLOC) ||
2954 		    (flags & LIBELF_F_RAWFILE_MMAP));
2955 		if (flags & LIBELF_F_RAWFILE_MALLOC)
2956 			free(m);
2957 #if	ELFTC_HAVE_MMAP
2958 		else
2959 			(void) munmap(m, fsize);
2960 #endif
2961 		return (NULL);
2962 	}
2963 
2964 	/* ar(1) archives aren't supported in RDWR mode. */
2965 #if 0
2966 	if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) {
2967 		(void) elf_end(e);
2968 		LIBELF_SET_ERROR(ARGUMENT, 0);
2969 		return (NULL);
2970 	}
2971 #endif
2972 
2973 	e->e_flags |= flags;
2974 	e->e_fd = fd;
2975 	e->e_cmd = c;
2976 
2977 	return (e);
2978 }
2979 
2980 static const char *_libelf_errors[] = {
2981 #define	DEFINE_ERROR(N,S)	[ELF_E_##N] = S
2982 	DEFINE_ERROR(NONE,	"No Error"),
2983 	DEFINE_ERROR(ARCHIVE,	"Malformed ar(1) archive"),
2984 	DEFINE_ERROR(ARGUMENT,	"Invalid argument"),
2985 	DEFINE_ERROR(CLASS,	"ELF class mismatch"),
2986 	DEFINE_ERROR(DATA,	"Invalid data buffer descriptor"),
2987 	DEFINE_ERROR(HEADER,	"Missing or malformed ELF header"),
2988 	DEFINE_ERROR(IO,	"I/O error"),
2989 	DEFINE_ERROR(LAYOUT,	"Layout constraint violation"),
2990 	DEFINE_ERROR(MODE,	"Incorrect ELF descriptor mode"),
2991 	DEFINE_ERROR(RANGE,	"Value out of range of target"),
2992 	DEFINE_ERROR(RESOURCE,	"Resource exhaustion"),
2993 	DEFINE_ERROR(SECTION,	"Invalid section descriptor"),
2994 	DEFINE_ERROR(SEQUENCE,	"API calls out of sequence"),
2995 	DEFINE_ERROR(UNIMPL,	"Unimplemented feature"),
2996 	DEFINE_ERROR(VERSION,	"Unknown ELF API version"),
2997 	DEFINE_ERROR(NUM,	"Unknown error")
2998 #undef	DEFINE_ERROR
2999 };
3000 
3001 /* PUBLIC */
3002 
3003 /* elf_errmsg.c */
3004 static const char *
3005 elf_errmsg(int error)
3006 {
3007 	int oserr;
3008 
3009 	if (error == ELF_E_NONE &&
3010 	    (error = LIBELF_PRIVATE(error)) == 0)
3011 	    return NULL;
3012 	else if (error == -1)
3013 	    error = LIBELF_PRIVATE(error);
3014 
3015 	oserr = error >> LIBELF_OS_ERROR_SHIFT;
3016 	error &= LIBELF_ELF_ERROR_MASK;
3017 
3018 	if (error < ELF_E_NONE || error >= ELF_E_NUM)
3019 		return _libelf_errors[ELF_E_NUM];
3020 	if (oserr) {
3021 		(void) snprintf((char *) LIBELF_PRIVATE(msg),
3022 		    sizeof(LIBELF_PRIVATE(msg)), "%s: %s",
3023 		    _libelf_errors[error], strerror(oserr));
3024 		return (const char *)&LIBELF_PRIVATE(msg);
3025 	}
3026 	return _libelf_errors[error];
3027 }
3028 
3029 /* elf_errno.c */
3030 static int
3031 elf_errno(void)
3032 {
3033 	int old;
3034 
3035 	old = LIBELF_PRIVATE(error);
3036 	LIBELF_PRIVATE(error) = 0;
3037 	return (old & LIBELF_ELF_ERROR_MASK);
3038 }
3039 
3040 /* elf_version.c */
3041 static unsigned int
3042 elf_version(unsigned int v)
3043 {
3044 	unsigned int old;
3045 
3046 	if ((old = LIBELF_PRIVATE(version)) == EV_NONE)
3047 		old = EV_CURRENT;
3048 
3049 	if (v == EV_NONE)
3050 		return old;
3051 	if (v > EV_CURRENT) {
3052 		LIBELF_SET_ERROR(VERSION, 0);
3053 		return EV_NONE;
3054 	}
3055 
3056 	LIBELF_PRIVATE(version) = v;
3057 	return (old);
3058 }
3059 
3060 /* elf_begin.c */
3061 static Elf *
3062 elf_begin(int fd, Elf_Cmd c, Elf *a)
3063 {
3064 	Elf *e;
3065 
3066 	e = NULL;
3067 
3068 	if (LIBELF_PRIVATE(version) == EV_NONE) {
3069 		LIBELF_SET_ERROR(SEQUENCE, 0);
3070 		return (NULL);
3071 	}
3072 
3073 	switch (c) {
3074 	case ELF_C_NULL:
3075 		return (NULL);
3076 
3077 	case ELF_C_WRITE:
3078 		/*
3079 		 * The ELF_C_WRITE command is required to ignore the
3080 		 * descriptor passed in.
3081 		 */
3082 		a = NULL;
3083 		break;
3084 
3085 	case ELF_C_RDWR:
3086 		if (a != NULL) { /* not allowed for ar(1) archives. */
3087 			LIBELF_SET_ERROR(ARGUMENT, 0);
3088 			return (NULL);
3089 		}
3090 		/*FALLTHROUGH*/
3091 	case ELF_C_READ:
3092 		/*
3093 		 * Descriptor `a' could be for a regular ELF file, or
3094 		 * for an ar(1) archive.  If descriptor `a' was opened
3095 		 * using a valid file descriptor, we need to check if
3096 		 * the passed in `fd' value matches the original one.
3097 		 */
3098 		if (a &&
3099 		    ((a->e_fd != -1 && a->e_fd != fd) || c != a->e_cmd)) {
3100 			LIBELF_SET_ERROR(ARGUMENT, 0);
3101 			return (NULL);
3102 		}
3103 		break;
3104 
3105 	default:
3106 		LIBELF_SET_ERROR(ARGUMENT, 0);
3107 		return (NULL);
3108 
3109 	}
3110 
3111 	if (a == NULL)
3112 		e = _libelf_open_object(fd, c, 1);
3113 #if 0
3114 	else if (a->e_kind == ELF_K_AR)
3115 		e = _libelf_ar_open_member(a->e_fd, c, a);
3116 #endif
3117 	else
3118 		(e = a)->e_activations++;
3119 
3120 	return (e);
3121 }
3122 
3123 /* elf_end.c */
3124 static int
3125 elf_end(Elf *e)
3126 {
3127 	Elf *sv;
3128 	Elf_Scn *scn, *tscn;
3129 
3130 	if (e == NULL || e->e_activations == 0)
3131 		return (0);
3132 
3133 	if (--e->e_activations > 0)
3134 		return (e->e_activations);
3135 
3136 	assert(e->e_activations == 0);
3137 
3138 	while (e && e->e_activations == 0) {
3139 		switch (e->e_kind) {
3140 		case ELF_K_AR:
3141 			/*
3142 			 * If we still have open child descriptors, we
3143 			 * need to defer reclaiming resources till all
3144 			 * the child descriptors for the archive are
3145 			 * closed.
3146 			 */
3147 			if (e->e_u.e_ar.e_nchildren > 0)
3148 				return (0);
3149 			break;
3150 		case ELF_K_ELF:
3151 			/*
3152 			 * Reclaim all section descriptors.
3153 			 */
3154 			STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next,
3155 			    tscn)
3156 				scn = _libelf_release_scn(scn);
3157 			break;
3158 		case ELF_K_NUM:
3159 			assert(0);
3160 		default:
3161 			break;
3162 		}
3163 
3164 		if (e->e_rawfile) {
3165 			if (e->e_flags & LIBELF_F_RAWFILE_MALLOC)
3166 				free(e->e_rawfile);
3167 #if	ELFTC_HAVE_MMAP
3168 			else if (e->e_flags & LIBELF_F_RAWFILE_MMAP)
3169 				(void) munmap(e->e_rawfile, e->e_rawsize);
3170 #endif
3171 		}
3172 
3173 		sv = e;
3174 		if ((e = e->e_parent) != NULL)
3175 			e->e_u.e_ar.e_nchildren--;
3176 		sv = _libelf_release_elf(sv);
3177 	}
3178 
3179 	return (0);
3180 }
3181 
3182 /* gelf_shdr.c */
3183 static GElf_Shdr *
3184 gelf_getshdr(Elf_Scn *s, GElf_Shdr *d)
3185 {
3186 	int ec;
3187 	void *sh;
3188 #if 0
3189 	Elf32_Shdr *sh32;
3190 #endif
3191 	Elf64_Shdr *sh64;
3192 
3193 	if (d == NULL) {
3194 		LIBELF_SET_ERROR(ARGUMENT, 0);
3195 		return (NULL);
3196 	}
3197 
3198 	if ((sh = _libelf_getshdr(s, ELFCLASSNONE)) == NULL)
3199 		return (NULL);
3200 
3201 	ec = s->s_elf->e_class;
3202 	assert(/* ec == ELFCLASS32 || */ ec == ELFCLASS64);
3203 
3204 #if 0
3205 	if (ec == ELFCLASS32) {
3206 		sh32 = (Elf32_Shdr *) sh;
3207 
3208 		d->sh_name      = sh32->sh_name;
3209 		d->sh_type      = sh32->sh_type;
3210 		d->sh_flags     = (Elf64_Xword) sh32->sh_flags;
3211 		d->sh_addr      = (Elf64_Addr) sh32->sh_addr;
3212 		d->sh_offset    = (Elf64_Off) sh32->sh_offset;
3213 		d->sh_size      = (Elf64_Xword) sh32->sh_size;
3214 		d->sh_link      = sh32->sh_link;
3215 		d->sh_info      = sh32->sh_info;
3216 		d->sh_addralign = (Elf64_Xword) sh32->sh_addralign;
3217 		d->sh_entsize   = (Elf64_Xword) sh32->sh_entsize;
3218 	} else
3219 #endif
3220 	{
3221 		sh64 = (Elf64_Shdr *) sh;
3222 		*d = *sh64;
3223 	}
3224 
3225 	return (d);
3226 }
3227 
3228 /* gelf_sym.c */
3229 static GElf_Sym *
3230 gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst)
3231 {
3232 	int ec;
3233 	Elf *e;
3234 	size_t msz;
3235 	Elf_Scn *scn;
3236 	uint32_t sh_type;
3237 #if 0
3238 	Elf32_Sym *sym32;
3239 #endif
3240 	Elf64_Sym *sym64;
3241 	struct _Libelf_Data *d;
3242 
3243 	d = (struct _Libelf_Data *) ed;
3244 
3245 	if (d == NULL || ndx < 0 || dst == NULL ||
3246 	    (scn = d->d_scn) == NULL ||
3247 	    (e = scn->s_elf) == NULL) {
3248 		LIBELF_SET_ERROR(ARGUMENT, 0);
3249 		return (NULL);
3250 	}
3251 
3252 	ec = e->e_class;
3253 	assert(/* ec == ELFCLASS32 || */ ec == ELFCLASS64);
3254 
3255 #if 0
3256 	if (ec == ELFCLASS32)
3257 		sh_type = scn->s_shdr.s_shdr32.sh_type;
3258 	else
3259 #endif
3260 		sh_type = scn->s_shdr.s_shdr64.sh_type;
3261 
3262 	if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) {
3263 		LIBELF_SET_ERROR(ARGUMENT, 0);
3264 		return (NULL);
3265 	}
3266 
3267 	msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);
3268 
3269 	assert(msz > 0);
3270 	assert(ndx >= 0);
3271 
3272 	if (msz * (size_t) ndx >= d->d_data.d_size) {
3273 		LIBELF_SET_ERROR(ARGUMENT, 0);
3274 		return (NULL);
3275 	}
3276 
3277 #if 0
3278 	if (ec == ELFCLASS32) {
3279 		sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx;
3280 
3281 		dst->st_name  = sym32->st_name;
3282 		dst->st_value = (Elf64_Addr) sym32->st_value;
3283 		dst->st_size  = (Elf64_Xword) sym32->st_size;
3284 		dst->st_info  = sym32->st_info;
3285 		dst->st_other = sym32->st_other;
3286 		dst->st_shndx = sym32->st_shndx;
3287 	} else
3288 #endif
3289 	{
3290 		sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx;
3291 
3292 		*dst = *sym64;
3293 	}
3294 
3295 	return (dst);
3296 }
3297 
3298 /* elf_scn.c */
3299 static Elf_Scn *
3300 elf_nextscn(Elf *e, Elf_Scn *s)
3301 {
3302 	if (e == NULL || (e->e_kind != ELF_K_ELF) ||
3303 	    (s && s->s_elf != e)) {
3304 		LIBELF_SET_ERROR(ARGUMENT, 0);
3305 		return (NULL);
3306 	}
3307 
3308 	return (s == NULL ? elf_getscn(e, (size_t) 1) :
3309 	    STAILQ_NEXT(s, s_next));
3310 }
3311 
3312 /* elf_strptr.c */
3313 static char *
3314 elf_strptr(Elf *e, size_t scndx, size_t offset)
3315 {
3316 	Elf_Scn *s;
3317 	Elf_Data *d;
3318 	GElf_Shdr shdr;
3319 	uint64_t alignment, count;
3320 
3321 	if (e == NULL || e->e_kind != ELF_K_ELF) {
3322 		LIBELF_SET_ERROR(ARGUMENT, 0);
3323 		return (NULL);
3324 	}
3325 
3326 	if ((s = elf_getscn(e, scndx)) == NULL ||
3327 	    gelf_getshdr(s, &shdr) == NULL)
3328 		return (NULL);
3329 
3330 	if (shdr.sh_type != SHT_STRTAB ||
3331 	    offset >= shdr.sh_size) {
3332 		LIBELF_SET_ERROR(ARGUMENT, 0);
3333 		return (NULL);
3334 	}
3335 
3336 	d = NULL;
3337 	if (e->e_flags & ELF_F_LAYOUT) {
3338 
3339 		/*
3340 		 * The application is taking responsibility for the
3341 		 * ELF object's layout, so we can directly translate
3342 		 * an offset to a `char *' address using the `d_off'
3343 		 * members of Elf_Data descriptors.
3344 		 */
3345 		while ((d = elf_getdata(s, d)) != NULL) {
3346 
3347 			if (d->d_buf == 0 || d->d_size == 0)
3348 				continue;
3349 
3350 			if (d->d_type != ELF_T_BYTE) {
3351 				LIBELF_SET_ERROR(DATA, 0);
3352 				return (NULL);
3353 			}
3354 
3355 			if (offset >= d->d_off &&
3356 			    offset < d->d_off + d->d_size)
3357 				return ((char *) d->d_buf + offset - d->d_off);
3358 		}
3359 	} else {
3360 		/*
3361 		 * Otherwise, the `d_off' members are not useable and
3362 		 * we need to compute offsets ourselves, taking into
3363 		 * account 'holes' in coverage of the section introduced
3364 		 * by alignment requirements.
3365 		 */
3366 		count = (uint64_t) 0;	/* cumulative count of bytes seen */
3367 		while ((d = elf_getdata(s, d)) != NULL && count <= offset) {
3368 
3369 			if (d->d_buf == NULL || d->d_size == 0)
3370 				continue;
3371 
3372 			if (d->d_type != ELF_T_BYTE) {
3373 				LIBELF_SET_ERROR(DATA, 0);
3374 				return (NULL);
3375 			}
3376 
3377 			if ((alignment = d->d_align) > 1) {
3378 				if ((alignment & (alignment - 1)) != 0) {
3379 					LIBELF_SET_ERROR(DATA, 0);
3380 					return (NULL);
3381 				}
3382 				count = roundup2(count, alignment);
3383 			}
3384 
3385 			if (offset < count) {
3386 				/* offset starts in the 'hole' */
3387 				LIBELF_SET_ERROR(ARGUMENT, 0);
3388 				return (NULL);
3389 			}
3390 
3391 			if (offset < count + d->d_size) {
3392 				if (d->d_buf != NULL)
3393 					return ((char *) d->d_buf +
3394 					    offset - count);
3395 				LIBELF_SET_ERROR(DATA, 0);
3396 				return (NULL);
3397 			}
3398 
3399 			count += d->d_size;
3400 		}
3401 	}
3402 
3403 	LIBELF_SET_ERROR(ARGUMENT, 0);
3404 	return (NULL);
3405 }
3406 
3407 /* elf_data.c */
3408 static Elf_Data *
3409 elf_getdata(Elf_Scn *s, Elf_Data *ed)
3410 {
3411 	Elf *e;
3412 	unsigned int sh_type;
3413 	int elfclass, elftype;
3414 	size_t count, fsz, msz;
3415 	struct _Libelf_Data *d;
3416 	uint64_t sh_align, sh_offset, sh_size;
3417 	int (*xlate)(unsigned char *_d, size_t _dsz, unsigned char *_s,
3418 	    size_t _c, int _swap);
3419 
3420 	d = (struct _Libelf_Data *) ed;
3421 
3422 	if (s == NULL || (e = s->s_elf) == NULL ||
3423 	    (d != NULL && s != d->d_scn)) {
3424 		LIBELF_SET_ERROR(ARGUMENT, 0);
3425 		return (NULL);
3426 	}
3427 
3428 	assert(e->e_kind == ELF_K_ELF);
3429 
3430 	if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL)
3431 		return (&d->d_data);
3432 
3433 	if (d != NULL)
3434 		return (&STAILQ_NEXT(d, d_next)->d_data);
3435 
3436 	if (e->e_rawfile == NULL) {
3437 		/*
3438 		 * In the ELF_C_WRITE case, there is no source that
3439 		 * can provide data for the section.
3440 		 */
3441 		LIBELF_SET_ERROR(ARGUMENT, 0);
3442 		return (NULL);
3443 	}
3444 
3445 	elfclass = e->e_class;
3446 
3447 	assert(/* elfclass == ELFCLASS32 || */ elfclass == ELFCLASS64);
3448 
3449 #if 0
3450 	if (elfclass == ELFCLASS32) {
3451 		sh_type   = s->s_shdr.s_shdr32.sh_type;
3452 		sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset;
3453 		sh_size   = (uint64_t) s->s_shdr.s_shdr32.sh_size;
3454 		sh_align  = (uint64_t) s->s_shdr.s_shdr32.sh_addralign;
3455 	} else
3456 #endif
3457 	{
3458 		sh_type   = s->s_shdr.s_shdr64.sh_type;
3459 		sh_offset = s->s_shdr.s_shdr64.sh_offset;
3460 		sh_size   = s->s_shdr.s_shdr64.sh_size;
3461 		sh_align  = s->s_shdr.s_shdr64.sh_addralign;
3462 	}
3463 
3464 	if (sh_type == SHT_NULL) {
3465 		LIBELF_SET_ERROR(SECTION, 0);
3466 		return (NULL);
3467 	}
3468 
3469 	if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST ||
3470 	    elftype > ELF_T_LAST || (sh_type != SHT_NOBITS &&
3471 	    sh_offset + sh_size > (uint64_t) e->e_rawsize)) {
3472 		LIBELF_SET_ERROR(SECTION, 0);
3473 		return (NULL);
3474 	}
3475 
3476 	if ((fsz = (/* elfclass == ELFCLASS32 ? elf32_fsize :*/ elf64_fsize)
3477             (elftype, (size_t) 1, e->e_version)) == 0) {
3478 		LIBELF_SET_ERROR(UNIMPL, 0);
3479 		return (NULL);
3480 	}
3481 
3482 	if (sh_size % fsz) {
3483 		LIBELF_SET_ERROR(SECTION, 0);
3484 		return (NULL);
3485 	}
3486 
3487 	if (sh_size / fsz > SIZE_MAX) {
3488 		LIBELF_SET_ERROR(RANGE, 0);
3489 		return (NULL);
3490 	}
3491 
3492 	count = (size_t) (sh_size / fsz);
3493 
3494 	msz = _libelf_msize(elftype, elfclass, e->e_version);
3495 
3496 	if (count > 0 && msz > SIZE_MAX / count) {
3497 		LIBELF_SET_ERROR(RANGE, 0);
3498 		return (NULL);
3499 	}
3500 
3501 	assert(msz > 0);
3502 	assert(count <= SIZE_MAX);
3503 	assert(msz * count <= SIZE_MAX);
3504 
3505 	if ((d = _libelf_allocate_data(s)) == NULL)
3506 		return (NULL);
3507 
3508 	d->d_data.d_buf     = NULL;
3509 	d->d_data.d_off     = 0;
3510 	d->d_data.d_align   = sh_align;
3511 	d->d_data.d_size    = msz * count;
3512 	d->d_data.d_type    = elftype;
3513 	d->d_data.d_version = e->e_version;
3514 
3515 	if (sh_type == SHT_NOBITS || sh_size == 0) {
3516 	        STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
3517 		return (&d->d_data);
3518         }
3519 
3520 	if ((d->d_data.d_buf = malloc(msz * count)) == NULL) {
3521 		(void) _libelf_release_data(d);
3522 		LIBELF_SET_ERROR(RESOURCE, 0);
3523 		return (NULL);
3524 	}
3525 
3526 	d->d_flags  |= LIBELF_F_DATA_MALLOCED;
3527 
3528 	xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass);
3529 	if (!(*xlate)(d->d_data.d_buf, (size_t) d->d_data.d_size,
3530 	    e->e_rawfile + sh_offset, count,
3531 	    e->e_byteorder != LIBELF_PRIVATE(byteorder))) {
3532 		_libelf_release_data(d);
3533 		LIBELF_SET_ERROR(DATA, 0);
3534 		return (NULL);
3535 	}
3536 
3537 	STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
3538 
3539 	return (&d->d_data);
3540 }
3541 
3542 #endif /* !_PRIVATE_LIBELF_H_ */
3543