This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
ELF file than is provided by objdump. In particular it can display DWARF
debugging information which (at the moment) objdump cannot. */
\f
+#include "sysdep.h"
#include <assert.h>
-#include <sys/types.h>
#include <sys/stat.h>
-#include <stdio.h>
#include <time.h>
/* for PATH_MAX */
#define BFD64
#endif
+#include "bfd.h"
+#include "bucomm.h"
#include "dwarf.h"
#include "elf/common.h"
#include "aout/ar.h"
-#include "bucomm.h"
#include "getopt.h"
#include "libiberty.h"
break;
}
+ if (sec->sh_type == SHT_NOBITS)
+ break;
+
dynamic_addr = sec->sh_offset;
dynamic_size = sec->sh_size;
if (!is_relocatable)
return 1;
+ /* SH uses RELA but uses in place value instead of the addend field. */
+ if (elf_header.e_machine == EM_SH)
+ return 0;
+
for (relsec = section_headers;
relsec < section_headers + elf_header.e_shnum;
++relsec)
return p;
}
+
+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 & 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;
+ 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 int
-process_arm_specific (FILE *file)
+process_attributes (FILE *file, const char *public_name,
+ unsigned int proc_type,
+ unsigned char *(*display_pub_attribute) (unsigned char *),
+ unsigned char *(*display_proc_gnu_attribute)
+ (unsigned char *, int))
{
Elf_Internal_Shdr *sect;
unsigned char *contents;
i < elf_header.e_shnum;
i++, sect++)
{
- if (sect->sh_type != SHT_ARM_ATTRIBUTES)
+ if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
continue;
contents = get_data (NULL, file, sect->sh_offset, 1, sect->sh_size,
{
int namelen;
bfd_boolean public_section;
+ bfd_boolean gnu_section;
section_len = byte_get (p, 4);
p += 4;
}
len -= section_len;
printf ("Attribute Section: %s\n", p);
- if (strcmp ((char *)p, "aeabi") == 0)
+ if (public_name && strcmp ((char *)p, public_name) == 0)
public_section = TRUE;
else
public_section = FALSE;
+ if (strcmp ((char *)p, "gnu") == 0)
+ gnu_section = TRUE;
+ else
+ gnu_section = FALSE;
namelen = strlen ((char *)p) + 1;
p += namelen;
section_len -= namelen + 4;
if (public_section)
{
while (p < end)
- p = display_arm_attribute(p);
+ p = display_pub_attribute (p);
+ }
+ else if (gnu_section)
+ {
+ while (p < end)
+ p = display_gnu_attribute (p,
+ display_proc_gnu_attribute);
}
else
{
return 1;
}
+static int
+process_arm_specific (FILE *file)
+{
+ return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
+ display_arm_attribute, NULL);
+}
+
+static int
+process_power_specific (FILE *file)
+{
+ return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
+ display_power_gnu_attribute);
+}
+
static int
process_mips_specific (FILE *file)
{
size_t options_offset = 0;
size_t conflicts_offset = 0;
+ process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
+ display_mips_gnu_attribute);
+
/* We have a lot of special sections. Thanks SGI! */
if (dynamic_section == NULL)
/* No information available. */
case EM_MIPS_RS3_LE:
return process_mips_specific (file);
break;
+ case EM_PPC:
+ return process_power_specific (file);
+ break;
default:
break;
}