svn commit: r212199 - in stable/7: cddl/contrib/opensolaris/tools/ctf/cvt lib/libelf

Kai Wang kaiw at FreeBSD.org
Sat Sep 4 12:06:10 UTC 2010


Author: kaiw
Date: Sat Sep  4 12:06:09 2010
New Revision: 212199
URL: http://svn.freebsd.org/changeset/base/212199

Log:
  MFC r210324, r210438.
  
  r210324:
    - Correctly handle sections of type SHT_NOBITS.  For these sections:
      - elf_getdata() and elf_rawdata() should return an "Elf_Data" structure
        that has its "d_buf" member set to NULL and "d_size" member set to
        the nominal 'size' of the section.
      - Update the manual page for these functions.
    - Fix a memory leak in an error handling path inside elf_getdata().
    - Use _libelf_allocate_data() in elf_newdata() for consistency.
  
  r210438: (np)
    Catch up with r210324.  d_buf will be NULL for SHT_NOBITS sections, do not
    attempt to copy from it in that case.

Modified:
  stable/7/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
  stable/7/lib/libelf/elf_data.c
  stable/7/lib/libelf/elf_getdata.3
Directory Properties:
  stable/7/cddl/contrib/opensolaris/   (props changed)
  stable/7/lib/libelf/   (props changed)

Modified: stable/7/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
==============================================================================
--- stable/7/cddl/contrib/opensolaris/tools/ctf/cvt/output.c	Sat Sep  4 12:06:02 2010	(r212198)
+++ stable/7/cddl/contrib/opensolaris/tools/ctf/cvt/output.c	Sat Sep  4 12:06:09 2010	(r212199)
@@ -644,7 +644,7 @@ write_file(Elf *src, const char *srcname
 		}
 
 #if !defined(sun)
-		if (ddata->d_buf == NULL) {
+		if (ddata->d_buf == NULL && sdata->d_buf != NULL) {
 			ddata->d_buf = xmalloc(shdr.sh_size);
 			bcopy(sdata->d_buf, ddata->d_buf, shdr.sh_size);
 		}

Modified: stable/7/lib/libelf/elf_data.c
==============================================================================
--- stable/7/lib/libelf/elf_data.c	Sat Sep  4 12:06:02 2010	(r212198)
+++ stable/7/lib/libelf/elf_data.c	Sat Sep  4 12:06:09 2010	(r212199)
@@ -39,7 +39,6 @@ Elf_Data *
 elf_getdata(Elf_Scn *s, Elf_Data *d)
 {
 	Elf *e;
-	char *dst;
 	size_t fsz, msz, count;
 	int elfclass, elftype;
 	unsigned int sh_type;
@@ -79,20 +78,22 @@ elf_getdata(Elf_Scn *s, Elf_Data *d)
 		sh_align  = s->s_shdr.s_shdr64.sh_addralign;
 	}
 
+	if (sh_type == SHT_NULL)
+		return (NULL);
+
 	if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST ||
-	    elftype > ELF_T_LAST ||
-	    sh_offset + sh_size > (uint64_t) e->e_rawsize) {
+	    elftype > ELF_T_LAST || (sh_type != SHT_NOBITS &&
+	    sh_offset + sh_size > (uint64_t) e->e_rawsize)) {
 		LIBELF_SET_ERROR(SECTION, 0);
 		return (NULL);
 	}
 
-	if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize)(elftype,
-		 (size_t) 1, e->e_version)) == 0) {
+	if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize)
+            (elftype, (size_t) 1, e->e_version)) == 0) {
 		LIBELF_SET_ERROR(UNIMPL, 0);
 		return (NULL);
 	}
 
