From e259f126f5077923e415e306915de50ed0f0db56 Mon Sep 17 00:00:00 2001 From: Ying Huang Date: Tue, 5 Mar 2024 17:51:17 +0800 Subject: [PATCH] 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 --- 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 diff --git a/backends/Makefile.am b/backends/Makefile.am index bbb2aac79ab8..b946fd30495f 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -37,7 +37,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \ 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,14 @@ 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 + 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) diff --git a/backends/mips_init.c b/backends/mips_init.c new file mode 100644 index 000000000000..cedd08ca1339 --- /dev/null +++ b/backends/mips_init.c @@ -0,0 +1,52 @@ +/* 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#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" + +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); + return eh; +} diff --git a/backends/mips_reloc.def b/backends/mips_reloc.def new file mode 100644 index 000000000000..5120980c13eb --- /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 . */ + +/* 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) diff --git a/backends/mips_symbol.c b/backends/mips_symbol.c new file mode 100644 index 000000000000..f2a46495ed6b --- /dev/null +++ b/backends/mips_symbol.c @@ -0,0 +1,63 @@ +/* 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include +#include +#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; + } +} diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c index 084a1544b286..a5f7467a09d2 100644 --- 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])) diff --git a/libelf/libelfP.h b/libelf/libelfP.h index ed061abb0066..bdd2cc6ac27d 100644 --- a/libelf/libelfP.h +++ b/libelf/libelfP.h @@ -617,4 +617,7 @@ extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, #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) #endif /* libelfP.h */ -- 2.39.3