--- old/usr/src/cmd/sgs/elfdump/Makefile.com	2015-03-23 21:41:44.276230485 -0400
+++ new/usr/src/cmd/sgs/elfdump/Makefile.com	2015-03-23 21:41:44.306718423 -0400
@@ -31,7 +31,7 @@
 COMOBJ =	main.o			corenote.o \
 		dwarf.o			struct_layout.o \
 		struct_layout_i386.o 	struct_layout_amd64.o \
- 		struct_layout_sparc.o 	struct_layout_sparcv9.o
+		struct_layout_sparc.o 	struct_layout_sparcv9.o
 
 COMOBJ32 =	elfdump32.o fake_shdr32.o
 
@@ -59,7 +59,6 @@
 LINTFLAGS64 +=	-x
 
 CERRWARN +=	-_gcc=-Wno-uninitialized
-CERRWARN +=	-_gcc=-Wno-switch
 
 BLTDEFS =	msg.h
 BLTDATA =	msg.c
--- old/usr/src/cmd/sgs/elfdump/common/_elfdump.h	2015-03-23 21:41:45.708785348 -0400
+++ new/usr/src/cmd/sgs/elfdump/common/_elfdump.h	2015-03-23 21:41:45.721315777 -0400
@@ -223,8 +223,8 @@
 #endif
 
 extern	corenote_ret_t	corenote(Half, int, Word, const char *, Word);
-extern	void	dump_eh_frame(uchar_t *, size_t, uint64_t, Half e_machine,
-		    uchar_t *e_ident, uint64_t gotaddr);
+extern	void	dump_eh_frame(const char *, char *, uchar_t *, size_t, uint64_t,
+		    Half e_machine, uchar_t *e_ident, uint64_t gotaddr);
 extern	void	dump_hex_bytes(const void *, size_t, int, int, int);
 
 extern	int	fake_shdr_cache32(const char *, int, Elf *, Elf32_Ehdr *,
--- old/usr/src/cmd/sgs/elfdump/common/dwarf.c	2015-03-23 21:41:46.222488863 -0400
+++ new/usr/src/cmd/sgs/elfdump/common/dwarf.c	2015-03-23 21:41:46.246000626 -0400
@@ -40,6 +40,8 @@
  * Data from eh_frame section used by dump_cfi()
  */
 typedef struct {
+	const char	*file;
+	const char	*sh_name;
 	Half		e_machine;	/* ehdr->e_machine */
 	uchar_t		*e_ident;	/* ehdr->e_ident */
 	uint64_t	sh_addr;	/* Address of eh_frame section */
@@ -70,12 +72,18 @@
  *	The requested datum is extracted, byte swapped if necessary,
  *	and returned.
  */
-static uint64_t
-dwarf_extract_uint(uchar_t *data, uint64_t *ndx, int size, int do_swap)
+static dwarf_error_t
+dwarf_extract_uint(uchar_t *data, size_t len, uint64_t *ndx, int size,
+    int do_swap, uint64_t *ret)
 {
+	if (((*ndx + size) > len) ||
+	    ((*ndx + size) < *ndx))
+		return (DW_OVERFLOW);
+
 	switch (size) {
 	case 1:
-		return (data[(*ndx)++]);
+		*ret = (data[(*ndx)++]);
+		return (DW_SUCCESS);
 	case 2:
 		{
 			Half	r;
@@ -88,7 +96,8 @@
 				UL_ASSIGN_HALF(p, data);
 
 			(*ndx) += 2;
-			return (r);
+			*ret = r;
+			return (DW_SUCCESS);
 		}
 	case 4:
 		{
@@ -102,7 +111,8 @@
 				UL_ASSIGN_WORD(p, data);
 
 			(*ndx) += 4;
-			return (r);
+			*ret = r;
+			return (DW_SUCCESS);
 		}
 
 	case 8:
@@ -117,13 +127,14 @@
 				UL_ASSIGN_LWORD(p, data);
 
 			(*ndx) += 8;
-			return (r);
+			*ret = r;
+			return (DW_SUCCESS);
 		}
+	default:
+		return (DW_BAD_ENCODING);
 	}
 
-	/* If here, an invalid size was specified */
-	assert(0);
-	return (0);
+	/* NOTREACHED */
 }
 
 /*
@@ -176,7 +187,7 @@
  *	data - Address of base of eh_frame section being processed
  *	off - Offset of current FDE within eh_frame
  *	ndx - Index of current position within current FDE
- *	len - Length of eh_frame section
+ *	len - Length of FDE
  *	state - Object, CIE, and FDE state for current request
  *	msg - Header message to issue before producing output.
  *	indent - # of indentation characters issued for each line of output.
@@ -263,10 +274,17 @@
 			continue;
 
 		case 0x2:		/* v2: DW_CFA_offset, reg, offset */
-			soper = uleb_extract(&data[off], ndx) *
-			    state->ciedalign;
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			oper1 *= state->ciedalign;
 			dbg_print(0, MSG_ORIG(MSG_CFA_CFAOFF), PREFIX,
-			    REGNAME(LOW_OP(op), rbuf1), EC_SXWORD(soper));
+			    REGNAME(LOW_OP(op), rbuf1), EC_XWORD(oper1));
 			continue;
 
 		case 0x3:		/* v2: DW_CFA_restore, reg */
@@ -301,9 +319,23 @@
 			break;
 
 		case 0x01:		/* v2: DW_CFA_set_loc, address */
-			cur_pc = dwarf_ehe_extract(&data[off], ndx,
-			    state->cieRflag, state->e_ident, B_FALSE,
-			    state->sh_addr, off + *ndx, state->gotaddr);
+			switch (dwarf_ehe_extract(&data[off], len, ndx,
+			    &cur_pc, state->cieRflag, state->e_ident, B_FALSE,
+			    state->sh_addr, off + *ndx, state->gotaddr)) {
+			case DW_OVERFLOW:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			case DW_BAD_ENCODING:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWBADENC),
+				    state->file, state->sh_name,
+				    state->cieRflag);
+				return;
+			case DW_SUCCESS:
+				break;
+			}
 			dbg_print(0, MSG_ORIG(MSG_CFA_CFASET), PREFIX,
 			    EC_XWORD(cur_pc));
 			break;
