elf_getdata(3E) elf_getdata(3E)
NAME
elfgetdata, elfnewdata, elfrawdata - Abschnittsdaten lesen
SYNTAX
cc [option ...] datei ... -lelf [bibliothek ...]
#include <libelf.h>
ElfData *elfgetdata(ElfScn *scn, ElfData *data);
ElfData *elfnewdata(ElfScn *scn);
ElfData *elfrawdata(ElfScn *scn, ElfData *data);
BESCHREIBUNG
Diese Funktionen lesen und manipulieren die Daten, die mit dem
Abschnittsdeskriptor scn verknüpft sind. Beim Lesen einer bereits vor-
handenen Datei ist ein Abschnitt mit einem einzelnen Datenpuffer ver-
knüpft. Ein Programm kann einen neuen Abschnitt aus Teilen zusammen-
setzen, wobei die Daten aus mehreren Datenpuffern kombiniert werden.
Aus diesem Grund sollten die Daten eines Abschnitts als Liste von Puf-
fern betrachtet werden, welche jeweils durch einen Datendeskriptor
bearbeitet werden.
Mit elfgetdata() ist ein Programm in der Lage, der Reihe nach auf die
Datenabschnitte einer Liste zuzugreifen. Wenn der übergebene Datende-
skriptor data Null ist, liefert die Funktion den ersten Puffer zurück,
der mit dem Abschnitt verknüpft ist. Ansonsten sollte data ein Daten-
deskriptor sein, der mit scn verknüpft ist; in diesem Fall erhält das
Programm Zugriff auf das nächste Datenelement des Abschnitts. Wenn scn
Null ist oder wenn ein Fehler auftritt, liefert elfgetdata() einen
Nullzeiger als Ergebnis.
elfgetdata() übersetzt die Daten aus den Dateidarstellungen in Spei-
cherdarstellungen [siehe elfxlate(3E)]; das Programm sieht Objekte
von Speicherdatentypen in Abhängigkeit von der Dateiklasse [siehe
elf(3E)]. Die Arbeitsversion der Bibliothek [siehe elfversion(3E)]
gibt an, welche Version der Speicherstrukturen von elfgetdata() dem
Programm gegenüber verwendet werden soll.
elfnewdata() erzeugt einen neuen Datendeskriptor für einen Abschnitt;
sind bereits Datenelemente für den Abschnitt vorhanden, so wird der
Datendeskriptor an das Ende angehängt. Wie noch beschrieben wird, ist
der neue Datendeskriptor leer und zeigt damit an, daß das Element noch
keine Daten enthält. Der Typ des Deskriptors (dtype weiter unten)
wird zunächst auf ELFTBYTE gesetzt, da dies am gebräuchlichsten ist;
die Version dversion weiter unten) wird auf die Arbeitsversion
gesetzt. Das Programm ist für die Einstellung und die Änderung der
Deskriptorkomponenten verantwortlich. Diese Funktion setzt implizit
das ELFFDIRTY-Bit für die Abschnittsdaten [siehe elfflag(3E)]. Wenn
scn gleich Null ist oder wenn ein Fehler auftritt, liefert
elfnewdata() einen Nullzeiger als Ergebnis zurück.
Seite 1 Reliant UNIX 5.44 Gedruckt 11/98
elf_getdata(3E) elf_getdata(3E)
elfrawdata() unterscheidet sich von elfgetdata() dadurch, daß nur
die nicht interpretierten Bytes, unabhängig vom Typ des Abschnitts,
zurückgegeben werden. Diese Funktion sollte üblicherweise dazu verwen-
det werden, einen Dateiabschnitt zu lesen und zwar nur dann, wenn das
Programm die automatische Datenübersetzung, wie sie unten beschrieben
ist, vermeiden soll. Ein Programm darf weiterhin den Dateideskriptor,
der mit elf verknüpft ist, vor der ersten Raw-Operation weder schlie-
ßen noch deaktivieren [siehe elfcntl(3E)], da elfrawdata() die Daten
aus der Datei lesen könnte, um sicherzustellen, daß keine Konflikte
mit der Funktion elfgetdata() auftreten. Eine ähnliche Möglichkeit,
die für ganze Dateien anwendbar ist, ist unter elfrawfile(3E)
beschrieben. Wenn elfgetdata() die richtige Übersetzung anbietet, so
sollte diese Funktion gegenüber elfrawdata() bevorzugt werden. Wenn
scn gleich Null ist, oder wenn ein Fehler auftritt, liefert
elfrawdata() einen Nullzeiger als Ergebnis zurück.
Die Struktur ElfData enthält folgende Komponenten:
void *dbuf;
ElfType dtype;
sizet dsize;
offt doff;
sizet dalign;
unsigned dversion;
Diese Komponenten stehen zur direkten Manipulation durch das Programm
zur Verfügung. Es folgt die Beschreibung der Komponenten.
dbuf Zeiger auf den Datenpuffer; ein Datenelement ohne Daten
enthält einen Nullzeiger.
dtype Der Wert dieser Komponente gibt den Typ der Daten an, auf
die dbuf zeigt. Der Typ eines Abschnitts bestimmt, wie der
Inhalt interpretiert wird. Dies wird unten näher ausge-
führt.
dsize Diese Komponente enthält die Gesamtlänge des Speichers (in
Bytes), die die Daten beanspruchen. Dieser Wert kann sich
von der Länge der Darstellung in der Datei unterscheiden.
Die Länge ist gleich Null, wenn keine Daten vorhanden sind
(Siehe die Erläuterungen zu SHTNOBITS).
doff Diese Komponente liefert den Offset innerhalb eines
Abschnitts, an dem sich der Puffer befindet. Dieser Offset
ist relativ zum Abschnitt der Datei, nicht zum Speicherob-
jekt.
dalign Diese Komponente enthält die benötigte Ausrichtung des Puf-
fers, vom Anfang des Abschnitts an gerechnet. Dies bedeu-
tet, daß doff ein Vielfaches des Wertes dieser Komponente
sein muß. Ist der Wert dieser Komponente beispielsweise
vier, dann wird der Anfang des Puffers innerhalb des
Seite 2 Reliant UNIX 5.44 Gedruckt 11/98
elf_getdata(3E) elf_getdata(3E)
Abschnitts auf eine 4-Byte-Grenze ausgerichtet. Die Aus-
richtung des gesamten Abschnitts ergibt sich aus dem Maxi-
malwert seiner einzelnen Elemente; dadurch wird garantiert,
daß die Ausrichtung eines Puffers innerhalb des Abschnitts
und innerhalb einer Datei korrekt ist.
dversion Diese Komponente enthält die Versionsnummer des Objekts aus
dem Puffer. Wenn die Bibliothek die Daten aus der Objektda-
tei erstmals liest, wird die Arbeitsversion verwendet, um
die Übersetzung der Speicherobjekte zu kontrollieren.
Ausrichtung der Daten
Wie oben bereits erwähnt, gelten für die Pufferausrichtungen innerhalb
von Abschnitten explizite Vorschriften. Daher kann es dazu kommen, daß
zwischen den Puffern eines Abschnitts "Löcher" entstehen. Programme,
die Ausgabedateien erzeugen, können diese Löcher auf zwei Arten behan-
deln.
Zum einen kann das Programm elffill() verwenden, um der Bibliothek
mitzuteilen, auf welchen Wert die Bytes in diesen Löchern gesetzt wer-
den sollen. Werden Löcher in der Datei erzeugt, wird das Füll-Byte
verwendet, um diese Daten zu initialisieren. Das voreingestellte
Füll-Byte der Bibliothek ist Null; es kann mit elffill() geändert
werden.
Zum anderen kann das Anwendungsprogramm eigene Datenpuffer anlegen, um
diese Löcher zu belegen; in den Löchern können dann Werte abgelegt
werden, die dem Abschnitt entsprechen. Ein Programm kann sogar ver-
schiedene Füllwerte für verschiedene Abschnitte verwenden. Beispiels-
weise kann der Inhalt von Bytes in Textabschnitten auf Leeranweisungen
(No-Operation) gesetzt werden, während Löcher in Datenabschnitten mit
Null-Bytes gefüllt werden. Bei Verwendung dieser Methode findet die
Bibliothek keine Löcher zum Füllen, da das Anwendungsprogramm diese
eliminiert hat.
Abschnitts- und Speichertypen
elfgetdata() interpretiert die Abschnittsdaten abhängig vom
Abschnittstyp. Der Typ eines Abschnitts ist im Kopf eines Abschnitts
festgehalten. Die folgende Tabelle zeigt die Abschnittstypen und die
Art und Weise, wie die Bibliothek sie durch Speicherdatentypen für die
32-Bit-Dateiklasse darstellt. Für andere Klassen würde es ähnliche
Tabellen geben. Impliziert ist, daß die Speicherdatentypen die Über-
setzung durch elfxlate() kontrollieren.
Seite 3 Reliant UNIX 5.44 Gedruckt 11/98
elf_getdata(3E) elf_getdata(3E)
______________________________________________________________________
| Abschnittstyp | Elf_Typ | 32-Bit Typ |
|_______________________|_____________________|_______________________|
| SHTDYNAMIC | ELFTDYN | Elf32Dyn |
|_______________________|_____________________|_______________________|
| SHTDYNSYM | ELFTSYM | Elf32Sym |
|_______________________|_____________________|_______________________|
| SHTHASH | ELFTWORD | Elf32Word |
|_______________________|_____________________|_______________________|
| SHTNOBITS | ELFTBYTE | unsigned char |
|_______________________|_____________________|_______________________|
| SHTNOTE | ELFTBYTE | unsigned char |
|_______________________|_____________________|_______________________|
| SHTNULL | keiner | keiner |
|_______________________|_____________________|_______________________|
| SHTPROGBITS | ELFTBYTE | unsigned char |
|_______________________|_____________________|_______________________|
| SHTREL | ELFTREL | Elf32Rel |
|_______________________|_____________________|_______________________|
| SHTRELA | ELFTRELA | Elf32Rela |
|_______________________|_____________________|_______________________|
| SHTSTRTAB | ELFTBYTE | unsigned char |
|_______________________|_____________________|_______________________|
| SHTSYMTAB | ELFTSYM | Elf32Sym |
|_______________________|_____________________|_______________________|
| andere | ELFTBYTE | unsigned char |
|_______________________|_____________________|_______________________|
elfrawdata() erzeugt einen Puffer vom Typ ELFTBYTE.
Wie bereits erwähnt, kontrolliert die Arbeitsversion des Programms,
welche Strukturen die Bibliothek für das Anwendungsprogramm erzeugt.
Auf die gleiche Weise interpretiert die Bibliothek die Abschnittstypen
anhand der Versionen. Wenn ein Abschnittstyp zu einer Version
"gehört", die aktueller als die Arbeitsversion des Programms ist,
übersetzt die Bibliothek die Abschnittsdaten nicht. Da das Anwendungs-
programm das Datenformat in diesem Fall nicht kennen kann, liefert die
Bibliothek einen unübersetzten Puffer des ELFTBYTE zurück; für einen
nicht erkannten Abschnittstyp würde genauso vorgegangen.
Ein Abschnitt mit dem speziellen Typ SHTNOBITS belegt keinen Platz in
einer Objektdatei, selbst wenn der Abschnittskopf eine Größe ungleich
Null angibt. elfgetdata() und elfrawdata() "arbeiten" auf solch
einem Abschnitt, wobei die Struktur data als Pufferzeiger einen Null-
zeiger und als Typ den oben angegebenen erhält. Obwohl keine Daten
verfügbar sind, wird dsize auf die Größe aus dem Abschnittskopf
gesetzt. Wenn ein Programm einen neuen Abschnitt des Typs SHTNOBITS
anlegt, sollte elfnewdata() verwendet werden, um dem Abschnitt Daten-
puffer hinzuzufügen. Diese "leeren" Datenpuffer sollten für die Kompo-
nenten dsize die gewünschte Größe und für dbuf den Wert Null enthal-
ten.
Seite 4 Reliant UNIX 5.44 Gedruckt 11/98
elf_getdata(3E) elf_getdata(3E)
BEISPIELE
Der folgende Programmauszug liest die Tabelle mit den Namen der
Abschnitte (die Fehlerbehandlung ist ausgelassen). Unter
elfstrptr(3E) ist eine alternative Behandlung der String-Tabelle
angeführt.
ehdr = elf32getehdr(elf);
scn = elfgetscn(elf, (sizet)ehdr->eshstrndx);
shdr = elf32getshdr(scn);
if (shdr->shtype != SHTSTRTAB)
{
/* keine String-Tabelle */
}
data = 0;
if ((data = elfgetdata(scn, data)] == 0 data->dsize == 0)
{
/* Fehler oder keine Daten */
}
Die Komponente eshstrndx in einem ELF-Kopf enthält den Abschnittsta-
bellenindex der String-Tabelle. Das Programm holt einen Abschnittsde-
skriptor für diesen Abschnitt, prüft, ob es sich um eine String-Ta-
belle handelt und liest dann die Daten aus. Am Ende dieses Programm-
ausschnitts zeigt data->dbuf auf das erste Byte der String-Tabelle,
und data->dsize enthält die Länge der String-Tabelle in Bytes.
SIEHE AUCH
elf(3E), elfcntl(3E), elffill(3E), elfflag(3E), elfgetehdr(3E),
elfgetscn(3E), elfgetshdr(3E), elfrawfile(3E), elfversion(3E),
elfxlate(3E).
Seite 5 Reliant UNIX 5.44 Gedruckt 11/98