summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/sgs/elfdump/common/elfdump.c17
-rw-r--r--usr/src/cmd/sgs/elfdump/common/elfdump.msg1
-rw-r--r--usr/src/cmd/sgs/libld/common/unwind.amd.c22
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README1
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