@@ -317,8 +349,23 @@
 			 * the code.
 			 */
 			i = 1 << (op - 0x02);
-			oper1 = dwarf_extract_uint(data + off, ndx, i,
-			    state->do_swap) * state->ciecalign;
+			switch (dwarf_extract_uint(data + off, len,
+			    ndx, i, state->do_swap, &oper1)) {
+			case DW_BAD_ENCODING:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWBADENC),
+				    state->file, state->sh_name,
+				    i);
+				return;
+			case DW_OVERFLOW:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			case DW_SUCCESS:
+				break;
+			}
+			oper1 *= state->ciecalign;
 			cur_pc += oper1;
 			dbg_print(0, MSG_ORIG(MSG_CFA_ADV_LOC), PREFIX,
 			    loc_str, EC_XWORD(oper1), EC_XWORD(cur_pc));
@@ -326,9 +373,23 @@
 			break;
 
 		case 0x05:		/* v2: DW_CFA_offset_extended,reg,off */
-			oper1 = uleb_extract(&data[off], ndx);
-			soper = uleb_extract(&data[off], ndx) *
-			    state->ciedalign;
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			if (sleb_extract(&data[off], ndx, len, &soper) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			soper *= state->ciedalign;
 			dbg_print(0, MSG_ORIG(MSG_CFA_CFAOFF), PREFIX,
 			    REGNAME(oper1, rbuf1), EC_SXWORD(soper));
 			break;
@@ -337,34 +398,79 @@
 		case 0x0d:		/* v2: DW_CFA_def_cfa_register, reg */
 		case 0x08:		/* v2: DW_CFA_same_value, reg */
 		case 0x07:		/* v2: DW_CFA_undefined, reg */
-			oper1 = uleb_extract(&data[off], ndx);
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
 			dbg_print(0, MSG_ORIG(MSG_CFA_REG), PREFIX,
 			    REGNAME(oper1, rbuf1));
 			break;
 
 
 		case 0x09:		/* v2: DW_CFA_register, reg, reg */
-			oper1 = uleb_extract(&data[off], ndx);
-			oper2 = uleb_extract(&data[off], ndx);
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			if (uleb_extract(&data[off], ndx, len, &oper2) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
 			dbg_print(0, MSG_ORIG(MSG_CFA_REG_REG), PREFIX,
 			    REGNAME(oper1, rbuf1), REGNAME(oper2, rbuf2));
 			break;
 
 		case 0x0c:		/* v2: DW_CFA_def_cfa, reg, offset */
-			oper1 = uleb_extract(&data[off], ndx);
-			oper2 = uleb_extract(&data[off], ndx);
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			if (uleb_extract(&data[off], ndx, len, &oper2) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
 			dbg_print(0, MSG_ORIG(MSG_CFA_REG_OFFLLU), PREFIX,
 			    REGNAME(oper1, rbuf1), EC_XWORD(oper2));
 			break;
 
 		case 0x0e:		/* v2: DW_CFA_def_cfa_offset, offset */
-			oper1 = uleb_extract(&data[off], ndx);
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
 			dbg_print(0, MSG_ORIG(MSG_CFA_LLU), PREFIX,
 			    EC_XWORD(oper1));
 			break;
 
 		case 0x0f:		/* v3: DW_CFA_def_cfa_expression, blk */
-			oper1 = uleb_extract(&data[off], ndx);
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
 			dbg_print(0, MSG_ORIG(MSG_CFA_EBLK), PREFIX,
 			    EC_XWORD(oper1));
 			/* We currently do not decode the expression block */
@@ -373,8 +479,21 @@
 
 		case 0x10:		/* v3: DW_CFA_expression, reg, blk */
 		case 0x16:		/* v3: DW_CFA_val_expression,reg,blk */
-			oper1 = uleb_extract(&data[off], ndx);
-			oper2 = uleb_extract(&data[off], ndx);
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			if (uleb_extract(&data[off], ndx, len, &oper2) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
 			dbg_print(0, MSG_ORIG(MSG_CFA_REG_EBLK), PREFIX,
 			    REGNAME(oper1, rbuf1), EC_XWORD(oper2));
 			/* We currently do not decode the expression block */
@@ -382,47 +501,125 @@
 			break;
 
 		case 0x11:	/* v3: DW_CFA_offset_extended_sf, reg, off */
-			oper1 = uleb_extract(&data[off], ndx);
-			soper = sleb_extract(&data[off], ndx) *
-			    state->ciedalign;
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			if (sleb_extract(&data[off], ndx, len, &soper) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			soper *= state->ciedalign;
 			dbg_print(0, MSG_ORIG(MSG_CFA_CFAOFF), PREFIX,
 			    REGNAME(oper1, rbuf1), EC_SXWORD(soper));
 			break;
 
 		case 0x12:		/* v3: DW_CFA_def_cfa_sf, reg, offset */
-			oper1 = uleb_extract(&data[off], ndx);
-			soper = sleb_extract(&data[off], ndx) *
-			    state->ciedalign;
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			if (sleb_extract(&data[off], ndx, len, &soper) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			soper *= state->ciedalign;
 			dbg_print(0, MSG_ORIG(MSG_CFA_REG_OFFLLD), PREFIX,
 			    REGNAME(oper1, rbuf1), EC_SXWORD(soper));
 			break;
 
 		case 0x13:		/* DW_CFA_def_cfa_offset_sf, offset */
-			soper = sleb_extract(&data[off], ndx) *
-			    state->ciedalign;
+			if (sleb_extract(&data[off], ndx, len, &soper) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			soper *= state->ciedalign;
 			dbg_print(0, MSG_ORIG(MSG_CFA_LLD), PREFIX,
 			    EC_SXWORD(soper));
 			break;
 
 		case 0x14:		/* v3: DW_CFA_val_offset, reg, offset */
-			oper1 = uleb_extract(&data[off], ndx);
-			soper = uleb_extract(&data[off], ndx) *
-			    state->ciedalign;
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			if (sleb_extract(&data[off], ndx, len, &soper) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			soper *= state->ciedalign;
 			dbg_print(0, MSG_ORIG(MSG_CFA_REG_OFFLLD), PREFIX,
 			    REGNAME(oper1, rbuf1), EC_SXWORD(soper));
 			break;
 
 		case 0x15:	/* v3: DW_CFA_val_offset_sf, reg, offset */
-			oper1 = uleb_extract(&data[off], ndx);
-			soper = sleb_extract(&data[off], ndx) *
-			    state->ciedalign;
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			if (sleb_extract(&data[off], ndx, len, &soper) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			soper *= state->ciedalign;
 			dbg_print(0, MSG_ORIG(MSG_CFA_REG_OFFLLD), PREFIX,
 			    REGNAME(oper1, rbuf1), EC_SXWORD(soper));
 			break;
 
 		case 0x1d:	/* GNU: DW_CFA_MIPS_advance_loc8, delta */
-			oper1 = dwarf_extract_uint(data + off, ndx, i,
-			    state->do_swap) * state->ciecalign;
+			switch (dwarf_extract_uint(data + off, len,
+			    ndx, 8, state->do_swap, &oper1)) {
+			case DW_BAD_ENCODING:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWBADENC),
+				    state->file, state->sh_name,
+				    8);
+				return;
+			case DW_OVERFLOW:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			case DW_SUCCESS:
+				break;
+			}
+			oper1 *= state->ciecalign;
 			cur_pc += oper1;
 			dbg_print(0, MSG_ORIG(MSG_CFA_ADV_LOC), PREFIX,
 			    loc_str, EC_XWORD(oper1), EC_XWORD(cur_pc));
@@ -430,16 +627,37 @@
 			break;
 
 		case 0x2e:		/* GNU: DW_CFA_GNU_args_size, size */
-			oper1 = uleb_extract(&data[off], ndx);
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
 			dbg_print(0, MSG_ORIG(MSG_CFA_LLU), PREFIX,
 			    EC_XWORD(oper1));
 
 			break;
 
 		case 0x2f: /* GNU:DW_CFA_GNU_negative_offset_extended,reg,off */
-			oper1 = uleb_extract(&data[off], ndx);
-			soper = -uleb_extract(&data[off], ndx) *
-			    state->ciedalign;
+			if (uleb_extract(&data[off], ndx, len, &oper1) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+
+			if (sleb_extract(&data[off], ndx, len, &soper) ==
+			    DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    state->file, state->sh_name);
+				return;
+			}
+			soper = -soper * state->ciedalign;
+			soper *= state->ciedalign;
 			dbg_print(0, MSG_ORIG(MSG_CFA_CFAOFF), PREFIX,
 			    REGNAME(oper1, rbuf1), EC_SXWORD(soper));
 			break;
@@ -465,17 +683,21 @@
 }
 
 void
-dump_eh_frame(uchar_t *data, size_t datasize, uint64_t sh_addr,
-    Half e_machine, uchar_t *e_ident, uint64_t gotaddr)
+dump_eh_frame(const char *file, char *sh_name, uchar_t *data, size_t datasize,
+    uint64_t sh_addr, Half e_machine, uchar_t *e_ident, uint64_t gotaddr)
 {
 	Conv_dwarf_ehe_buf_t	dwarf_ehe_buf;
 	dump_cfi_state_t	cfi_state;
-	uint64_t	off, ndx;
+	uint64_t	off, ndx, length, id;
 	uint_t		cieid, cielength, cieversion, cieretaddr;
-	int		ciePflag, cieZflag, cieLflag, cieLflag_present;
-	uint_t		cieaugndx, length, id;
-	char		*cieaugstr;
+	int		ciePflag = 0, cieZflag = 0, cieLflag = 0;
+	int		cieLflag_present = 0;
+	uint_t		cieaugndx;
+	char		*cieaugstr = NULL;
+	boolean_t	have_cie = B_FALSE;
 
+	cfi_state.file = file;
+	cfi_state.sh_name = sh_name;
 	cfi_state.e_machine = e_machine;
 	cfi_state.e_ident = e_ident;
 	cfi_state.sh_addr = sh_addr;
@@ -496,28 +718,52 @@
 		 * zero length CIE, thus any information that does follow is
 		 * ignored by ld(1), and is therefore questionable.
 		 */
-		length = (uint_t)dwarf_extract_uint(data + off, &ndx,
-		    4, cfi_state.do_swap);
+		if (dwarf_extract_uint(data + off, datasize - off,
+		    &ndx, 4, cfi_state.do_swap, &length) == DW_OVERFLOW) {
+			(void) fprintf(stderr,
+			    MSG_INTL(MSG_ERR_DWOVRFLW),
+			    file, sh_name);
+			return;
+		}
+
 		if (length == 0) {
 			dbg_print(0, MSG_ORIG(MSG_UNW_ZEROTERM));
 			off += 4;
 			continue;
 		}
 
+		if (length > (datasize - off)) {
+			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADCIEFDELEN),
+			    file, sh_name, EC_XWORD(length),
+			    EC_XWORD(sh_addr + off));
+			/*
+			 * If length is wrong, we have no means to find the
+			 * next entry, just give up
+			 */
+			return;
+		}
+
 		/*
 		 * extract CIE id in native format
 		 */
-		id = (uint_t)dwarf_extract_uint(data + off, &ndx,
-		    4, cfi_state.do_swap);
+		if (dwarf_extract_uint(data + off, datasize - off, &ndx,
+		    4, cfi_state.do_swap, &id) == DW_OVERFLOW) {
+			(void) fprintf(stderr,
+			    MSG_INTL(MSG_ERR_DWOVRFLW),
+			    file, sh_name);
+			return;
+		}
 
 		/*
 		 * A CIE record has an id of '0', otherwise this is a
 		 * FDE entry and the 'id' is the CIE pointer.
 		 */
 		if (id == 0) {
-			uint64_t	persVal, ndx_save;
-			uint_t		axsize;
+			uint64_t	persVal, ndx_save = 0;
+			uint64_t	axsize;
 
+
+			have_cie = B_TRUE;
 			cielength = length;
 			cieid = id;
 			ciePflag = cfi_state.cieRflag = cieZflag = 0;
@@ -536,8 +782,21 @@
 			dbg_print(0, MSG_ORIG(MSG_UNW_CIEVERS),
 			    cieversion, cieaugstr);
 
-			cfi_state.ciecalign = uleb_extract(&data[off], &ndx);
-			cfi_state.ciedalign = sleb_extract(&data[off], &ndx);
+			if (uleb_extract(&data[off], &ndx, datasize - off,
+			    &cfi_state.ciecalign) == DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    file, sh_name);
+				return;
+			}
+
+			if (sleb_extract(&data[off], &ndx, datasize - off,
+			    &cfi_state.ciedalign) == DW_OVERFLOW) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW),
+				    file, sh_name);
+				return;
+			}
 			cieretaddr = data[off + ndx];
 			ndx += 1;
 
@@ -551,9 +810,17 @@
 			for (cieaugndx = 0; cieaugstr[cieaugndx]; cieaugndx++) {
 				switch (cieaugstr[cieaugndx]) {
 				case 'z':
-					axsize = uleb_extract(&data[off], &ndx);
+					if (uleb_extract(&data[off], &ndx,
+					    datasize - off, &axsize) ==
+					    DW_OVERFLOW) {
+						(void) fprintf(stderr,
+						    MSG_INTL(MSG_ERR_DWOVRFLW),
+						    file, sh_name);
+						return;
+					}
+
 					dbg_print(0, MSG_ORIG(MSG_UNW_CIEAXSIZ),
-					    axsize);
+					    EC_XWORD(axsize));
 					cieZflag = 1;
 					/*
 					 * The auxiliary section can contain
@@ -569,9 +836,23 @@
 					ciePflag = data[off + ndx];
 					ndx += 1;
 
-					persVal = dwarf_ehe_extract(&data[off],
-					    &ndx, ciePflag, e_ident, B_FALSE,
-					    sh_addr, off + ndx, gotaddr);
+					switch (dwarf_ehe_extract(&data[off],
+					    datasize - off, &ndx, &persVal,
+					    ciePflag, e_ident, B_FALSE, sh_addr,
+					    off + ndx, gotaddr)) {
+					case DW_OVERFLOW:
+						(void) fprintf(stderr,
+						    MSG_INTL(MSG_ERR_DWOVRFLW),
+						    file, sh_name);
+						return;
+					case DW_BAD_ENCODING:
+						(void) fprintf(stderr,
+						    MSG_INTL(MSG_ERR_DWBADENC),
+						    file, sh_name, ciePflag);
+						return;
+					case DW_SUCCESS:
+						break;
+					}
 					dbg_print(0,
 					    MSG_ORIG(MSG_UNW_CIEAXPERS));
 					dbg_print(0,
@@ -629,30 +910,68 @@
 			int	    fdecieptr = id;
 			uint64_t    fdeaddrrange;
 
+			if (!have_cie) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWNOCIE), file, sh_name);
+				return;
+			}
+
 			dbg_print(0, MSG_ORIG(MSG_UNW_FDE),
 			    EC_XWORD(sh_addr + off));
 			dbg_print(0, MSG_ORIG(MSG_UNW_FDELNGTH),
 			    fdelength, fdecieptr);
 
-			cfi_state.fdeinitloc = dwarf_ehe_extract(&data[off],
-			    &ndx, cfi_state.cieRflag, e_ident, B_FALSE,
-			    sh_addr, off + ndx, gotaddr);
-			fdeaddrrange = dwarf_ehe_extract(&data[off], &ndx,
-			    (cfi_state.cieRflag & ~DW_EH_PE_pcrel),
-			    e_ident, B_FALSE, sh_addr, off + ndx, gotaddr);
+			switch (dwarf_ehe_extract(&data[off], datasize - off,
+			    &ndx, &cfi_state.fdeinitloc, cfi_state.cieRflag,
+			    e_ident, B_FALSE, sh_addr, off + ndx, gotaddr)) {
+			case DW_OVERFLOW:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW), file, sh_name);
+				return;
+			case DW_BAD_ENCODING:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWBADENC), file, sh_name,
+				    cfi_state.cieRflag);
+				return;
+			case DW_SUCCESS:
+				break;
+			}
+
+			switch (dwarf_ehe_extract(&data[off], datasize - off,
+			    &ndx, &fdeaddrrange,
+			    (cfi_state.cieRflag & ~DW_EH_PE_pcrel), e_ident,
+			    B_FALSE, sh_addr, off + ndx, gotaddr)) {
+			case DW_OVERFLOW:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW), file, sh_name);
+				return;
+			case DW_BAD_ENCODING:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWBADENC), file, sh_name,
+				    (cfi_state.cieRflag & ~DW_EH_PE_pcrel));
+				return;
+			case DW_SUCCESS:
+				break;
+			}
 
 			dbg_print(0, MSG_ORIG(MSG_UNW_FDEINITLOC),
 			    EC_XWORD(cfi_state.fdeinitloc),
 			    EC_XWORD(fdeaddrrange),
 			    EC_XWORD(cfi_state.fdeinitloc + fdeaddrrange - 1));
 
-			if (cieaugstr[0])
+			if ((cieaugstr != NULL) && (cieaugstr[0] != '\0'))
 				dbg_print(0, MSG_ORIG(MSG_UNW_FDEAXVAL));
 			if (cieZflag) {
 				uint64_t    val;
 				uint64_t    lndx;
 
-				val = uleb_extract(&data[off], &ndx);
+				if (uleb_extract(&data[off], &ndx,
+				    datasize - off, &val) == DW_OVERFLOW) {
+					(void) fprintf(stderr,
+					    MSG_INTL(MSG_ERR_DWOVRFLW),
+					    file, sh_name);
+					return;
+				}
 				lndx = ndx;
 				ndx += val;
 				dbg_print(0, MSG_ORIG(MSG_UNW_FDEAXSIZE),
@@ -660,10 +979,23 @@
 				if (val && cieLflag_present) {
 					uint64_t    lsda;
 
-					lsda = dwarf_ehe_extract(&data[off],
-					    &lndx, cieLflag, e_ident,
-					    B_FALSE, sh_addr, off + lndx,
-					    gotaddr);
+					switch (dwarf_ehe_extract(&data[off],
+					    datasize - off, &lndx, &lsda,
+					    cieLflag, e_ident, B_FALSE, sh_addr,
+					    off + lndx, gotaddr)) {
+					case DW_OVERFLOW:
+						(void) fprintf(stderr,
+						    MSG_INTL(MSG_ERR_DWOVRFLW),
+						    file, sh_name);
+						return;
+					case DW_BAD_ENCODING:
+						(void) fprintf(stderr,
+						    MSG_INTL(MSG_ERR_DWBADENC),
+						    file, sh_name, cieLflag);
+						return;
+					case DW_SUCCESS:
+						break;
+					}
 					dbg_print(0,
 					    MSG_ORIG(MSG_UNW_FDEAXLSDA),
 					    EC_XWORD(lsda));
--- old/usr/src/cmd/sgs/elfdump/common/elfdump.c	2015-03-23 21:41:46.813527734 -0400
+++ new/usr/src/cmd/sgs/elfdump/common/elfdump.c	2015-03-23 21:41:46.830412501 -0400
@@ -551,7 +551,7 @@
 	Conv_dwarf_ehe_buf_t	dwarf_ehe_buf;
 	uint64_t		ndx, frame_ptr, fde_cnt, tabndx;
 	uint_t			vers, frame_ptr_enc, fde_cnt_enc, table_enc;
-	uint64_t		initloc, initloc0;
+	uint64_t		initloc, initloc0 = 0;
 	uint64_t		gotaddr = 0;
 	int			cnt;
 
@@ -563,6 +563,12 @@
 		}
 	}
 
+	if ((data == NULL) || (datasize == 0)) {
+		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
+		    file, _cache ->c_name);
+		return;
+	}
+
 	/*
 	 * Is this a .eh_frame_hdr?
 	 */
@@ -587,8 +593,20 @@
 
 		dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
 
-		frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
-		    ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
+		switch (dwarf_ehe_extract(data, datasize, &ndx,
+		    &frame_ptr, frame_ptr_enc, ehdr->e_ident, B_TRUE,
+		    shdr->sh_addr, ndx, gotaddr)) {
+		case DW_OVERFLOW:
+			(void) fprintf(stderr, MSG_INTL(MSG_ERR_DWOVRFLW),
+			    file, _cache->c_name);
+			return;
+		case DW_BAD_ENCODING:
+			(void) fprintf(stderr, MSG_INTL(MSG_ERR_DWBADENC),
+			    file, _cache->c_name, frame_ptr_enc);
+			return;
+		case DW_SUCCESS:
+			break;
+		}
 		if (eh_state->hdr_cnt == 1) {
 			eh_state->hdr_ndx = shndx;
 			eh_state->frame_ptr = frame_ptr;
@@ -598,8 +616,20 @@
 		    conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
 		    EC_XWORD(frame_ptr));
 
-		fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
-		    ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
+		switch (dwarf_ehe_extract(data, datasize, &ndx, &fde_cnt,
+		    fde_cnt_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx,
+		    gotaddr)) {
+		case DW_OVERFLOW:
+			(void) fprintf(stderr, MSG_INTL(MSG_ERR_DWOVRFLW),
+			    file, _cache->c_name);
+			return;
+		case DW_BAD_ENCODING:
+			(void) fprintf(stderr, MSG_INTL(MSG_ERR_DWBADENC),
+			    file, _cache->c_name, fde_cnt_enc);
+			return;
+		case DW_SUCCESS:
+			break;
+		}
 
 		dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
 		    conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
@@ -610,18 +640,48 @@
 		dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
 
 		for (tabndx = 0; tabndx < fde_cnt; tabndx++) {
-			initloc = dwarf_ehe_extract(data, &ndx, table_enc,
-			    ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
-			/*LINTED:E_VAR_USED_BEFORE_SET*/
+			uint64_t table;
+
+			switch (dwarf_ehe_extract(data, datasize, &ndx,
+			    &initloc, table_enc, ehdr->e_ident, B_TRUE,
+			    shdr->sh_addr, ndx, gotaddr)) {
+			case DW_OVERFLOW:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW), file,
+				    _cache->c_name);
+				return;
+			case DW_BAD_ENCODING:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWBADENC), file,
+				    _cache->c_name, table_enc);
+				return;
+			case DW_SUCCESS:
+				break;
+			}
 			if ((tabndx != 0) && (initloc0 > initloc))
 				(void) fprintf(stderr,
 				    MSG_INTL(MSG_ERR_BADSORT), file,
 				    _cache->c_name, EC_WORD(tabndx));
+			switch (dwarf_ehe_extract(data, datasize, &ndx, &table,
+			    table_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr,
+			    ndx, gotaddr)) {
+			case DW_OVERFLOW:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWOVRFLW), file,
+				    _cache->c_name);
+				return;
+			case DW_BAD_ENCODING:
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_ERR_DWBADENC), file,
+				    _cache->c_name, table_enc);
+				return;
+			case DW_SUCCESS:
+				break;
+			}
+
 			dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
 			    EC_XWORD(initloc),