-
 	if (sh_size % fsz) {
 		LIBELF_SET_ERROR(SECTION, 0);
 		return (NULL);
@@ -104,21 +105,25 @@ elf_getdata(Elf_Scn *s, Elf_Data *d)
 
 	assert(msz > 0);
 
-	if ((dst = malloc(msz*count)) == NULL) {
-		LIBELF_SET_ERROR(RESOURCE, 0);
-		return (NULL);
-	}
-
 	if ((d = _libelf_allocate_data(s)) == NULL)
 		return (NULL);
 
-	d->d_buf     = dst;
+	d->d_buf     = NULL;
 	d->d_off     = 0;
 	d->d_align   = sh_align;
 	d->d_size    = msz * count;
 	d->d_type    = elftype;
 	d->d_version = e->e_version;
 
+	if (sh_type == SHT_NOBITS)
+		return (d);
+
+	if ((d->d_buf = malloc(msz*count)) == NULL) {
+		(void) _libelf_release_data(d);
+		LIBELF_SET_ERROR(RESOURCE, 0);
+		return (NULL);
+	}
+
 	d->d_flags  |= LIBELF_F_MALLOCED;
 	STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
 
@@ -149,14 +154,10 @@ elf_newdata(Elf_Scn *s)
 		if (elf_getdata(s, NULL) == NULL)
 			return (NULL);
 
-	if ((d = malloc(sizeof(Elf_Data))) == NULL) {
-		LIBELF_SET_ERROR(RESOURCE, errno);
+	if ((d = _libelf_allocate_data(s)) == NULL)
 		return (NULL);
-	}
 
 	STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
-	d->d_flags = 0;
-	d->d_scn = s;
 
 	d->d_align = 1;
 	d->d_buf = NULL;
@@ -180,6 +181,7 @@ elf_rawdata(Elf_Scn *s, Elf_Data *d)
 {
 	Elf *e;
 	int elf_class;
+	uint32_t sh_type;
 	uint64_t sh_align, sh_offset, sh_size;
 
 	if (s == NULL || (e = s->s_elf) == NULL ||
@@ -199,19 +201,24 @@ elf_rawdata(Elf_Scn *s, Elf_Data *d)
 	assert(elf_class == ELFCLASS32 || elf_class == ELFCLASS64);
 
 	if (elf_class == ELFCLASS32) {
+		sh_type   = s->s_shdr.s_shdr32.sh_type;
 		sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset;
 		sh_size   = (uint64_t) s->s_shdr.s_shdr32.sh_size;
 		sh_align  = (uint64_t) s->s_shdr.s_shdr32.sh_addralign;
 	} else {
+		sh_type   = s->s_shdr.s_shdr64.sh_type;
 		sh_offset = s->s_shdr.s_shdr64.sh_offset;
 		sh_size   = s->s_shdr.s_shdr64.sh_size;
 		sh_align  = s->s_shdr.s_shdr64.sh_addralign;
 	}
 
+	if (sh_type == SHT_NULL)
+		return (NULL);
+
 	if ((d = _libelf_allocate_data(s)) == NULL)
 		return (NULL);
 
-	d->d_buf     = e->e_rawfile + sh_offset;
+	d->d_buf     = sh_type == SHT_NOBITS ? NULL : e->e_rawfile + sh_offset;
 	d->d_off     = 0;
 	d->d_align   = sh_align;
 	d->d_size    = sh_size;

Modified: stable/7/lib/libelf/elf_getdata.3
==============================================================================
--- stable/7/lib/libelf/elf_getdata.3	Sat Sep  4 12:06:02 2010	(r212198)
+++ stable/7/lib/libelf/elf_getdata.3	Sat Sep  4 12:06:09 2010	(r212199)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2006 Joseph Koshy.  All rights reserved.
+.\" Copyright (c) 2006,2008 Joseph Koshy.  All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -142,6 +142,32 @@ always returns
 .Vt Elf_Data
 structures of type
 .Dv ELF_T_BYTE .
+.Ss Special handling of SHT_NOBITS sections
+For sections of type
+.Dv SHT_NOBITS ,
+the functions
+.Fn elf_getdata
+and
+.Fn elf_rawdata
+return a pointer to a valid
+.Vt Elf_Data
+structure that has its
+.Va d_buf
+member set to NULL and its
+.Va d_size
+member set to the size of the section.
+.Pp
+If an application wishes to create a section of type
+.Dv SHT_NOBITS ,
+it should add a data buffer to the section using function
+.Fn elf_newdata .
+It should then set the
+.Va d_buf
+and
+.Va d_size
+members of the returned
+.Vt Elf_Data
+structure to NULL and the desired size of the section respectively.
 .Sh RETURN VALUES
 These functions return a valid pointer to a data descriptor if successful, or
 NULL if an error occurs.


More information about the svn-src-all mailing list