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

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/8/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
  stable/8/lib/libelf/elf_data.c
  stable/8/lib/libelf/elf_getdata.3
Directory Properties:
  stable/8/cddl/contrib/opensolaris/   (props changed)
  stable/8/lib/libelf/   (props changed)

Modified: stable/8/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
==============================================================================
--- stable/8/cddl/contrib/opensolaris/tools/ctf/cvt/output.c    Sat Sep  4 
11:50:23 2010        (r212197)
+++ stable/8/cddl/contrib/opensolaris/tools/ctf/cvt/output.c    Sat Sep  4 
12:06:02 2010        (r212198)
@@ -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/8/lib/libelf/elf_data.c
==============================================================================
--- stable/8/lib/libelf/elf_data.c      Sat Sep  4 11:50:23 2010        
(r212197)
+++ stable/8/lib/libelf/elf_data.c      Sat Sep  4 12:06:02 2010        
(r212198)
@@ -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/8/lib/libelf/elf_getdata.3
==============================================================================
--- stable/8/lib/libelf/elf_getdata.3   Sat Sep  4 11:50:23 2010        
(r212197)
+++ stable/8/lib/libelf/elf_getdata.3   Sat Sep  4 12:06:02 2010        
(r212198)
@@ -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.
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to