-			    EC_XWORD(dwarf_ehe_extract(data, &ndx,
-			    table_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr,
-			    ndx, gotaddr)));
+			    EC_XWORD(table));
 			initloc0 = initloc;
 		}
 	} else {		/* Display the .eh_frame section */
@@ -637,8 +697,8 @@
 			    file, EC_WORD(shndx), _cache->c_name,
 			    conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf));
 		}
-		dump_eh_frame(data, datasize, shdr->sh_addr,
-		    ehdr->e_machine, ehdr->e_ident, gotaddr);
+		dump_eh_frame(file, _cache->c_name, data, datasize,
+		    shdr->sh_addr, ehdr->e_machine, ehdr->e_ident, gotaddr);
 	}
 
 	/*
@@ -736,7 +796,7 @@
 	exception_range_entry	scratch, *ent, *cur_ent = &scratch;
 	char			index[MAXNDXSIZE];
 	Word			i, nelts;
-	Addr			addr, addr0, offset = 0;
+	Addr			addr, addr0 = 0, offset = 0;
 	Addr			exc_addr = _cache->c_shdr->sh_addr;
 
 	dbg_print(0, MSG_INTL(MSG_EXR_TITLE));
@@ -763,7 +823,6 @@
 		 * that addresses grow monotonically.
 		 */
 		addr = SRELPTR(ret_addr);
