svn commit: r213670 - stable/8/lib/libelf

Kai Wang kaiw at FreeBSD.org
Sun Oct 10 12:20:05 UTC 2010


Author: kaiw
Date: Sun Oct 10 12:20:04 2010
New Revision: 213670
URL: http://svn.freebsd.org/changeset/base/213670

Log:
  MFC r212373:
  
    libelf is overly strict about the type and alignment of Elf_Data
    objects inside one ELF section, which prevents the creation of a ELF
    section with mixed data types. For example, gcc LTO use libelf to
    create a .gnu_lto_XXX section that contains integers and a string
    table, which doesn't work with our libelf implementation.
  
    The changes made in this commit include:
    * Allow Elf_Data type to be different than section type.
    * Relax Elf_Data alignment check.
    * Align each Elf_Data by their own alignment instead of section alignment.

Modified:
  stable/8/lib/libelf/elf_update.c
Directory Properties:
  stable/8/lib/libelf/   (props changed)

Modified: stable/8/lib/libelf/elf_update.c
==============================================================================
--- stable/8/lib/libelf/elf_update.c	Sun Oct 10 12:18:53 2010	(r213669)
+++ stable/8/lib/libelf/elf_update.c	Sun Oct 10 12:20:04 2010	(r213670)
@@ -141,7 +141,7 @@ _libelf_compute_section_extents(Elf *e, 
 
 	/* Compute the section alignment. */
 	STAILQ_FOREACH(d, &s->s_data, d_next)  {
-		if (d->d_type != elftype) {
+		if (d->d_type > ELF_T_LAST) {
 			LIBELF_SET_ERROR(DATA, 0);
 			return (0);
 		}
@@ -149,11 +149,7 @@ _libelf_compute_section_extents(Elf *e, 
 			LIBELF_SET_ERROR(VERSION, 0);
 			return (0);
 		}
-		if ((d_align = d->d_align) % sh_align) {
-			LIBELF_SET_ERROR(LAYOUT, 0);
-			return (0);
-		}
-		if (d_align == 0 || (d_align & (d_align - 1))) {
+		if ((d_align = d->d_align) == 0 || (d_align & (d_align - 1))) {
 			LIBELF_SET_ERROR(DATA, 0);
 			return (0);
 		}
@@ -168,7 +164,7 @@ _libelf_compute_section_extents(Elf *e, 
 			if ((uint64_t) d->d_off + d->d_size > scn_size)
 				scn_size = d->d_off + d->d_size;
 		} else {
-			scn_size = roundup2(scn_size, scn_alignment);
+			scn_size = roundup2(scn_size, d->d_align);
 			d->d_off = scn_size;
 			scn_size += d->d_size;
 		}
@@ -560,8 +556,6 @@ _libelf_write_scn(Elf *e, char *nf, Elf_
 	elftype = _libelf_xlate_shtype(sh_type);
 	assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST);
 
-	msz = _libelf_msize(elftype, ec, e->e_version);
-
 	sh_off = s->s_offset;
 	assert(sh_off % _libelf_falign(elftype, ec) == 0);
 
@@ -608,6 +602,8 @@ _libelf_write_scn(Elf *e, char *nf, Elf_
 
 	STAILQ_FOREACH(d, &s->s_data, d_next) {
 
+		msz = _libelf_msize(d->d_type, ec, e->e_version);
+
 		if ((uint64_t) rc < sh_off + d->d_off)
 			(void) memset(nf + rc,
 			    LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc);
@@ -615,13 +611,12 @@ _libelf_write_scn(Elf *e, char *nf, Elf_
 		rc = sh_off + d->d_off;
 
 		assert(d->d_buf != NULL);
-		assert(d->d_type == (Elf_Type) elftype);
 		assert(d->d_version == e->e_version);
 		assert(d->d_size % msz == 0);
 
 		nobjects = d->d_size / msz;
 
-		fsz = _libelf_fsize(elftype, ec, e->e_version, nobjects);
+		fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects);
 
 		dst.d_buf    = nf + rc;
 		dst.d_size   = fsz;


More information about the svn-src-stable-8 mailing list