ELF_BEGIN(3ELF)             ELF Library Functions            ELF_BEGIN(3ELF)
NAME
       elf_begin, elf_end, elf_memory, elf_next, elf_rand - process ELF
       object files
SYNOPSIS
       cc [ 
flag... ] 
file ... 
-lelf [ 
library ... ]
       #include <libelf.h>       
Elf *elf_begin(
int fildes, 
Elf_Cmd cmd, 
Elf *ref);       
int elf_end(
Elf *elf);       
Elf *elf_memory(
char *image, 
size_t sz);       
Elf_Cmd elf_next(
Elf *elf);       
size_t elf_rand(
Elf *elf, 
size_t offset);
DESCRIPTION
       The 
elf_begin(), 
elf_end(), 
elf_memory(), 
elf_next(), and 
elf_rand()       functions work together to process Executable and Linking Format
       (ELF) object files, either individually or as members of archives.
       After obtaining an 
ELF descriptor from 
elf_begin() or 
elf_memory(),
       the program can read an existing file, update an existing file, or
       create a new file. The 
fildes argument is an open file descriptor
       that 
elf_begin() uses for reading or writing. The 
elf argument is an       
ELF descriptor previously returned from 
elf_begin(). The initial file
       offset (see 
lseek(2)) is unconstrained, and the resulting file offset
       is undefined.
       The 
cmd argument can take the following values:       
ELF_C_NULL                      When a program sets 
cmd to this value, 
elf_begin()                      returns a null pointer, without opening a new
                      descriptor. 
ref is ignored for this command. See the
                      examples below for more information.       
ELF_C_READ                      When a program wants to examine the contents of an
                      existing file, it should set 
cmd to this value.
                      Depending on the value of 
ref, this command examines
                      archive members or entire files. Three cases can
                      occur.
                          o      If 
ref is a null pointer, 
elf_begin()                                 allocates a new 
ELF descriptor and prepares
                                 to process the entire file. If the file
                                 being read is an archive, 
elf_begin() also
                                 prepares the resulting descriptor to
                                 examine the initial archive member on the
                                 next call to 
elf_begin(), as if the program
                                 had used  
elf_next() or 
elf_rand() to
                                 ``move'' to the initial member.
                          o      If 
ref is a non-null descriptor associated
                                 with an archive file, 
elf_begin() lets a
                                 program obtain a separate 
ELF descriptor
                                 associated with an individual member. The
                                 program should have used 
elf_next() or                                 
elf_rand() to position 
ref appropriately
                                 (except for the initial member, which                                 
elf_begin() prepares; see the example
                                 below). In this case, 
fildes should be the
                                 same file descriptor used for the parent
                                 archive.
                          o      If 
ref is a non-null 
ELF descriptor that is
                                 not an archive, 
elf_begin() increments the
                                 number of activations for the descriptor
                                 and returns 
ref, without allocating a new
                                 descriptor and without changing the
                                 descriptor's read/write permissions. To
                                 terminate the descriptor for 
ref, the
                                 program must call 
elf_end() once for each
                                 activation. See the examples below for more
                                 information.       
ELF_C_RDWR                      This command duplicates the actions of 
ELF_C_READ and
                      additionally allows the program to update the file
                      image (see 
elf_update(3ELF)). Using 
ELF_C_READ gives a
                      read-only view of the file, while 
ELF_C_RDWR lets the
                      program read 
and write the file. 
ELF_C_RDWR is not
                      valid for archive members. If  
ref is non-null, it
                      must have been created with the 
ELF_C_RDWR command.       
ELF_C_WRITE                      If the program wants to ignore previous file contents,
                      presumably to create a new file, it should set 
cmd to
                      this value. 
ref is ignored for this command.
       The 
elf_begin() function operates on all files (including files with
       zero bytes), providing it can allocate memory for its internal
       structures and read any necessary information from the file. Programs
       reading object files can call 