-		/*LINTED:E_VAR_USED_BEFORE_SET*/
 		if ((i != 0) && (addr0 > addr))
 			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSORT),
 			    file, _cache->c_name, EC_WORD(i));
@@ -3681,6 +3740,9 @@
 				    do_swap, pnstate.pn_type, pnstate.pn_desc,
 				    pnstate.pn_descsz);
 				switch (corenote_ret) {
+				case CORENOTE_R_OK_DUMP:
+					hexdump = 1;
+					break;
 				case CORENOTE_R_OK:
 					hexdump = 0;
 					break;
@@ -3698,6 +3760,13 @@
 					    conv_ehdr_mach(ehdr->e_machine,
 					    0, &inv_buf));
 					break;
+				case CORENOTE_R_BADTYPE:
+					(void) fprintf(stderr,
+					    MSG_INTL(MSG_NOTE_BADCORETYPE),
+					    file,
+					    EC_WORD(pnstate.pn_type));
+					break;
+
 				}
 			}
 
@@ -4918,6 +4987,8 @@
 		    &shnum, &flags) == 0)
 			return (ret);
 		break;
+	case CACHE_OK:
+		break;
 	case CACHE_FAIL:
 		return (ret);
 	}
--- old/usr/src/cmd/sgs/elfdump/common/elfdump.msg	2015-03-23 21:41:47.666729867 -0400
+++ new/usr/src/cmd/sgs/elfdump/common/elfdump.msg	2015-03-23 21:41:47.679329567 -0400
@@ -161,6 +161,7 @@
 			 range (0 - %d): %d\n";
 @ MSG_ERR_BADSIDYNTAG	"%s: [%d: %s][%d]: dynamic element \
 			 [%d: %s][%d] should have type %s: %s\n";
