8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sgs / libelf / common / decl.h
blob9ccca2e5a91501490462a5eb1f9ed635f40c0ee1
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
21 /* Copyright (c) 1988 AT&T */
22 /* All Rights Reserved */
26 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
29 #ifndef _DECL_H
30 #define _DECL_H
32 #include <thread.h>
33 #include <_libelf.h>
34 #include <sys/machelf.h>
35 #include <msg.h>
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
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;
51 * Data alignment
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.
62 typedef union
64 Elf32_Word w;
65 Elf32_Addr a;
66 Elf32_Off o;
67 } Elf32;
69 typedef union {
70 Elf64_Xword x;
71 Elf64_Word w;
72 Elf64_Addr a;
73 Elf64_Off o;
74 Elf_Void *p;
75 } Elf64;
79 * Memory allocation
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.
89 * Data descriptor
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
102 * have null db_raw.
105 struct Dnode
107 Elf_Data db_data;
108 Elf_Scn *db_scn; /* section parent */
109 Dnode *db_next;
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 */
126 * Section descriptor
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.
133 struct Elf_Scn
135 mutex_t s_mutex;
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)
155 #define SCNLOCK(x) \
156 if (elf_threaded) \
157 (void) mutex_lock(&((Elf_Scn *)x)->s_mutex);
159 #define SCNUNLOCK(x) \
160 if (elf_threaded) \
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 */
193 struct Snode32
195 Elf_Scn sb_scn; /* must be first */
196 Elf32_Shdr sb_shdr;
199 struct Snode64
201 Elf_Scn sb_scn; /* must be first */
202 Elf64_Shdr sb_shdr;
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.
217 typedef enum
219 ES_FRESH = 0, /* unchanged */
220 ES_COOKED, /* translated */
221 ES_FROZEN /* raw, can't be translated */
222 } Status;
226 * Elf descriptor
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.
262 struct Elf
264 rwlock_t ed_rwlock;
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) \
309 if (elf_threaded) \
310 (void) rw_rdlock(&((Elf *)e)->ed_rwlock);
312 #define ELFWLOCK(e) \
313 if (elf_threaded) \
314 (void) rw_wrlock(&((Elf *)e)->ed_rwlock);
316 #define ELFUNLOCK(e) \
317 if (elf_threaded) \
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 */
336 typedef enum
338 OK_YES = 0,
339 OK_NO = ~0
340 } Okay;
342 #define _(a) a
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); \
355 a = b; \
356 (void) mutex_unlock(&_elf_globals_mutex); \
357 } else \
358 a = b;
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);
412 #ifdef __cplusplus
414 #endif
416 #endif /* _DECL_H */