Module Name:    src
Committed By:   darran
Date:           Thu Jan 28 21:38:29 UTC 2010

Modified Files:
        src/external/bsd/libelf/dist: elf_data.c elf_getdata.3

Log Message:
Fix a problem with the handling of NOBITS sections (i.e. bss), where the
elf_getdata() function would return an invalid section error if the size
of the section was bigger than the raw size of the elf binary.
This is basically a sync with changeset 10 of the sourceforge repository
for this library (elftoolchain).


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/libelf/dist/elf_data.c
cvs rdiff -u -r1.1.1.1 -r1.2 src/external/bsd/libelf/dist/elf_getdata.3

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/libelf/dist/elf_data.c
diff -u src/external/bsd/libelf/dist/elf_data.c:1.3 src/external/bsd/libelf/dist/elf_data.c:1.4
--- src/external/bsd/libelf/dist/elf_data.c:1.3	Tue Dec 29 17:05:58 2009
+++ src/external/bsd/libelf/dist/elf_data.c	Thu Jan 28 21:38:29 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: elf_data.c,v 1.3 2009/12/29 17:05:58 thorpej Exp $	*/
+/*	$NetBSD: elf_data.c,v 1.4 2010/01/28 21:38:29 darran Exp $	*/
 
 /*-
  * Copyright (c) 2006 Joseph Koshy
@@ -41,7 +41,6 @@
 elf_getdata(Elf_Scn *s, Elf_Data *d)
 {
 	Elf *e;
-	char *dst;
 	size_t fsz, msz, count;
 	int elfclass, elftype;
 	unsigned int sh_type;
@@ -82,8 +81,8 @@
 	}
 
 	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);
 	}
@@ -106,22 +105,27 @@
 
 	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);
+
 	d->d_flags  |= LIBELF_F_MALLOCED;
+
+	if ((d->d_buf = malloc(msz*count)) == NULL) {
+		(void) _libelf_release_data(d);
+		LIBELF_SET_ERROR(RESOURCE, 0);
+		return (NULL);
+	}
+
 	STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
 
 	xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass);
@@ -181,6 +185,7 @@
 elf_rawdata(Elf_Scn *s, Elf_Data *d)
 {
 	Elf *e;
+	uint32_t sh_type;
 	int elf_class;
 	uint64_t sh_align, sh_offset, sh_size;
 
@@ -201,10 +206,12 @@
 	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;
@@ -213,7 +220,7 @@
 	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;

Index: src/external/bsd/libelf/dist/elf_getdata.3
diff -u src/external/bsd/libelf/dist/elf_getdata.3:1.1.1.1 src/external/bsd/libelf/dist/elf_getdata.3:1.2
--- src/external/bsd/libelf/dist/elf_getdata.3:1.1.1.1	Sat Dec 19 05:43:39 2009
+++ src/external/bsd/libelf/dist/elf_getdata.3	Thu Jan 28 21:38:29 2010
@@ -1,6 +1,6 @@
-.\"	$NetBSD: elf_getdata.3,v 1.1.1.1 2009/12/19 05:43:39 thorpej Exp $
+.\"	$NetBSD: elf_getdata.3,v 1.2 2010/01/28 21:38:29 darran Exp $
 .\"
-.\" 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
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD: src/lib/libelf/elf_getdata.3,v 1.2.10.1.2.1 2009/10/25 01:10:29 kensmith Exp $
 .\"
-.Dd August 26, 2006
+.Dd April 7, 2008
 .Os
 .Dt ELF_GETDATA 3
 .Sh NAME
@@ -144,6 +144,32 @@
 .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.

Reply via email to