+@ MSG_ERR_BADCIEFDELEN	"%s: %s: invalid CIE/FDE length: %#llx at %#llx\n"                         
 
 
 @ MSG_WARN_INVINTERP1	"%s: PT_INTERP header has no associated section\n"
@@ -181,6 +182,10 @@
 @ MSG_INFO_LINUXOSABI	"%s: %s object has Linux .note.ABI-tag section. \
 			Assuming %s\n"
 
+@ MSG_ERR_DWOVRFLW	"%s: %s: encoded DWARF data exceeds section size\n"
+@ MSG_ERR_DWBADENC	"%s: %s: bad DWARF encoding: %#x\n"
+@ MSG_ERR_DWNOCIE	"%s: %s: no CIE prior to FDE\n"
+
 # exception_range_entry table entries.
 # TRANSLATION_NOTE - the following entries provide for a series of one or more
 # standard 32-bit and 64-bit .exception_ranges table entries that align with
@@ -303,6 +308,7 @@
 			 architecture: %s\n"
 @ MSG_NOTE_BADCOREDATA	"%s: elfdump core file note data truncated or \
 			 otherwise malformed\n"
+@ MSG_NOTE_BADCORETYPE	"%s: unknown note type %#x\n"
 
 @ _END_
 
@@ -396,7 +402,7 @@
 @ MSG_UNW_CIECALGN	" codealign: %#llx  dataalign: %lld  \
 			  retaddr: %d"
 @ MSG_UNW_CIEAXVAL	" Augmentation Data:"
