Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Oct 2006 21:35:53 GMT
From:      John Birrell <jb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 107059 for review
Message-ID:  <200610012135.k91LZr6B089917@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <libelf.h>
-. \" and <gelf.h> (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) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610012135.k91LZr6B089917>