elf_kind(3ELF) or 
elf32_getehdr(3ELF)       to determine the file type (only object files have an 
ELF header). If
       the file is an archive with no more members to process, or an error
       occurs, 
elf_begin() returns a null pointer. Otherwise, the return
       value is a non-null 
ELF descriptor.
       Before the first call to 
elf_begin(), a program must call       
elf_version() to coordinate versions.
       The 
elf_end() function is used to terminate an 
ELF descriptor, 
elf,
       and to deallocate data associated with the descriptor. Until the
       program terminates a descriptor, the data remain allocated. A null
       pointer is allowed as an argument, to simplify error handling. If the
       program wants to write data associated with the 
ELF descriptor to the
       file, it must use 
elf_update() before calling 
elf_end().
       Calling 
elf_end() removes one activation and returns the remaining
       activation count. The library does not terminate the descriptor until
       the activation count reaches 
0. Consequently, a 
0 return value
       indicates the 
ELF descriptor is no longer valid.
       The 
elf_memory() function returns a pointer to an 
ELF descriptor.
       The 
ELF image has read operations enabled ( 
ELF_C_READ). The 
image       argument is a pointer to an image of the Elf file mapped into memory.
       The 
sz argument is the size of the 
ELF image. An 
ELF image that is
       mapped in with 
elf_memory() can be read and modified, but the 
ELF       image size cannot be changed.
       The 
elf_next() function provides sequential access to the next
       archive member. Having an 
ELF descriptor, 
elf, associated with an
       archive member, 
elf_next() prepares the containing archive to access
       the following member when the program calls 
elf_begin(). After
       successfully positioning an archive for the next member, 
elf_next()       returns the value 
ELF_C_READ. Otherwise, the open file was not an
       archive, 
elf was 
NULL, or an error occurred, and the return value is       
ELF_C_NULL. In either case, the return value can be passed as an
       argument to 
elf_begin(), specifying the appropriate action.
       The 
elf_rand() function provides random archive processing, preparing       
elf to access an arbitrary archive member. The 
elf argument must be a
       descriptor for the archive itself, not a member within the archive.
       The 
offset argument specifies the byte offset from the beginning of
       the archive to the archive header of the desired member. See       
elf_getarsym(3ELF) for more information about archive member offsets.
       When 
elf_rand() works, it returns 
offset. Otherwise, it returns 
0,
       because an error occurred, 
elf was  
NULL, or the file was not an
       archive (no archive member can have a zero offset). A program can mix
       random and sequential archive processing.
   System Services
       When processing a file, the library decides when to read or write the
       file, depending on the program's requests. Normally, the library
       assumes the file descriptor remains usable for the life of the 
ELF       descriptor. If, however, a program must process many files
       simultaneously and the underlying operating system limits the number
       of open files, the program can use 
elf_cntl() to let it reuse file
       descriptors. After calling 
elf_cntl() with appropriate arguments, the
       program can close the file descriptor without interfering with the
       library.
       All data associated with an 
ELF descriptor remain allocated until       
elf_end() terminates the descriptor's last activation. After the
       descriptors have been terminated, the storage is released; attempting
       to reference such data gives undefined behavior. Consequently, a
       program that deals with multiple input (or output) files must keep
       the 
ELF descriptors active until it finishes with them.
EXAMPLES
       Example 1: A sample program of calling the elf_begin() function.
       A prototype for reading a file appears on the next page. If the file
       is a simple object file, the program executes the loop one time,
       receiving a null descriptor in the second iteration. In this case,
       both 
elf and 
arf will have the same value, the activation count will
       be 
2, and the program calls 
elf_end() twice to terminate the
       descriptor. If the file is an archive, the loop processes each
       archive member in turn, ignoring those that are not object files.         