-@ MSG_UNW_CIEAXSIZ	"   size: %d"
+@ MSG_UNW_CIEAXSIZ	"   size: %lld"
 @ MSG_UNW_CIEAXPERS	"   personality:"
 @ MSG_UNW_CIEAXPERSENC	"       encoding: 0x%02x %s"
 @ MSG_UNW_CIEAXPERSRTN	"       routine:  %#08llx"
--- old/usr/src/cmd/sgs/include/dwarf.h	2015-03-23 21:41:48.143619729 -0400
+++ new/usr/src/cmd/sgs/include/dwarf.h	2015-03-23 21:41:48.157199707 -0400
@@ -247,14 +247,22 @@
 	LANG_ANSI_C_V1 = 1
 } LANG;
 
+typedef enum {
+	DW_SUCCESS = 0,
+	DW_BAD_ENCODING,
+	DW_OVERFLOW,
+} dwarf_error_t;
+
 /*
  * Little Endian Base 128 (leb128) encoding/decoding routines
  */
-extern	uint64_t	uleb_extract(unsigned char *, uint64_t *);
-extern	int64_t		sleb_extract(unsigned char *, uint64_t *);
-extern	uint64_t	dwarf_ehe_extract(unsigned char *, uint64_t *,
-			    uint_t, unsigned char *, boolean_t, uint64_t,
-			    uint64_t, uint64_t);
+extern	dwarf_error_t	uleb_extract(unsigned char *, uint64_t *, size_t,
+			    uint64_t *);
+extern	dwarf_error_t	sleb_extract(unsigned char *, uint64_t *, size_t,
+			    int64_t *);
+extern	dwarf_error_t	dwarf_ehe_extract(unsigned char *, size_t, uint64_t *,
+			    uint64_t *, uint_t, unsigned char *, boolean_t,
+			    uint64_t, uint64_t, uint64_t);
 
 #ifdef	__cplusplus
 }
