elf_getdata, elf_newdata, elf_rawdata -- get section data


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

#include <libelf.h>

Elf_Data *elf_getdata(Elf_Scn *scn, Elf_Data *data);

Elf_Data *elf_newdata(Elf_Scn *scn);

Elf_Data *elf_rawdata(Elf_Scn *scn, Elf_Data *data);


elf_getdata- retrieves data from a section, translating the data from file representations into memory representations.

elf_newdata- creates a new data descriptor for a section.

elf_rawdata- retrieves data from a section without interpreting it.

These functions access and manipulate the data associated with a section descriptor, scn. When the function is reading an existing file, each section has a single data buffer associated with it. However, a program may build a new section in pieces, composing the new data from several data buffers. Therefore, think of the data for a section as a list of buffers, each available through a data descriptor.

elf_getdata(S) lets a program step through a section's data list. If the incoming data descriptor, data, is null, elf_getdata( ) returns the first buffer associated with the section. If not null, data is a data descriptor associated with scn, and elf_getdata( ) gives the program access by returning a pointer to the next data element for the section. If scn is null or an error occurs, elf_getdata( ) returns a null pointer.

elf_getdata( ) translates the data from file representations into memory representations (see elf_xlate(S)). Then it presents objects with memory data types to the program, based on the file's class (see elf(S)). The working library version (see elf_version(S)) specifies which version of the memory structures to present to the program.

elf_newdata(S)) creates a new data descriptor for a section and appends it to any data elements already associated with the section. As described below, the new data descriptor appears empty, indicating that the element holds no data.

For convenience, the descriptor's type (d_type below) is set to ELF_T_BYTE, and the version (d_version below) is set to the working version. The program must set or change the descriptor members as needed. This function implicitly sets the bit ELF_F_DIRTY for the section's data (see elf_flag(S)). If scn is null or an error occurs, elf_newdata( ) returns a null pointer.

elf_rawdata(S) differs from elf_getdata( ) by returning only uninterpreted bytes, regardless of the section type. Generally, use this function only to retrieve a section image from a file being read, and then only when a program must avoid the automatic data translation described below.

Moreover, a program can not close or disable (see elf_cntl(S)) the file descriptor associated with elf before the initial raw operation, because elf_rawdata( ) might read the data from the file to ensure it doesn't interfere with elf_getdata( ).

For a related routine that applies to the entire file, see elf_rawfile(S).

If elf_getdata( ) provides the right translation, use it instead of elf_rawdata( ).

If scn is null or an error occurs, elf_rawdata( ) returns a null pointer.

The Elf_Data(S) structure includes the following members:

   	void		*d_buf;
   	Elf_Type	d_type;
   	size_t		d_size;
   	off_t		d_off;
   	size_t		d_align;
   	unsigned	d_version;
These members are available for direct manipulation by the program. Descriptions appear below.

A pointer to the data buffer resides here. A data element with no data has a null pointer.

This member specifies the type of data in the data buffer. The type determines how to interpret the section contents, as summarized below.

This member holds the total size, in bytes, of the memory occupied by the data. This may differ from the size as represented in the file. The size is zero if no data exist. (See below for the discussion of SHT_NOBITS.)

This member gives the offset, within the section, at which the buffer resides. This offset is relative to the section of the file, not the memory object.

This member holds the buffer's required alignment from the beginning of the section. That is, d_off is a multiple of this value. For example, if the value is four, the beginning of the buffer is four-byte-aligned within the section. Moreover, the entire section is aligned to the maximum of its constituents, thus ensuring proper alignment for a buffer within the section and within the file.

This member holds the version number of the objects in the buffer. When the library originally read the data from the object file, it used the working version number to control the translation to memory objects.

Data alignment

As mentioned above, data buffers within a section have explicit alignment constraints. Consequently, adjacent buffers sometimes do not abut, causing ``holes'' within a section. Programs that create output files have two ways of dealing with those holes.

First, the program can use elf_fill(S) to tell the library how to set the intervening bytes. When the library must generate gaps in the file, it uses the fill byte to initialize the data there. The library's initial fill value is zero, but elf_fill( ) lets the application change that.