if (elf_version(EV_CURRENT) == EV_NONE)         {              /* library out of date */              /* recover from error */         }         cmd = ELF_C_READ;         arf = elf_begin(fildes, cmd, (Elf *)0);         while ((elf = elf_begin(fildes, cmd, arf)) != 0)         {              if ((ehdr = elf32_getehdr(elf)) != 0)              {                   /* process the file ... */              }              cmd = elf_next(elf);              elf_end(elf);         }         elf_end(arf);       Alternatively, the next example illustrates random archive
       processing. After identifying the file as an archive, the program
       repeatedly processes archive members of interest. For clarity, this
       example omits error checking and ignores simple object files.
       Additionally, this fragment preserves the 
ELF descriptors for all
       archive members, because it does not call 
elf_end() to terminate
       them.         
elf_version(EV_CURRENT);         arf = elf_begin(fildes, ELF_C_READ, (Elf *)0);         if (elf_kind(arf) != ELF_K_AR)         {              /* not an archive */         }         /* initial processing */         /* set offset = ... for desired member header */         while (elf_rand(arf, offset) == offset)         {              if ((elf = elf_begin(fildes, ELF_C_READ, arf)) == 0)                   break;              if ((ehdr = elf32_getehdr(elf)) != 0)              {                   /* process archive member ... */              }              /* set offset = ... for desired member header */         }       An archive starts with a ``magic string'' that has 
SARMAG bytes; the
       initial archive member follows immediately. An application could thus
       provide the following function to rewind an archive (the function
       returns 
-1 for errors and 
0 otherwise).         
#include <ar.h>         #include <libelf.h>         int         rewindelf(Elf *elf)         {              if (elf_rand(elf, (size_t)SARMAG) == SARMAG)                   return 0;              return -1;         }       The following outline shows how one might create a new 
ELF file. This
       example is simplified to show the overall flow.         
elf_version(EV_CURRENT);         fildes = open("path/name", O_RDWR|O_TRUNC|O_CREAT, 0666);         if ((elf = elf_begin(fildes, ELF_C_WRITE, (Elf *)0)) == 0)              return;         ehdr = elf32_newehdr(elf);         phdr = elf32_newphdr(elf, count);         scn = elf_newscn(elf);         shdr = elf32_getshdr(scn);         data = elf_newdata(scn);         elf_update(elf, ELF_C_WRITE);         elf_end(elf);       Finally, the following outline shows how one might update an existing       
ELF file. Again, this example is simplified to show the overall flow.         
elf_version(EV_CURRENT);         fildes = open("path/name", O_RDWR);         elf = elf_begin(fildes, ELF_C_RDWR, (Elf *)0);         /* add new or delete old information */         ...         /* ensure that the memory image of the file is complete */         elf_update(elf, ELF_C_NULL);         elf_update(elf, ELF_C_WRITE);   /* update file */         elf_end(elf);       Notice that both file creation examples open the file with write 
and       read permissions. On systems that support 
mmap(2), the library uses
       it to enhance performance, and 
mmap(2) requires a readable file
       descriptor.  Although the library can use a write-only file
       descriptor, the application will not obtain the performance
       advantages of 
mmap(2).
ATTRIBUTES
       See 
attributes(7) for descriptions of the following attributes:
       +--------------------+-----------------+
       |  ATTRIBUTE TYPE    | ATTRIBUTE VALUE |
       +--------------------+-----------------+
       |Interface Stability | Stable          |
       +--------------------+-----------------+
       |MT-Level            | MT-Safe         |
       +--------------------+-----------------+
SEE ALSO
       creat(2), 
lseek(2), 
mmap(2), 
open(2), 
elf(3ELF), 
elf32_getehdr(3ELF),       
elf_cntl(3ELF), 
elf_getarhdr(3ELF), 
elf_getarsym(3ELF),       
elf_getbase(3ELF), 
elf_getdata(3ELF), 
elf_getscn(3ELF),       
elf_kind(3ELF), 
elf_rawfile(3ELF), 
elf_update(3ELF),       
elf_version(3ELF), 
ar.h(3HEAD), 
libelf(3LIB), 
attributes(7)                                July 11, 2001                ELF_BEGIN(3ELF)