From patchwork Thu Nov 2 06:55:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ying Huang X-Patchwork-Id: 78908 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A23C53858C39 for ; Thu, 2 Nov 2023 06:56:48 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from va-2-40.ptr.blmpb.com (va-2-40.ptr.blmpb.com [209.127.231.40]) by sourceware.org (Postfix) with UTF8SMTPS id 71D1C3858D37 for ; Thu, 2 Nov 2023 06:56:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 71D1C3858D37 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=oss.cipunited.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=oss.cipunited.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 71D1C3858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=209.127.231.40 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698908197; cv=none; b=h8HPGNXPfOUw18UMwu8x+5r70p+w9VP7YQAu8wttDMoUaxi25+Axsd2lAQFU7qhW6NwJPvKiRdW5UZ6vfdhjQAywQ+WQLXUAZpCIPB+Tstey+AmP4+OP6juY9IckiMI7lAiMsmPkEY1oq4rQ8Pvz9BSBIxgpaQcPEkLDfZBCviU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698908197; c=relaxed/simple; bh=+Ww0hc3PFC1iLsyH+4o+HBUkMWLZhHCFmXqfNJW3YGo=; h=DKIM-Signature:Subject:From:Date:Mime-Version:To:Message-Id; b=V3e0TAKaYgJaT1eWaQhv1t05xGTQ4hJHN6aTHXDHgAQ4mWvViGl1WGdt8DFor69HmXhfMGvz+2l8t6Zj9UaRp+C17bzs3Nne5YmwVqzntNus2B7nrjL/os2y9/qlMDQvDCLdyQpwYFHhNHOn7T8WIasXncE1A2TbjEPw15myTGA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=feishu2303200042; d=oss.cipunited.com; t=1698908179; h=from:subject:mime-version:from:date:message-id:subject:to:cc: reply-to:content-type:mime-version:in-reply-to:message-id; bh=QV55Xhb5SY+uZNqTzhyTNV7iE5oO/XwlQwMBVuJlzBU=; b=YtDbiXBuZaorpJgUAxUnGYIM1u9WweKt7iGyzBJm5AkCOwR6vv62sNhMackmkgiUIZ052r n1Kny32p2VauyvDX4zyGvNi10WoRHMniwPx/VITqqa2p4h458mGSY5NF5sTywo6UA9RcYo qYR1KOmqjVZYGw4WIeC3KXy2uyJKMuSU6+95Ce6YF3D/zPFJnoeRSp+yhA7TfVmJ4d54y/ KlXKtIVyAtS6kblCrc3xU8WnYCXzKg4RWr1PiKSJ5rM0CHd+Ud+kQvqNlkUUBxbOma8S29 3e761BOdMIIZfsNc+nGyMNemRHxpZCCJjGwWdkxkr1li3LFHZaw83/7BkxIS7Q== In-Reply-To: <20231102065602.3128526-1-ying.huang@oss.cipunited.com> Cc: , "Ying Huang" Subject: [PATCH v2 2/5] readelf: Adapt src/readelf -h/-S/-r/-w/-l/-d/-a on mips From: "Ying Huang" Date: Thu, 2 Nov 2023 14:55:59 +0800 Mime-Version: 1.0 To: References: <20231102065602.3128526-1-ying.huang@oss.cipunited.com> X-Mailer: git-send-email 2.30.2 Message-Id: <20231102065602.3128526-3-ying.huang@oss.cipunited.com> X-Original-From: Ying Huang X-Lms-Return-Path: X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Ying Huang -h: support show Flags name -S: support show mips related section type -r: support show type 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" Also add test/run-readelf-reloc.sh file to test new type2/type3 of src/readelf -r. --- backends/Makefile.am | 2 +- backends/mips_attrs.c | 140 +++++++++ backends/mips_init.c | 7 + backends/mips_symbol.c | 571 +++++++++++++++++++++++++++++++++++++ libelf/libelfP.h | 1 + src/readelf.c | 188 +++++++++--- tests/Makefile.am | 4 +- tests/run-readelf-reloc.sh | 42 +++ 8 files changed, 906 insertions(+), 49 deletions(-) create mode 100644 backends/mips_attrs.c create mode 100755 tests/run-readelf-reloc.sh diff --git a/backends/Makefile.am b/backends/Makefile.am index b946fd30..ad95526e 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -102,7 +102,7 @@ loongarch_SRCS = loongarch_init.c loongarch_symbol.c loongarch_cfi.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..950047c3 --- /dev/null +++ b/backends/mips_attrs.c @@ -0,0 +1,140 @@ +/* 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND mips_ +#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 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, +}; + +/* Object attribute values. */ +enum +{ + /* This is reserved for backward-compatibility with an earlier + implementation of the MIPS NaN2008 functionality. */ + Val_GNU_MIPS_ABI_FP_NAN2008 = 8, +}; + +/* 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 e26da609..905d97eb 100644 --- a/backends/mips_init.c +++ b/backends/mips_init.c @@ -48,5 +48,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 a9dd5c09..6418a01d 100644 --- a/backends/mips_symbol.c +++ b/backends/mips_symbol.c @@ -61,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 EF_MIPS_MACH_3900: + case EF_MIPS_MACH_4010: + case EF_MIPS_MACH_4100: + case EF_MIPS_MACH_4111: + case EF_MIPS_MACH_4120: + case EF_MIPS_MACH_4650: + case EF_MIPS_MACH_5400: + case EF_MIPS_MACH_5500: + case EF_MIPS_MACH_5900: + case EF_MIPS_MACH_SB1: + case EF_MIPS_MACH_9000: + case EF_MIPS_MACH_LS2E: + case EF_MIPS_MACH_LS2F: + case EF_MIPS_MACH_GS464: + case EF_MIPS_MACH_GS464E: + case EF_MIPS_MACH_GS264E: + case EF_MIPS_MACH_OCTEON: + case EF_MIPS_MACH_OCTEON2: + case EF_MIPS_MACH_OCTEON3: + case EF_MIPS_MACH_XLR: + case EF_MIPS_MACH_IAMR2: + case 0: + break; + default: + return false; + } + + switch ((flags & EF_MIPS_ABI)) + { + case EF_MIPS_ABI_O32: + case EF_MIPS_ABI_O64: + case EF_MIPS_ABI_EABI32: + case EF_MIPS_ABI_EABI64: + case 0: + break; + default: + return false; + } + + switch ((flags & EF_MIPS_ARCH)) + { + case EF_MIPS_ARCH_1: + case EF_MIPS_ARCH_2: + case EF_MIPS_ARCH_3: + case EF_MIPS_ARCH_4: + case EF_MIPS_ARCH_5: + case EF_MIPS_ARCH_32: + case EF_MIPS_ARCH_32R2: + case EF_MIPS_ARCH_32R6: + case EF_MIPS_ARCH_64: + case EF_MIPS_ARCH_64R2: + case EF_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 EF_MIPS_MACH_3900: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_3900); + return "3900"; + case EF_MIPS_MACH_4010: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4010); + return "4010"; + case EF_MIPS_MACH_4100: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4100); + return "4100"; + case EF_MIPS_MACH_4111: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4111); + return "4111"; + case EF_MIPS_MACH_4120: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4120); + return "4120"; + case EF_MIPS_MACH_4650: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4650); + return "4650"; + case EF_MIPS_MACH_5400: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_5400); + return "5400"; + case EF_MIPS_MACH_5500: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_5500); + return "5500"; + case EF_MIPS_MACH_5900: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_5900); + return "5900"; + case EF_MIPS_MACH_SB1: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_SB1); + return "sb1"; + case EF_MIPS_MACH_9000: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_9000); + return "9000"; + case EF_MIPS_MACH_LS2E: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_LS2E); + return "loongson-2e"; + case EF_MIPS_MACH_LS2F: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_LS2F); + return "loongson-2f"; + case EF_MIPS_MACH_GS464: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_GS464); + return "gs464"; + case EF_MIPS_MACH_GS464E: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_GS464E); + return "gs464e"; + case EF_MIPS_MACH_GS264E: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_GS264E); + return "gs264e"; + case EF_MIPS_MACH_OCTEON: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_OCTEON); + return "octeon"; + case EF_MIPS_MACH_OCTEON2: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_OCTEON2); + return "octeon2"; + case EF_MIPS_MACH_OCTEON3: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_OCTEON3); + return "octeon3"; + case EF_MIPS_MACH_XLR: + *flagref &= ~((Elf64_Word) EF_MIPS_MACH_XLR); + return "xlr"; + case EF_MIPS_MACH_IAMR2: + *flagref &= ~((Elf64_Word) EF_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 EF_MIPS_ABI_O32: + *flagref &= ~((Elf64_Word) EF_MIPS_ABI_O32); + return "o32"; + case EF_MIPS_ABI_O64: + *flagref &= ~((Elf64_Word) EF_MIPS_ABI_O64); + return "o64"; + case EF_MIPS_ABI_EABI32: + *flagref &= ~((Elf64_Word) EF_MIPS_ABI_EABI32); + return "eabi32"; + case EF_MIPS_ABI_EABI64: + *flagref &= ~((Elf64_Word) EF_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 EF_MIPS_ARCH_1: + *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_1); + return "mips1"; + case EF_MIPS_ARCH_2: + *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_2); + return "mips2"; + case EF_MIPS_ARCH_3: + *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_3); + return "mips3"; + case EF_MIPS_ARCH_4: + *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_4); + return "mips4"; + case EF_MIPS_ARCH_5: + *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_5); + return "mips5"; + case EF_MIPS_ARCH_32: + *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_32); + return "mips32"; + case EF_MIPS_ARCH_32R2: + *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_32R2); + return "mips32r2"; + case EF_MIPS_ARCH_32R6: + *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_32R6); + return "mips32r6"; + case EF_MIPS_ARCH_64: + *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_64); + return "mips64"; + case EF_MIPS_ARCH_64R2: + *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_64R2); + return "mips64r2"; + case EF_MIPS_ARCH_64R6: + *flagref &= ~((Elf64_Word) EF_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/libelf/libelfP.h b/libelf/libelfP.h index bdd2cc6a..6565ee02 100644 --- a/libelf/libelfP.h +++ b/libelf/libelfP.h @@ -620,4 +620,5 @@ extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, #define ELF64_MIPS_R_TYPE1(i) ((i) & 0xff) #define ELF64_MIPS_R_TYPE2(i) (((i) >> 8) & 0xff) #define ELF64_MIPS_R_TYPE3(i) (((i) >> 16) & 0xff) +#define is_debug_section_type(type) (type == SHT_PROGBITS || type == SHT_MIPS_DWARF) #endif /* libelfP.h */ diff --git a/src/readelf.c b/src/readelf.c index db31ad09..b1c459d1 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -2219,17 +2219,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 - : _(""), - 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 + : _(""), + 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: %lx"), (unsigned long) type2 & 0xffffffff); + else + printf ("%s", rtype2); + + printf ("\n Type3: "); + if (rtype3 == NULL) + printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff); + else + printf ("%s", rtype3); + printf("\n"); + } + } else { /* This is a relocation against a STT_SECTION symbol. */ @@ -2253,16 +2277,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 - : _(""), - 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 + : _(""), + 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: %lx"), (unsigned long) type2 & 0xffffffff); + else + printf ("%s", rtype2); + + printf ("\n Type3: "); + if (rtype3 == NULL) + printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff); + else + printf ("%s", rtype3); + printf("\n"); + } + } } } } @@ -2410,19 +2458,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 - : _(""), - 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 + : _(""), + 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: %lx"), (unsigned long) type2 & 0xffffffff); + else + printf ("%s", rtype2); + + printf ("\n Type3: "); + if (rtype3 == NULL) + printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff); + else + printf ("%s", rtype3); + printf("\n"); + } + } else { /* This is a relocation against a STT_SECTION symbol. */ @@ -2446,18 +2518,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 - : _(""), - 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 + : _(""), + 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 ("%s", rtype2); + + printf ("\n Type3: "); + if (rtype3 == NULL) + printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff); + else + printf ("%s", rtype3); + printf("\n"); + } + } } } } @@ -11976,7 +12072,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 && is_debug_section_type(shdr->sh_type)) { const char *name = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); @@ -12006,7 +12102,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 && is_debug_section_type(shdr->sh_type)) { static const struct { diff --git a/tests/Makefile.am b/tests/Makefile.am index d0ae7c6d..a44d18a0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -212,7 +212,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ $(asm_TESTS) run-disasm-bpf.sh run-low_high_pc-dw-form-indirect.sh \ run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \ run-readelf-dw-form-indirect.sh run-strip-largealign.sh \ - run-readelf-Dd.sh + run-readelf-Dd.sh run-readelf-reloc.sh if !BIARCH export ELFUTILS_DISABLE_BIARCH = 1 @@ -631,7 +631,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \ testfile_nvidia_linemap.bz2 \ testfile-largealign.o.bz2 run-strip-largealign.sh \ - run-funcretval++11.sh + run-funcretval++11.sh run-readelf-reloc.sh if USE_VALGRIND diff --git a/tests/run-readelf-reloc.sh b/tests/run-readelf-reloc.sh new file mode 100755 index 00000000..0a279f65 --- /dev/null +++ b/tests/run-readelf-reloc.sh @@ -0,0 +1,42 @@ +#! /bin/bash +# Copyright (C) 2018 Red Hat, Inc. +# This file is part of elfutils. +# +# This file 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 3 of the License, or +# (at your option) any later version. +# +# 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 a copy of the GNU General Public License +# along with this program. If not, see . + +. $srcdir/test-subr.sh + +tempfiles test-readelf-h.txt test-readelf-reloc.txt +testrun ${abs_top_builddir}/src/readelf -h ${abs_top_builddir}/src/strip.o > test-readelf-h.txt +machine=`cat test-readelf-h.txt | grep Machine` +class=`cat test-readelf-h.txt | grep Class` +endian=`cat test-readelf-h.txt | grep Data` +if [[ "$machine" == *MIPS* && "$class" == *ELF64 && "$endian" == *little* ]]; then +testrun ${abs_top_builddir}/src/readelf -r ${abs_top_builddir}/src/strip.o | head -n 12 | tail -n 10 > test-readelf-reloc.txt + +testrun_compare cat test-readelf-reloc.txt << EOF + Offset Type Value Addend Name + 0x0000000000000008 MIPS_GPREL16 000000000000000000 +0 .text + Type2: MIPS_SUB + Type3: MIPS_HI16 + 0x0000000000000010 MIPS_GPREL16 000000000000000000 +0 .text + Type2: MIPS_SUB + Type3: MIPS_LO16 + 0x0000000000000014 MIPS_CALL16 000000000000000000 +0 gelf_getehdr + Type2: MIPS_NONE + Type3: MIPS_NONE +EOF +fi + +exit 0