Second, the application can generate its own data buffers to occupy the gaps, filling the gaps with values appropriate for the section being created. A program can use different fill values for different sections. For example, it can set text sections' bytes to no-operation instructions, while filling data section holes with zero. When you use this technique, the library finds no holes to fill, because the application has eliminated them.

Section and memory types

elf_getdata( ) interprets the data in sections according to the section type specified in the section header, available through elf_getshdr(S). The following table shows the section types and how the library represents them with memory data types for the 32-bit file class. Other classes have similar tables. By implication, memory data type controls translation by elf_xlate( ).

Section Type Elf_Type 32-Bit Type
SHT_NOBITS ELF_T_BYTE unsigned char
SHT_NOTE ELF_T_BYTE unsigned char
SHT_NULL none none
SHT_STRTAB ELF_T_BYTE unsigned char
other ELF_T_BYTE unsigned char

 |Section Type  | Elf_Type    | 32-Bit Type    |
 |SHT_DYNAMIC   | ELF_T_DYN   | Elf32_Dyn      |
 |SHT_DYNSYM    | ELF_T_SYM   | Elf32_Sym      |
 |SHT_HASH      | ELF_T_WORD  | Elf32_Word     |
 |SHT_NOBITS    | ELF_T_BYTE  | unsigned char  |
 |SHT_NOTE      | ELF_T_BYTE  | unsigned char  |
 |SHT_NULL      | none        | none           |
 |SHT_PROGBITS  | ELF_T_BYTE  | unsigned char  |
 |SHT_REL       | ELF_T_REL   | Elf32_Rel      |
 |SHT_RELA      | ELF_T_RELA  | Elf32_Rela     |
 |SHT_STRTAB    | ELF_T_BYTE  | unsigned char  |
 |SHT_SYMTAB    | ELF_T_SYM   | Elf32_Sym      |
 |other         | ELF_T_BYTE  | unsigned char  |
elf_rawdata( ) creates a buffer with type ELF_T_BYTE.

As mentioned above, the program's working version controls what structures the library creates for the application. The library similarly interprets section types according to the versions.

If the library does not recognize the section type, it presents an untranslated buffer of type ELF_T_BYTE.

If a section type belongs to a version newer than the application's working version, the library does not translate the section data. The application cannot know the data format, so the library presents an untranslated buffer of type ELF_T_BYTE.

A section with a special type, SHT_NOBITS, occupies no space in an object file, even when the section header indicates a non-zero size. elf_getdata( ) and elf_rawdata( ) work properly on such a section, setting the data structure to have a null buffer pointer and the type SHT_NOBITS. Although no data is present, the d_size value is set to the size specified in the section header. If your program creates a new section of type SHT_NOBITS, use elf_newdata( ) to add data buffers to the section. For these ``empty'' data buffers, set the d_size members to the desired size and the d_buf members to null.


Error conditions are identified through the routine elf_error(S).


The following fragment gets the string table that holds section names (ignoring error checking). See elf_strptr(S) for a variation of string table handling.

   ehdr = elf32_getehdr(elf);
   scn = elf_getscn(elf, (size_t)ehdr->e_shstrndx);
   shdr = elf32_getshdr(scn);
   if (shdr->sh_type != SHT_STRTAB)
   	/* not a string table */
   data = 0;
   if ((data = elf_getdata(scn, data)) == 0 || data->d_size == 0)
   	/* error or no data */

The e_shstrndx(S) member in an ELF header holds the section table index of the string table. The program gets a section descriptor for that section, verifies that it is a string table, and then retrieves the data. When this fragment finishes, data->d_buf points at the first byte of the string table, and data->d_size holds the string table's size in bytes.

See also

elf(S), elf_cntl(S), elf_fill(S), elf_flag(S), elf_getehdr(S), elf_getscn(S), elf_getshdr(S), elf_rawfile(S), elf_strptr(S), elf_version(S), elf_xlate(S)

Standards conformance

elf_getdata(S), elf_newdata(S), and elf_rawdata(S) are not part of any currently supported standard; they were developed by UNIX System Laboratories, Inc. and are maintained by The SCO Group.
© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003