From 9a36c9226c4a237208a7735f0e6a6fd1eefb60ab Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 21 Jun 2016 15:10:10 -0700 Subject: Add support for BPF Signed-off-by: Richard Henderson --- backends/ChangeLog | 10 ++++++++ backends/Makefile.am | 15 ++++++++++-- backends/bpf_init.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++ backends/bpf_regs.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ backends/bpf_reloc.def | 31 ++++++++++++++++++++++++ backends/common-reloc.c | 7 ++++-- 6 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 backends/bpf_init.c create mode 100644 backends/bpf_regs.c create mode 100644 backends/bpf_reloc.def (limited to 'backends') diff --git a/backends/ChangeLog b/backends/ChangeLog index afda37a9..7cd19065 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,13 @@ +2016-06-28 Richard Henderson + + * Makefile.am (modules): Add bpf. + (libebl_pic): Add libebl_bpf_pic.a. + (am_libebl_bpf_pic_a_OBJECTS): New. + * bpf_init.c, bpf_regs.c, bpf_reloc.def: New files. + * common-reloc.c (copy_reloc_p): Honor NO_COPY_RELOC. + (init_reloc): Likewise. + + 2016-05-20 Andreas Schwab * Makefile.am (modules): Add m68k. diff --git a/backends/Makefile.am b/backends/Makefile.am index bf523912..b553ec34 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -33,12 +33,12 @@ AM_CPPFLAGS += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \ modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \ - tilegx m68k + tilegx m68k bpf libebl_pic = libebl_i386_pic.a libebl_sh_pic.a libebl_x86_64_pic.a \ libebl_ia64_pic.a libebl_alpha_pic.a libebl_arm_pic.a \ libebl_aarch64_pic.a libebl_sparc_pic.a libebl_ppc_pic.a \ libebl_ppc64_pic.a libebl_s390_pic.a libebl_tilegx_pic.a \ - libebl_m68k_pic.a + libebl_m68k_pic.a libebl_bpf_pic.a noinst_LIBRARIES = $(libebl_pic) noinst_DATA = $(libebl_pic:_pic.a=.so) @@ -118,6 +118,16 @@ m68k_SRCS = m68k_init.c m68k_symbol.c m68k_regs.c \ libebl_m68k_pic_a_SOURCES = $(m68k_SRCS) am_libebl_m68k_pic_a_OBJECTS = $(m68k_SRCS:.c=.os) +bpf_SRCS = bpf_init.c bpf_regs.c +# The disam hook depends on this if we have linux/bpf.h. +if HAVE_LINUX_BPF_H +cpu_bpf = ../libcpu/libcpu_bpf.a +else +cpu_bpf = +endif +libebl_bpf_pic_a_SOURCES = $(bpf_SRCS) +am_libebl_bpf_pic_a_OBJECTS = $(bpf_SRCS:.c=.os) + libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw) @rm -f $(@:.so=.map) @@ -131,6 +141,7 @@ libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw) libebl_i386.so: $(cpu_i386) libebl_x86_64.so: $(cpu_x86_64) +libebl_bpf.so: $(cpu_bpf) install: install-am install-ebl-modules install-ebl-modules: diff --git a/backends/bpf_init.c b/backends/bpf_init.c new file mode 100644 index 00000000..22842e26 --- /dev/null +++ b/backends/bpf_init.c @@ -0,0 +1,60 @@ +/* Initialization of BPF specific backend library. + 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 bpf_ +#define RELOC_PREFIX R_BPF_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on bpf_reloc.def. */ +#define NO_RELATIVE_RELOC +#define NO_COPY_RELOC +#include "common-reloc.c" + + +const char * +bpf_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh, size_t ehlen) +{ + /* Check whether the Elf_BH object has a sufficent size. */ + if (ehlen < sizeof (Ebl)) + return NULL; + + /* We handle it. */ + eh->name = "BPF"; + bpf_init_reloc (eh); + HOOK (eh, register_info); +#ifdef HAVE_LINUX_BPF_H + HOOK (eh, disasm); +#endif + + return MODVERSION; +} diff --git a/backends/bpf_regs.c b/backends/bpf_regs.c new file mode 100644 index 00000000..180af83b --- /dev/null +++ b/backends/bpf_regs.c @@ -0,0 +1,64 @@ +/* Register names and numbers for BPF DWARF. + 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 + +#ifdef HAVE_LINUX_BPF_H +#include +#else +#define MAX_BPF_REG 10 +#endif + +#define BACKEND bpf_ +#include "libebl_CPU.h" + +ssize_t +bpf_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + ssize_t len; + + if (name == NULL) + return MAX_BPF_REG; + if (regno < 0 || regno >= MAX_BPF_REG) + return -1; + + *prefix = ""; + *setname = "integer"; + *bits = 64; + *type = DW_ATE_signed; + + len = snprintf(name, namelen, "r%d", regno); + return ((size_t)len < namelen ? len : -1); +} diff --git a/backends/bpf_reloc.def b/backends/bpf_reloc.def new file mode 100644 index 00000000..a410da97 --- /dev/null +++ b/backends/bpf_reloc.def @@ -0,0 +1,31 @@ +/* List the relocation types for BPF. -*- C -*- + 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, EXEC|DYN) +RELOC_TYPE (MAP_FD, REL|EXEC|DYN) diff --git a/backends/common-reloc.c b/backends/common-reloc.c index 3317b6c9..096ed1c7 100644 --- a/backends/common-reloc.c +++ b/backends/common-reloc.c @@ -124,12 +124,13 @@ EBLHOOK(reloc_valid_use) (Elf *elf, int reloc) return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1))); } - +#ifndef NO_COPY_RELOC bool EBLHOOK(copy_reloc_p) (int reloc) { return reloc == R_TYPE (COPY); } +#endif bool EBLHOOK(none_reloc_p) (int reloc) @@ -151,8 +152,10 @@ EBLHOOK(init_reloc) (Ebl *ebl) ebl->reloc_type_name = EBLHOOK(reloc_type_name); ebl->reloc_type_check = EBLHOOK(reloc_type_check); ebl->reloc_valid_use = EBLHOOK(reloc_valid_use); - ebl->copy_reloc_p = EBLHOOK(copy_reloc_p); ebl->none_reloc_p = EBLHOOK(none_reloc_p); +#ifndef NO_COPY_RELOC + ebl->copy_reloc_p = EBLHOOK(copy_reloc_p); +#endif #ifndef NO_RELATIVE_RELOC ebl->relative_reloc_p = EBLHOOK(relative_reloc_p); #endif -- cgit v1.2.1