Author: delphij
Date: Fri Aug 23 23:34:54 2013
New Revision: 254746
URL: http://svnweb.freebsd.org/changeset/base/254746

Log:
  Update vendor/illumos/dist to 14148:fe28bd725808:
  
  Illumos DTrace issues:
    4005 libctf can't deal with extended sections

Modified:
  vendor/illumos/dist/lib/libctf/common/ctf_lib.c

Modified: vendor/illumos/dist/lib/libctf/common/ctf_lib.c
==============================================================================
--- vendor/illumos/dist/lib/libctf/common/ctf_lib.c     Fri Aug 23 23:25:58 
2013        (r254745)
+++ vendor/illumos/dist/lib/libctf/common/ctf_lib.c     Fri Aug 23 23:34:54 
2013        (r254746)
@@ -193,6 +193,7 @@ ctf_fdopen(int fd, int *errp)
 {
        ctf_sect_t ctfsect, symsect, strsect;
        ctf_file_t *fp = NULL;
+       size_t shstrndx, shnum;
 
        struct stat64 st;
        ssize_t nbytes;
@@ -255,11 +256,10 @@ ctf_fdopen(int fd, int *errp)
 #else
                uchar_t order = ELFDATA2LSB;
 #endif
-               GElf_Half i, n;
                GElf_Shdr *sp;
 
                void *strs_map;
-               size_t strs_mapsz;
+               size_t strs_mapsz, i;
                const char *strs;
 
                if (hdr.e32.e_ident[EI_DATA] != order)
@@ -275,11 +275,38 @@ ctf_fdopen(int fd, int *errp)
                        ehdr_to_gelf(&e32, &hdr.e64);
                }
 
-               if (hdr.e64.e_shstrndx >= hdr.e64.e_shnum)
+               shnum = hdr.e64.e_shnum;
+               shstrndx = hdr.e64.e_shstrndx;
+
+               /* Extended ELF sections */
+               if ((shstrndx == SHN_XINDEX) || (shnum == 0)) {
+                       if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
+                               Elf32_Shdr x32;
+
+                               if (pread64(fd, &x32, sizeof (x32),
+                                   hdr.e64.e_shoff) != sizeof (x32))
+                                       return (ctf_set_open_errno(errp,
+                                           errno));
+
+                               shnum = x32.sh_size;
+                               shstrndx = x32.sh_link;
+                       } else {
+                               Elf64_Shdr x64;
+
+                               if (pread64(fd, &x64, sizeof (x64),
+                                   hdr.e64.e_shoff) != sizeof (x64))
+                                       return (ctf_set_open_errno(errp,
+                                           errno));
+
+                               shnum = x64.sh_size;
+                               shstrndx = x64.sh_link;
+                       }
+               }
+
+               if (shstrndx >= shnum)
                        return (ctf_set_open_errno(errp, ECTF_CORRUPT));
 
-               n = hdr.e64.e_shnum;
-               nbytes = sizeof (GElf_Shdr) * n;
+               nbytes = sizeof (GElf_Shdr) * shnum;
 
                if ((sp = malloc(nbytes)) == NULL)
                        return (ctf_set_open_errno(errp, errno));
@@ -291,7 +318,7 @@ ctf_fdopen(int fd, int *errp)
                if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
                        Elf32_Shdr *sp32;
 
-                       nbytes = sizeof (Elf32_Shdr) * n;
+                       nbytes = sizeof (Elf32_Shdr) * shnum;
 
                        if ((sp32 = malloc(nbytes)) == NULL || pread64(fd,
                            sp32, nbytes, hdr.e64.e_shoff) != nbytes) {
@@ -299,7 +326,7 @@ ctf_fdopen(int fd, int *errp)
                                return (ctf_set_open_errno(errp, errno));
                        }
 
-                       for (i = 0; i < n; i++)
+                       for (i = 0; i < shnum; i++)
                                shdr_to_gelf(&sp32[i], &sp[i]);
 
                        free(sp32);
@@ -313,14 +340,14 @@ ctf_fdopen(int fd, int *errp)
                 * Now mmap the section header strings section so that we can
                 * perform string comparison on the section names.
                 */
-               strs_mapsz = sp[hdr.e64.e_shstrndx].sh_size +
-                   (sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
+               strs_mapsz = sp[shstrndx].sh_size +
+                   (sp[shstrndx].sh_offset & ~_PAGEMASK);
 
                strs_map = mmap64(NULL, strs_mapsz, PROT_READ, MAP_PRIVATE,
-                   fd, sp[hdr.e64.e_shstrndx].sh_offset & _PAGEMASK);
+                   fd, sp[shstrndx].sh_offset & _PAGEMASK);
 
                strs = (const char *)strs_map +
-                   (sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
+                   (sp[shstrndx].sh_offset & ~_PAGEMASK);
 
                if (strs_map == MAP_FAILED) {
                        free(sp);
@@ -331,15 +358,15 @@ ctf_fdopen(int fd, int *errp)
                 * Iterate over the section header array looking for the CTF
                 * section and symbol table.  The strtab is linked to symtab.
                 */
-               for (i = 0; i < n; i++) {
+               for (i = 0; i < shnum; i++) {
                        const GElf_Shdr *shp = &sp[i];
                        const GElf_Shdr *lhp = &sp[shp->sh_link];
 
-                       if (shp->sh_link >= hdr.e64.e_shnum)
+                       if (shp->sh_link >= shnum)
                                continue; /* corrupt sh_link field */
 
-                       if (shp->sh_name >= sp[hdr.e64.e_shstrndx].sh_size ||
-                           lhp->sh_name >= sp[hdr.e64.e_shstrndx].sh_size)
+                       if (shp->sh_name >= sp[shstrndx].sh_size ||
+                           lhp->sh_name >= sp[shstrndx].sh_size)
                                continue; /* corrupt sh_name field */
 
                        if (shp->sh_type == SHT_PROGBITS &&
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to