diff options
-rw-r--r-- | usr/src/cmd/sgs/elfdump/common/elfdump.c | 17 | ||||
-rw-r--r-- | usr/src/cmd/sgs/elfdump/common/elfdump.msg | 1 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/unwind.amd.c | 22 | ||||
-rw-r--r-- | usr/src/cmd/sgs/packages/common/SUNWonld-README | 1 |
4 files changed, 31 insertions, 10 deletions
diff --git a/usr/src/cmd/sgs/elfdump/common/elfdump.c b/usr/src/cmd/sgs/elfdump/common/elfdump.c index ea76beec4c..c8b00357a2 100644 --- a/usr/src/cmd/sgs/elfdump/common/elfdump.c +++ b/usr/src/cmd/sgs/elfdump/common/elfdump.c @@ -536,9 +536,22 @@ unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, const char *file, ndx = 0; /* - * extract length in lsb format + * Extract length in lsb format. A zero length + * indicates that this CIE is a terminator and that + * processing for this unwind information should end. + * However, skip this entry and keep processing, just + * in case there is any other information remaining in + * this section. Note, ld(1) will terminate the + * processing of the .eh_frame contents for this file + * after a zero length CIE, thus any information that + * does follow is ignored by ld(1), and is therefore + * questionable. */ - length = LSB32EXTRACT(data + off + ndx); + if ((length = LSB32EXTRACT(data + off + ndx)) == 0) { + dbg_print(0, MSG_ORIG(MSG_UNW_ZEROTERM)); + off += 4; + continue; + } ndx += 4; /* diff --git a/usr/src/cmd/sgs/elfdump/common/elfdump.msg b/usr/src/cmd/sgs/elfdump/common/elfdump.msg index 08bd0f3692..d2575f468b 100644 --- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg +++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg @@ -310,6 +310,7 @@ @ MSG_UNW_BINSRTAB1 " Binary Search Table:" @ MSG_UNW_BINSRTAB2 " InitialLoc FdeLoc" @ MSG_UNW_BINSRTABENT " 0x%016llx 0x%016llx" +@ MSG_UNW_ZEROTERM "ZERO terminator: [0x00000000]" @ MSG_UNW_CIE "CIE: [0x%08llx]" @ MSG_UNW_CIELNGTH " length: 0x%02x cieid: %d" @ MSG_UNW_CIEVERS " version: %d augstring: `%s'" diff --git a/usr/src/cmd/sgs/libld/common/unwind.amd.c b/usr/src/cmd/sgs/libld/common/unwind.amd.c index 5ba9c33416..a6b671ba81 100644 --- a/usr/src/cmd/sgs/libld/common/unwind.amd.c +++ b/usr/src/cmd/sgs/libld/common/unwind.amd.c @@ -356,23 +356,29 @@ make_amd64_unwindhdr(Ofl_desc *ofl) for (LIST_TRAVERSE(&ofl->ofl_unwind, lnp, osp)) { Is_desc *isp; Listnode *_lnp; + for (LIST_TRAVERSE(&osp->os_isdescs, _lnp, isp)) { - unsigned char *data; + uchar_t *data; size_t datasize; uint64_t off; uint_t length, id; - data = (unsigned char *)isp->is_indata->d_buf; + data = (uchar_t *)isp->is_indata->d_buf; datasize = isp->is_indata->d_size; off = 0; while (off < datasize) { - uint_t ndx; + uint_t ndx = 0; - ndx = 0; /* - * extract length in lsb format + * Extract length in lsb format. A zero length + * indicates that this CIE is a terminator and + * that processing for this unwind information + * should end. */ - length = LSB32EXTRACT(data + off + ndx); + if ((length = + LSB32EXTRACT(data + off + ndx)) == 0) + break; + ndx += 4; /* @@ -467,7 +473,7 @@ bintabcompare(const void *p1, const void *p2) uintptr_t populate_amd64_unwindhdr(Ofl_desc *ofl) { - unsigned char *hdrdata; + uchar_t *hdrdata; uint_t *binarytable; uint_t hdroff; Listnode *lnp; @@ -520,7 +526,7 @@ populate_amd64_unwindhdr(Ofl_desc *ofl) fde_count = 0; for (LIST_TRAVERSE(&ofl->ofl_unwind, lnp, osp)) { - unsigned char *fdata; + uchar_t *fdata; uint64_t fdatasize; uint_t foff; uint64_t fndx; diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README index 243c7583dd..24acc63911 100644 --- a/usr/src/cmd/sgs/packages/common/SUNWonld-README +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README @@ -1335,3 +1335,4 @@ Bugid Risk Synopsis 6681761 lies, darn lies, and linker README files 6509323 Need to disable the Multiple Files loading - same name, different directories (or its stat() use) +6685125 ld/elfdump do not handle ZERO terminator .eh_frame amd64 unwind entry |