elf_getdata(3E) elf_getdata(3E)
NAME
elfgetdata, elfnewdata, elfrawdata - get section data
SYNOPSIS
cc [flag ...] file ... -lelf [library ...]
#include <libelf.h>
ElfData *elfgetdata(ElfScn *scn, ElfData *data);
ElfData *elfnewdata(ElfScn *scn);
ElfData *elfrawdata(ElfScn *scn, ElfData *data);
DESCRIPTION
These functions access and manipulate the data associated with a sec-
tion descriptor, scn. When reading an existing file, a section will
have a single data buffer associated with it. A program may build a
new section in pieces, however, composing the new data from multiple
data buffers. For this reason, "the" data for a section should be
viewed as a list of buffers, each of which is available through a data
descriptor.
elfgetdata() lets a program step through a section's data list. If
the incoming data descriptor, data, is null, the function returns the
first buffer associated with the section. Otherwise, data should be a
data descriptor associated with scn, and the function gives the pro-
gram access to the next data element for the section. If scn is null
or an error occurs, elfgetdata() returns a null pointer.
elfgetdata() translates the data from file representations into
memory representations [see elfxlate(3E)] and presents objects with
memory data types to the program, based on the file's class [see
elf(3E)]. The working library version [see elfversion(3E)] specifies
what version of the memory structures the program wishes elfgetdata()
to present.
elfnewdata() creates a new data descriptor for a section, appending
it to any data elements already associated with the section. As
described below, the new data descriptor appears empty, indicating the
element holds no data. For convenience, the descriptor's type (dtype
below) is set to ELFTBYTE, and the version (dversion below) is set
to the working version. The program is responsible for setting (or
changing) the descriptor members as needed. This function implicitly
sets the ELFFDIRTY bit for the section's data [see elfflag(3E)]. If
scn is null or an error occurs, elfnewdata() returns a null pointer.
elfrawdata() differs from elfgetdata() by returning only uninter-
preted bytes, regardless of the section type. This function typically
should be used 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 may not close or
Page 1 Reliant UNIX 5.44 Printed 11/98
elf_getdata(3E) elf_getdata(3E)
disable [see elfcntl(3E)] the file descriptor associated with elf
before the initial raw operation, because elfrawdata() might read the
data from the file to ensure it doesn't interfere with elfgetdata().
See elfrawfile(3E) for a related facility that applies to the entire
file. When elfgetdata() provides the right translation, its use is
recommended over elfrawdata(). If scn is null or an error occurs,
elfrawdata() returns a null pointer.
The ElfData structure includes the following members.
void *dbuf;
ElfType dtype;
sizet dsize;
offt doff;
sizet dalign;
unsigned dversion;
These members are available for direct manipulation by the program.
Descriptions appear below.
dbuf A pointer to the data buffer resides here. A data element
with no data has a null pointer.
dtype This member's value specifies the type of the data to which
dbuf points. A section's type determines how to interpret
the section contents, as summarized below.
dsize This member holds the total size, in bytes, of the memory
occupied by the data. This may differ from the size as rep-
resented in the file. The size will be zero if no data
exist (see the discussion of SHTNOBITS).
doff This member gives the offset, within the section, at which
the buffer resides. This offset is relative to the file's
section, not the memory object's.
dalign This member holds the buffer's required alignment, from the
beginning of the section. That is, doff will be a multiple
of this member's value. For example, if this member's value
is four, the beginning of the buffer will be four-byte
aligned within the section. Moreover, the entire section
will be aligned to the maximum of its constituents, thus
ensuring appropriate alignment for a buffer within the sec-
tion and within the file.
dversion 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 to control the
translation to memory objects.
Page 2 Reliant UNIX 5.44 Printed 11/98
elf_getdata(3E) elf_getdata(3E)
Data alignment
As mentioned above, data buffers within a section have explicit align-
ment constraints. Consequently, adjacent buffers sometimes will not
abut, causing "holes" within a section. Programs that create output
files have two ways of dealing with these holes.
First, the program can use elffill() 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, and elffill() lets the applica-
tion 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 might even use different fill values for dif-
ferent sections. For example, it could set text sections' bytes to
no-operation instructions, while filling data section holes with zero.
Using this technique, the library finds no holes to fill, because the
application eliminated them.
Section and memory types
elfgetdata() interprets sections' data according to the section type,
as noted in the section header available through elfgetshdr(). 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
would have similar tables. By implication, the memory data types con-
trol translation by elfxlate().
Page 3 Reliant UNIX 5.44 Printed 11/98
elf_getdata(3E) elf_getdata(3E)
______________________________________________________________________
| Section type | ElfType | 32-Bit Type |
|______________________|______________________|_______________________|
| SHTDYNAMIC | ELFTDYN | Elf32Dyn |
|______________________|______________________|_______________________|
| SHTDYNSYM | ELFTSYM | Elf32Sym |
|______________________|______________________|_______________________|
| SHTHASH | ELFTWORD | Elf32Word |
|______________________|______________________|_______________________|
| SHTNOBITS | ELFTBYTE | unsigned char |
|______________________|______________________|_______________________|
| SHTNOTE | ELFTBYTE | unsigned char |
|______________________|______________________|_______________________|
| SHTNULL | none | none |
|______________________|______________________|_______________________|
| SHTPROGBITS | ELFTBYTE | unsigned char |
|______________________|______________________|_______________________|
| SHTREL | ELFTREL | Elf32Rel |
|______________________|______________________|_______________________|
| SHTRELA | ELFTRELA | Elf32Rela |
|______________________|______________________|_______________________|
| SHTSTRTAB | ELFTBYTE | unsigned char |
|______________________|______________________|_______________________|
| SHTSYMTAB | ELFTSYM | Elf32Sym |
|______________________|______________________|_______________________|
| other | ELFTBYTE | unsigned char |
|______________________|______________________|_______________________|
elfrawdata() creates a buffer with type ELFTBYTE.
As mentioned above, the program's working version controls what struc-
tures the library creates for the application. The library similarly
interprets section types according to the versions. If a section type
"belongs" to a version newer than the application's working version,
the library does not translate the section data. Because the applica-
tion cannot know the data format in this case, the library presents an
untranslated buffer of type ELFTBYTE, just as it would for an
unrecognized section type.
A section with a special type, SHTNOBITS, occupies no space in an
object file, even when the section header indicates a non-zero size.
elfgetdata() and elfrawdata() "work" on such a section, setting the
data structure to have a null buffer pointer and the type indicated
above. Although no data is present, the dsize value is set to the
size from the section header. When a program is creating a new section
of type SHTNOBITS, it should use elfnewdata() to add data buffers to
the section. These "empty" data buffers should have the dsize members
set to the desired size and the dbuf members set to null.
Page 4 Reliant UNIX 5.44 Printed 11/98
elf_getdata(3E) elf_getdata(3E)
EXAMPLES
The following fragment obtains the string table that holds section
names (ignoring error checking). See elfstrptr(3E) for a variation of
string table handling.
ehdr = elf32getehdr(elf);
scn = elfgetscn(elf, (sizet)ehdr->eshstrndx);
shdr = elf32getshdr(scn);
if (shdr->shtype != SHTSTRTAB)
{
/* not a string table */
}
data = 0;
if ((data = elfgetdata(scn, data)) == 0 data->dsize == 0)
{
/* error or no data */
}
The eshstrndx member in an ELF header holds the section table index
of the string table. The program gets a section descriptor for that
section, verifies it is a string table, and then retrieves the data.
When this fragment finishes, data->dbuf points at the first byte of
the string table, and data->dsize holds the string table's size in
bytes.
SEE ALSO
elf(3E), elfcntl(3E), elffill(3E), elfflag(3E), elfgetehdr(3E),
elfgetscn(3E), elfgetshdr(3E), elfrawfile(3E), elfversion(3E),
elfxlate(3E).
Page 5 Reliant UNIX 5.44 Printed 11/98