Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ elf_begin(3E) — UnixWare 2.01

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

ar(4)

cof2elf(1)

creat(2)

elf(3E)

elf_cntl(3E)

elf_end(3E)

elf_getarhdr(3E)

elf_getbase(3E)

elf_getdata(3E)

elf_getehdr(3E)

elf_getphdr(3E)

elf_getscn(3E)

elf_kind(3E)

elf_next(3E)

elf_rand(3E)

elf_rawfile(3E)

elf_update(3E)

elf_version(3E)

lseek(2)

mmap(2)

open(2)

truncate(3C)






       elf_begin(3E)                                          elf_begin(3E)


       NAME
             elf_begin - make a file descriptor

       SYNOPSIS
             cc [flag . . . ] file . . . -lelf [library] . . .
             #include <libelf.h>
             Elf *elf_begin(int fildes, Elf_Cmd cmd, Elf *ref);

       DESCRIPTION
             elf_begin, elf_next, elf_rand, and elf_end work together to
             process ELF object files, either individually or as members of
             archives.  After obtaining an ELF descriptor from elf_begin,
             the program may read an existing file, update an existing
             file, or create a new file.  fildes is an open file descriptor
             that elf_begin uses for reading or writing.  The initial file
             offset [see lseek(2)] is unconstrained, and the resulting file
             offset is undefined.

             cmd may have 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 elf_next(3E) and the
                             examples below for more information.

             ELF_C_READ      When a program wishes 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.

                             First, 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.

                             Second, 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


                           Copyright 1994 Novell, Inc.               Page 1













      elf_begin(3E)                                          elf_begin(3E)


                            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.

                            Finally, 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 elf_next(3E) and 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(3E)].
                            That is, 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 wishes to ignore previous file
                            contents, presumably to create a new file, it
                            should set cmd to this value.  ref is ignored
                            for this command.

            elf_begin ``works'' 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 thus may call elf_kind or
            elf_getehdr 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.




                          Copyright 1994 Novell, Inc.               Page 2













       elf_begin(3E)                                          elf_begin(3E)


          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
             may 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
             A prototype for reading a file appears below.  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 two, 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.



















                           Copyright 1994 Novell, Inc.               Page 3













      elf_begin(3E)                                          elf_begin(3E)


                 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 */
                 }




                          Copyright 1994 Novell, Inc.               Page 4













       elf_begin(3E)                                          elf_begin(3E)


             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 . . . */

                  close(creat("path/name", 0666));
                  elf_update(elf, ELF_C_WRITE);
                  elf_end(elf);

             In the example above, the call to creat truncates the file,
             thus ensuring the resulting file will have the ``right'' size.
             Without truncation, the updated file might be as big as the
             original, even if information were deleted.  The library
             truncates the file, if it can, with ftruncate [see
             truncate(3C)].  Some systems, however, do not support
             ftruncate, and the call to creat protects against this.

             Notice that both file creation examples open the file with
             write and read permissions.  On systems that support mmap, the
             library uses it to enhance performance, and mmap 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.





                           Copyright 1994 Novell, Inc.               Page 5













      elf_begin(3E)                                          elf_begin(3E)


      REFERENCES
            ar(4), cof2elf(1), creat(2), elf(3E), elf_cntl(3E),
            elf_end(3E), elf_getarhdr(3E), elf_getbase(3E),
            elf_getdata(3E), elf_getehdr(3E), elf_getphdr(3E),
            elf_getscn(3E), elf_kind(3E), elf_next(3E), elf_rand(3E),
            elf_rawfile(3E), elf_update(3E), elf_version(3E), lseek(2),
            mmap(2), open(2), truncate(3C)

      NOTICES
            COFF is an object file format that preceded ELF on some
            computer architectures (Intel, for example).  For these
            architectures, when a program calls elf_begin on a COFF file,
            the library translates COFF structures to their ELF
            equivalents, allowing programs to read (but not to write) a
            COFF file as if it were ELF . This conversion happens only to
            the memory image and not to the file itself.  After the
            initial elf_begin, file offsets and addresses in the ELF
            header, the program headers, and the section headers retain
            the original COFF values [see elf_getehdr, elf_getphdr, and
            elf_getshdr].  A program may call elf_update to adjust these
            values (without writing the file), and the library will then
            present a consistent, ELF view of the file.  Data obtained
            through elf_getdata are translated (the COFF symbol table is
            presented as ELF , and so on).  Data viewed through
            elf_rawdata undergo no conversion, allowing the program to
            view the bytes from the file itself.

            Some COFF debugging information is not translated, though this
            does not affect the semantics of a running program.

            Although the ELF library supports COFF , programmers are
            strongly encouraged to recompile their programs, obtaining ELF
            object files.















                          Copyright 1994 Novell, Inc.               Page 6








Typewritten Software • bear@typewritten.org • Edmonds, WA 98026