changeset 14146:51c57658a98a

4003 dldump() can't deal with extended sections Reviewed by: Jason King <jason.brian.king@gmail.com> Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net> Approved by: Robert Mustacchi <rm@joyent.com>
author Richard Lowe <richlowe@richlowe.net>
date Tue, 06 Aug 2013 21:29:05 -0400
parents f40648257ac6
children 6d4e8fd19fe1
files usr/src/cmd/sgs/librtld/common/dldump.c usr/src/cmd/sgs/librtld/common/librtld.msg usr/src/cmd/sgs/packages/common/SUNWonld-README
diffstat 3 files changed, 50 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/sgs/librtld/common/dldump.c	Tue Aug 06 21:21:56 2013 +0000
+++ b/usr/src/cmd/sgs/librtld/common/dldump.c	Tue Aug 06 21:29:05 2013 -0400
@@ -25,7 +25,6 @@
  *
  * dldump(3c) creates a new file image from the specified input file.
  */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include	<sys/param.h>
 #include	<sys/procfs.h>
@@ -158,7 +157,7 @@
 	Elf_Data	*data;
 	Half		endx = 1;
 	int		fd = 0, err, num;
-	size_t		shstr_size = 1;
+	size_t		shstr_size = 1, shndx;
 	Addr		edata;
 	char		*shstr, *_shstr, *ipath = NAME(lmp);
 	prstatus_t	*status = 0, _status;
@@ -309,7 +308,13 @@
 	/*
 	 * Obtain the input files section header string table.
 	 */
-	if ((scn = elf_getscn(ielf, iehdr->e_shstrndx)) == NULL) {
+
+	if (elf_getshdrstrndx(ielf, &shndx) == -1) {
+		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDRSTRNDX), ipath);
+		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
+		return (1);
+	}
+	if ((scn = elf_getscn(ielf, shndx)) == NULL) {
 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSCN), ipath);
 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 		return (1);
@@ -327,10 +332,18 @@
 	 * add an additional entry (marked FLG_C_END) to make the processing of
 	 * this cache easier.
 	 */
-	num = iehdr->e_shnum;
+
+	if (elf_getshdrnum(ielf, &shndx) == -1) {
+		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDRNUM), opath);
+		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
+		return (1);
+	}
+
+	num = shndx;
+
 	if (status)
 		num++;
-	if ((icache = malloc((num + 1) * sizeof (Cache))) == 0) {
+	if ((icache = calloc(num + 1, sizeof (Cache))) == 0) {
 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 		return (1);
 	}
@@ -420,7 +433,7 @@
 			if (status) {
 				_icache++;
 				_icache->c_name =
-					(char *)MSG_ORIG(MSG_SCN_HEAP);
+				    (char *)MSG_ORIG(MSG_SCN_HEAP);
 				_icache->c_flags = FLG_C_HEAP;
 
 				_icache->c_scn = 0;
@@ -624,7 +637,27 @@
 			_icache->c_info = shstr;
 
 			/* LINTED */
-			oehdr->e_shstrndx = (Half)elf_ndxscn(scn);
+			if (elf_ndxscn(scn) >= SHN_LORESERVE) {
+				Elf_Scn	*_scn;
+				Shdr	*shdr0;
+
+				/*
+				 * libelf deals with e_shnum for us, but we
+				 * need to deal with e_shstrndx ourselves.
+				 */
+				oehdr->e_shstrndx = SHN_XINDEX;
+				if ((_scn = elf_getscn(oelf, 0)) == NULL) {
+					eprintf(lml, ERR_ELF,
+					    MSG_ORIG(MSG_ELF_GETSCN), opath);
+					cleanup(ielf, oelf, melf, icache,
+					    mcache, fd, opath);
+					return (1);
+				}
+				shdr0 = elf_getshdr(_scn);
+				shdr0->sh_link = elf_ndxscn(scn);
+			} else {
+				oehdr->e_shstrndx = (Half)elf_ndxscn(scn);
+			}
 
 		} else if (_icache->c_flags == FLG_C_HEAP) {
 			/*
@@ -727,10 +760,16 @@
 		return (1);
 	}
 
+	if (elf_getshdrnum(melf, &shndx) == -1) {
+		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDRNUM), opath);
+		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
+		return (1);
+	}
+
 	/*
 	 * Construct a cache to maintain the memory files section information.
 	 */
-	if ((mcache = malloc(mehdr->e_shnum * sizeof (Cache))) == 0) {
+	if ((mcache = calloc(shndx, sizeof (Cache))) == 0) {
 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 		return (1);
 	}
--- a/usr/src/cmd/sgs/librtld/common/librtld.msg	Tue Aug 06 21:21:56 2013 +0000
+++ b/usr/src/cmd/sgs/librtld/common/librtld.msg	Tue Aug 06 21:29:05 2013 -0400
@@ -22,8 +22,6 @@
 #
 # CDDL HEADER END
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-
 
 @ _START_
 
@@ -70,6 +68,8 @@
 @ MSG_ELF_GETPHDR	"%s: elf_getphdr"
 @ MSG_ELF_GETSCN	"%s: elf_getscn"
 @ MSG_ELF_GETSHDR	"%s: elf_getshdr"
+@ MSG_ELF_GETSHDRNUM	"%s: elf_getshdrnum"
+@ MSG_ELF_GETSHDRSTRNDX	"%s: elf_getshdrstrndx"
 @ MSG_ELF_NEWDATA	"%s: elf_newdata"
 @ MSG_ELF_NEWEHDR	"%s: elf_newehdr"
 @ MSG_ELF_NEWPHDR	"%s: elf_newphdr"
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README	Tue Aug 06 21:21:56 2013 +0000
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README	Tue Aug 06 21:29:05 2013 -0400
@@ -1649,3 +1649,4 @@
 3722	link-editor is over restrictive of R_AMD64_32 addends
 3926	multiple extern map file definitions corrupt symbol table entry
 3999	libld extended section handling is broken
+4003	dldump() can't deal with extended sections