1elf_begin(3ELF) ELF Library Functions elf_begin(3ELF)
2
3
4
6 elf_begin, elf_end, elf_memory, elf_next, elf_rand - process ELF object
7 files
8
10 cc [ flag... ] file ... -lelf [ library ... ]
11 #include <libelf.h>
12
13 Elf *elf_begin(int fildes, Elf_Cmd cmd, Elf *ref);
14
15
16 int elf_end(Elf *elf);
17
18
19 Elf *elf_memory(char *image, size_t sz);
20
21
22 Elf_Cmd elf_next(Elf *elf);
23
24
25 size_t elf_rand(Elf *elf, size_t offset);
26
27
29 The elf_begin(), elf_end(), elf_memory(), elf_next(), and elf_rand()
30 functions work together to process Executable and Linking Format (ELF)
31 object files, either individually or as members of archives. After
32 obtaining an ELF descriptor from elf_begin() or elf_memory(), the pro‐
33 gram can read an existing file, update an existing file, or create a
34 new file. The fildes argument is an open file descriptor that
35 elf_begin() uses for reading or writing. The elf argument is an ELF
36 descriptor previously returned from elf_begin(). The initial file off‐
37 set (see lseek(2)) is unconstrained, and the resulting file offset is
38 undefined.
39
40
41 The cmd argument can take the following values:
42
43 ELF_C_NULL When a program sets cmd to this value, elf_begin()
44 returns a null pointer, without opening a new descrip‐
45 tor. ref is ignored for this command. See the examples
46 below for more information.
47
48
49 ELF_C_READ When a program wants to examine the contents of an
50 existing file, it should set cmd to this value. Depend‐
51 ing on the value of ref, this command examines archive
52 members or entire files. Three cases can occur.
53
54 o If ref is a null pointer, elf_begin() allo‐
55 cates a new ELF descriptor and prepares to
56 process the entire file. If the file being
57 read is an archive, elf_begin() also prepares
58 the resulting descriptor to examine the ini‐
59 tial archive member on the next call to
60 elf_begin(), as if the program had used
61 elf_next() or elf_rand() to ``move'' to the
62 initial member.
63
64 o If ref is a non-null descriptor associated
65 with an archive file, elf_begin() lets a pro‐
66 gram obtain a separate ELF descriptor associ‐
67 ated with an individual member. The program
68 should have used elf_next() or elf_rand() to
69 position ref appropriately (except for the
70 initial member, which elf_begin() prepares;
71 see the example below). In this case, fildes
72 should be the same file descriptor used for
73 the parent archive.
74
75 o If ref is a non-null ELF descriptor that is
76 not an archive, elf_begin() increments the
77 number of activations for the descriptor and
78 returns ref, without allocating a new
79 descriptor and without changing the descrip‐
80 tor's read/write permissions. To terminate
81 the descriptor for ref, the program must call
82 elf_end() once for each activation. See the
83 examples below for more information.
84
85
86 ELF_C_RDWR This command duplicates the actions of ELF_C_READ and
87 additionally allows the program to update the file image
88 (see elf_update(3ELF)). Using ELF_C_READ gives a read-
89 only view of the file, while ELF_C_RDWR lets the program
90 read and write the file. ELF_C_RDWR is not valid for ar‐
91 chive members. If ref is non-null, it must have been
92 created with the ELF_C_RDWR command.
93
94
95 ELF_C_WRITE If the program wants to ignore previous file contents,
96 presumably to create a new file, it should set cmd to
97 this value. ref is ignored for this command.
98
99
100
101 The elf_begin() function operates on all files (including files with
102 zero bytes), providing it can allocate memory for its internal struc‐
103 tures and read any necessary information from the file. Programs read‐
104 ing object files can call elf_kind(3ELF) or elf32_getehdr(3ELF) to
105 determine the file type (only object files have an ELF header). If the
106 file is an archive with no more members to process, or an error occurs,
107 elf_begin() returns a null pointer. Otherwise, the return value is a
108 non-null ELF descriptor.
109
110
111 Before the first call to elf_begin(), a program must call elf_version()
112 to coordinate versions.
113
114
115 The elf_end() function is used to terminate an ELF descriptor, elf, and
116 to deallocate data associated with the descriptor. Until the program
117 terminates a descriptor, the data remain allocated. A null pointer is
118 allowed as an argument, to simplify error handling. If the program
119 wants to write data associated with the ELF descriptor to the file, it
120 must use elf_update() before calling elf_end().
121
122
123 Calling elf_end() removes one activation and returns the remaining
124 activation count. The library does not terminate the descriptor until
125 the activation count reaches 0. Consequently, a 0 return value indi‐
126 cates the ELF descriptor is no longer valid.
127
128
129 The elf_memory() function returns a pointer to an ELF descriptor. The
130 ELF image has read operations enabled ( ELF_C_READ). The image argument
131 is a pointer to an image of the Elf file mapped into memory. The sz
132 argument is the size of the ELF image. An ELF image that is mapped in
133 with elf_memory() can be read and modified, but the ELF image size can‐
134 not be changed.
135
136
137 The elf_next() function provides sequential access to the next archive
138 member. Having an ELF descriptor, elf, associated with an archive mem‐
139 ber, elf_next() prepares the containing archive to access the following
140 member when the program calls elf_begin(). After successfully position‐
141 ing an archive for the next member, elf_next() returns the value
142 ELF_C_READ. Otherwise, the open file was not an archive, elf was NULL,
143 or an error occurred, and the return value is ELF_C_NULL. In either
144 case, the return value can be passed as an argument to elf_begin(),
145 specifying the appropriate action.
146
147
148 The elf_rand() function provides random archive processing, preparing
149 elf to access an arbitrary archive member. The elf argument must be a
150 descriptor for the archive itself, not a member within the archive. The
151 offset argument specifies the byte offset from the beginning of the ar‐
152 chive to the archive header of the desired member. See
153 elf_getarsym(3ELF) for more information about archive member offsets.
154 When elf_rand() works, it returns offset. Otherwise, it returns 0,
155 because an error occurred, elf was NULL, or the file was not an ar‐
156 chive (no archive member can have a zero offset). A program can mix
157 random and sequential archive processing.
158
159 System Services
160 When processing a file, the library decides when to read or write the
161 file, depending on the program's requests. Normally, the library
162 assumes the file descriptor remains usable for the life of the ELF
163 descriptor. If, however, a program must process many files simultane‐
164 ously and the underlying operating system limits the number of open
165 files, the program can use elf_cntl() to let it reuse file descriptors.
166 After calling elf_cntl() with appropriate arguments, the program can
167 close the file descriptor without interfering with the library.
168
169
170 All data associated with an ELF descriptor remain allocated until
171 elf_end() terminates the descriptor's last activation. After the
172 descriptors have been terminated, the storage is released; attempting
173 to reference such data gives undefined behavior. Consequently, a pro‐
174 gram that deals with multiple input (or output) files must keep the ELF
175 descriptors active until it finishes with them.
176
178 Example 1 A sample program of calling the elf_begin() function.
179
180
181 A prototype for reading a file appears on the next page. If the file is
182 a simple object file, the program executes the loop one time, receiving
183 a null descriptor in the second iteration. In this case, both elf and
184 arf will have the same value, the activation count will be 2, and the
185 program calls elf_end() twice to terminate the descriptor. If the file
186 is an archive, the loop processes each archive member in turn, ignoring
187 those that are not object files.
188
189
190 if (elf_version(EV_CURRENT) == EV_NONE)
191 {
192 /* library out of date */
193 /* recover from error */
194 }
195 cmd = ELF_C_READ;
196 arf = elf_begin(fildes, cmd, (Elf *)0);
197 while ((elf = elf_begin(fildes, cmd, arf)) != 0)
198 {
199 if ((ehdr = elf32_getehdr(elf)) != 0)
200 {
201 /* process the file ... */
202 }
203 cmd = elf_next(elf);
204 elf_end(elf);
205 }
206 elf_end(arf);
207
208
209
210 Alternatively, the next example illustrates random archive processing.
211 After identifying the file as an archive, the program repeatedly pro‐
212 cesses archive members of interest. For clarity, this example omits
213 error checking and ignores simple object files. Additionally, this
214 fragment preserves the ELF descriptors for all archive members, because
215 it does not call elf_end() to terminate them.
216
217
218 elf_version(EV_CURRENT);
219 arf = elf_begin(fildes, ELF_C_READ, (Elf *)0);
220 if (elf_kind(arf) != ELF_K_AR)
221 {
222 /* not an archive */
223 }
224 /* initial processing */
225 /* set offset = ... for desired member header */
226 while (elf_rand(arf, offset) == offset)
227 {
228 if ((elf = elf_begin(fildes, ELF_C_READ, arf)) == 0)
229 break;
230 if ((ehdr = elf32_getehdr(elf)) != 0)
231 {
232 /* process archive member ... */
233 }
234 /* set offset = ... for desired member header */
235 }
236
237
238
239 An archive starts with a ``magic string'' that has SARMAG bytes; the
240 initial archive member follows immediately. An application could thus
241 provide the following function to rewind an archive (the function
242 returns −1 for errors and 0 otherwise).
243
244
245 #include <ar.h>
246 #include <libelf.h>
247 int
248 rewindelf(Elf *elf)
249 {
250 if (elf_rand(elf, (size_t)SARMAG) == SARMAG)
251 return 0;
252 return −1;
253 }
254
255
256
257 The following outline shows how one might create a new ELF file. This
258 example is simplified to show the overall flow.
259
260
261 elf_version(EV_CURRENT);
262 fildes = open("path/name", O_RDWR|O_TRUNC|O_CREAT, 0666);
263 if ((elf = elf_begin(fildes, ELF_C_WRITE, (Elf *)0)) == 0)
264 return;
265 ehdr = elf32_newehdr(elf);
266 phdr = elf32_newphdr(elf, count);
267 scn = elf_newscn(elf);
268 shdr = elf32_getshdr(scn);
269 data = elf_newdata(scn);
270 elf_update(elf, ELF_C_WRITE);
271 elf_end(elf);
272
273
274
275 Finally, the following outline shows how one might update an existing
276 ELF file. Again, this example is simplified to show the overall flow.
277
278
279 elf_version(EV_CURRENT);
280 fildes = open("path/name", O_RDWR);
281 elf = elf_begin(fildes, ELF_C_RDWR, (Elf *)0);
282 /* add new or delete old information */
283 ...
284 /* ensure that the memory image of the file is complete */
285 elf_update(elf, ELF_C_NULL);
286 elf_update(elf, ELF_C_WRITE); /* update file */
287 elf_end(elf);
288
289
290
291 Notice that both file creation examples open the file with write and
292 read permissions. On systems that support mmap(2), the library uses it
293 to enhance performance, and mmap(2) requires a readable file descrip‐
294 tor. Although the library can use a write-only file descriptor, the
295 application will not obtain the performance advantages of mmap(2).
296
297
299 See attributes(5) for descriptions of the following attributes:
300
301
302
303
304 ┌─────────────────────────────┬─────────────────────────────┐
305 │ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
306 ├─────────────────────────────┼─────────────────────────────┤
307 │Interface Stability │Stable │
308 ├─────────────────────────────┼─────────────────────────────┤
309 │MT-Level │MT-Safe │
310 └─────────────────────────────┴─────────────────────────────┘
311
313 creat(2), lseek(2), mmap(2), open(2), ar.h(3HEAD), elf(3ELF),
314 elf32_getehdr(3ELF), elf_cntl(3ELF), elf_getarhdr(3ELF),
315 elf_getarsym(3ELF), elf_getbase(3ELF), elf_getdata(3ELF),
316 elf_getscn(3ELF), elf_kind(3ELF), elf_rawfile(3ELF), elf_update(3ELF),
317 elf_version(3ELF), libelf(3LIB), attributes(5)
318
319
320
321SunOS 5.11 11 Jul 2001 elf_begin(3ELF)