[PATCH 2/5] readelf: Adapt src/readelf -h/-S/-r/-w/-l/-d/-a on mips
Ying Huang
ying.huang@oss.cipunited.com
Tue Apr 11 08:12:43 GMT 2023
From: Ying Huang <ying.huang@oss.cipunited.com>
-h: support show Flags name
-S: support show mips related section type
-r: support show type and relocation info value of Relocation section
-w: can work and can show correct "strp" contents
-l: support show mips related program header entry type
-d: can show mips related Dynamic type name
-a: support show complete Object attribute section ".gnu.attributes"
---
backends/Makefile.am | 2 +-
backends/mips_attrs.c | 107 +++++++
backends/mips_init.c | 7 +
backends/mips_symbol.c | 572 +++++++++++++++++++++++++++++++++++++
libebl/eblreloctypecheck.c | 8 +-
libebl/eblreloctypename.c | 8 +-
libelf/elf.h | 93 +++++-
src/readelf.c | 190 +++++++++---
8 files changed, 932 insertions(+), 55 deletions(-)
create mode 100644 backends/mips_attrs.c
diff --git a/backends/Makefile.am b/backends/Makefile.am
index bda1b604..428a1a03 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -100,7 +100,7 @@ loongarch_SRCS = loongarch_init.c loongarch_symbol.c
arc_SRCS = arc_init.c arc_symbol.c
-mips_SRCS = mips_init.c mips_symbol.c
+mips_SRCS = mips_init.c mips_symbol.c mips_attrs.c
libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \
$(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \
diff --git a/backends/mips_attrs.c b/backends/mips_attrs.c
new file mode 100644
index 00000000..1419814e
--- /dev/null
+++ b/backends/mips_attrs.c
@@ -0,0 +1,107 @@
+/* Object attribute tags for MIPS.
+ Copyright (C) 2023 CIP United Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND arm_
+#include "libebl_CPU.h"
+
+#define KNOWN_VALUES(...) do \
+ { \
+ static const char *table[] = { __VA_ARGS__ }; \
+ if (value < sizeof table / sizeof table[0]) \
+ *value_name = table[value]; \
+ } while (0)
+
+/* copy binutils-2.34/binutils/readelf.c display_mips_gnu_attribute */
+bool
+mips_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
+ const char *vendor, int tag, uint64_t value,
+ const char **tag_name, const char **value_name)
+{
+ if (!strcmp (vendor, "gnu"))
+ switch (tag)
+ {
+ case Tag_GNU_MIPS_ABI_FP:
+ *tag_name = "Tag_GNU_MIPS_ABI_FP";
+ switch (value)
+ {
+ case Val_GNU_MIPS_ABI_FP_ANY:
+ *value_name = "Hard or soft float";
+ return true;
+ case Val_GNU_MIPS_ABI_FP_DOUBLE:
+ *value_name = "Hard float (double precision)";
+ return true;
+ case Val_GNU_MIPS_ABI_FP_SINGLE:
+ *value_name = "Hard float (single precision)";
+ return true;
+ case Val_GNU_MIPS_ABI_FP_SOFT:
+ *value_name = "Soft float";
+ return true;
+ case Val_GNU_MIPS_ABI_FP_OLD_64:
+ *value_name = "Hard float (MIPS32r2 64-bit FPU 12 callee-saved)";
+ return true;
+ case Val_GNU_MIPS_ABI_FP_XX:
+ *value_name = "Hard float (32-bit CPU, Any FPU)";
+ return true;
+ case Val_GNU_MIPS_ABI_FP_64:
+ *value_name = "Hard float (32-bit CPU, 64-bit FPU)";
+ return true;
+ case Val_GNU_MIPS_ABI_FP_64A:
+ *value_name = "Hard float compat (32-bit CPU, 64-bit FPU)";
+ return true;
+ case Val_GNU_MIPS_ABI_FP_NAN2008:
+ *value_name = "NaN 2008 compatibility";
+ return true;
+ default:
+ return true;
+ }
+ return true;
+ case Tag_GNU_MIPS_ABI_MSA:
+ *tag_name = "Tag_GNU_MIPS_ABI_MSA";
+ switch (value)
+ {
+ case Val_GNU_MIPS_ABI_MSA_ANY:
+ *value_name = "Any MSA or not";
+ return true;
+ case Val_GNU_MIPS_ABI_MSA_128:
+ *value_name = "128-bit MSA";
+ return true;
+ default:
+ return true;
+ }
+ return true;
+ }
+
+ return false;
+}
diff --git a/backends/mips_init.c b/backends/mips_init.c
index f70d62e4..5bba822b 100644
--- a/backends/mips_init.c
+++ b/backends/mips_init.c
@@ -45,5 +45,12 @@ mips_init (Elf *elf __attribute__ ((unused)),
/* We handle it. */
mips_init_reloc (eh);
HOOK (eh, reloc_simple_type);
+ HOOK (eh, section_type_name);
+ HOOK (eh, machine_flag_check);
+ HOOK (eh, machine_flag_name);
+ HOOK (eh, segment_type_name);
+ HOOK (eh, dynamic_tag_check);
+ HOOK (eh, dynamic_tag_name);
+ HOOK (eh, check_object_attribute);
return eh;
}
diff --git a/backends/mips_symbol.c b/backends/mips_symbol.c
index 4f1bd3e6..e760d58d 100644
--- a/backends/mips_symbol.c
+++ b/backends/mips_symbol.c
@@ -39,6 +39,7 @@
#define BACKEND mips_
#include "libebl_CPU.h"
#include "libelfP.h"
+
/* Check for the simple reloc types. */
Elf_Type
mips_reloc_simple_type (Ebl *ebl, int type,
@@ -60,3 +61,574 @@ mips_reloc_simple_type (Ebl *ebl, int type,
return ELF_T_NUM;
}
}
+
+/* copy binutils-2.34/binutils/readelf.c get_mips_section_type_name */
+const char *
+mips_section_type_name (int type,
+ char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (type)
+ {
+ case SHT_MIPS_LIBLIST:
+ return "MIPS_LIBLIST";
+ case SHT_MIPS_MSYM:
+ return "MIPS_MSYM";
+ case SHT_MIPS_CONFLICT:
+ return "MIPS_CONFLICT";
+ case SHT_MIPS_GPTAB:
+ return "MIPS_GPTAB";
+ case SHT_MIPS_UCODE:
+ return "MIPS_UCODE";
+ case SHT_MIPS_DEBUG:
+ return "MIPS_DEBUG";
+ case SHT_MIPS_REGINFO:
+ return "MIPS_REGINFO";
+ case SHT_MIPS_PACKAGE:
+ return "MIPS_PACKAGE";
+ case SHT_MIPS_PACKSYM:
+ return "MIPS_PACKSYM";
+ case SHT_MIPS_RELD:
+ return "MIPS_RELD";
+ case SHT_MIPS_IFACE:
+ return "MIPS_IFACE";
+ case SHT_MIPS_CONTENT:
+ return "MIPS_CONTENT";
+ case SHT_MIPS_OPTIONS:
+ return "MIPS_OPTIONS";
+ case SHT_MIPS_SHDR:
+ return "MIPS_SHDR";
+ case SHT_MIPS_FDESC:
+ return "MIPS_FDESC";
+ case SHT_MIPS_EXTSYM:
+ return "MIPS_EXTSYM";
+ case SHT_MIPS_DENSE:
+ return "MIPS_DENSE";
+ case SHT_MIPS_PDESC:
+ return "MIPS_PDESC";
+ case SHT_MIPS_LOCSYM:
+ return "MIPS_LOCSYM";
+ case SHT_MIPS_AUXSYM:
+ return "MIPS_AUXSYM";
+ case SHT_MIPS_OPTSYM:
+ return "MIPS_OPTSYM";
+ case SHT_MIPS_LOCSTR:
+ return "MIPS_LOCSTR";
+ case SHT_MIPS_LINE:
+ return "MIPS_LINE";
+ case SHT_MIPS_RFDESC:
+ return "MIPS_RFDESC";
+ case SHT_MIPS_DELTASYM:
+ return "MIPS_DELTASYM";
+ case SHT_MIPS_DELTAINST:
+ return "MIPS_DELTAINST";
+ case SHT_MIPS_DELTACLASS:
+ return "MIPS_DELTACLASS";
+ case SHT_MIPS_DWARF:
+ return "MIPS_DWARF";
+ case SHT_MIPS_DELTADECL:
+ return "MIPS_DELTADECL";
+ case SHT_MIPS_SYMBOL_LIB:
+ return "MIPS_SYMBOL_LIB";
+ case SHT_MIPS_EVENTS:
+ return "MIPS_EVENTS";
+ case SHT_MIPS_TRANSLATE:
+ return "MIPS_TRANSLATE";
+ case SHT_MIPS_PIXIE:
+ return "MIPS_PIXIE";
+ case SHT_MIPS_XLATE:
+ return "MIPS_XLATE";
+ case SHT_MIPS_XLATE_DEBUG:
+ return "MIPS_XLATE_DEBUG";
+ case SHT_MIPS_WHIRL:
+ return "MIPS_WHIRL";
+ case SHT_MIPS_EH_REGION:
+ return "MIPS_EH_REGION";
+ case SHT_MIPS_XLATE_OLD:
+ return "MIPS_XLATE_OLD";
+ case SHT_MIPS_PDR_EXCEPTION:
+ return "MIPS_PDR_EXCEPTION";
+ case SHT_MIPS_ABIFLAGS:
+ return "MIPS_ABIFLAGS";
+ case SHT_MIPS_XHASH:
+ return "MIPS_XHASH";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+/* Check whether machine flags are valid. */
+bool
+mips_machine_flag_check (GElf_Word flags)
+{
+ if ((flags &~ (EF_MIPS_NOREORDER |
+ EF_MIPS_PIC |
+ EF_MIPS_CPIC |
+ EF_MIPS_UCODE |
+ EF_MIPS_ABI2 |
+ EF_MIPS_OPTIONS_FIRST |
+ EF_MIPS_32BITMODE |
+ EF_MIPS_NAN2008 |
+ EF_MIPS_FP64 |
+ EF_MIPS_ARCH_ASE_MDMX |
+ EF_MIPS_ARCH_ASE_M16 |
+ EF_MIPS_ARCH_ASE_MICROMIPS)) == 0)
+ return false;
+
+ switch(flags & EF_MIPS_MACH)
+ {
+ case E_MIPS_MACH_3900:
+ case E_MIPS_MACH_4010:
+ case E_MIPS_MACH_4100:
+ case E_MIPS_MACH_4111:
+ case E_MIPS_MACH_4120:
+ case E_MIPS_MACH_4650:
+ case E_MIPS_MACH_5400:
+ case E_MIPS_MACH_5500:
+ case E_MIPS_MACH_5900:
+ case E_MIPS_MACH_SB1:
+ case E_MIPS_MACH_9000:
+ case E_MIPS_MACH_LS2E:
+ case E_MIPS_MACH_LS2F:
+ case E_MIPS_MACH_GS464:
+ case E_MIPS_MACH_GS464E:
+ case E_MIPS_MACH_GS264E:
+ case E_MIPS_MACH_OCTEON:
+ case E_MIPS_MACH_OCTEON2:
+ case E_MIPS_MACH_OCTEON3:
+ case E_MIPS_MACH_XLR:
+ case E_MIPS_MACH_IAMR2:
+ case 0:
+ break;
+ default:
+ return false;
+ }
+
+ switch ((flags & EF_MIPS_ABI))
+ {
+ case E_MIPS_ABI_O32:
+ case E_MIPS_ABI_O64:
+ case E_MIPS_ABI_EABI32:
+ case E_MIPS_ABI_EABI64:
+ case 0:
+ break;
+ default:
+ return false;
+ }
+
+ switch ((flags & EF_MIPS_ARCH))
+ {
+ case E_MIPS_ARCH_1:
+ case E_MIPS_ARCH_2:
+ case E_MIPS_ARCH_3:
+ case E_MIPS_ARCH_4:
+ case E_MIPS_ARCH_5:
+ case E_MIPS_ARCH_32:
+ case EF_MIPS_ARCH_32R2:
+ case E_MIPS_ARCH_32R6:
+ case E_MIPS_ARCH_64:
+ case EF_MIPS_ARCH_64R2:
+ case E_MIPS_ARCH_64R6:
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
+/* copy binutils-2.34/binutils/readelf.c get_machine_flags */
+const char *
+mips_machine_flag_name (Elf64_Word orig __attribute__ ((unused)), Elf64_Word *flagref)
+{
+ if (*flagref & EF_MIPS_NOREORDER)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_NOREORDER);
+ return "noreorder";
+ }
+
+ if (*flagref & EF_MIPS_PIC)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_PIC);
+ return "pic";
+ }
+
+ if (*flagref & EF_MIPS_CPIC)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_CPIC);
+ return "cpic";
+ }
+
+ if (*flagref & EF_MIPS_UCODE)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_UCODE);
+ return "ugen_reserved";
+ }
+
+ if (*flagref & EF_MIPS_ABI2)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_ABI2);
+ return "abi2";
+ }
+
+ if (*flagref & EF_MIPS_OPTIONS_FIRST)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_OPTIONS_FIRST);
+ return "odk first";
+ }
+
+ if (*flagref & EF_MIPS_32BITMODE)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_32BITMODE);
+ return "32bitmode";
+ }
+
+ if (*flagref & EF_MIPS_NAN2008)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_NAN2008);
+ return "nan2008";
+ }
+
+ if (*flagref & EF_MIPS_FP64)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_FP64);
+ return "fp64";
+ }
+
+ switch (*flagref & EF_MIPS_MACH)
+ {
+ case E_MIPS_MACH_3900:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_3900);
+ return "3900";
+ case E_MIPS_MACH_4010:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_4010);
+ return "4010";
+ case E_MIPS_MACH_4100:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_4100);
+ return "4100";
+ case E_MIPS_MACH_4111:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_4111);
+ return "4111";
+ case E_MIPS_MACH_4120:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_4120);
+ return "4120";
+ case E_MIPS_MACH_4650:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_4650);
+ return "4650";
+ case E_MIPS_MACH_5400:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_5400);
+ return "5400";
+ case E_MIPS_MACH_5500:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_5500);
+ return "5500";
+ case E_MIPS_MACH_5900:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_5900);
+ return "5900";
+ case E_MIPS_MACH_SB1:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_SB1);
+ return "sb1";
+ case E_MIPS_MACH_9000:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_9000);
+ return "9000";
+ case E_MIPS_MACH_LS2E:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_LS2E);
+ return "loongson-2e";
+ case E_MIPS_MACH_LS2F:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_LS2F);
+ return "loongson-2f";
+ case E_MIPS_MACH_GS464:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_GS464);
+ return "gs464";
+ case E_MIPS_MACH_GS464E:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_GS464E);
+ return "gs464e";
+ case E_MIPS_MACH_GS264E:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_GS264E);
+ return "gs264e";
+ case E_MIPS_MACH_OCTEON:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_OCTEON);
+ return "octeon";
+ case E_MIPS_MACH_OCTEON2:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_OCTEON2);
+ return "octeon2";
+ case E_MIPS_MACH_OCTEON3:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_OCTEON3);
+ return "octeon3";
+ case E_MIPS_MACH_XLR:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_XLR);
+ return "xlr";
+ case E_MIPS_MACH_IAMR2:
+ *flagref &= ~((Elf64_Word) E_MIPS_MACH_IAMR2);
+ return "interaptiv-mr2";
+ case 0:
+ /* We simply ignore the field in this case to avoid confusion:
+ MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
+ extension. */
+ break;
+ default:
+ *flagref &= ~((Elf64_Word) EF_MIPS_MACH);
+ return "unknown CPU";
+ }
+ switch (*flagref & EF_MIPS_ABI)
+ {
+ case E_MIPS_ABI_O32:
+ *flagref &= ~((Elf64_Word) E_MIPS_ABI_O32);
+ return "o32";
+ case E_MIPS_ABI_O64:
+ *flagref &= ~((Elf64_Word) E_MIPS_ABI_O64);
+ return "o64";
+ case E_MIPS_ABI_EABI32:
+ *flagref &= ~((Elf64_Word) E_MIPS_ABI_EABI32);
+ return "eabi32";
+ case E_MIPS_ABI_EABI64:
+ *flagref &= ~((Elf64_Word) E_MIPS_ABI_EABI64);
+ return "eabi64";
+ case 0:
+ /* We simply ignore the field in this case to avoid confusion:
+ MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
+ This means it is likely to be an o32 file, but not for
+ sure. */
+ break;
+ default:
+ *flagref &= ~((Elf64_Word) EF_MIPS_ABI);
+ return "unknown ABI";
+ }
+
+ if (*flagref & EF_MIPS_ARCH_ASE_MDMX)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_ASE_MDMX);
+ return "mdmx";
+ }
+
+ if (*flagref & EF_MIPS_ARCH_ASE_M16)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_ASE_M16);
+ return "mips16";
+ }
+
+ if (*flagref & EF_MIPS_ARCH_ASE_MICROMIPS)
+ {
+ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_ASE_MICROMIPS);
+ return "micromips";
+ }
+
+ switch (*flagref & EF_MIPS_ARCH)
+ {
+ case E_MIPS_ARCH_1:
+ *flagref &= ~((Elf64_Word) E_MIPS_ARCH_1);
+ return "mips1";
+ case E_MIPS_ARCH_2:
+ *flagref &= ~((Elf64_Word) E_MIPS_ARCH_2);
+ return "mips2";
+ case E_MIPS_ARCH_3:
+ *flagref &= ~((Elf64_Word) E_MIPS_ARCH_3);
+ return "mips3";
+ case E_MIPS_ARCH_4:
+ *flagref &= ~((Elf64_Word) E_MIPS_ARCH_4);
+ return "mips4";
+ case E_MIPS_ARCH_5:
+ *flagref &= ~((Elf64_Word) E_MIPS_ARCH_5);
+ return "mips5";
+ case E_MIPS_ARCH_32:
+ *flagref &= ~((Elf64_Word) E_MIPS_ARCH_32);
+ return "mips32";
+ case EF_MIPS_ARCH_32R2:
+ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_32R2);
+ return "mips32r2";
+ case E_MIPS_ARCH_32R6:
+ *flagref &= ~((Elf64_Word) E_MIPS_ARCH_32R6);
+ return "mips32r6";
+ case E_MIPS_ARCH_64:
+ *flagref &= ~((Elf64_Word) E_MIPS_ARCH_64);
+ return "mips64";
+ case EF_MIPS_ARCH_64R2:
+ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_64R2);
+ return "mips64r2";
+ case E_MIPS_ARCH_64R6:
+ *flagref &= ~((Elf64_Word) E_MIPS_ARCH_64R6);
+ return "mips64r6";
+ default:
+ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH);
+ return "unknown ISA";
+ }
+ return NULL;
+}
+
+/* copy binutils-2.34/binutils/readelf.c get_mips_segment_type */
+const char *
+mips_segment_type_name (int segment, char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (segment)
+ {
+ case PT_MIPS_REGINFO:
+ return "REGINFO";
+ case PT_MIPS_RTPROC:
+ return "RTPROC";
+ case PT_MIPS_OPTIONS:
+ return "OPTIONS";
+ case PT_MIPS_ABIFLAGS:
+ return "ABIFLAGS";
+ default:
+ return NULL;
+ }
+}
+
+bool
+mips_dynamic_tag_check (int64_t tag)
+{
+ return ((tag &~ (DT_MIPS_RLD_VERSION
+ | DT_MIPS_TIME_STAMP
+ | DT_MIPS_ICHECKSUM
+ | DT_MIPS_IVERSION
+ | DT_MIPS_FLAGS
+ | DT_MIPS_BASE_ADDRESS
+ | DT_MIPS_MSYM
+ | DT_MIPS_CONFLICT
+ | DT_MIPS_LIBLIST
+ | DT_MIPS_LOCAL_GOTNO
+ | DT_MIPS_CONFLICTNO
+ | DT_MIPS_LIBLISTNO
+ | DT_MIPS_SYMTABNO
+ | DT_MIPS_UNREFEXTNO
+ | DT_MIPS_GOTSYM
+ | DT_MIPS_HIPAGENO
+ | DT_MIPS_RLD_MAP
+ | DT_MIPS_DELTA_CLASS
+ | DT_MIPS_DELTA_CLASS_NO
+ | DT_MIPS_DELTA_INSTANCE
+ | DT_MIPS_DELTA_INSTANCE_NO
+ | DT_MIPS_DELTA_RELOC
+ | DT_MIPS_DELTA_RELOC_NO
+ | DT_MIPS_DELTA_SYM
+ | DT_MIPS_DELTA_SYM_NO
+ | DT_MIPS_DELTA_CLASSSYM
+ | DT_MIPS_DELTA_CLASSSYM_NO
+ | DT_MIPS_CXX_FLAGS
+ | DT_MIPS_PIXIE_INIT
+ | DT_MIPS_SYMBOL_LIB
+ | DT_MIPS_LOCALPAGE_GOTIDX
+ | DT_MIPS_LOCAL_GOTIDX
+ | DT_MIPS_HIDDEN_GOTIDX
+ | DT_MIPS_PROTECTED_GOTIDX
+ | DT_MIPS_OPTIONS
+ | DT_MIPS_INTERFACE
+ | DT_MIPS_DYNSTR_ALIGN
+ | DT_MIPS_INTERFACE_SIZE
+ | DT_MIPS_RLD_TEXT_RESOLVE_ADDR
+ | DT_MIPS_PERF_SUFFIX
+ | DT_MIPS_COMPACT_SIZE
+ | DT_MIPS_GP_VALUE
+ | DT_MIPS_AUX_DYNAMIC
+ | DT_MIPS_PLTGOT
+ | DT_MIPS_RWPLT
+ | DT_MIPS_RLD_MAP_REL
+ | DT_MIPS_XHASH)) == 0);
+}
+
+/* copy binutils-2.34/binutils/readelf.c get_mips_dynamic_type*/
+const char *
+mips_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (tag)
+ {
+ case DT_MIPS_RLD_VERSION:
+ return "MIPS_RLD_VERSION";
+ case DT_MIPS_TIME_STAMP:
+ return "MIPS_TIME_STAMP";
+ case DT_MIPS_ICHECKSUM:
+ return "MIPS_ICHECKSUM";
+ case DT_MIPS_IVERSION:
+ return "MIPS_IVERSION";
+ case DT_MIPS_FLAGS:
+ return "MIPS_FLAGS";
+ case DT_MIPS_BASE_ADDRESS:
+ return "MIPS_BASE_ADDRESS";
+ case DT_MIPS_MSYM:
+ return "MIPS_MSYM";
+ case DT_MIPS_CONFLICT:
+ return "MIPS_CONFLICT";
+ case DT_MIPS_LIBLIST:
+ return "MIPS_LIBLIST";
+ case DT_MIPS_LOCAL_GOTNO:
+ return "MIPS_LOCAL_GOTNO";
+ case DT_MIPS_CONFLICTNO:
+ return "MIPS_CONFLICTNO";
+ case DT_MIPS_LIBLISTNO:
+ return "MIPS_LIBLISTNO";
+ case DT_MIPS_SYMTABNO:
+ return "MIPS_SYMTABNO";
+ case DT_MIPS_UNREFEXTNO:
+ return "MIPS_UNREFEXTNO";
+ case DT_MIPS_GOTSYM:
+ return "MIPS_GOTSYM";
+ case DT_MIPS_HIPAGENO:
+ return "MIPS_HIPAGENO";
+ case DT_MIPS_RLD_MAP:
+ return "MIPS_RLD_MAP";
+ case DT_MIPS_RLD_MAP_REL:
+ return "MIPS_RLD_MAP_REL";
+ case DT_MIPS_DELTA_CLASS:
+ return "MIPS_DELTA_CLASS";
+ case DT_MIPS_DELTA_CLASS_NO:
+ return "MIPS_DELTA_CLASS_NO";
+ case DT_MIPS_DELTA_INSTANCE:
+ return "MIPS_DELTA_INSTANCE";
+ case DT_MIPS_DELTA_INSTANCE_NO:
+ return "MIPS_DELTA_INSTANCE_NO";
+ case DT_MIPS_DELTA_RELOC:
+ return "MIPS_DELTA_RELOC";
+ case DT_MIPS_DELTA_RELOC_NO:
+ return "MIPS_DELTA_RELOC_NO";
+ case DT_MIPS_DELTA_SYM:
+ return "MIPS_DELTA_SYM";
+ case DT_MIPS_DELTA_SYM_NO:
+ return "MIPS_DELTA_SYM_NO";
+ case DT_MIPS_DELTA_CLASSSYM:
+ return "MIPS_DELTA_CLASSSYM";
+ case DT_MIPS_DELTA_CLASSSYM_NO:
+ return "MIPS_DELTA_CLASSSYM_NO";
+ case DT_MIPS_CXX_FLAGS:
+ return "MIPS_CXX_FLAGS";
+ case DT_MIPS_PIXIE_INIT:
+ return "MIPS_PIXIE_INIT";
+ case DT_MIPS_SYMBOL_LIB:
+ return "MIPS_SYMBOL_LIB";
+ case DT_MIPS_LOCALPAGE_GOTIDX:
+ return "MIPS_LOCALPAGE_GOTIDX";
+ case DT_MIPS_LOCAL_GOTIDX:
+ return "MIPS_LOCAL_GOTIDX";
+ case DT_MIPS_HIDDEN_GOTIDX:
+ return "MIPS_HIDDEN_GOTIDX";
+ case DT_MIPS_PROTECTED_GOTIDX:
+ return "MIPS_PROTECTED_GOTIDX";
+ case DT_MIPS_OPTIONS:
+ return "MIPS_OPTIONS";
+ case DT_MIPS_INTERFACE:
+ return "MIPS_INTERFACE";
+ case DT_MIPS_DYNSTR_ALIGN:
+ return "MIPS_DYNSTR_ALIGN";
+ case DT_MIPS_INTERFACE_SIZE:
+ return "MIPS_INTERFACE_SIZE";
+ case DT_MIPS_RLD_TEXT_RESOLVE_ADDR:
+ return "MIPS_RLD_TEXT_RESOLVE_ADDR";
+ case DT_MIPS_PERF_SUFFIX:
+ return "MIPS_PERF_SUFFIX";
+ case DT_MIPS_COMPACT_SIZE:
+ return "MIPS_COMPACT_SIZE";
+ case DT_MIPS_GP_VALUE:
+ return "MIPS_GP_VALUE";
+ case DT_MIPS_AUX_DYNAMIC:
+ return "MIPS_AUX_DYNAMIC";
+ case DT_MIPS_PLTGOT:
+ return "MIPS_PLTGOT";
+ case DT_MIPS_RWPLT:
+ return "MIPS_RWPLT";
+ case DT_MIPS_XHASH:
+ return "MIPS_XHASH";
+ default:
+ return NULL;
+ }
+ return NULL;
+}
diff --git a/libebl/eblreloctypecheck.c b/libebl/eblreloctypecheck.c
index 80e67ef7..e3c43944 100644
--- a/libebl/eblreloctypecheck.c
+++ b/libebl/eblreloctypecheck.c
@@ -32,10 +32,14 @@
#endif
#include <libeblP.h>
-
+#include <libelfP.h>
bool
ebl_reloc_type_check (Ebl *ebl, int reloc)
{
- return ebl != NULL ? ebl->reloc_type_check (reloc) : false;
+ int relocNew = reloc;
+ GElf_Ehdr ehdr;
+ if(ebl->elf->class == ELFCLASS64 && gelf_getehdr(ebl->elf, &ehdr) != NULL && ehdr.e_machine == EM_MIPS)
+ relocNew = ELF64_MIPS_R_TYPE(reloc);
+ return ebl != NULL ? ebl->reloc_type_check (relocNew) : false;
}
diff --git a/libebl/eblreloctypename.c b/libebl/eblreloctypename.c
index e53ec0c0..4276d8e3 100644
--- a/libebl/eblreloctypename.c
+++ b/libebl/eblreloctypename.c
@@ -33,14 +33,18 @@
#include <stdio.h>
#include <libeblP.h>
-
+#include <libelfP.h>
const char *
ebl_reloc_type_name (Ebl *ebl, int reloc, char *buf, size_t len)
{
const char *res;
+ int relocNew = reloc;
+ GElf_Ehdr ehdr;
+ if(ebl->elf->class == ELFCLASS64 && gelf_getehdr(ebl->elf, &ehdr) != NULL && ehdr.e_machine == EM_MIPS)
+ relocNew = ELF64_MIPS_R_TYPE(reloc);
- res = ebl != NULL ? ebl->reloc_type_name (reloc, buf, len) : NULL;
+ res = ebl != NULL ? ebl->reloc_type_name (relocNew, buf, len) : NULL;
if (res == NULL)
/* There are no generic relocation type names. */
res = "<INVALID RELOC>";
diff --git a/libelf/elf.h b/libelf/elf.h
index aa903837..6284564f 100644
--- a/libelf/elf.h
+++ b/libelf/elf.h
@@ -1684,11 +1684,26 @@ typedef struct
#define EF_MIPS_PIC 2 /* Contains PIC code. */
#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence. */
#define EF_MIPS_XGOT 8
-#define EF_MIPS_64BIT_WHIRL 16
+//copy binutils-2.34/elfcpp/mips.h
+#define EF_MIPS_UCODE 16
#define EF_MIPS_ABI2 32
#define EF_MIPS_ABI_ON32 64
+//copy machine flag from binutils-2.34/elfcpp/mips.h
+/* Process the .MIPS.options section first by ld */
+#define EF_MIPS_OPTIONS_FIRST 0x00000080
+/* Indicates code compiled for a 64-bit machine in 32-bit mode
+ (regs are 32-bits wide). */
+#define EF_MIPS_32BITMODE 0x00000100
#define EF_MIPS_FP64 512 /* Uses FP64 (12 callee-saved). */
-#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */
+#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */
+/* Architectural Extensions used by this file */
+#define EF_MIPS_ARCH_ASE 0x0f000000
+/* Use MDMX multimedia extensions */
+#define EF_MIPS_ARCH_ASE_MDMX 0x08000000
+/* Use MIPS-16 ISA extensions */
+#define EF_MIPS_ARCH_ASE_M16 0x04000000
+/* Use MICROMIPS ISA extensions. */
+#define EF_MIPS_ARCH_ASE_MICROMIPS 0x02000000
#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */
/* Legal values for MIPS architecture level. */
@@ -1702,6 +1717,49 @@ typedef struct
#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */
#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32r2 code. */
#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64r2 code. */
+/* -mips32r6 code. */
+#define E_MIPS_ARCH_32R6 0x90000000
+/* -mips64r6 code. */
+#define E_MIPS_ARCH_64R6 0xa0000000
+/* The ABI of the file. Also see EF_MIPS_ABI2 above. */
+#define EF_MIPS_ABI 0x0000F000
+/* The original o32 abi. */
+#define E_MIPS_ABI_O32 0x00001000
+/* O32 extended to work on 64 bit architectures */
+#define E_MIPS_ABI_O64 0x00002000
+/* EABI in 32 bit mode */
+#define E_MIPS_ABI_EABI32 0x00003000
+/* EABI in 64 bit mode */
+#define E_MIPS_ABI_EABI64 0x00004000
+/* Machine variant if we know it. This field was invented at Cygnus,
+ but it is hoped that other vendors will adopt it. If some standard
+ is developed, this code should be changed to follow it. */
+#define EF_MIPS_MACH 0x00FF0000
+/* Cygnus is choosing values between 80 and 9F;
+ 00 - 7F should be left for a future standard;
+ the rest are open. */
+
+#define E_MIPS_MACH_3900 0x00810000
+#define E_MIPS_MACH_4010 0x00820000
+#define E_MIPS_MACH_4100 0x00830000
+#define E_MIPS_MACH_4650 0x00850000
+#define E_MIPS_MACH_4120 0x00870000
+#define E_MIPS_MACH_4111 0x00880000
+#define E_MIPS_MACH_SB1 0x008a0000
+#define E_MIPS_MACH_OCTEON 0x008b0000
+#define E_MIPS_MACH_XLR 0x008c0000
+#define E_MIPS_MACH_OCTEON2 0x008d0000
+#define E_MIPS_MACH_OCTEON3 0x008e0000
+#define E_MIPS_MACH_5400 0x00910000
+#define E_MIPS_MACH_5900 0x00920000
+#define E_MIPS_MACH_IAMR2 0x00930000
+#define E_MIPS_MACH_5500 0x00980000
+#define E_MIPS_MACH_9000 0x00990000
+#define E_MIPS_MACH_LS2E 0x00A00000
+#define E_MIPS_MACH_LS2F 0x00A10000
+#define E_MIPS_MACH_GS464 0x00A20000
+#define E_MIPS_MACH_GS464E 0x00A30000
+#define E_MIPS_MACH_GS264E 0x00A40000
/* The following are unofficial names and should not be used. */
@@ -1762,6 +1820,7 @@ typedef struct
#define SHT_MIPS_EH_REGION 0x70000027
#define SHT_MIPS_XLATE_OLD 0x70000028
#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+#define SHT_MIPS_ABIFLAGS 0x7000002a
#define SHT_MIPS_XHASH 0x7000002b
/* Legal values for sh_flags field of Elf32_Shdr. */
@@ -1789,6 +1848,31 @@ typedef struct
/* MIPS specific values for `st_info'. */
#define STB_MIPS_SPLIT_COMMON 13
+//copy gnu attr tags from binutils-2.34/elfcpp/mips.h
+/* Object attribute tags. */
+enum
+{
+ /* 0-3 are generic. */
+
+ /* Floating-point ABI used by this object file. */
+ Tag_GNU_MIPS_ABI_FP = 4,
+
+ /* MSA ABI used by this object file. */
+ Tag_GNU_MIPS_ABI_MSA = 8,
+};
+
+/* Object attribute values. */
+enum
+{
+ /* Values defined for Tag_GNU_MIPS_ABI_MSA. */
+
+ /* Not tagged or not using any ABIs affected by the differences. */
+ Val_GNU_MIPS_ABI_MSA_ANY = 0,
+
+ /* Using 128-bit MSA. */
+ Val_GNU_MIPS_ABI_MSA_128 = 1,
+};
+
/* Entries found in sections of type SHT_MIPS_GPTAB. */
typedef union
@@ -2218,8 +2302,11 @@ enum
Val_GNU_MIPS_ABI_FP_64 = 6,
/* Using -mips32r2 -mfp64 -mno-odd-spreg. */
Val_GNU_MIPS_ABI_FP_64A = 7,
+ /* This is reserved for backward-compatibility with an earlier
+ implementation of the MIPS NaN2008 functionality. */
+ Val_GNU_MIPS_ABI_FP_NAN2008 = 8,
/* Maximum allocated FP ABI value. */
- Val_GNU_MIPS_ABI_FP_MAX = 7
+ Val_GNU_MIPS_ABI_FP_MAX = 9
};
/* HPPA specific definitions. */
diff --git a/src/readelf.c b/src/readelf.c
index 6950204e..6e9a02c1 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -1125,7 +1125,7 @@ print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
ehdr->e_ident[EI_VERSION] == EV_CURRENT ? _("(current)")
: "(\?\?\?)");
- char buf[512];
+ char buf[64];
printf (_(" OS/ABI: %s\n"),
ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
@@ -2193,17 +2193,41 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
(long int) GELF_R_SYM (rel->r_info));
}
else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
- printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
- likely (ebl_reloc_type_check (ebl,
- GELF_R_TYPE (rel->r_info)))
- /* Avoid the leading R_ which isn't carrying any
- information. */
- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
- buf, sizeof (buf)) + 2
- : _("<INVALID RELOC>"),
- class == ELFCLASS32 ? 10 : 18, sym->st_value,
- elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
+ {
+ unsigned long inf = rel->r_info;
+ printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ likely (ebl_reloc_type_check (ebl,
+ GELF_R_TYPE (rel->r_info)))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : _("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, sym->st_value,
+ elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
+
+ /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753 */
+ if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
+ {
+ unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
+ unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
+ const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
+ const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
+ printf(" Type2: ");
+ if (rtype2 == NULL)
+ printf (_("unrecognized: %-7lx"), (unsigned long) type2 & 0xffffffff);
+ else
+ printf ("%-17.17s", rtype2);
+
+ printf ("\n Type3: ");
+ if (rtype3 == NULL)
+ printf (_("unrecognized: %-7lx"), (unsigned long) type3 & 0xffffffff);
+ else
+ printf ("%-17.17s", rtype3);
+ printf("\n");
+ }
+ }
else
{
/* This is a relocation against a STT_SECTION symbol. */
@@ -2227,16 +2251,40 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
(long int) (sym->st_shndx == SHN_XINDEX
? xndx : sym->st_shndx));
else
- printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
- ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
- /* Avoid the leading R_ which isn't carrying any
- information. */
- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
- buf, sizeof (buf)) + 2
- : _("<INVALID RELOC>"),
- class == ELFCLASS32 ? 10 : 18, sym->st_value,
- elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
+ {
+ unsigned long inf = rel->r_info;
+ printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : _("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, sym->st_value,
+ elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
+
+ /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753 */
+ if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
+ {
+ unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
+ unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
+ const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
+ const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
+ printf(" Type2: ");
+ if (rtype2 == NULL)
+ printf (_("unrecognized: %-7lx"), (unsigned long) type2 & 0xffffffff);
+ else
+ printf ("%-17.17s", rtype2);
+
+ printf ("\n Type3: ");
+ if (rtype3 == NULL)
+ printf (_("unrecognized: %-7lx"), (unsigned long) type3 & 0xffffffff);
+ else
+ printf ("%-17.17s", rtype3);
+ printf("\n");
+ }
+ }
}
}
}
@@ -2384,19 +2432,43 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
(long int) GELF_R_SYM (rel->r_info));
}
else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
- printf ("\
+ {
+ unsigned long inf = rel->r_info;
+ printf ("\
%#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
- likely (ebl_reloc_type_check (ebl,
- GELF_R_TYPE (rel->r_info)))
- /* Avoid the leading R_ which isn't carrying any
- information. */
- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
- buf, sizeof (buf)) + 2
- : _("<INVALID RELOC>"),
- class == ELFCLASS32 ? 10 : 18, sym->st_value,
- rel->r_addend,
- elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ likely (ebl_reloc_type_check (ebl,
+ GELF_R_TYPE (rel->r_info)))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : _("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, sym->st_value,
+ rel->r_addend,
+ elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
+
+ /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753 */
+ if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
+ {
+ unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
+ unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
+ const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
+ const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
+ printf(" Type2: ");
+ if (rtype2 == NULL)
+ printf (_("unrecognized: %-7lx"), (unsigned long) type2 & 0xffffffff);
+ else
+ printf ("%-17.17s", rtype2);
+
+ printf ("\n Type3: ");
+ if (rtype3 == NULL)
+ printf (_("unrecognized: %-7lx"), (unsigned long) type3 & 0xffffffff);
+ else
+ printf ("%-17.17s", rtype3);
+ printf("\n");
+ }
+ }
else
{
/* This is a relocation against a STT_SECTION symbol. */
@@ -2420,18 +2492,42 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
(long int) (sym->st_shndx == SHN_XINDEX
? xndx : sym->st_shndx));
else
- printf ("\
+ {
+ unsigned long inf = rel->r_info;
+ printf ("\
%#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
- ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
- /* Avoid the leading R_ which isn't carrying any
- information. */
- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
- buf, sizeof (buf)) + 2
- : _("<INVALID RELOC>"),
- class == ELFCLASS32 ? 10 : 18, sym->st_value,
- rel->r_addend,
- elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : _("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, sym->st_value,
+ rel->r_addend,
+ elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
+
+ /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753 */
+ if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
+ {
+ unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
+ unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
+ const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
+ const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
+ printf(" Type2: ");
+ if (rtype2 == NULL)
+ printf (_("unrecognized: %-7lx"), (unsigned long) type2 & 0xffffffff);
+ else
+ printf ("%-17.17s", rtype2);
+
+ printf ("\n Type3: ");
+ if (rtype3 == NULL)
+ printf (_("unrecognized: %-7lx"), (unsigned long) type3 & 0xffffffff);
+ else
+ printf ("%-17.17s", rtype3);
+ printf("\n");
+ }
+ }
}
}
}
@@ -11633,7 +11729,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
+ if (shdr != NULL && (shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_MIPS_DWARF))
{
const char *name = elf_strptr (ebl->elf, shstrndx,
shdr->sh_name);
@@ -11663,7 +11759,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
+ if (shdr != NULL && (shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_MIPS_DWARF))
{
static const struct
{
--
2.30.2
More information about the Elfutils-devel
mailing list