4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
21 /* Copyright (c) 1988 AT&T */
22 /* All Rights Reserved */
26 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
34 #include <sys/machelf.h>
42 typedef struct Member Member
;
43 typedef struct Memlist Memlist
;
44 typedef struct Memident Memident
;
45 typedef struct Dnode Dnode
;
46 typedef struct Snode32 Snode32
;
47 typedef struct Snode64 Snode64
;
52 * An elf file is defined to have its structures aligned on
53 * appropriate boundaries. The following type lets the
54 * library test whether the file's alignment meets its own
55 * constraints in memory. This assumes every machine uses
56 * an alignment that is no greater than an object's size.
57 * The pointer isn't relevant for the file, but the code uses
58 * it to get memory alignment. ANSI C void * holds any pointer,
59 * making it appropriate here.
80 * Structures are obtained several ways: file mapping,
81 * malloc(), from the user. A status bit in the structures
82 * tells whether an object was obtained with malloc() and
83 * therefore should be released with free(). The bits
84 * named ...ALLOC indicate this.
90 * db_data must be first in the Dnode structure, because
91 * &db_data must == &Dnode.
93 * db_buf is a pointer to an allocated buffer. The same value
94 * goes into db_data.d_buf originally, but the user can touch
95 * it. If the data buffer is not to be freed, db_buf is null.
97 * When "reading" an input file's buffer, the data are left
98 * alone until needed. When they've been converted to internal
99 * form, the READY flag is set.
101 * db_raw points to a parallel raw buffer. Raw buffers
108 Elf_Scn
*db_scn
; /* section parent */
110 Dnode
*db_raw
; /* raw data */
111 off_t db_off
; /* orig file offset, 0 o/w */
112 size_t db_fsz
; /* orig file size, 0 o/w */
113 size_t db_shsz
; /* orig shdr size, 0 o/w */
114 size_t db_osz
; /* output size for update */
115 Elf_Void
*db_buf
; /* allocated data buffer */
116 unsigned db_uflags
; /* user flags: ELF_F_... */
117 unsigned db_myflags
; /* internal flags: DBF_... */
118 Elf64_Off db_xoff
; /* extended offset for 32-bit Elf64 */
121 #define DBF_ALLOC 0x1 /* applies to Dnode itself */
122 #define DBF_READY 0x2 /* buffer ready */
127 * These are sometimes allocated in a block. If the SF_ALLOC
128 * bit is set in the flags, the Scn address may be passed to free.
129 * The caller must first follow the s_next list to the next freeable
130 * node, because free can clobber the s_next value in the block.
136 Elf_Scn
*s_next
; /* next section */
137 Elf
*s_elf
; /* parent file */
138 Dnode
*s_hdnode
; /* head Dnode */
139 Dnode
*s_tlnode
; /* tail Dnode */
140 Elf_Void
*s_shdr
; /* Elf32 or Elf64 scn header */
141 size_t s_index
; /* section index */
142 int s_err
; /* for delaying data error */
143 unsigned s_shflags
; /* user shdr flags */
144 unsigned s_uflags
; /* user flags */
145 unsigned s_myflags
; /* SF_... */
146 Dnode s_dnode
; /* every scn needs one */
150 * Designates whether or not we are in a threaded_app.
152 extern int *_elf_libc_threaded
;
153 #define elf_threaded (_elf_libc_threaded && *_elf_libc_threaded)
157 (void) mutex_lock(&((Elf_Scn *)x)->s_mutex);
159 #define SCNUNLOCK(x) \
161 (void) mutex_unlock(&((Elf_Scn *)x)->s_mutex);
163 #define UPGRADELOCKS(e, s)\
164 if (elf_threaded) { \
165 (void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
166 (void) rw_unlock(&((Elf *)e)->ed_rwlock); \
167 (void) rw_wrlock(&((Elf *)e)->ed_rwlock); \
170 #define DOWNGRADELOCKS(e, s)\
171 if (elf_threaded) { \
172 (void) rw_unlock(&((Elf *)e)->ed_rwlock); \
173 (void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
174 (void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \
177 #define READLOCKS(e, s) \
178 if (elf_threaded) { \
179 (void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
180 (void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \
183 #define READUNLOCKS(e, s) \
184 if (elf_threaded) { \
185 (void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
186 (void) rw_unlock(&((Elf *)e)->ed_rwlock); \
189 #define SF_ALLOC 0x1 /* applies to Scn */
190 #define SF_READY 0x2 /* has section been cooked */
195 Elf_Scn sb_scn
; /* must be first */
201 Elf_Scn sb_scn
; /* must be first */
207 * A file's status controls how the library can use file data.
208 * This is important to keep "raw" operations and "cooked"
209 * operations from interfering with each other.
211 * A file's status is "fresh" until something touches it.
212 * If the first thing is a raw operation, we freeze the data
213 * and force all cooking operations to make a copy. If the
214 * first operation cooks, raw operations use the file system.
219 ES_FRESH
= 0, /* unchanged */
220 ES_COOKED
, /* translated */
221 ES_FROZEN
/* raw, can't be translated */
227 * The major handle between user code and the library.
229 * Descriptors can have parents: archive members reference
230 * the archive itself. Relevant "offsets:"
232 * ed_baseoff The file offset, relative to zero, to the first
233 * byte in the file. For all files, this gives
234 * the lseek(fd, ed_baseoff, 0) value.
236 * ed_memoff The offset from the beginning of the nesting file
237 * to the bytes of a member. For an archive member,
238 * this is the offset from the beginning of the
239 * archive to the member bytes (not the hdr). If an
240 * archive member slides, memoff changes.
242 * ed_siboff Similar to ed_memoff, this gives the offset from
243 * the beginning of the nesting file to the following
244 * sibling's header (not the sibling's bytes). This
245 * value is necessary, because of archive sliding.
247 * ed_nextoff For an archive, this gives the offset of the next
248 * member to process on elf_begin. That is,
249 * (ed_ident + ed_nextoff) gives pointer to member hdr.
251 * Keeping these absolute and relative offsets allows nesting of
252 * files, including archives within archives, etc. The only current
253 * nesting file is archive, but others might be supported.
255 * ed_image This is a pointer to the base memory image holding
256 * the file. Library code assumes the image is aligned
257 * to a boundary appropriate for any object. This must
258 * be true, because we get an image only from malloc
259 * or mmap, both of which guarantee alignment.
265 Elf
*ed_parent
; /* archive parent */
266 int ed_activ
; /* activation count */
267 int ed_fd
; /* file descriptor */
268 Status ed_status
; /* file's memory status */
269 off_t ed_baseoff
; /* base file offset, zero based */
270 size_t ed_memoff
; /* offset within archive */
271 size_t ed_siboff
; /* sibling offset with archive */
272 size_t ed_nextoff
; /* next archive member hdr offset */
273 char *ed_image
; /* pointer to file image */
274 size_t ed_imagesz
; /* # bytes in ed_image */
275 char *ed_wrimage
; /* pointer to output image */
276 size_t ed_wrimagesz
; /* # bytes in ed_wrimagesz */
277 char *ed_ident
; /* file start, getident() bytes */
278 size_t ed_identsz
; /* # bytes for getident() */
279 char *ed_raw
; /* raw file ptr */
280 size_t ed_fsz
; /* file size */
281 unsigned *ed_vm
; /* virtual memory map */
282 size_t ed_vmsz
; /* # regions in vm */
283 unsigned ed_encode
; /* data encoding */
284 unsigned ed_version
; /* file version */
285 int ed_class
; /* file class */
286 Elf_Kind ed_kind
; /* file type */
287 Elf_Void
*ed_ehdr
; /* Elf{32,64}_Ehdr elf header */
288 Elf_Void
*ed_phdr
; /* Elf{32,64}_Phdr phdr table */
289 size_t ed_phdrsz
; /* sizeof phdr table */
290 Elf_Void
*ed_shdr
; /* Elf{32,64}_Shdr shdr table */
291 Elf_Scn
*ed_hdscn
; /* head scn */
292 Elf_Scn
*ed_tlscn
; /* tail scn */
293 size_t ed_scntabsz
; /* number sects. alloc. in table */
294 Memlist
*ed_memlist
; /* list of archive member nodes */
295 Member
*ed_armem
; /* archive member header */
296 Elf_Void
*ed_arsym
; /* archive symbol table */
297 size_t ed_arsymsz
; /* archive symbol table size */
298 size_t ed_arsymoff
; /* archive symbol table hdr offset */
299 char *ed_arstr
; /* archive string table */
300 size_t ed_arstrsz
; /* archive string table size */
301 size_t ed_arstroff
; /* archive string table hdr offset */
302 unsigned ed_myflags
; /* EDF_... */
303 unsigned ed_ehflags
; /* ehdr flags */
304 unsigned ed_phflags
; /* phdr flags */
305 unsigned ed_uflags
; /* elf descriptor flags */
308 #define ELFRLOCK(e) \
310 (void) rw_rdlock(&((Elf *)e)->ed_rwlock);
312 #define ELFWLOCK(e) \
314 (void) rw_wrlock(&((Elf *)e)->ed_rwlock);
316 #define ELFUNLOCK(e) \
318 (void) rw_unlock(&((Elf *)e)->ed_rwlock);
320 #define EDF_ASALLOC 0x1 /* applies to ed_arsym */
321 #define EDF_EHALLOC 0x2 /* applies to ed_ehdr */
322 #define EDF_PHALLOC 0x4 /* applies to ed_phdr */
323 #define EDF_SHALLOC 0x8 /* applies to ed_shdr */
324 #define EDF_COFFAOUT 0x10 /* original file was coff a.out */
325 #define EDF_RAWALLOC 0x20 /* applies to ed_raw */
326 #define EDF_READ 0x40 /* file can be read */
327 #define EDF_WRITE 0x80 /* file can be written */
328 #define EDF_MEMORY 0x100 /* file opened via elf_memory() */
329 #define EDF_ASTRALLOC 0x200 /* applies to ed_arstr */
330 #define EDF_MPROTECT 0x400 /* applies to slideable archives */
331 #define EDF_IMALLOC 0x800 /* wrimage dynamically allocated */
332 #define EDF_WRALLOC 0x1000 /* wrimage is to by dyn allocated */
333 #define EDF_ARSYM64 0x2000 /* archive symbol table is 64-bit format */
345 * Max size for an Elf error message string
347 #define MAXELFERR 1024
350 * General thread management macros
352 #define ELFACCESSDATA(a, b) \
353 if (elf_threaded) { \
354 (void) mutex_lock(&_elf_globals_mutex); \
356 (void) mutex_unlock(&_elf_globals_mutex); \
360 #define ELFRWLOCKINIT(lock) \
361 if (elf_threaded) { \
362 (void) rwlock_init((lock), USYNC_THREAD, 0); \
365 #define ELFMUTEXINIT(lock) \
366 if (elf_threaded) { \
367 (void) mutex_init(lock, USYNC_THREAD, 0); \
370 extern Member
*_elf_armem(Elf
*, char *, size_t);
371 extern void _elf_arinit(Elf
*);
372 extern Okay
_elf_cook(Elf
*);
373 extern Okay
_elf_cookscn(Elf_Scn
* s
);
374 extern Okay
_elf32_cookscn(Elf_Scn
* s
);
375 extern Okay
_elf64_cookscn(Elf_Scn
* s
);
376 extern Dnode
*_elf_dnode(void);
377 extern Elf_Data
*_elf_locked_getdata(Elf_Scn
*, Elf_Data
*);
378 extern size_t _elf32_entsz(Elf
*elf
, Elf32_Word
, unsigned);
379 extern size_t _elf64_entsz(Elf
*elf
, Elf64_Word
, unsigned);
380 extern Okay
_elf_inmap(Elf
*);
381 extern char *_elf_outmap(int, size_t, unsigned *);
382 extern size_t _elf_outsync(int, char *, size_t, unsigned);
383 extern size_t _elf32_msize(Elf_Type
, unsigned);
384 extern size_t _elf64_msize(Elf_Type
, unsigned);
385 extern Elf_Type
_elf32_mtype(Elf
*, Elf32_Word
, unsigned);
386 extern Elf_Type
_elf64_mtype(Elf
*, Elf64_Word
, unsigned);
387 extern char *_elf_read(int, off_t
, size_t);
388 extern Snode32
*_elf32_snode(void);
389 extern Snode64
*_elf64_snode(void);
390 extern void _elf_unmap(char *, size_t);
391 extern Okay
_elf_vm(Elf
*, size_t, size_t);
392 extern int _elf32_ehdr(Elf
*, int);
393 extern int _elf32_phdr(Elf
*, int);
394 extern int _elf32_shdr(Elf
*, int);
395 extern int _elf64_ehdr(Elf
*, int);
396 extern int _elf64_phdr(Elf
*, int);
397 extern int _elf64_shdr(Elf
*, int);
398 extern int _elf_byte
;
399 extern const Elf32_Ehdr _elf32_ehdr_init
;
400 extern const Elf64_Ehdr _elf64_ehdr_init
;
401 extern unsigned _elf_encode
;
402 extern _elf_execfill_func_t
*_elf_execfill_func
;
403 extern void _elf_seterr(Msg
, int);
404 extern const Snode32 _elf32_snode_init
;
405 extern const Snode64 _elf64_snode_init
;
406 extern const Dnode _elf_dnode_init
;
407 extern unsigned _elf_work
;
408 extern mutex_t _elf_globals_mutex
;
409 extern off_t
_elf64_update(Elf
* elf
, Elf_Cmd cmd
);
410 extern int _elf64_swap_wrimage(Elf
*elf
);