Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ elf_begin(3E) — Dell System V Release 4 Issue 2.2

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

cof2elf(1)

creat(2)

lseek(2)

mmap(2)

open(2)

truncate(2)

elf(3E)

ar(4)



elf_begin(3E)             UNIX System V(ELF Library)              elf_begin(3E)


NAME
      elfbegin - make a file descriptor

SYNOPSIS
      cc [flag ...] file ...  -lelf [library ...]

      #include <libelf.h>
      Elf *elfbegin(int fildes, ElfCmd cmd, Elf *ref);

DESCRIPTION
      elfbegin, elfnext, elfrand, and elfend work together to process ELF
      object files, either individually or as members of archives.  After
      obtaining an ELF descriptor from elfbegin, the program may read an
      existing file, update an existing file, or create a new file.  fildes is
      an open file descriptor that elfbegin 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.

      ELFCNULL      When a program sets cmd to this value, elfbegin returns
                      a null pointer, without opening a new descriptor.  ref is
                      ignored for this command.  See elfnext(3E) and the
                      examples below for more information.

      ELFCREAD      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, elfbegin allocates a
                      new ELF descriptor and prepares to process the entire
                      file.  If the file being read is an archive, elfbegin
                      also prepares the resulting descriptor to examine the
                      initial archive member on the next call to elfbegin, as
                      if the program had used elfnext or elfrand to ``move''
                      to the initial member.

                      Second, if ref is a non-null descriptor associated with
                      an archive file, elfbegin lets a program obtain a
                      separate ELF descriptor associated with an individual
                      member.  The program should have used elfnext or
                      elfrand to position ref appropriately (except for the
                      initial member, which elfbegin 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, elfbegin 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


10/89                                                                    Page 1







elf_begin(3E)             UNIX System V(ELF Library)              elf_begin(3E)


                      descriptor for ref, the program must call elfend once
                      for each activation.  See elfnext(3E) and the examples
                      below for more information.

      ELFCRDWR      This command duplicates the actions of ELFCREAD and
                      additionally allows the program to update the file image
                      [see elfupdate(3E)].  That is, using ELFCREAD gives a
                      read-only view of the file, while ELFCRDWR lets the
                      program read and write the file.  ELFCRDWR is not valid
                      for archive members.  If ref is non-null, it must have
                      been created with the ELFCRDWR command.

      ELFCWRITE     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.

      elfbegin ``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 elfkind or elfgetehdr 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, elfbegin returns a null pointer.
      Otherwise, the return value is a non-null ELF descriptor.

      Before the first call to elfbegin, a program must call elfversion to
      coordinate versions.

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 elfcntl to let it reuse file descriptors.  After calling
      elfcntl 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 elfend
      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 elfend 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.


Page 2                                                                    10/89







elf_begin(3E)             UNIX System V(ELF Library)              elf_begin(3E)


           if (elfversion(EVCURRENT) == EVNONE)
           {
                   /* library out of date */
                   /* recover from error */
           }
           cmd = ELFCREAD;
           arf = elfbegin(fildes, cmd, (Elf *)0);
           while ((elf = elfbegin(fildes, cmd, arf)) != 0)
           {
                   if ((ehdr = elf32getehdr(elf)) != 0)
                   {
                           /* process the file ... */
                   }
                   cmd = elfnext(elf);
                   elfend(elf);
           }
           elfend(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 elfend to terminate them.

           elfversion(EVCURRENT);
           arf = elfbegin(fildes, ELFCREAD, (Elf *)0);
           if (elfkind(arf) != ELFKAR)
           {
                   /* not an archive */
           }
           /* initial processing */
           /* set offset = ... for desired member header */
           while (elfrand(arf, offset) == offset)
           {
                   if ((elf = elfbegin(fildes, ELFCREAD, arf)) == 0)
                           break;
                   if ((ehdr = elf32getehdr(elf)) != 0)
                   {
                           /* process archive member ... */
                   }
                   /* set offset = ... for desired member header */
           }

      The following outline shows how one might create a new ELF file.  This
      example is simplified to show the overall flow.








10/89                                                                    Page 3







elf_begin(3E)             UNIX System V(ELF Library)              elf_begin(3E)


           elfversion(EVCURRENT);
           fildes = open("path/name", ORDWR|OTRUNC|OCREAT, 0666);
           if ((elf = elfbegin(fildes, ELFCWRITE, (Elf *)0)) == 0)
                   return;
           ehdr = elf32newehdr(elf);
           phdr = elf32newphdr(elf, count);
           scn = elfnewscn(elf);
           shdr = elf32getshdr(scn);
           data = elfnewdata(scn);
           elfupdate(elf, ELFCWRITE);
           elfend(elf);

      Finally, the following outline shows how one might update an existing ELF
      file.  Again, this example is simplified to show the overall flow.

           elfversion(EVCURRENT);
           fildes = open("path/name", ORDWR);
           elf = elfbegin(fildes, ELFCRDWR, (Elf *)0);

           /* add new or delete old information ... */

           close(creat("path/name", 0666));
           elfupdate(elf, ELFCWRITE);
           elfend(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(2)].  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.

SEE ALSO
      cof2elf(1), creat(2), lseek(2), mmap(2), open(2), truncate(2), elf(3E),
      elfcntl(3E), elfend(3E), elfgetarhdr(3E), elfgetbase(3E),
      elfgetdata(3E), elfgetehdr(3E), elfgetphdr(3E), elfgetscn(3E),
      elfkind(3E), elfnext(3E), elfrand(3E), elfrawfile(3E),
      elfupdate(3E), elfversion(3E), ar(4)

NOTES
      COFF is an object file format that preceded ELF . When a program calls
      elfbegin 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 elfbegin, file offsets and
      addresses in the ELF header, the program headers, and the section headers


Page 4                                                                    10/89







elf_begin(3E)             UNIX System V(ELF Library)              elf_begin(3E)


      retain the original COFF values [see elfgetehdr, elfgetphdr, and
      elfgetshdr].  A program may call elfupdate to adjust these values
      (without writing the file), and the library will then present a
      consistent, ELF view of the file.  Data obtained through elfgetdata are
      translated (the COFF symbol table is presented as ELF , etc.).  Data
      viewed through elfrawdata 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.









































10/89                                                                    Page 5





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