Hi people! Just a little patch to make readelf -A to print a nice list of comma-separated hwcap names, instead of rubbish :)
2016-06-08 Jose E. Marchesi <jose.march...@oracle.com> * sparc_attrs.c (sparc_check_object_attribute): Fix the calculation of GNU_Sparc_HWCAPS and GNU_Sparc_HWCAPS2 tags values. diff --git a/backends/sparc_attrs.c b/backends/sparc_attrs.c index e95b577..505a01d 100644 --- a/backends/sparc_attrs.c +++ b/backends/sparc_attrs.c @@ -41,33 +41,60 @@ sparc_check_object_attribute (Ebl *ebl __attribute__ ((unused)), const char *vendor, int tag, uint64_t value, const char **tag_name, const char **value_name) { + static const char *hwcaps[30] = + { + "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2", + "asi_blk_init", "fmaf", NULL, "vis3", "hpc", "random", "trans", "fjfmau", + "ima", "asi_cache_sparing", "aes", "des", "kasumi", "camellia", + "md5", "sha1", "sha256", "sha512", "mpmul", "mont", "pause", + "cbcond", "crc32c" + }; + + static const char *hwcaps2[11] = + { + "fjathplus", "vis3b", "adp", "sparc5", "mwait", "xmpmul", + "xmont", "nsec", "fjathhpc", "fjdes", "fjaes" + }; + + /* NAME must be large enough to contain up to N comma-separated list + of atributes in the arrays defined above. */ + static char name [30 * 16 + 30]; + name[0] = '\0'; + if (!strcmp (vendor, "gnu")) switch (tag) { case 4: - *tag_name = "GNU_Sparc_HWCAPS"; - static const char *hwcaps[30] = - { - "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2", - "asi_blk_init", "fmaf", NULL, "vis3", "hpc", "random", "trans", "fjfmau", - "ima", "asi_cache_sparing", "aes", "des", "kasumi", "camellia", - "md5", "sha1", "sha256", "sha512", "mpmul", "mont", "pause", - "cbcond", "crc32c" - }; - if (value < 30 && hwcaps[value] != NULL) - *value_name = hwcaps[value]; - return true; - case 8: - *tag_name = "GNU_Sparc_HWCAPS2"; - static const char *hwcaps2[11] = - { - "fjathplus", "vis3b", "adp", "sparc5", "mwait", "xmpmul", - "xmont", "nsec", "fjathhpc", "fjdes", "fjaes" - }; - if (value < 11) - *value_name = hwcaps2[value]; - return true; + { + const char **caps; + int cap; + + if (tag == 4) + { + *tag_name = "GNU_Sparc_HWCAPS"; + caps = hwcaps; + cap = sizeof (hwcaps) / sizeof (hwcaps[0]); + } + else + { + *tag_name = "GNU_Sparc_HWCAPS2"; + caps = hwcaps2; + cap = sizeof (hwcaps2) / sizeof (hwcaps2[0]); + } + + char *s = name; + for (cap--; cap >= 0; cap--) + if (value & (1 << cap)) + { + if (*s != '\0') + s = strcat (s, ","); + s = strcat (s, caps[cap]); + } + + *value_name = s; + return true; + } } return false;