--- old/usr/src/cmd/sgs/libld/common/libld.msg	2015-03-23 21:41:48.610341779 -0400
+++ new/usr/src/cmd/sgs/libld/common/libld.msg	2015-03-23 21:41:48.643752173 -0400
@@ -474,6 +474,10 @@
 @ MSG_SCN_MULTICOMDAT	"file %s: section [%u]%s: cannot be susceptible to multiple \
 			 COMDAT mechanisms: %s"
 
+@ MSG_SCN_DWFOVRFLW	"%s: section %s: encoded DWARF data exceeds \
+			 section size"
+@ MSG_SCN_DWFBADENC	"%s: section %s: invalid DWARF encoding: %#x"                         
+
 # Symbol processing errors
 
 @ MSG_SYM_NOSECDEF	"symbol '%s' in file %s has no section definition"
--- old/usr/src/cmd/sgs/libld/common/unwind.c	2015-03-23 21:41:49.218502494 -0400
+++ new/usr/src/cmd/sgs/libld/common/unwind.c	2015-03-23 21:41:49.233935719 -0400
@@ -537,7 +537,8 @@
 	for (APLIST_TRAVERSE(ofl->ofl_unwind, idx, osp)) {
 		uchar_t		*data;
 		size_t		size;
-		uint64_t	off = 0;
+		uint64_t	off = 0, ujunk;
+		int64_t		sjunk;
 		uint_t		cieRflag = 0, ciePflag = 0;
 		Shdr		*shdr;
 
@@ -601,16 +602,40 @@
 				/*
 				 * calign & dalign
 				 */
-				(void) uleb_extract(&data[off], &ndx);
-				(void) sleb_extract(&data[off], &ndx);
+				if (uleb_extract(&data[off], &ndx,
+				    size - off, &ujunk) == DW_OVERFLOW) {
+					ld_eprintf(ofl, ERR_FATAL,
+					    MSG_INTL(MSG_SCN_DWFOVRFLW),
+					    ofl->ofl_name,
+					    osp->os_name);
+					return (S_ERROR);
+				}
+
+				if (sleb_extract(&data[off], &ndx,
+				    size - off, &sjunk) == DW_OVERFLOW) {
+					ld_eprintf(ofl, ERR_FATAL,
+					    MSG_INTL(MSG_SCN_DWFOVRFLW),
+					    ofl->ofl_name,
+					    osp->os_name);
+					return (S_ERROR);
+				}
 
 				/*
 				 * retreg
 				 */
-				if (cieversion == 1)
+				if (cieversion == 1) {
 					ndx++;
-				else
-					(void) uleb_extract(&data[off], &ndx);
+				} else {
+					if (uleb_extract(&data[off], &ndx,
+					    size - off, &ujunk) ==
+					    DW_OVERFLOW) {
+						ld_eprintf(ofl, ERR_FATAL,
+						    MSG_INTL(MSG_SCN_DWFOVRFLW),
+						    ofl->ofl_name,
+						    osp->os_name);
+						return (S_ERROR);
+					}
+				}
 				/*
 				 * we walk through the augmentation
 				 * section now looking for the Rflag
@@ -621,8 +646,15 @@
 					switch (cieaugstr[cieaugndx]) {
 					case 'z':
 					    /* size */
-					    (void) uleb_extract(&data[off],
-						&ndx);
+					    if (uleb_extract(&data[off],
+					        &ndx, size - off, &ujunk) ==
+						DW_OVERFLOW) {
+						ld_eprintf(ofl, ERR_FATAL,
+						    MSG_INTL(MSG_SCN_DWFOVRFLW),
+						    ofl->ofl_name,
+						    osp->os_name);
+						return (S_ERROR);
+					    }
 					    break;
 					case 'P':
 					    /* personality */
@@ -633,11 +665,26 @@
 						 * value to move on to the next
 						 * field.
 						 */
-					    (void) dwarf_ehe_extract(
-						&data[off],
-						&ndx, ciePflag,
+					    switch (dwarf_ehe_extract(
+						&data[off], size - off,
+						&ndx, &ujunk, ciePflag,
 						ofl->ofl_dehdr->e_ident, B_FALSE,
-						shdr->sh_addr, off + ndx, 0);
+						shdr->sh_addr, off + ndx, 0)) {
+					    case DW_OVERFLOW:
+						ld_eprintf(ofl, ERR_FATAL,
+						    MSG_INTL(MSG_SCN_DWFOVRFLW),
+						    ofl->ofl_name,
+						    osp->os_name);
+						return (S_ERROR);
+					    case DW_BAD_ENCODING:
+						ld_eprintf(ofl, ERR_FATAL,
+						    MSG_INTL(MSG_SCN_DWFBADENC),
+						    ofl->ofl_name,
+						    osp->os_name, ciePflag);
+						return (S_ERROR);
+					    case DW_SUCCESS:
+						break;
+					    }
 					    break;
 					case 'R':
 					    /* code encoding */
@@ -661,11 +708,25 @@
 					gotaddr =
 					    ofl->ofl_osgot->os_shdr->sh_addr;
 
-				initloc = dwarf_ehe_extract(&data[off],
-				    &ndx, cieRflag, ofl->ofl_dehdr->e_ident,
-				    B_FALSE,
-				    shdr->sh_addr, off + ndx,
-				    gotaddr);
+				switch (dwarf_ehe_extract(&data[off],
+				    size - off, &ndx, &initloc, cieRflag,
+				    ofl->ofl_dehdr->e_ident, B_FALSE,
+				    shdr->sh_addr, off + ndx, gotaddr)) {
+				case DW_OVERFLOW:
+					ld_eprintf(ofl, ERR_FATAL,
+					    MSG_INTL(MSG_SCN_DWFOVRFLW),
+					    ofl->ofl_name,
+					    osp->os_name);
+					return (S_ERROR);
+				case DW_BAD_ENCODING:
+					ld_eprintf(ofl, ERR_FATAL,
+					    MSG_INTL(MSG_SCN_DWFBADENC),
+					    ofl->ofl_name,
+					    osp->os_name, cieRflag);
+					return (S_ERROR);
+				case DW_SUCCESS:
+					break;
+				}
 
 				/*
 				 * Ignore FDEs with initloc set to 0.
--- old/usr/src/cmd/sgs/tools/common/leb128.c	2015-03-23 21:41:49.901926642 -0400
+++ new/usr/src/cmd/sgs/tools/common/leb128.c	2015-03-23 21:41:49.984834993 -0400
@@ -99,8 +99,8 @@
  *
  */
 
-uint64_t
-uleb_extract(unsigned char *data, uint64_t *dotp)
+dwarf_error_t
+uleb_extract(unsigned char *data, uint64_t *dotp, size_t len, uint64_t *ret)
 {
 	uint64_t	dot = *dotp;
 	uint64_t	res = 0;
@@ -111,6 +111,9 @@
 	data += dot;
 
 	while (more) {
+		if (dot > len)
+			return (DW_OVERFLOW);
+
 		/*
 		 * Pull off lower 7 bits
 		 */
@@ -134,11 +137,12 @@
 		more = ((*data++) & 0x80) >> 7;
 	}
 	*dotp = dot;
-	return (res);
+	*ret = res;
+	return (DW_SUCCESS);
 }
 
-int64_t
-sleb_extract(unsigned char *data, uint64_t *dotp)
+dwarf_error_t
+sleb_extract(unsigned char *data, uint64_t *dotp, size_t len, int64_t *ret)
 {
 	uint64_t	dot = *dotp;
 	int64_t		res = 0;
@@ -149,6 +153,9 @@
 	data += dot;
 
 	while (more) {
+		if (dot > len)
+			return (DW_OVERFLOW);
+
 		/*
 		 * Pull off lower 7 bits
 		 */
@@ -177,8 +184,8 @@
 	 * Make sure value is properly sign extended.
 	 */
 	res = (res << (64 - shift)) >> (64 - shift);
-
-	return (res);
+	*ret = res;
+	return (DW_SUCCESS);
 }
 
 /*
@@ -196,10 +203,11 @@
  *	dbase - The base address to which DW_EH_PE_datarel is relative
  *		(if frame_hdr is false)
  */
-uint64_t
-dwarf_ehe_extract(unsigned char *data, uint64_t *dotp, uint_t ehe_flags,
-    unsigned char *eident, boolean_t frame_hdr, uint64_t sh_base,
-    uint64_t sh_offset, uint64_t dbase)
+dwarf_error_t
+dwarf_ehe_extract(unsigned char *data, size_t len, uint64_t *dotp,
+    uint64_t *ret, uint_t ehe_flags, unsigned char *eident,
+    boolean_t frame_hdr, uint64_t sh_base, uint64_t sh_offset,
+    uint64_t dbase)
 {
 	uint64_t    dot = *dotp;
 	uint_t	    lsb;
@@ -219,7 +227,8 @@
 
 	switch (ehe_flags & 0x0f) {
 	case DW_EH_PE_omit:
-		return (0);
+		*ret = 0;
+		return (DW_SUCCESS);
 	case DW_EH_PE_absptr:
 		fsize = wordsize;
 		break;
@@ -236,11 +245,12 @@
 		fsize = 2;
 		break;
 	case DW_EH_PE_uleb128:
-		return (uleb_extract(data, dotp));
+		return (uleb_extract(data, dotp, len, ret));
 	case DW_EH_PE_sleb128:
-		return ((uint64_t)sleb_extract(data, dotp));
+		return (sleb_extract(data, dotp, len, (int64_t *)ret));
 	default:
-		return (0);
+		*ret = 0;
+		return (DW_BAD_ENCODING);
 	}
 
 	if (lsb) {
@@ -253,6 +263,9 @@
 		for (cnt = 0; cnt < fsize;
 		    cnt++, dot++) {
 			uint64_t val;
+
+			if (dot > len)
+				return (DW_OVERFLOW);
 			val = data[dot];
 			result |= val << (cnt * 8);
 		}
@@ -264,7 +277,10 @@
 		result = 0;
 		for (cnt = 0; cnt < fsize;
 		    cnt++, dot++) {
-			uint64_t	val;
+			uint64_t val;
+
+			if (dot > len)
+				return (DW_OVERFLOW);
 			val = data[dot];
 			result |= val << ((fsize - cnt - 1) * 8);
 		}
@@ -307,5 +323,6 @@
 	    ((sizeof (uint64_t) - fsize) * 8);
 
 	*dotp = dot;
-	return (result);
+	*ret = result;
+	return (DW_SUCCESS);
 }
