From owner-p4-projects@FreeBSD.ORG Sun Oct 1 21:35:55 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E0B6516A47B; Sun, 1 Oct 2006 21:35:54 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8A88016A407 for ; Sun, 1 Oct 2006 21:35:54 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1F75443D46 for ; Sun, 1 Oct 2006 21:35:54 +0000 (GMT) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k91LZsov089920 for ; Sun, 1 Oct 2006 21:35:54 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k91LZr6B089917 for perforce@freebsd.org; Sun, 1 Oct 2006 21:35:53 GMT (envelope-from jb@freebsd.org) Date: Sun, 1 Oct 2006 21:35:53 GMT Message-Id: <200610012135.k91LZr6B089917@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jb@freebsd.org using -f From: John Birrell To: Perforce Change Reviews Cc: Subject: PERFORCE change 107059 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 Oct 2006 21:35:55 -0000 http://perforce.freebsd.org/chv.cgi?CH=107059 Change 107059 by jb@jb_freebsd7 on 2006/10/01 21:35:23 IFlibbsdelf Affected files ... .. //depot/projects/dtrace/src/lib/libelf/Makefile#12 integrate .. //depot/projects/dtrace/src/lib/libelf/_libelf.h#8 integrate .. //depot/projects/dtrace/src/lib/libelf/elf.3#4 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_begin.3#3 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_begin.c#5 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_data.c#1 branch .. //depot/projects/dtrace/src/lib/libelf/elf_end.c#3 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_errmsg.c#9 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_flag.c#2 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_flagdata.3#3 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_getdata.3#2 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_memory.3#2 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_memory.c#6 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_scn.c#2 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_strptr.3#1 branch .. //depot/projects/dtrace/src/lib/libelf/elf_types.m4#2 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_update.3#1 branch .. //depot/projects/dtrace/src/lib/libelf/gelf.3#2 integrate .. //depot/projects/dtrace/src/lib/libelf/gelf_checksum.3#1 branch .. //depot/projects/dtrace/src/lib/libelf/gelf_checksum.c#1 branch .. //depot/projects/dtrace/src/lib/libelf/gelf_dyn.c#1 branch .. //depot/projects/dtrace/src/lib/libelf/gelf_fsize.c#2 integrate .. //depot/projects/dtrace/src/lib/libelf/gelf_getdyn.3#1 branch .. //depot/projects/dtrace/src/lib/libelf/gelf_getrel.3#1 branch .. //depot/projects/dtrace/src/lib/libelf/gelf_getrela.3#1 branch .. //depot/projects/dtrace/src/lib/libelf/gelf_getsym.3#1 branch .. //depot/projects/dtrace/src/lib/libelf/gelf_newphdr.3#2 integrate .. //depot/projects/dtrace/src/lib/libelf/gelf_sym.c#1 branch .. //depot/projects/dtrace/src/lib/libelf/gelf_update.c#2 integrate .. //depot/projects/dtrace/src/lib/libelf/gelf_xlate.c#4 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf.h#8 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf_allocate.c#4 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf_checksum.c#1 branch .. //depot/projects/dtrace/src/lib/libelf/libelf_data.c#1 branch .. //depot/projects/dtrace/src/lib/libelf/libelf_fsize.m4#3 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf_xlate.c#1 branch Differences ... ==== //depot/projects/dtrace/src/lib/libelf/Makefile#12 (text+ko) ==== @@ -7,6 +7,7 @@ elf_dump.c \ elf_dump_argv.c \ elf_end.c elf_errmsg.c elf_errno.c \ + elf_data.c \ elf_fill.c \ elf_flag.c \ elf_getbase.c \ @@ -25,26 +26,36 @@ elf_rawdata.c \ elf_rawfile.c \ elf_scn.c \ + elf_strptr.c \ + elf_update.c \ elf_version.c \ + gelf_checksum.c \ gelf_fsize.c \ gelf_getclass.c \ gelf_getshdr.c \ + gelf_dyn.c \ gelf_ehdr.c \ gelf_phdr.c \ + gelf_rel.c \ + gelf_rela.c \ + gelf_sym.c \ gelf_update.c \ gelf_xlate.c \ libelf.c \ libelf_allocate.c \ libelf_ar.c \ + libelf_checksum.c \ + libelf_data.c \ libelf_ehdr.c \ - libelf_phdr.c + libelf_phdr.c \ + libelf_xlate.c INCS= libelf.h gelf.h DPSRCS+= libelf_fsize.c libelf_msize.c libelf_convert.c CLEANFILES+= libelf_fsize.c libelf_msize.c libelf_convert.c CFLAGS+= -I${.OBJDIR} -I${.CURDIR} -OBJS+= libelf_convert.o libelf_msize.o +OBJS+= libelf_convert.o libelf_fsize.o libelf_msize.o OSRELDATE!= sysctl -n kern.osreldate @@ -68,33 +79,30 @@ elf_next.3 \ elf_rawfile.3 \ elf_rand.3 \ + elf_strptr.3 \ + elf_update.3 \ elf_version.3 \ gelf.3 \ + gelf_checksum.3 \ gelf_fsize.3 \ gelf_getclass.3 \ + gelf_getdyn.3 \ gelf_getehdr.3 \ gelf_getphdr.3 \ + gelf_getrel.3 \ + gelf_getrela.3 \ gelf_getshdr.3 \ + gelf_getsym.3 \ gelf_newehdr.3 \ gelf_newphdr.3 \ gelf_update_ehdr.3 \ gelf_xlatetof.3 MLINKS+= \ - gelf.3 gelf_checksum.3 \ - gelf.3 gelf_getdyn.3 \ gelf.3 gelf_getmove.3 \ - gelf.3 gelf_getrel.3 \ - gelf.3 gelf_getrela.3 \ - gelf.3 gelf_getsym.3 \ gelf.3 gelf_getsyminfo.3 \ - gelf_update_ehdr.3 gelf_update_phdr.3 \ - gelf_update_ehdr.3 gelf_update_shdr.3 \ gelf.3 gelf_update_move.3 \ - gelf.3 gelf_update_rela.3 \ - gelf.3 gelf_update_sym.3 \ - gelf.3 gelf_update_syminfo.3 \ - gelf_xlatetof.3 gelf_xlatetom.3 + gelf.3 gelf_update_syminfo.3 MLINKS+= \ elf_errmsg.3 elf_errno.3 \ @@ -108,12 +116,17 @@ elf_getscn.3 elf_ndxscn.3 \ elf_getscn.3 elf_newscn.3 \ elf_getscn.3 elf_nextscn.3 \ - elf.3 elf_strptr.3 \ - elf.3 elf_update.3 + gelf_getdyn.3 gelf_update_dyn.3 \ + gelf_getrel.3 gelf_update_rel.3 \ + gelf_getrela.3 gelf_update_rela.3 \ + gelf_getsym.3 gelf_update_sym.3 \ + gelf_update_ehdr.3 gelf_update_phdr.3 \ + gelf_update_ehdr.3 gelf_update_shdr.3 \ + gelf_xlatetof.3 gelf_xlatetom.3 .for E in 32 64 MLINKS+= \ - elf.3 elf${E}_checksum.3 \ + gelf_checksum.3 elf${E}_checksum.3 \ gelf_fsize.3 elf${E}_fsize.3 \ gelf_getehdr.3 elf${E}_getehdr.3 \ gelf_getphdr.3 elf${E}_getphdr.3 \ ==== //depot/projects/dtrace/src/lib/libelf/_libelf.h#8 (text+ko) ==== @@ -69,11 +69,8 @@ * Flags for library internal use. These use the upper 16 bits of a * flags field. */ -#define LIBELF_F_ALLOCED 0x010000 /* whether e_rawfile is malloc'ed */ +#define LIBELF_F_MALLOCED 0x010000 /* whether data was malloc'ed */ #define LIBELF_F_MMAP 0x020000 /* whether e_rawfile was mmap'ed */ -#define LIBELF_F_EHDR_DIRTY 0x040000 /* TODO: check if these 3 can be */ -#define LIBELF_F_PHDR_DIRTY 0x080000 /* folded into one flag. */ -#define LIBELF_F_SHDR_DIRTY 0x100000 struct _Elf { int e_activations; /* activation count */ @@ -114,15 +111,19 @@ }; struct _Elf_Scn { - STAILQ_HEAD(, _Elf_Scn) s_data; /* list of Elf_Data descriptors */ - struct _Elf *s_elf; /* parent ELF descriptor */ - unsigned int s_flags; /* flags for the section as a whole */ - size_t s_ndx; /* index# for this section */ - STAILQ_ENTRY(_Elf_Scn) s_next; union { Elf32_Shdr s_shdr32; Elf64_Shdr s_shdr64; } s_shdr; + STAILQ_HEAD(, _Elf_Data) s_data; /* list of Elf_Data descriptors */ + STAILQ_HEAD(, _Elf_Data) s_rawdata; /* raw data for this section */ + STAILQ_ENTRY(_Elf_Scn) s_next; + struct _Elf *s_elf; /* parent ELF descriptor */ + unsigned int s_flags; /* flags for the section as a whole */ + size_t s_ndx; /* index# for this section */ + uint64_t s_offset; /* managed by elf_update() */ + uint64_t s_rawoff; /* original offset in the file */ + uint64_t s_size; /* managed by elf_update() */ }; @@ -135,13 +136,18 @@ * Prototypes */ +Elf_Data *_libelf_allocate_data(Elf_Scn *_s); Elf *_libelf_allocate_elf(void); +Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); Elf *_libelf_ar_open(Elf *_e); +unsigned long _libelf_checksum(Elf *_e, int _elfclass); int _libelf_dump32(Elf *_elf, const char *_name, const char *_outfile, unsigned int _flags); int _libelf_dump64(Elf *_elf, const char *_name, const char *_outfile, unsigned int _flags); void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); +size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, + size_t count); void (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass)) (char *_dst, char *_src, int _cnt, int _byteswap); void *_libelf_getphdr(Elf *_e, int _elfclass); @@ -149,6 +155,11 @@ int _libelf_malign(Elf_Type _t, int _elfclass); size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); -void _libelf_release_elf(Elf *_e); +Elf_Data *_libelf_release_data(Elf_Data *_d); +Elf *_libelf_release_elf(Elf *_e); +Elf_Scn *_libelf_release_scn(Elf_Scn *_s); +Elf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, + unsigned int _encoding, int _elfclass, int _direction); +int _libelf_xlate_shtype(size_t _sht); #endif /* __LIBELF_H_ */ ==== //depot/projects/dtrace/src/lib/libelf/elf.3#4 (text+ko) ==== @@ -23,30 +23,447 @@ .\" .\" $FreeBSD$ .\" -.Dd June 1, 2006 +.Dd September 1, 2006 .Os .Dt ELF 3 .Sh NAME +.Nm elf +.Nd API for manipulating ELF objects .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h +.Sh DESCRIPTION +The +.Lb libelf +library provides functions that allow an application to read and +manipulate ELF object files, and to read +.Xr ar 1 +archives. +The library allows the manipulation of ELF objects in a byte ordering +and word-size independent way, allowing an application to read and +create ELF objects for 32 and 64 bit architectures and for little- +and big-endian machines. +.Pp +This manual page serves to provide an overview of the functionality in +the ELF library. +Further information may found in the manual pages for individual +.Xr ELF 3 +functions that comprise the library. +.Ss ELF Concepts +As described in +.Xr elf 5 , +ELF files contain several data structures that are laid out in a +specific way. +ELF files begin with an +.Dq Executable Header , +and may contain an optional +.Dq Program Header Table , +and optional data in the form of ELF +.Dq sections . +A +.Dq Section Header Table +describes the content of the data in these sections. +.Pp +ELF objects have an associated +.Dq "ELF class" +which denotes the natural machine word size for the architecture +the object is associated with. +Objects for 32 bit architectures have an ELF class of +.Dv ELFCLASS32 . +Objects for 64 bit architectures have an ELF class of +.Dv ELFCLASS64 . +.Pp +ELF objects also have an associated +.Dq endianness +which denotes the endianness of the machine architecture associated +with the object. +This may be +.Dv ELFDATA2LSB +for little-endian architectures and +.Dv ELFDATA2MSB +for big-endian architectures. +.Pp +ELF objects are also associated with an API version number. +This version number determines the layout of the individual components +of an ELF file and the semantics associated with these. +.Ss Data Representation And Translation +The +.Xr ELF 3 +library distinguishes between +.Dq native +representations of ELF data structures and their +.Dq file +representations. +.Pp +An application would work with ELF data in its +.Dq native +representation, i.e., using the native byteorder and alignment mandated +by the processor the application is running on. +The +.Dq file +representation of the same data could use a different byte ordering +and follow different constraints on object alignment than these native +constraints. +.Pp +Accordingly, the +.Xr ELF 3 +library offers translation facilities +.Xr ( elf32_xlatetof 3 , +.Xr elf32_xlatetom 3 , +.Xr elf64_xlatetof 3 +and +.Xr elf64_xlatetom 3 ) +to and from these +representations and also provides higher-level APIs that retrieve and store +data from the ELF object in a transparent manner. +.Ss Library Working Version +Conceptually, there are three version numbers associated with an +application using the ELF library to manipulate ELF objects: +.Bl -bullet -compact -offset indent +.It +The ELF version that the application was compiled against. +This version determines the ABI expected by the application. +.It +The ELF version of the ELF object being manipulated by the +application through the ELF library. +.It +The ELF version (or set of versions) supported by the ELF library itself. +.El +.Pp +In order to facilitate working with ELF objects of differing versions, +the ELF library requires the application to call the +.Fn elf_version +function before invoking many of its operations, in order to inform +the library of the application's desired working version. +.Pp +In the current implementation, all three versions have to be +.Dv EV_CURRENT . +.Ss Namespace use +The ELF library uses the following prefixes: +.Bl -tag -width "ELF_F_*" +.It elf_* +Used for class-independent functions. +.It elf32_* +Used for functions working with 32 bit ELF objects. +.It elf64_* +Used for functions working with 64 bit ELF objects. +.It Elf_* +Used for class-independent data types. +.It ELF_C_* +Used for command values used in a few functions. +These symbols are defined as members of the +.Vt Elf_Cmd +enumeration. +.It ELF_E_* +Used for error numbers. +.It ELF_F_* +Used for flags. +.It ELF_K_* +These constants define the kind of file associated with an ELF +descriptor. +See +.Xr elf_kind 3 . +The symbols are defined by the +.Vt Elf_Kind +enumeration. +.It ELF_T_* +These values are defined by the +.Vt Elf_Type +enumeration, and denote the types of ELF data structures +that can be present in an ELF object. +.El +.Ss Descriptors +Applications communicate with the library using descriptors. +These are: +.Bl -tag -width ".Vt Elf_Data" +.It Vt Elf +An +.Vt Elf +descriptor represents an ELF object or an +.Xr ar 1 +archive. +It is allocated using one of the +.Fn elf_begin +or +.Fn elf_memory +functions. +An +.Vt Elf +descriptor can be used to read and write data to an ELF file. +An +.Vt Elf +descriptor can be associated with zero or more +.Vt Elf_Scn +section descriptors. +.Pp +Given an ELF descriptor, the application may retrieve the ELF +object's class-dependent +.Dq "Executable Header" +structures using the +.Fn elf32_getehdr +or +.Fn elf64_getehdr +functions. +A new Ehdr structure may be allocated using the +.Fn elf64_newehdr +or +.Fn elf64_newehdr +functions. +.Pp +The +.Dq "Program Header Table" +associated with an ELF descriptor may be allocated using the +.Fn elf32_getphdr +or +.Fn elf64_getphdr +functions. +A new program header table may be allocated or an existing table +resized using the +.Fn elf32_newphdr +or +.Fn elf64_newphdr +functions. +.Pp +The +.Vt Elf +structure is opaque and has no members visible to the +application. +.\" TODO describe the Elf_Arhdr and Elf_Arsym structures. +.It Vt Elf_Data +An +.Vt Elf_Data +data structure describes an individual chunk of a ELF file as +represented in memory. +It has the following application visible members: +.Bl -tag -width ".Vt unsigned int d_version" +.It Vt "uint64_t d_align" +The alignment of the data buffer within its containing ELF section. +.It Vt "uint64_t d_off" +The offset with the containing section where this descriptors data +would be placed. +.It Vt "uint64_t d_size" +The number of bytes of data in this descriptor. +.It Vt "void *d_buf" +A pointer to data in memory. +.It Vt "Elf_Type d_type" +The ELF type (see below) of the data in this descriptor. +.It Vt "unsigned int d_version" +The operating version for the data in this buffer. +.El +.Pp +.Vt Elf_Data +descriptors are usually associated with +.Vt Elf_Scn +descriptors. +Existing data descriptors associated with an ELF section may be +structures are retrieved using the +.Fn elf_getdata +function. +The +.Fn elf_newdata +function may be used to attach new data descriptors to an ELF section. +.It Vt Elf_Scn +.Vt Elf_Scn +descriptors represent a section in an ELF object. +.Pp +They are retrieved using the +.Fn elf_getscn +function. +An application may iterate through the existing sections of an ELF +object using the +.Fn elf_nextscn +function. +New sections may be allocated using the +.Fn elf_newscn +function. +.Pp +The +.Vt Elf_Scn +descriptor is opaque and contains no application modifiable fields. +.El +.Ss Functional Grouping +This section contains a brief overview of the available functionality +in the ELF library. +Each function listed here is described further in its own manual page. +.Bl -tag -width indent +.It "Archive Access" +.Bl -tag -compact +.It Fn elf_getarsym +Retrieve the archive symbol table. +.It Fn elf_getarhdr +Retrieve the archive header for an object. +.It Fn elf_getbase +Retrieve the offset of a member inside an archive. +.It Fn elf_next +Iterate through an +.Xr ar 1 +archive. +.It Fn elf_rand +Random access inside an +.Xr ar 1 +archive. +.El +.It "Data Structures" +.Bl -tag -compact +.It Fn elf_getdata +Retrieve translated data for an ELF section. +.It Fn elf_getscn +Retrieve the section descriptor for a named section. +.It Fn elf_ndxscn +Retrieve the index for a section. +.It Fn elf_newdata +Add a new +.Vt Elf_Data +descriptor to an ELF section. +.It Fn elf_newscn +Add a new section descriptor to an ELF descriptor. +.It Fn elf_nextscn +Iterate through the sections in an ELF object. +.It Fn elf_rawdata +Retrieve untranslated data for an ELF sectino. +.It Fn elf_rawfile +Return a pointer to the untranslated file contents for an ELF object. +.It Fn elf32_getehdr , Fn elf64_getehdr +Retrieve the Executable Header in an ELF object. +.It Fn elf32_getphdr , Fn elf64_getphdr +Retrieve the Program Header Table in an ELF object. +.It Fn elf32_getshdr , Fn elf64_getshdr +Retrieve the ELF section header associated with an +.Vt Elf_Scn +descriptor. +.It Fn elf32_newehdr , Fn elf64_newehdr +Allocate an Executable Header in an ELF object. +.It Fn elf32_newphdr , Fn elf64_newphdr +Allocate or resize the Program Header Table in an ELF object. +.El +.It "Data Translation" +.Bl -tag -compact +.It Fn elf32_xlatetof , Fn elf64_xlatetof +Translate an ELF data structure from its native representation to its +file representation. +.It Fn elf32_xlatetom , Fn elf64_xlatetom +Translate an ELF data structure from its file representation to a +native representation. +.El +.It "Error Reporting" +.Bl -tag -compact +.It Fn elf_errno +Retrieve the current error. +.It Fn elf_errmsg +Retrieve a human readable description of the current error. +.El +.It "Initialization" +.Bl -tag -compact +.It Fn elf_begin +Opens an +.Xr ar 1 +archive or ELF object given a file descriptor. +.It Fn elf_end +Close an ELF descriptor and release all its resources. +.It Fn elf_memory +Opens an +.Xr ar 1 +archive or ELF object present in a memory arena. +.It Fn elf_version +Sets the operating version. +.El +.It "IO Control" +.Bl -tag -compact +.It Fn elf_cntl +Manage the association between and ELF descriptor and its underlying file. +.It Fn elf_flagdata +Mark an +.Vt Elf_Data +descriptor as dirty. +.It Fn elf_flagehdr +Mark the ELF Executable Header in an ELF descriptor as dirty. +.It Fn elf_flagphdr +Mark the ELF Program Header Table in an ELF descriptor as dirty. +.It Fn elf_flagscn +Mark an +.Vt Elf_Scn +descriptor as dirty. +.It Fn elf_flagshdr +Mark an ELF Section Header as dirty. +.It Fn elf_update +Recompute ELF object layout and optionally write the modified object +back to the underlying file. +.El +.It "Queries" +.Bl -tag -compact +.It Fn elf32_checksum , Fn elf64_checkum +Compute checksum of an ELF object. +.It Fn elf_getident +Retrieve the identification bytes for an ELF object. +.It Fn elf_hash +Compute the ELF hash value of a string. +.It Fn elf_kind +Query the kind of object associated with an ELF descriptor. +.It Fn elf32_fsize , Fn elf64_fsize +Return the size of the file representation of an ELF type. +.El +.El +.Ss Controlling ELF Object Layout +In the usual mode of operation, library will compute section +offsets and alignments based on the contents of an ELF descriptor's +sections without need for further intervention by the +application. +.Pp +However, if the application wishes to take complete charge of the +layout of the ELF file, it may set the +.Dv ELF_F_LAYOUT +flag on an ELF descriptor, following which the library will use the +section offsets and alignments specified by the application when +laying out the file. +.Pp +Gaps in between sections will be filled with the fill character +set by function +.Fn elf_fill . +.Ss Error Handling +In case an error is encountered, these library functions set an +internal error number and signal the presence of the error by +returning an special return value. The application can check the +current error number by calling +.Xr elf_errno 3 . +A human readable description of the recorded error is available by +calling +.Xr elf_errmsg 3 . +.Ss Memory Management Rules +The library keeps track of all +.Vt Elf_Scn +and +.Vt Elf_Data +descriptors associated with an ELF descriptor and recovers them +when the descriptor is closed using +.Xr elf_end 3 . +Thus the application must not call +.Xr free 3 +on data structures allocated by the ELF library. +.Pp +Conversely the library will not +free data that it has not allocated. +As an example, an application may call +.Xr elf_newdata 3 +to allocate a new +.Vt Elf_Data +descriptor and can set the +.Va d_off +member of the descriptor to point to a region of memory allocated +using +.Xr malloc 3 . +It is the applications responsibility to free this arena, though the +library will reclaim the space used by the +.Vt Elf_Data +descriptor itself. .Sh SEE ALSO -.Xr elf_errno 3 , -.Xr elf_errmsg 3 , -.Xr elf_fill 3 , -.Xr elf_version 3 , -.Xr gelf 3 -. \" TODO describe the concept of translation, data structure -. \" alignments and byte ordering, and the programming model -. \" (natively ordered data structures getting translated to -. \" file representation at update() time. Describe the ELF_F_DIRTY -. \" bit. -. \" Describe the ELF_F_LAYOUT bit. -. \" Memory management discipline: Note that no ELF data structure should -. \" be explicitly free()'ed by the application. All free'ing happens when -. \" an elf_end() is done, after which pointers go stale. -. \" Describe all prefixes used by the library and namespace use by -. \" and (in gelf.3). -. \" Describe the members of the Elf_Data and the rules governing their -. \" use. +.Xr gelf 3 , +.Xr elf 5 +.Sh HISTORY +The original ELF(3) API was developed for Unix System V. +The current implementation of the ELF(3) API appeared in +.Fx 7.0 . +.Sh AUTHORS +The ELF library was written by +.An "Joseph Koshy" +.Aq jkoshy@FreeBSD.org . ==== //depot/projects/dtrace/src/lib/libelf/elf_begin.3#3 (text+ko) ==== @@ -250,13 +250,18 @@ was not a descriptor for an .Xr ar 1 archive. -.It Bq Er ELF_E_MODE +.It Bq Er ELF_E_ARGUMENT An .Xr ar 1 archive was opened with with .Ar cmd set to .Dv ELF_C_RDWR . +.It Bq Er ELF_E_IO +Function +.Fn elf_begin +was unable to truncate a file opened for writing using +.Dv ELF_C_WRITE . .It Bq Er ELF_E_RESOURCE An out of memory condition was encountered. .It Bq Er ELF_E_SEQUENCE @@ -264,11 +269,6 @@ .Fn elf_begin was called before a working version was established with .Xr elf_version 3 . -.It Bq Er ELF_E_TRUNCATE -Function -.Fn elf_begin -was unable to truncate a file opened for writing using -.Dv ELF_C_WRITE . .El .Sh SEE ALSO .Xr elf 3 , ==== //depot/projects/dtrace/src/lib/libelf/elf_begin.c#5 (text+ko) ==== @@ -53,14 +53,14 @@ * and then the raw data is immediately mapped back in. */ if (fstat(fd, &sb) < 0) { - LIBELF_SET_ERROR(STAT, errno); + LIBELF_SET_ERROR(IO, errno); return (NULL); } m = NULL; if ((m = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t) 0)) == MAP_FAILED) { - LIBELF_SET_ERROR(MMAP, errno); + LIBELF_SET_ERROR(IO, errno); return (NULL); } @@ -75,7 +75,7 @@ if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) { (void) elf_end(e); - LIBELF_SET_ERROR(MODE, 0); + LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -148,7 +148,7 @@ * not writeable. */ if (ftruncate(fd, (off_t) 0) < 0) { - LIBELF_SET_ERROR(TRUNCATE, errno); + LIBELF_SET_ERROR(IO, errno); return (NULL); } ==== //depot/projects/dtrace/src/lib/libelf/elf_end.c#3 (text+ko) ==== @@ -39,6 +39,7 @@ elf_end(Elf *e) { Elf *sv; + Elf_Scn *scn, *tscn; if (e == NULL || e->e_activations == 0) return (0); @@ -61,6 +62,11 @@ return (0); break; case ELF_K_ELF: + /* + * Reclaim all section descriptors. + */ + STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) + scn = _libelf_release_scn(scn); break; case ELF_K_NUM: assert(0); @@ -74,7 +80,7 @@ sv = e; if ((e = e->e_parent) != NULL) e->e_u.e_ar.e_nchildren--; - _libelf_release_elf(sv); + sv = _libelf_release_elf(sv); } return (0); ==== //depot/projects/dtrace/src/lib/libelf/elf_errmsg.c#9 (text+ko) ==== @@ -44,15 +44,14 @@ DEFINE_ERROR(CLASS, "ELF class mismatch"), DEFINE_ERROR(DATA, "Invalid data buffer descriptor"), DEFINE_ERROR(HEADER, "Missing or malformed ELF header"), - DEFINE_ERROR(MMAP, "File mapping failed"), + DEFINE_ERROR(IO, "I/O error"), + DEFINE_ERROR(LAYOUT, "Layout constraint violation"), DEFINE_ERROR(MODE, "Incorrect ELF descriptor mode"), DEFINE_ERROR(RANGE, "Value out of range of target"), DEFINE_ERROR(RESOURCE, "Resource exhaustion"), - DEFINE_ERROR(SECTION, "Section descriptor was invalid"), + DEFINE_ERROR(SECTION, "Invalid section descriptor"), DEFINE_ERROR(SEQUENCE, "API calls out of sequence"), - DEFINE_ERROR(STAT, "Cannot determine file parameters"), - DEFINE_ERROR(TRUNCATE, "File truncation failed"), - DEFINE_ERROR(UNIMPL, "Feature is unimplemented"), + DEFINE_ERROR(UNIMPL, "Unimplemented feature"), DEFINE_ERROR(VERSION, "Unknown ELF API version"), DEFINE_ERROR(NUM, "Unknown error") #undef DEFINE_ERROR ==== //depot/projects/dtrace/src/lib/libelf/elf_flag.c#2 (text+ko) ==== @@ -44,16 +44,11 @@ if ((c != ELF_C_SET && c != ELF_C_CLR) || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL || e->e_kind != ELF_K_ELF || - flags == 0 || (flags & ~ELF_F_DIRTY) != 0) { + (flags & ~ELF_F_DIRTY) != 0) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } - if (e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - if (c == ELF_C_SET) r = scn->s_flags |= flags; else @@ -65,25 +60,30 @@ unsigned int elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags) { - int r; + int ec; + void *ehdr; if (e == NULL) return (0); if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_cmd == ELF_C_READ) || (e->e_kind != ELF_K_ELF) || - flags == 0 || (flags & ~ELF_F_DIRTY) != 0) { + (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } - r = 0; - if (c == ELF_C_SET) { - e->e_flags |= LIBELF_F_EHDR_DIRTY; - r = flags; - } else - e->e_flags &= LIBELF_F_EHDR_DIRTY; - return (r); + if (ec == ELFCLASS32) + ehdr = e->e_u.e_elf.e_ehdr.e_ehdr32; + else + ehdr = e->e_u.e_elf.e_ehdr.e_ehdr64; + + if (ehdr == NULL) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (0); + } + + return (elf_flagelf(e, c, flags)); } unsigned int @@ -95,8 +95,8 @@ return (0); if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_cmd == ELF_C_READ) || (e->e_kind != ELF_K_ELF) || - flags == 0 || (flags & ~(ELF_F_DIRTY|ELF_F_LAYOUT)) != 0) { + (e->e_kind != ELF_K_ELF) || + (flags & ~(ELF_F_DIRTY|ELF_F_LAYOUT)) != 0) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } @@ -111,43 +111,41 @@ unsigned int elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags) { - int r; + int ec; + void *phdr; if (e == NULL) return (0); if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_cmd == ELF_C_READ) || (e->e_kind != ELF_K_ELF) || - flags == 0 || (flags & ~ELF_F_DIRTY) != 0) { + (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } - r = 0; - if (c == ELF_C_SET) { - e->e_flags |= LIBELF_F_PHDR_DIRTY; - r = flags; - } else - e->e_flags &= ~LIBELF_F_PHDR_DIRTY; - return (r); + if (ec == ELFCLASS32) + phdr = e->e_u.e_elf.e_phdr.e_phdr32; + else + phdr = e->e_u.e_elf.e_phdr.e_phdr64; + + if (phdr == NULL) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (0); + } + + return (elf_flagelf(e, c, flags)); } unsigned int elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags) { - Elf *e; int r; if (s == NULL) return (0); - e = s->s_elf; - - assert(e != NULL); - assert(e->e_kind == ELF_K_ELF); - if ((c != ELF_C_SET && c != ELF_C_CLR) || - e->e_cmd == ELF_C_READ || flags == 0 || (flags & ~ELF_F_DIRTY) != 0) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); @@ -163,31 +161,5 @@ unsigned int elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags) { - Elf *e; - int r; - - if (s == NULL) - return (0); - - e = s->s_elf; - - assert(e != NULL); - assert(e->e_kind == ELF_K_ELF); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - e->e_cmd == ELF_C_READ || flags == 0 || - (flags & ~ELF_F_DIRTY) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - r = 0; - if (c == ELF_C_SET) { - s->s_flags |= LIBELF_F_SHDR_DIRTY; - r = flags; - } else - s->s_flags &= ~LIBELF_F_SHDR_DIRTY; - - return (r); + return (elf_flagscn(s, c, flags)); } - ==== //depot/projects/dtrace/src/lib/libelf/elf_flagdata.3#3 (text+ko) ==== @@ -51,8 +51,8 @@ .Ft "unsigned int" .Fn elf_flagshdr "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" .Sh DESCRIPTION >>> TRUNCATED FOR MAIL (1000 lines) <<<