[DSO_BINARY_TYPE__BUILDID_DEBUGINFO]            = 'b',
                [DSO_BINARY_TYPE__SYSTEM_PATH_DSO]              = 'd',
                [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]          = 'K',
+               [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP]     = 'm',
                [DSO_BINARY_TYPE__GUEST_KALLSYMS]               = 'g',
                [DSO_BINARY_TYPE__GUEST_KMODULE]                = 'G',
+               [DSO_BINARY_TYPE__GUEST_KMODULE_COMP]           = 'M',
                [DSO_BINARY_TYPE__GUEST_VMLINUX]                = 'V',
        };
 
                break;
 
        case DSO_BINARY_TYPE__GUEST_KMODULE:
+       case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
                path__join3(filename, size, symbol_conf.symfs,
                            root_dir, dso->long_name);
                break;
 
        case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
+       case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
                __symbol__join_symfs(filename, size, dso->long_name);
                break;
 
        return ret;
 }
 
+static int decompress_dummy(const char *input __maybe_unused,
+                           int output __maybe_unused)
+{
+       return -1;
+}
+
+static const struct {
+       const char *fmt;
+       int (*decompress)(const char *input, int output);
+} compressions[] = {
+       { "gz", decompress_dummy },
+       { NULL, },
+};
+
+bool is_supported_compression(const char *ext)
+{
+       unsigned i;
+
+       for (i = 0; compressions[i].fmt; i++) {
+               if (!strcmp(ext, compressions[i].fmt))
+                       return true;
+       }
+       return false;
+}
+
+bool is_kmodule_extension(const char *ext)
+{
+       if (strncmp(ext, "ko", 2))
+               return false;
+
+       if (ext[2] == '\0' || (ext[2] == '.' && is_supported_compression(ext+3)))
+               return true;
+
+       return false;
+}
+
+bool is_kernel_module(const char *pathname, bool *compressed)
+{
+       const char *ext = strrchr(pathname, '.');
+
+       if (ext == NULL)
+               return false;
+
+       if (is_supported_compression(ext + 1)) {
+               if (compressed)
+                       *compressed = true;
+               ext -= 3;
+       } else if (compressed)
+               *compressed = false;
+
+       return is_kmodule_extension(ext + 1);
+}
+
+bool decompress_to_file(const char *ext, const char *filename, int output_fd)
+{
+       unsigned i;
+
+       for (i = 0; compressions[i].fmt; i++) {
+               if (!strcmp(ext, compressions[i].fmt))
+                       return !compressions[i].decompress(filename,
+                                                          output_fd);
+       }
+       return false;
+}
+
+bool dso__needs_decompress(struct dso *dso)
+{
+       return dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
+               dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
+}
+
 /*
  * Global list of open DSOs and the counter.
  */
 
        DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
        DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
        DSO_BINARY_TYPE__GUEST_KMODULE,
+       DSO_BINARY_TYPE__GUEST_KMODULE_COMP,
        DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
+       DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP,
        DSO_BINARY_TYPE__KCORE,
        DSO_BINARY_TYPE__GUEST_KCORE,
        DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
 char dso__symtab_origin(const struct dso *dso);
 int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type,
                                   char *root_dir, char *filename, size_t size);
+bool is_supported_compression(const char *ext);
+bool is_kmodule_extension(const char *ext);
+bool is_kernel_module(const char *pathname, bool *compressed);
+bool decompress_to_file(const char *ext, const char *filename, int output_fd);
+bool dso__needs_decompress(struct dso *dso);
 
 /*
  * The dso__data_* external interface provides following functions:
 
 {
        struct map *map;
        struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename);
+       bool compressed;
 
        if (dso == NULL)
                return NULL;
                dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
        else
                dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
+
+       /* _KMODULE_COMP should be next to _KMODULE */
+       if (is_kernel_module(filename, &compressed) && compressed)
+               dso->symtab_type++;
+
        map_groups__insert(&machine->kmaps, map);
        return map;
 }
                        struct map *map;
                        char *long_name;
 
-                       if (dot == NULL || strcmp(dot, ".ko"))
+                       if (dot == NULL)
                                continue;
+
+                       /* On some system, modules are compressed like .ko.gz */
+                       if (is_supported_compression(dot + 1) &&
+                           is_kmodule_extension(dot - 2))
+                               dot -= 3;
+
                        snprintf(dso_name, sizeof(dso_name), "[%.*s]",
                                 (int)(dot - dent->d_name), dent->d_name);
 
                        dot = strrchr(name, '.');
                        if (dot == NULL)
                                goto out_problem;
+                       /* On some system, modules are compressed like .ko.gz */
+                       if (is_supported_compression(dot + 1))
+                               dot -= 3;
+                       if (!is_kmodule_extension(dot + 1))
+                               goto out_problem;
                        snprintf(short_module_name, sizeof(short_module_name),
                                        "[%.*s]", (int)(dot - name), name);
                        strxfrchar(short_module_name, '-', '_');
 
        return 0;
 }
 
+static int decompress_kmodule(struct dso *dso, const char *name,
+                             enum dso_binary_type type)
+{
+       int fd;
+       const char *ext = strrchr(name, '.');
+       char tmpbuf[] = "/tmp/perf-kmod-XXXXXX";
+
+       if ((type != DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP &&
+            type != DSO_BINARY_TYPE__GUEST_KMODULE_COMP) ||
+           type != dso->symtab_type)
+               return -1;
+
+       if (!ext || !is_supported_compression(ext + 1))
+               return -1;
+
+       fd = mkstemp(tmpbuf);
+       if (fd < 0)
+               return -1;
+
+       if (!decompress_to_file(ext + 1, name, fd)) {
+               close(fd);
+               fd = -1;
+       }
+
+       unlink(tmpbuf);
+
+       return fd;
+}
+
 bool symsrc__possibly_runtime(struct symsrc *ss)
 {
        return ss->dynsym || ss->opdsec;
        Elf *elf;
        int fd;
 
-       fd = open(name, O_RDONLY);
+       if (dso__needs_decompress(dso))
+               fd = decompress_kmodule(dso, name, type);
+       else
+               fd = open(name, O_RDONLY);
+
        if (fd < 0)
                return -1;
 
 
        DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
        DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
        DSO_BINARY_TYPE__GUEST_KMODULE,
+       DSO_BINARY_TYPE__GUEST_KMODULE_COMP,
        DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
+       DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP,
        DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
        DSO_BINARY_TYPE__NOT_FOUND,
 };
                return dso->kernel == DSO_TYPE_GUEST_KERNEL;
 
        case DSO_BINARY_TYPE__GUEST_KMODULE:
+       case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
        case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
+       case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
                /*
                 * kernel modules know their symtab type - it's set when
                 * creating a module dso in machine__new_module().
                return -1;
 
        kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
-               dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE;
+               dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
+               dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
+               dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
 
        /*
         * Iterate over candidate debug images.