| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525 |
- From 8d3bb7db9d6f07decfc59d83988cda54e5a8b0cd Mon Sep 17 00:00:00 2001
- From: Ying Huang <[email protected]>
- Date: Tue, 5 Mar 2024 17:51:17 +0800
- Subject: [PATCH 1/7] Support Mips architecture
- * backends/Makefile.am (modules): Add mips.
- (mips_SRCS): New var for mips_init.c mips_symbol.c.
- (libebl_backends_a_SOURCES): Add mips_SRCS.
- * backends/mips_init.c: New file.
- * backends/mips_reloc.def: Likewise.
- * backends/mips_symbol.c: Likewise.
- * libebl/eblopenbackend.c (mips_init): Declare.
- (machines): Add mips.
- * libelf/libelfP.h: Add ELF64_MIPS_R_TYPE{1,2,3}
- Signed-off-by: Ying Huang <[email protected]>
- ---
- backends/Makefile.am | 6 ++-
- backends/mips_init.c | 52 +++++++++++++++++++++++
- backends/mips_reloc.def | 93 +++++++++++++++++++++++++++++++++++++++++
- backends/mips_symbol.c | 63 ++++++++++++++++++++++++++++
- libebl/eblopenbackend.c | 2 +
- libelf/libelfP.h | 3 ++
- 6 files changed, 217 insertions(+), 2 deletions(-)
- create mode 100644 backends/mips_init.c
- create mode 100644 backends/mips_reloc.def
- create mode 100644 backends/mips_symbol.c
- --- a/backends/Makefile.am
- +++ b/backends/Makefile.am
- @@ -37,7 +37,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/libebl -I
- noinst_LIBRARIES = libebl_backends.a libebl_backends_pic.a
-
- modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \
- - m68k bpf riscv csky loongarch arc
- + m68k bpf riscv csky loongarch arc mips
-
- i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \
- i386_retval.c i386_regs.c i386_auxv.c \
- @@ -102,12 +102,16 @@ loongarch_SRCS = loongarch_init.c loonga
-
- arc_SRCS = arc_init.c arc_symbol.c
-
- +mips_SRCS = mips_init.c mips_symbol.c mips_attrs.c mips_initreg.c \
- + mips_cfi.c mips_unwind.c mips_regs.c mips_retval.c \
- + mips_corenote.c mips64_corenote.c
- +
- libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \
- $(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \
- $(aarch64_SRCS) $(sparc_SRCS) $(ppc_SRCS) \
- $(ppc64_SRCS) $(s390_SRCS) \
- $(m68k_SRCS) $(bpf_SRCS) $(riscv_SRCS) $(csky_SRCS) \
- - $(loongarch_SRCS) $(arc_SRCS)
- + $(loongarch_SRCS) $(arc_SRCS) $(mips_SRCS)
-
- libebl_backends_pic_a_SOURCES =
- am_libebl_backends_pic_a_OBJECTS = $(libebl_backends_a_SOURCES:.c=.os)
- --- /dev/null
- +++ b/backends/mips_init.c
- @@ -0,0 +1,74 @@
- +/* Initialization of MIPS specific backend library.
- + Copyright (C) 2024 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
- +
- +#define BACKEND mips_
- +#define RELOC_PREFIX R_MIPS_
- +#include "libebl_CPU.h"
- +#include "libelfP.h"
- +
- +#define RELOC_TYPE_ID(type) ((type) & 0xff)
- +
- +/* This defines the common reloc hooks based on mips_reloc.def. */
- +#include "common-reloc.c"
- +
- +extern __typeof (EBLHOOK (core_note)) mips64_core_note attribute_hidden;
- +
- +Ebl *
- +mips_init (Elf *elf __attribute__ ((unused)),
- + GElf_Half machine __attribute__ ((unused)),
- + Ebl *eh)
- +{
- + /* 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, machine_section_flag_check);
- + HOOK (eh, segment_type_name);
- + HOOK (eh, dynamic_tag_check);
- + HOOK (eh, dynamic_tag_name);
- + HOOK (eh, check_object_attribute);
- + HOOK (eh, check_special_symbol);
- + HOOK (eh, check_reloc_target_type);
- + HOOK (eh, set_initial_registers_tid);
- + HOOK (eh, abi_cfi);
- + HOOK (eh, unwind);
- + HOOK (eh, register_info);
- + HOOK (eh, return_value_location);
- + if (eh->class == ELFCLASS64)
- + eh->core_note = mips64_core_note;
- + else
- + HOOK (eh, core_note);
- + eh->frame_nregs = 71;
- + return eh;
- +}
- --- /dev/null
- +++ b/backends/mips_reloc.def
- @@ -0,0 +1,93 @@
- +/* List the relocation types for MIPS. -*- C -*-
- + Copyright (C) 2024 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/>. */
- +
- +/* NAME, REL|EXEC|DYN */
- +
- +
- +RELOC_TYPE (NONE, REL|EXEC|DYN)
- +RELOC_TYPE (16, REL|EXEC|DYN)
- +RELOC_TYPE (32, REL)
- +RELOC_TYPE (REL32, REL|EXEC|DYN)
- +RELOC_TYPE (26, REL|DYN)
- +RELOC_TYPE (HI16, REL)
- +RELOC_TYPE (LO16, REL|EXEC|DYN)
- +RELOC_TYPE (GPREL16, REL|EXEC|DYN)
- +RELOC_TYPE (LITERAL, REL|EXEC|DYN)
- +RELOC_TYPE (GOT16, REL|EXEC|DYN)
- +RELOC_TYPE (PC16, REL)
- +RELOC_TYPE (CALL16, REL)
- +RELOC_TYPE (GPREL32, REL)
- +RELOC_TYPE (SHIFT5, REL)
- +RELOC_TYPE (SHIFT6, REL)
- +RELOC_TYPE (64, REL)
- +RELOC_TYPE (GOT_DISP, REL)
- +RELOC_TYPE (GOT_PAGE, REL)
- +RELOC_TYPE (GOT_OFST, REL)
- +RELOC_TYPE (GOT_HI16, REL)
- +RELOC_TYPE (GOT_LO16, REL)
- +RELOC_TYPE (SUB, REL)
- +RELOC_TYPE (INSERT_A, REL)
- +RELOC_TYPE (INSERT_B, REL)
- +RELOC_TYPE (DELETE, REL)
- +RELOC_TYPE (HIGHER, REL)
- +RELOC_TYPE (HIGHEST, REL)
- +RELOC_TYPE (CALL_HI16, REL)
- +RELOC_TYPE (CALL_LO16, REL)
- +RELOC_TYPE (SCN_DISP, REL)
- +RELOC_TYPE (REL16, REL)
- +RELOC_TYPE (ADD_IMMEDIATE, REL)
- +RELOC_TYPE (PJUMP, REL)
- +RELOC_TYPE (RELGOT, REL)
- +RELOC_TYPE (JALR, REL)
- +RELOC_TYPE (TLS_DTPMOD32, DYN)
- +RELOC_TYPE (TLS_DTPREL32, REL)
- +RELOC_TYPE (TLS_DTPMOD64, DYN)
- +RELOC_TYPE (TLS_DTPREL64, REL)
- +RELOC_TYPE (TLS_GD, REL)
- +RELOC_TYPE (TLS_LDM, REL)
- +RELOC_TYPE (TLS_DTPREL_HI16, REL)
- +RELOC_TYPE (TLS_DTPREL_LO16, REL)
- +RELOC_TYPE (TLS_GOTTPREL, REL)
- +RELOC_TYPE (TLS_TPREL32, REL)
- +RELOC_TYPE (TLS_TPREL64, REL)
- +RELOC_TYPE (TLS_TPREL_HI16, REL)
- +RELOC_TYPE (TLS_TPREL_LO16, REL)
- +RELOC_TYPE (GLOB_DAT, REL)
- +RELOC_TYPE (PC21_S2, REL)
- +RELOC_TYPE (PC26_S2, REL)
- +RELOC_TYPE (PC18_S3, REL)
- +RELOC_TYPE (PC19_S2, REL)
- +RELOC_TYPE (PCHI16, REL)
- +RELOC_TYPE (PCLO16, REL)
- +RELOC_TYPE (COPY, REL)
- +RELOC_TYPE (JUMP_SLOT, REL)
- +RELOC_TYPE (PC32, REL)
- +RELOC_TYPE (EH, REL)
- +RELOC_TYPE (GNU_REL16_S2, REL)
- +RELOC_TYPE (GNU_VTINHERIT, REL)
- +RELOC_TYPE (GNU_VTENTRY, REL)
- --- /dev/null
- +++ b/backends/mips_symbol.c
- @@ -0,0 +1,671 @@
- +/* MIPS specific symbolic name handling.
- + Copyright (C) 2024 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 <system.h>
- +
- +#include <elf.h>
- +#include <stddef.h>
- +#include <string.h>
- +#include <stdio.h>
- +#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,
- + int *addsub __attribute__ ((unused)))
- +{
- + int typeNew = type;
- + if(ebl->elf->class == ELFCLASS64)
- + typeNew = ELF64_MIPS_R_TYPE1(type);
- + switch (typeNew)
- + {
- + case R_MIPS_64:
- + return ELF_T_XWORD;
- + case R_MIPS_32:
- + return ELF_T_WORD;
- + case R_MIPS_16:
- + return ELF_T_HALF;
- +
- + default:
- + 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;
- +}
- +
- +bool
- +mips_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word sh_type)
- +{
- + return (sh_type == SHT_MIPS_DWARF);
- +}
- +
- +/* Check whether given symbol's st_value and st_size are OK despite failing
- + normal checks. */
- +bool
- +mips_check_special_symbol (Elf *elf,
- + const GElf_Sym *sym __attribute__ ((unused)),
- + const char *name __attribute__ ((unused)),
- + const GElf_Shdr *destshdr)
- +{
- + size_t shstrndx;
- + if (elf_getshdrstrndx (elf, &shstrndx) != 0)
- + return false;
- + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name);
- + if (sname == NULL)
- + return false;
- + return (strcmp (sname, ".got") == 0 || strcmp (sname, ".bss") == 0);
- +}
- +
- +/* Check whether SHF_MASKPROC flags are valid. */
- +bool
- +mips_machine_section_flag_check (GElf_Xword sh_flags)
- +{
- + return ((sh_flags &~ (SHF_MIPS_GPREL |
- + SHF_MIPS_MERGE |
- + SHF_MIPS_ADDR |
- + SHF_MIPS_STRINGS |
- + SHF_MIPS_NOSTRIP |
- + SHF_MIPS_LOCAL |
- + SHF_MIPS_NAMES |
- + SHF_MIPS_NODUPE)) == 0);
- +}
- +
- +/* 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;
- +}
- --- a/libebl/eblopenbackend.c
- +++ b/libebl/eblopenbackend.c
- @@ -57,6 +57,7 @@ Ebl *riscv_init (Elf *, GElf_Half, Ebl *
- Ebl *csky_init (Elf *, GElf_Half, Ebl *);
- Ebl *loongarch_init (Elf *, GElf_Half, Ebl *);
- Ebl *arc_init (Elf *, GElf_Half, Ebl *);
- +Ebl *mips_init (Elf *, GElf_Half, Ebl *);
-
- /* This table should contain the complete list of architectures as far
- as the ELF specification is concerned. */
- @@ -154,6 +155,7 @@ static const struct
- { csky_init, "elf_csky", "csky", 4, EM_CSKY, ELFCLASS32, ELFDATA2LSB },
- { loongarch_init, "elf_loongarch", "loongarch", 9, EM_LOONGARCH, ELFCLASS64, ELFDATA2LSB },
- { arc_init, "elf_arc", "arc", 3, EM_ARCV2, ELFCLASS32, ELFDATA2LSB },
- + { mips_init, "elf_mips", "mips", 4, EM_MIPS, 0, 0 },
- };
- #define nmachines (sizeof (machines) / sizeof (machines[0]))
-
- --- a/libelf/libelfP.h
- +++ b/libelf/libelfP.h
- @@ -617,4 +617,8 @@ extern void __libelf_reset_rawdata (Elf_
- #define INVALID_NDX(ndx, type, data) \
- unlikely ((data)->d_size / sizeof (type) <= (unsigned int) (ndx))
-
- +#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 */
- --- /dev/null
- +++ b/backends/mips_cfi.c
- @@ -0,0 +1,68 @@
- +/* MIPS ABI-specified defaults for DWARF CFI.
- + Copyright (C) 2009 Red Hat, Inc.
- + Copyright (C) 2024 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 <dwarf.h>
- +
- +#define BACKEND mips_
- +#include "libebl_CPU.h"
- +
- +int
- +mips_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
- +{
- + static const uint8_t abi_cfi[] =
- + {
- + DW_CFA_def_cfa, ULEB128_7 (31), ULEB128_7 (0),
- + /* Callee-saved regs. */
- + DW_CFA_same_value, ULEB128_7 (16), /* s0 */
- + DW_CFA_same_value, ULEB128_7 (17), /* s1 */
- + DW_CFA_same_value, ULEB128_7 (18), /* s2 */
- + DW_CFA_same_value, ULEB128_7 (19), /* s3 */
- + DW_CFA_same_value, ULEB128_7 (20), /* s4 */
- + DW_CFA_same_value, ULEB128_7 (21), /* s5 */
- + DW_CFA_same_value, ULEB128_7 (22), /* s6 */
- + DW_CFA_same_value, ULEB128_7 (23), /* s7 */
- + DW_CFA_same_value, ULEB128_7 (28), /* gp */
- + DW_CFA_same_value, ULEB128_7 (29), /* sp */
- + DW_CFA_same_value, ULEB128_7 (30), /* fp */
- +
- + DW_CFA_val_offset, ULEB128_7 (29), ULEB128_7 (0),
- + };
- +
- + abi_info->initial_instructions = abi_cfi;
- + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
- + abi_info->data_alignment_factor = 8;
- +
- + abi_info->return_address_register = 31; /* %ra */
- +
- + return 0;
- +}
- --- /dev/null
- +++ b/backends/mips_initreg.c
- @@ -0,0 +1,61 @@
- +/* Fetch live process registers from TID.
- + Copyright (C) 2024 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 <stdlib.h>
- +#if (defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)) && defined(__linux__)
- +# include <sys/user.h>
- +# include <sys/ptrace.h>
- +#include <asm/ptrace.h>
- +#endif
- +
- +#define BACKEND mips_
- +#include "libebl_CPU.h"
- +
- +
- +bool
- +mips_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
- + ebl_tid_registers_t *setfunc __attribute__ ((unused)),
- + void *arg __attribute__ ((unused)))
- +{
- +#if (!defined(mips) && !defined(__mips) && !defined(__mips__) && !defined(MIPS) && !defined(__MIPS__)) || !defined(__linux__)
- + return false;
- +#else /* __mips__ */
- +/* For PTRACE_GETREGS */
- +
- + struct pt_regs gregs;
- + if (ptrace (PTRACE_GETREGS, tid, 0, &gregs) != 0)
- + return false;
- + if (! setfunc (-1, 1, (Dwarf_Word *) &gregs.cp0_epc, arg))
- + return false;
- + return setfunc (0, 32, (Dwarf_Word *) &gregs.regs[0], arg);
- +#endif /* __mips__ */
- +}
- --- /dev/null
- +++ b/backends/mips_unwind.c
- @@ -0,0 +1,84 @@
- +/* Get previous frame state for an existing frame state.
- + Copyright (C) 2016 The Qt Company Ltd.
- + Copyright (C) 2024 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
- +
- +#define BACKEND mips_
- +#define SP_REG 29
- +#define FP_REG 30
- +#define LR_REG 31
- +#define FP_OFFSET 0
- +#define LR_OFFSET 8
- +#define SP_OFFSET 16
- +
- +#include "libebl_CPU.h"
- +
- +/* There was no CFI. Maybe we happen to have a frame pointer and can unwind from that? */
- +
- +bool
- +EBLHOOK(unwind) (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr pc __attribute__ ((unused)),
- + ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc,
- + ebl_pid_memory_read_t *readfunc, void *arg,
- + bool *signal_framep __attribute__ ((unused)))
- +{
- + Dwarf_Word fp, lr, sp;
- +
- + if (!getfunc(LR_REG, 1, &lr, arg))
- + return false;
- +
- + if (lr == 0 || !setfunc(-1, 1, &lr, arg))
- + return false;
- +
- + if (!getfunc(FP_REG, 1, &fp, arg))
- + fp = 0;
- +
- + if (!getfunc(SP_REG, 1, &sp, arg))
- + sp = 0;
- +
- + Dwarf_Word newLr, newFp, newSp;
- +
- + if (!readfunc(fp + LR_OFFSET, &newLr, arg))
- + newLr = 0;
- +
- + if (!readfunc(fp + FP_OFFSET, &newFp, arg))
- + newFp = 0;
- +
- + newSp = fp + SP_OFFSET;
- +
- + // These are not fatal if they don't work. They will just prevent unwinding at the next frame.
- + setfunc(LR_REG, 1, &newLr, arg);
- + setfunc(FP_REG, 1, &newFp, arg);
- + setfunc(SP_REG, 1, &newSp, arg);
- +
- + // If the fp is invalid, we might still have a valid lr.
- + // But if the fp is valid, then the stack should be moving in the right direction.
- + return fp == 0 || newSp > sp;
- +}
- --- /dev/null
- +++ b/backends/mips_corenote.c
- @@ -0,0 +1,104 @@
- +/* MIPS specific core note handling.
- + Copyright (C) 2024 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 <elf.h>
- +#include <inttypes.h>
- +#include <stddef.h>
- +#include <stdio.h>
- +#include <sys/time.h>
- +#include "libebl_CPU.h"
- +
- +#ifndef BITS
- +# define BITS 32
- +#define BACKEND mips_
- +#else
- +# define BITS 64
- +# define BACKEND mips64_
- +#endif
- +
- +#define PRSTATUS_REGS_SIZE (45 * (BITS / 8))
- +static const Ebl_Register_Location prstatus_regs[] =
- + {
- + { .offset = 0, .regno = 0, .count = (BITS == 32 ? 40 : 34), .bits = BITS },
- + { .offset = BITS/8 * (BITS == 32 ? 41 : 35), .regno = (BITS == 32 ? 41 : 35), .count = (BITS == 32 ? 4 : 10), .bits = BITS },
- + };
- +
- +#define PRSTATUS_REGSET_ITEMS \
- + { \
- + .name = "pc", .type = ELF_T_ADDR, .format = 'x', \
- + .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + ((BITS/8) * (BITS == 32 ? 40 : 34)), \
- + .group = "register", \
- + .pc_register = true \
- + }
- +
- +static const Ebl_Register_Location mips_fpregset_regs[] =
- + {
- + { .offset = 0, .regno = 38, .count = 32, .bits = 64 }, /* fp0-fp31 */
- + };
- +
- +static const Ebl_Core_Item mips_fpregset_items[] =
- + {
- + {
- + .name = "fcs", .type = ELF_T_WORD, .format = 'x',
- + .offset = 32 * 8, .group = "register"
- + },
- + {
- + .name = "fir", .type = ELF_T_WORD, .format = 'x',
- + .offset = 32 * 8 + 4, .group = "register"
- + }
- + };
- +
- +#if BITS == 32
- +# define ULONG uint32_t
- +# define ALIGN_ULONG 4
- +# define TYPE_ULONG ELF_T_WORD
- +#define TYPE_LONG ELF_T_SWORD
- +#else
- +#define ULONG uint64_t
- +#define ALIGN_ULONG 8
- +#define TYPE_ULONG ELF_T_XWORD
- +#define TYPE_LONG ELF_T_SXWORD
- +#endif
- +#define PID_T int32_t
- +#define UID_T uint32_t
- +#define GID_T uint32_t
- +#define ALIGN_PID_T 4
- +#define ALIGN_UID_T 4
- +#define ALIGN_GID_T 4
- +#define TYPE_PID_T ELF_T_SWORD
- +#define TYPE_UID_T ELF_T_WORD
- +#define TYPE_GID_T ELF_T_WORD
- +
- +#define EXTRA_NOTES \
- + EXTRA_REGSET_ITEMS (NT_FPREGSET, 32 * 8 + 4 * 2, mips_fpregset_regs, mips_fpregset_items)
- +
- +#include "linux-core-note.c"
- --- /dev/null
- +++ b/backends/mips_regs.c
- @@ -0,0 +1,135 @@
- +/* Register names and numbers for mips DWARF.
- + Copyright (C) 2006 Red Hat, Inc.
- + Copyright (C) 2024 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 <assert.h>
- +#include <dwarf.h>
- +#include <string.h>
- +
- +#define BACKEND mips_
- +#include "libebl_CPU.h"
- +#include <system.h>
- +ssize_t
- +mips_register_info (Ebl *ebl __attribute__ ((unused)),
- + int regno, char *name, size_t namelen,
- + const char **prefix, const char **setname,
- + int *bits, int *type)
- +{
- + if (name == NULL)
- + return 72;
- +
- + if (regno < 0 || regno > 71 || namelen < 4)
- + return -1;
- +
- + *prefix = "$";
- + if (regno < 38)
- + {
- + *setname = "integer";
- + *type = DW_ATE_signed;
- + *bits = 32;
- + }
- + else
- + {
- + *setname = "FPU";
- + *type = DW_ATE_float;
- + *bits = 64;
- + }
- +
- + if (regno < 32)
- + {
- + if (regno < 10)
- + {
- + name[0] = regno + '0';
- + namelen = 1;
- + }
- + else
- + {
- + name[0] = (regno / 10) + '0';
- + name[1] = (regno % 10) + '0';
- + namelen = 2;
- + }
- + if (regno == 28 || regno == 29 || regno == 31)
- + *type = DW_ATE_address;
- + }
- + else if (regno == 32)
- + {
- + return stpcpy (name, "lo") + 1 - name;
- + }
- + else if (regno == 33)
- + {
- + return stpcpy (name, "hi") + 1 - name;
- + }
- + else if (regno == 34)
- + {
- + return stpcpy (name, "pc") + 1 - name;
- + }
- + else if (regno == 35)
- + {
- + *type = DW_ATE_address;
- + return stpcpy (name, "bad") + 1 - name;
- + }
- + else if (regno == 36)
- + {
- + return stpcpy (name, "sr") + 1 - name;
- + }
- + else if (regno == 37)
- + {
- + *type = DW_ATE_address;
- + return stpcpy (name, "cause") + 1 - name;
- + }
- + else if (regno < 70)
- + {
- + name[0] = 'f';
- + if (regno < 38 + 10)
- + {
- + name[1] = (regno - 38) + '0';
- + namelen = 2;
- + }
- + else
- + {
- + name[1] = (regno - 38) / 10 + '0';
- + name[2] = (regno - 38) % 10 + '0';
- + namelen = 3;
- + }
- + }
- + else if (regno == 70)
- + {
- + return stpcpy (name, "fsr") + 1 - name;
- + }
- + else if (regno == 71)
- + {
- + return stpcpy (name, "fir") + 1 - name;
- + }
- +
- + name[namelen++] = '\0';
- + return namelen;
- +}
- --- /dev/null
- +++ b/backends/mips_retval.c
- @@ -0,0 +1,196 @@
- +/* Function return value location for Linux/mips ABI.
- + Copyright (C) 2005 Red Hat, Inc.
- + Copyright (C) 2024 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 <assert.h>
- +#include <dwarf.h>
- +#include <string.h>
- +#include <elf.h>
- +#include <stdio.h>
- +
- +#define BACKEND mips_
- +#include "libebl_CPU.h"
- +#include "libdwP.h"
- +#include <stdio.h>
- +
- +/* $v0 or pair $v0, $v1 */
- +static const Dwarf_Op loc_intreg_o32[] =
- + {
- + { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 4 },
- + { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 },
- + };
- +
- +static const Dwarf_Op loc_intreg[] =
- + {
- + { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 8 },
- + { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 8 },
- + };
- +#define nloc_intreg 1
- +#define nloc_intregpair 4
- +
- +/* $f0 (float), or pair $f0, $f1 (double).
- + * f2/f3 are used for COMPLEX (= 2 doubles) returns in Fortran */
- +static const Dwarf_Op loc_fpreg_o32[] =
- + {
- + { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 4 },
- + { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 4 },
- + { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 4 },
- + { .atom = DW_OP_regx, .number = 35 }, { .atom = DW_OP_piece, .number = 4 },
- + };
- +
- +/* $f0, or pair $f0, $f2. */
- +static const Dwarf_Op loc_fpreg[] =
- + {
- + { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 8 },
- + { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 8 },
- + };
- +#define nloc_fpreg 1
- +#define nloc_fpregpair 4
- +#define nloc_fpregquad 8
- +
- +/* The return value is a structure and is actually stored in stack space
- + passed in a hidden argument by the caller. But, the compiler
- + helpfully returns the address of that space in $v0. */
- +static const Dwarf_Op loc_aggregate[] =
- + {
- + { .atom = DW_OP_breg2, .number = 0 }
- + };
- +#define nloc_aggregate 1
- +
- +int
- +mips_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
- +{
- + unsigned int regsize = (gelf_getclass (functypedie->cu->dbg->elf) == ELFCLASS32 ) ? 4 : 8;
- + if (!regsize)
- + return -2;
- +
- + /* Start with the function's type, and get the DW_AT_type attribute,
- + which is the type of the return value. */
- +
- + Dwarf_Attribute attr_mem;
- + Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type, &attr_mem);
- + if (attr == NULL)
- + /* The function has no return value, like a `void' function in C. */
- + return 0;
- +
- + Dwarf_Die die_mem;
- + Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- + int tag = dwarf_tag (typedie);
- +
- + /* Follow typedefs and qualifiers to get to the actual type. */
- + while (tag == DW_TAG_typedef
- + || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- + || tag == DW_TAG_restrict_type)
- + {
- + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- + typedie = dwarf_formref_die (attr, &die_mem);
- + tag = dwarf_tag (typedie);
- + }
- +
- + switch (tag)
- + {
- + case -1:
- + return -1;
- +
- + case DW_TAG_subrange_type:
- + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
- + {
- + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- + typedie = dwarf_formref_die (attr, &die_mem);
- + tag = dwarf_tag (typedie);
- + }
- + /* Fall through. */
- + FALLTHROUGH;
- +
- + case DW_TAG_base_type:
- + case DW_TAG_enumeration_type:
- + CASE_POINTER:
- + {
- + Dwarf_Word size;
- + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
- + &attr_mem), &size) != 0)
- + {
- + if (dwarf_is_pointer (tag))
- + size = regsize;
- + else
- + return -1;
- + }
- + if (tag == DW_TAG_base_type)
- + {
- + Dwarf_Word encoding;
- + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
- + &attr_mem), &encoding) != 0)
- + return -1;
- +
- +#define ARCH_LOC(loc, regsize) ((regsize) == 4 ? (loc ## _o32) : (loc))
- +
- + if (encoding == DW_ATE_float)
- + {
- + *locp = ARCH_LOC(loc_fpreg, regsize);
- + if (size <= regsize)
- + return nloc_fpreg;
- +
- + if (size <= 2*regsize)
- + return nloc_fpregpair;
- +
- + if (size <= 4*regsize)
- + return nloc_fpregquad;
- +
- + goto aggregate;
- + }
- + }
- + *locp = ARCH_LOC(loc_intreg, regsize);
- + if (size <= regsize)
- + return nloc_intreg;
- + if (size <= 2*regsize)
- + return nloc_intregpair;
- +
- + /* Else fall through. Shouldn't happen though (at least with gcc) */
- + }
- + FALLTHROUGH;
- +
- + case DW_TAG_structure_type:
- + case DW_TAG_class_type:
- + case DW_TAG_union_type:
- + case DW_TAG_array_type:
- + aggregate:
- + *locp = loc_aggregate;
- + return nloc_aggregate;
- + case DW_TAG_unspecified_type:
- + return 0;
- + }
- +
- + /* XXX We don't have a good way to return specific errors from ebl calls.
- + This value means we do not understand the type, but it is well-formed
- + DWARF and might be valid. */
- + return -2;
- +}
- --- a/libelf/elf_getdata.c
- +++ b/libelf/elf_getdata.c
- @@ -135,6 +135,119 @@ __libelf_data_type (GElf_Ehdr *ehdr, int
-
- /* Convert the data in the current section. */
- static void
- +convert_data_for_mips64el (Elf_Scn *scn, int eclass,
- + int data, size_t size, Elf_Type type)
- +{
- + /* Do we need to convert the data and/or adjust for alignment? */
- + if (data == MY_ELFDATA || type == ELF_T_BYTE)
- + {
- + /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, need to convert
- + relocation info(raw data). Some eu-utils use read-mmap method to map file, so
- + we need to malloc and memcpy raw data to avoid segment fault. After modification,
- + the correct value are saved in the malloced memory not in process address space. */
- + scn->data_base = malloc (size);
- + if (scn->data_base == NULL)
- + {
- + __libelf_seterrno (ELF_E_NOMEM);
- + return;
- + }
- +
- + /* The copy will be appropriately aligned for direct access. */
- + memcpy (scn->data_base, scn->rawdata_base, size);
- + }
- + else
- + {
- + xfct_t fp;
- +
- + scn->data_base = malloc (size);
- + if (scn->data_base == NULL)
- + {
- + __libelf_seterrno (ELF_E_NOMEM);
- + return;
- + }
- +
- + /* Make sure the source is correctly aligned for the conversion
- + function to directly access the data elements. */
- + char *rawdata_source;
- + /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, need to convert
- + relocation info(raw data). Some eu-utils use read-mmap method to map file, so
- + we need to malloc and memcpy raw data to avoid segment fault. After modification,
- + the correct value are saved in the malloced memory not in process address space. */
- + rawdata_source = malloc (size);
- + if (rawdata_source == NULL)
- + {
- + __libelf_seterrno (ELF_E_NOMEM);
- + return;
- + }
- +
- + /* The copy will be appropriately aligned for direct access. */
- + memcpy (rawdata_source, scn->rawdata_base, size);
- +
- + /* Get the conversion function. */
- + fp = __elf_xfctstom[eclass - 1][type];
- +
- + fp (scn->data_base, rawdata_source, size, 0);
- +
- + if (rawdata_source != scn->rawdata_base)
- + free (rawdata_source);
- + }
- +
- + scn->data_list.data.d.d_buf = scn->data_base;
- + scn->data_list.data.d.d_size = size;
- + scn->data_list.data.d.d_type = type;
- + scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
- + scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
- + scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
- +
- + scn->data_list.data.s = scn;
- +
- + /* In mips64 little-endian, r_info consists of four byte fields(contains
- + three reloc types) and a 32-bit symbol index. In order to adapt
- + GELF_R_SYM and GELF_R_TYPE, need to convert r_info to get correct symbol
- + index and type. */
- + /* references:
- + https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf
- + Page40 && Page41 */
- + GElf_Shdr shdr_mem;
- + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- + if (shdr->sh_type == SHT_REL)
- + {
- + size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_REL, 1, EV_CURRENT);
- + int nentries = shdr->sh_size / sh_entsize;
- + for (int cnt = 0; cnt < nentries; ++cnt)
- + {
- + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) &scn->data_list.data.d;
- + Elf64_Rel *value = &((Elf64_Rel *) data_scn->d.d_buf)[cnt];
- + Elf64_Xword info = value->r_info;
- + value->r_info = (((info & 0xffffffff) << 32)
- + | ((info >> 56) & 0xff)
- + | ((info >> 40) & 0xff00)
- + | ((info >> 24) & 0xff0000)
- + | ((info >> 8) & 0xff000000));
- + ((Elf64_Rel *) data_scn->d.d_buf)[cnt] = *value;
- + }
- + }
- + else if (shdr->sh_type == SHT_RELA)
- + {
- + size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_RELA, 1, EV_CURRENT);
- + int nentries = shdr->sh_size / sh_entsize;
- + for (int cnt = 0; cnt < nentries; cnt++)
- + {
- + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) &scn->data_list.data.d;
- + Elf64_Rela *value = &((Elf64_Rela *) data_scn->d.d_buf)[cnt];
- + Elf64_Xword info = value->r_info;
- + value->r_info = (((info & 0xffffffff) << 32)
- + | ((info >> 56) & 0xff)
- + | ((info >> 40) & 0xff00)
- + | ((info >> 24) & 0xff0000)
- + | ((info >> 8) & 0xff000000));
- + ((Elf64_Rela *) data_scn->d.d_buf)[cnt] = *value;
- + }
- + }
- +}
- +
- +/* Convert the data in the current section. */
- +static void
- convert_data (Elf_Scn *scn, int eclass,
- int data, size_t size, Elf_Type type)
- {
- @@ -451,8 +564,23 @@ __libelf_set_data_list_rdlock (Elf_Scn *
- return;
- }
-
- - /* Convert according to the version and the type. */
- - convert_data (scn, elf->class,
- + GElf_Shdr shdr_mem;
- + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- + GElf_Ehdr ehdr_mem;
- + GElf_Ehdr *ehdr = gelf_getehdr (scn->elf, &ehdr_mem);
- + if (shdr != NULL && (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
- + scn->elf->class == ELFCLASS64 && ehdr != NULL &&
- + ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
- + convert_data_for_mips64el (scn, elf->class,
- + (elf->class == ELFCLASS32
- + || (offsetof (struct Elf, state.elf32.ehdr)
- + == offsetof (struct Elf, state.elf64.ehdr))
- + ? elf->state.elf32.ehdr->e_ident[EI_DATA]
- + : elf->state.elf64.ehdr->e_ident[EI_DATA]),
- + scn->rawdata.d.d_size, scn->rawdata.d.d_type);
- + else
- + /* Convert according to the version and the type. */
- + convert_data (scn, elf->class,
- (elf->class == ELFCLASS32
- || (offsetof (struct Elf, state.elf32.ehdr)
- == offsetof (struct Elf, state.elf64.ehdr))
- --- a/libelf/elf_update.c
- +++ b/libelf/elf_update.c
- @@ -228,7 +228,60 @@ elf_update (Elf *elf, Elf_Cmd cmd)
- size = -1;
- }
- else
- + {
- + /* Because we converted the relocation info in mips order when we call elf_getdata.c,
- + so we need to convert the modified data in original order bits before writing the
- + data to the file. */
- + Elf_Scn *scn = NULL;
- + while ((scn = elf_nextscn (elf, scn)) != NULL)
- + {
- + GElf_Shdr shdr_mem;
- + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- + GElf_Ehdr ehdr_mem;
- + GElf_Ehdr *ehdr = gelf_getehdr (scn->elf, &ehdr_mem);
- + if (shdr != NULL && (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
- + scn->elf->class == ELFCLASS64 &&
- + ehdr != NULL && ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
- + {
- + Elf_Data *d = elf_getdata (scn, NULL);
- + if (shdr->sh_type == SHT_REL)
- + {
- + size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_REL, 1, EV_CURRENT);
- + int nentries = shdr->sh_size / sh_entsize;
- + for (int cnt = 0; cnt < nentries; ++cnt)
- + {
- + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) d;
- + Elf64_Rel *value = &((Elf64_Rel *) data_scn->d.d_buf)[cnt];
- + Elf64_Xword info = value->r_info;
- + value->r_info = (info >> 32
- + | ((info << 56) & 0xff00000000000000)
- + | ((info << 40) & 0xff000000000000)
- + | ((info << 24) & 0xff0000000000)
- + | ((info << 8) & 0xff00000000));
- + ((Elf64_Rel *) data_scn->d.d_buf)[cnt] = *value;
- + }
- + }
- + else if (shdr->sh_type == SHT_RELA)
- + {
- + size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_RELA, 1, EV_CURRENT);
- + int nentries = shdr->sh_size / sh_entsize;
- + for (int cnt = 0; cnt < nentries; cnt++)
- + {
- + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) d;
- + Elf64_Rela *value = &((Elf64_Rela *) data_scn->d.d_buf)[cnt];
- + Elf64_Xword info = value->r_info;
- + value->r_info = (info >> 32
- + | ((info << 56) & 0xff00000000000000)
- + | ((info << 40) & 0xff000000000000)
- + | ((info << 24) & 0xff0000000000)
- + | ((info << 8) & 0xff00000000));
- + ((Elf64_Rela *) data_scn->d.d_buf)[cnt] = *value;
- + }
- + }
- + }
- + }
- size = write_file (elf, size, change_bo, shnum);
- + }
- }
-
- out:
- --- /dev/null
- +++ b/backends/mips_attrs.c
- @@ -0,0 +1,140 @@
- +/* Object attribute tags for MIPS.
- + Copyright (C) 2024 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 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;
- +}
- --- a/src/readelf.c
- +++ b/src/readelf.c
- @@ -2219,17 +2219,41 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *
- (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: %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 *
- (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: %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
- (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: %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
- (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 ("%s", rtype2);
- +
- + printf ("\n Type3: ");
- + if (rtype3 == NULL)
- + printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff);
- + else
- + printf ("%s", rtype3);
- + printf("\n");
- + }
- + }
- }
- }
- }
- @@ -12043,7 +12139,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *
- 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);
- @@ -12073,7 +12169,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *
- 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
- {
- --- a/tests/Makefile.am
- +++ b/tests/Makefile.am
- @@ -214,7 +214,7 @@ TESTS = run-arextract.sh run-arsymtest.s
- 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-dwfl-core-noncontig.sh run-cu-dwp-section-info.sh \
- - run-declfiles.sh
- + run-declfiles.sh run-readelf-reloc.sh
-
- if !BIARCH
- export ELFUTILS_DISABLE_BIARCH = 1
- @@ -646,7 +646,8 @@ EXTRA_DIST = run-arextract.sh run-arsymt
- testfile-dwp-5-cu-index-overflow.dwp.bz2 \
- testfile-dwp-4-cu-index-overflow.bz2 \
- testfile-dwp-4-cu-index-overflow.dwp.bz2 \
- - testfile-dwp-cu-index-overflow.source
- + testfile-dwp-cu-index-overflow.source \
- + run-readelf-reloc.sh
-
-
- if USE_VALGRIND
- --- /dev/null
- +++ b/tests/run-readelf-reloc.sh
- @@ -0,0 +1,42 @@
- +#! /bin/bash
- +# Copyright (C) 2024 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 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 <http://www.gnu.org/licenses/>.
- +
- +. $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
- --- a/src/elflint.c
- +++ b/src/elflint.c
- @@ -936,7 +936,9 @@ section [%2d] '%s': symbol %zu (%s): non
- }
-
- if (GELF_ST_TYPE (sym->st_info) == STT_SECTION
- - && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
- + && GELF_ST_BIND (sym->st_info) != STB_LOCAL
- + && ehdr->e_machine != EM_MIPS
- + && strcmp (name, "_DYNAMIC_LINKING") != 0)
- ERROR (_("\
- section [%2d] '%s': symbol %zu (%s): non-local section symbol\n"),
- idx, section_name (ebl, idx), cnt, name);
- @@ -3828,6 +3830,10 @@ cannot get section header for section [%
- && ebl_bss_plt_p (ebl))
- good_type = SHT_NOBITS;
-
- + if (ehdr->e_machine == EM_MIPS
- + && (strstr(special_sections[s].name, ".debug") != NULL))
- + good_type = SHT_MIPS_DWARF;
- +
- /* In a debuginfo file, any normal section can be SHT_NOBITS.
- This is only invalid for DWARF sections and .shstrtab. */
- if (shdr->sh_type != good_type
- @@ -3988,12 +3994,21 @@ section [%2zu] '%s': size not multiple o
- ERROR (_("section [%2zu] '%s'"
- " contains invalid processor-specific flag(s)"
- " %#" PRIx64 "\n"),
- - cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
- + cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
- sh_flags &= ~(GElf_Xword) SHF_MASKPROC;
- }
- if (sh_flags & SHF_MASKOS)
- - if (gnuld)
- - sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN;
- + {
- + if (gnuld)
- + sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN;
- + if (!ebl_machine_section_flag_check (ebl,
- + sh_flags & SHF_MASKOS))
- + ERROR (_("section [%2zu] '%s'"
- + " contains invalid os-specific flag(s)"
- + " %#" PRIx64 "\n"),
- + cnt, section_name (ebl, cnt), sh_flags & SHF_MASKOS);
- + sh_flags &= ~(GElf_Xword) SHF_MASKOS;
- + }
- if (sh_flags != 0)
- ERROR (_("section [%2zu] '%s' contains unknown flag(s)"
- " %#" PRIx64 "\n"),
- @@ -4059,6 +4074,7 @@ section [%2zu] '%s': merge flag set but
- switch (shdr->sh_type)
- {
- case SHT_PROGBITS:
- + case SHT_MIPS_DWARF:
- break;
-
- case SHT_NOBITS:
- @@ -4716,7 +4732,7 @@ program header offset in ELF header and
- if (shdr != NULL
- && ((is_debuginfo && shdr->sh_type == SHT_NOBITS)
- || (! is_debuginfo
- - && (shdr->sh_type == SHT_PROGBITS
- + && (is_debug_section_type(shdr->sh_type)
- || shdr->sh_type == SHT_X86_64_UNWIND)))
- && elf_strptr (ebl->elf, shstrndx, shdr->sh_name) != NULL
- && ! strcmp (".eh_frame_hdr",
- --- /dev/null
- +++ b/backends/mips64_corenote.c
- @@ -0,0 +1,2 @@
- +#define BITS 64
- +#include "mips_corenote.c"
- --- a/libebl/eblcorenotetypename.c
- +++ b/libebl/eblcorenotetypename.c
- @@ -94,6 +94,8 @@ ebl_core_note_type_name (Ebl *ebl, uint3
- KNOWNSTYPE (ARM_SYSTEM_CALL);
- KNOWNSTYPE (SIGINFO);
- KNOWNSTYPE (FILE);
- + KNOWNSTYPE (MIPS_FP_MODE);
- + KNOWNSTYPE (MIPS_MSA);
- #undef KNOWNSTYPE
-
- default:
- --- a/tests/run-allregs.sh
- +++ b/tests/run-allregs.sh
- @@ -2904,4 +2904,83 @@ FPU registers:
- 62: ft10 (ft10), float 64 bits
- 63: ft11 (ft11), float 64 bits
- EOF
- +
- +# See run-readelf-mixed-corenote.sh for instructions to regenerate
- +# this core file.
- +regs_test testfile-mips64-core <<\EOF
- +integer registers:
- + 0: $0 (0), signed 32 bits
- + 1: $1 (1), signed 32 bits
- + 2: $2 (2), signed 32 bits
- + 3: $3 (3), signed 32 bits
- + 4: $4 (4), signed 32 bits
- + 5: $5 (5), signed 32 bits
- + 6: $6 (6), signed 32 bits
- + 7: $7 (7), signed 32 bits
- + 8: $8 (8), signed 32 bits
- + 9: $9 (9), signed 32 bits
- + 10: $10 (10), signed 32 bits
- + 11: $11 (11), signed 32 bits
- + 12: $12 (12), signed 32 bits
- + 13: $13 (13), signed 32 bits
- + 14: $14 (14), signed 32 bits
- + 15: $15 (15), signed 32 bits
- + 16: $16 (16), signed 32 bits
- + 17: $17 (17), signed 32 bits
- + 18: $18 (18), signed 32 bits
- + 19: $19 (19), signed 32 bits
- + 20: $20 (20), signed 32 bits
- + 21: $21 (21), signed 32 bits
- + 22: $22 (22), signed 32 bits
- + 23: $23 (23), signed 32 bits
- + 24: $24 (24), signed 32 bits
- + 25: $25 (25), signed 32 bits
- + 26: $26 (26), signed 32 bits
- + 27: $27 (27), signed 32 bits
- + 28: $28 (28), address 32 bits
- + 29: $29 (29), address 32 bits
- + 30: $30 (30), signed 32 bits
- + 31: $31 (31), address 32 bits
- + 32: $lo (lo), signed 32 bits
- + 33: $hi (hi), signed 32 bits
- + 34: $pc (pc), signed 32 bits
- + 35: $bad (bad), address 32 bits
- + 36: $sr (sr), signed 32 bits
- + 37: $cause (cause), address 32 bits
- +FPU registers:
- + 38: $f0 (f0), float 64 bits
- + 39: $f1 (f1), float 64 bits
- + 40: $f2 (f2), float 64 bits
- + 41: $f3 (f3), float 64 bits
- + 42: $f4 (f4), float 64 bits
- + 43: $f5 (f5), float 64 bits
- + 44: $f6 (f6), float 64 bits
- + 45: $f7 (f7), float 64 bits
- + 46: $f8 (f8), float 64 bits
- + 47: $f9 (f9), float 64 bits
- + 48: $f10 (f10), float 64 bits
- + 49: $f11 (f11), float 64 bits
- + 50: $f12 (f12), float 64 bits
- + 51: $f13 (f13), float 64 bits
- + 52: $f14 (f14), float 64 bits
- + 53: $f15 (f15), float 64 bits
- + 54: $f16 (f16), float 64 bits
- + 55: $f17 (f17), float 64 bits
- + 56: $f18 (f18), float 64 bits
- + 57: $f19 (f19), float 64 bits
- + 58: $f20 (f20), float 64 bits
- + 59: $f21 (f21), float 64 bits
- + 60: $f22 (f22), float 64 bits
- + 61: $f23 (f23), float 64 bits
- + 62: $f24 (f24), float 64 bits
- + 63: $f25 (f25), float 64 bits
- + 64: $f26 (f26), float 64 bits
- + 65: $f27 (f27), float 64 bits
- + 66: $f28 (f28), float 64 bits
- + 67: $f29 (f29), float 64 bits
- + 68: $f30 (f30), float 64 bits
- + 69: $f31 (f31), float 64 bits
- + 70: $fsr (fsr), float 64 bits
- + 71: $fir (fir), float 64 bits
- +EOF
- exit 0
- --- a/tests/run-readelf-mixed-corenote.sh
- +++ b/tests/run-readelf-mixed-corenote.sh
- @@ -716,4 +716,101 @@ Note segment of 1408 bytes at offset 0x3
- 2000155000-2000157000 00122000 8192 /lib64/libc-2.27.so
- EOF
-
- +# To reproduce this core dump, do this on a mips machine:
- +# $ gcc -x c <(echo 'int main () { return *(int *)0x12345678; }')
- +# $ ./a.out
- +testfiles testfile-mips64-core
- +testrun_compare ${abs_top_builddir}/src/readelf -n testfile-mips64-core <<\EOF
- +
- +Note segment of 2572 bytes at offset 0x3c0:
- + Owner Data size Type
- + CORE 480 PRSTATUS
- + info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
- + sigpend: <>
- + sighold: <>
- + pid: 1660204, ppid: 1457483, pgrp: 1660204, sid: 1457483
- + utime: 0.000000, stime: 0.012000, cutime: 0.000000, cstime: 0.000000
- + pc: 0x000000aaacce0a64, fpvalid: 1
- + bad: 0x12345678 sr: 0 cause: 0x0400ccf3
- + f0: 0x1000000800000000 f1: 0x0000000000000000 f2: 0x0000000000000000
- + f3: 0x0000000000000000 f4: 0x0000000000000000 f5: 0x0000000000000000
- + f6: 0x0000000000000000
- + 0: 0 1: 0 2: 1
- + 3: 0 4: 305419896 5: 0
- + 6: -73593800 7: 255 8: 1
- + 9: 0 10: -73593464 11: 255
- + 12: -73593448 13: 255 14: 0
- + 15: 0 16: -244869184 17: 255
- + 18: -244886336 19: 255 20: -73593472
- + 21: 255 22: -1 23: -1
- + 24: 3 25: 0 26: 3167716
- + 27: 0 28: 0x00000024 29: 0x00000000
- + 30: 49495 31: 0x00000000 lo: -73593464
- + hi: 255 bad: 0x12345678 sr: 0
- + cause: 0x0400ccf3 f0: 0x1000000800000000
- + f1: 0x0000000000000000 f2: 0x0000000000000000
- + f3: 0x0000000000000000 f4: 0x0000000000000000
- + f5: 0x0000000000000000 f6: 0x0000000000000000
- + CORE 136 PRPSINFO
- + state: 0, sname: R, zomb: 0, nice: 0, flag: 0x0000000000402600
- + uid: 1014, gid: 100, pid: 1660204, ppid: 1457483, pgrp: 1660204
- + sid: 1457483
- + fname: a.out, psargs: ./a.out
- + CORE 128 SIGINFO
- + si_signo: 11, si_errno: 1, si_code: 0
- + sender PID: 305419896, sender UID: 0
- + CORE 320 AUXV
- + SYSINFO_EHDR: 0xffff14c000
- + HWCAP: 0x7806
- + PAGESZ: 16384
- + CLKTCK: 100
- + PHDR: 0xaaacce0040
- + PHENT: 56
- + PHNUM: 9
- + BASE: 0xfff1694000
- + FLAGS: 0
- + ENTRY: 0xaaacce08d0
- + UID: 1014
- + EUID: 1014
- + GID: 100
- + EGID: 100
- + SECURE: 0
- + RANDOM: 0xfffb9d0f9c
- + EXECFN: 0xfffb9d3ff0
- + PLATFORM: 0xfffb9d0fb5
- + BASE_PLATFORM: 0xfffb9d0fac
- + NULL
- + CORE 549 FILE
- + 9 files:
- + aaacce0000-aaacce4000 00000000 16384 /tmp/a.out
- + aaaccf0000-aaaccf4000 00000000 16384 /tmp/a.out
- + fff1470000-fff165c000 00000000 2015232 /usr/lib/mips64el-linux-gnuabi64/libc.so.6
- + fff165c000-fff1668000 001ec000 49152 /usr/lib/mips64el-linux-gnuabi64/libc.so.6
- + fff1668000-fff1670000 001e8000 32768 /usr/lib/mips64el-linux-gnuabi64/libc.so.6
- + fff1670000-fff1678000 001f0000 32768 /usr/lib/mips64el-linux-gnuabi64/libc.so.6
- + fff1694000-fff16c4000 00000000 196608 /usr/lib/mips64el-linux-gnuabi64/ld.so.1
- + fff16d0000-fff16d4000 0002c000 16384 /usr/lib/mips64el-linux-gnuabi64/ld.so.1
- + fff16d4000-fff16d8000 00030000 16384 /usr/lib/mips64el-linux-gnuabi64/ld.so.1
- + CORE 264 FPREGSET
- + fcs: 0x000c0000, fir: 0x00f70501
- + f0: 0xffffffffffffffff f1: 0xffffffffffffffff
- + f2: 0xffffffffffffffff f3: 0xffffffffffffffff
- + f4: 0xffffffffffffffff f5: 0xffffffffffffffff
- + f6: 0xffffffffffffffff f7: 0xffffffffffffffff
- + f8: 0xffffffffffffffff f9: 0xffffffffffffffff
- + f10: 0xffffffffffffffff f11: 0xffffffffffffffff
- + f12: 0xffffffffffffffff f13: 0xffffffffffffffff
- + f14: 0xffffffffffffffff f15: 0xffffffffffffffff
- + f16: 0xffffffffffffffff f17: 0xffffffffffffffff
- + f18: 0xffffffffffffffff f19: 0xffffffffffffffff
- + f20: 0xffffffffffffffff f21: 0xffffffffffffffff
- + f22: 0xffffffffffffffff f23: 0xffffffffffffffff
- + f24: 0xffffffffffffffff f25: 0xffffffffffffffff
- + f26: 0xffffffffffffffff f27: 0xffffffffffffffff
- + f28: 0xffffffffffffffff f29: 0xffffffffffffffff
- + f30: 0xffffffffffffffff f31: 0xffffffffffffffff
- + LINUX 4 MIPS_FP_MODE
- + LINUX 528 MIPS_MSA
- +EOF
- +
- exit 0
|