+static unsigned char *
+display_gnu_attribute (unsigned char * p,
+ unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
+{
+ int tag;
+ unsigned int len;
+ int val;
+ int type;
+
+ tag = read_uleb128 (p, &len);
+ p += len;
+
+ /* Tag_compatibility is the only generic GNU attribute defined at
+ present. */
+ if (tag == 32)
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf ("flag = %d, vendor = %s\n", val, p);
+ p += strlen ((char *) p) + 1;
+ return p;
+ }
+
+ if ((tag & 2) == 0 && display_proc_gnu_attribute)
+ return display_proc_gnu_attribute (p, tag);
+
+ if (tag & 1)
+ type = 1; /* String. */
+ else
+ type = 2; /* uleb128. */
+ printf (" Tag_unknown_%d: ", tag);
+
+ if (type == 1)
+ {
+ printf ("\"%s\"\n", p);
+ p += strlen ((char *) p) + 1;
+ }
+ else
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf ("%d (0x%x)\n", val, val);
+ }
+
+ return p;
+}
+
+static unsigned char *
+display_power_gnu_attribute (unsigned char *p, int tag)
+{
+ int type;
+ unsigned int len;
+ int val;
+
+ if (tag == Tag_GNU_Power_ABI_FP)
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_GNU_Power_ABI_FP: ");
+
+ switch (val)
+ {
+ case 0:
+ printf ("Hard or soft float\n");
+ break;
+ case 1:
+ printf ("Hard float\n");
+ break;
+ case 2:
+ printf ("Soft float\n");
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+ }
+
+ if (tag == Tag_GNU_Power_ABI_Vector)
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_GNU_Power_ABI_Vector: ");
+ switch (val)
+ {
+ case 0:
+ printf ("Any\n");
+ break;
+ case 1:
+ printf ("Generic\n");
+ break;
+ case 2:
+ printf ("AltiVec\n");
+ break;
+ case 3:
+ printf ("SPE\n");
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+ }
+
+ if (tag & 1)
+ type = 1; /* String. */
+ else
+ type = 2; /* uleb128. */
+ printf (" Tag_unknown_%d: ", tag);
+
+ if (type == 1)
+ {
+ printf ("\"%s\"\n", p);
+ p += strlen ((char *) p) + 1;
+ }
+ else
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf ("%d (0x%x)\n", val, val);
+ }
+
+ return p;
+}
+
+static unsigned char *
+display_mips_gnu_attribute (unsigned char *p, int tag)
+{
+ int type;
+ unsigned int len;
+ int val;
+
+ if (tag == Tag_GNU_MIPS_ABI_FP)
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_GNU_MIPS_ABI_FP: ");
+
+ switch (val)
+ {
+ case 0:
+ printf ("Hard or soft float\n");
+ break;
+ case 1:
+ printf ("Hard float (-mdouble-float)\n");
+ break;
+ case 2:
+ printf ("Hard float (-msingle-float)\n");
+ break;
+ case 3:
+ printf ("Soft float\n");
+ break;
+ case 4:
+ printf ("64-bit float (-mips32r2 -mfp64)\n");
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+ }
+
+ if (tag & 1)
+ type = 1; /* String. */
+ else
+ type = 2; /* uleb128. */
+ printf (" Tag_unknown_%d: ", tag);
+
+ if (type == 1)
+ {
+ printf ("\"%s\"\n", p);
+ p += strlen ((char *) p) + 1;
+ }
+ else
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf ("%d (0x%x)\n", val, val);
+ }
+
+ return p;
+}
+