summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@linux-m68k.org>2016-05-20 19:37:29 +0200
committerMark Wielaard <mjw@redhat.com>2016-05-23 13:32:01 +0200
commit37bb3fcd9010f6fead99568613b2aa8a7fcdc703 (patch)
tree91eb79cdcc1543b014bf89fd6bec81e6985c818e
parent239cd48bc87ffbf95e6fe2dd6bd708b3fc9b1855 (diff)
downloadelfutils-37bb3fcd9010f6fead99568613b2aa8a7fcdc703.tar.gz
Add support for m68k
Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
-rw-r--r--backends/ChangeLog14
-rw-r--r--backends/Makefile.am10
-rw-r--r--backends/linux-core-note.c4
-rw-r--r--backends/m68k_corenote.c71
-rw-r--r--backends/m68k_init.c60
-rw-r--r--backends/m68k_regs.c96
-rw-r--r--backends/m68k_reloc.def70
-rw-r--r--backends/m68k_retval.c153
-rw-r--r--backends/m68k_symbol.c70
-rw-r--r--libebl/ChangeLog4
-rw-r--r--libebl/eblopenbackend.c2
11 files changed, 550 insertions, 4 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog
index cf70a52f..afda37a9 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,17 @@
+2016-05-20 Andreas Schwab <schwab@linux-m68k.org>
+
+ * Makefile.am (modules): Add m68k.
+ (libebl_pic): Add libebl_m68k_pic.a.
+ (m68k_SRCS, libebl_m68k_pic_a_SOURCES)
+ (am_libebl_m68k_pic_a_OBJECTS): Define.
+ * m68k_init.c: New file.
+ * m68k_symbol.c: New file.
+ * m68k_regs.c: New file.
+ * m68k_retval.c: New file.
+ * m68k_corenote.c: New file.
+ * m68k_reloc.def: New file.
+ * linux-core-note.c (ALIGN_INT): Only define if not defined.
+
2016-02-26 Jose E. Marchesi <jose.marchesi@oracle.com>
* sparc_initreg.c (EBLHOOK): Provide a dummy
diff --git a/backends/Makefile.am b/backends/Makefile.am
index b16f9486..bf523912 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -33,11 +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
+ tilegx m68k
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_ppc64_pic.a libebl_s390_pic.a libebl_tilegx_pic.a \
+ libebl_m68k_pic.a
noinst_LIBRARIES = $(libebl_pic)
noinst_DATA = $(libebl_pic:_pic.a=.so)
@@ -112,6 +113,11 @@ tilegx_SRCS = tilegx_init.c tilegx_symbol.c tilegx_regs.c \
libebl_tilegx_pic_a_SOURCES = $(tilegx_SRCS)
am_libebl_tilegx_pic_a_OBJECTS = $(tilegx_SRCS:.c=.os)
+m68k_SRCS = m68k_init.c m68k_symbol.c m68k_regs.c \
+ m68k_retval.c m68k_corenote.c
+libebl_m68k_pic_a_SOURCES = $(m68k_SRCS)
+am_libebl_m68k_pic_a_OBJECTS = $(m68k_SRCS:.c=.os)
+
libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw)
@rm -f $(@:.so=.map)
diff --git a/backends/linux-core-note.c b/backends/linux-core-note.c
index ff2b226f..c00c0b17 100644
--- a/backends/linux-core-note.c
+++ b/backends/linux-core-note.c
@@ -41,7 +41,9 @@
#define ALIGN_SHORT 2
#define TYPE_SHORT ELF_T_HALF
#define INT int32_t
-#define ALIGN_INT 4
+#ifndef ALIGN_INT
+# define ALIGN_INT 4
+#endif
#define TYPE_INT ELF_T_SWORD
#ifndef PR_REG
# define PR_REG ULONG
diff --git a/backends/m68k_corenote.c b/backends/m68k_corenote.c
new file mode 100644
index 00000000..e839edfd
--- /dev/null
+++ b/backends/m68k_corenote.c
@@ -0,0 +1,71 @@
+/* M68K specific core note handling.
+ 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>
+
+#define BACKEND m68k_
+#include "libebl_CPU.h"
+
+static const Ebl_Register_Location prstatus_regs[] =
+ {
+ { .offset = 0, .regno = 1, .count = 14, .bits = 32 }, /* d1-d7, a0-a6 */
+ { .offset = 14 * 4, .regno = 0, .count = 1, .bits = 32 }, /* d0 */
+ { .offset = 15 * 4, .regno = 15, .count = 1, .bits = 32 }, /* a7 */
+ { .offset = 18 * 4, .regno = 24, .count = 1, .bits = 32 } /* pc */
+ };
+#define PRSTATUS_REGS_SIZE (20 * 4)
+
+#define ULONG uint32_t
+#define PID_T int32_t
+#define UID_T uint16_t
+#define GID_T uint16_t
+#define ALIGN_INT 2
+#define ALIGN_ULONG 2
+#define ALIGN_PID_T 2
+#define ALIGN_UID_T 2
+#define ALIGN_GID_T 2
+#define TYPE_ULONG ELF_T_WORD
+#define TYPE_PID_T ELF_T_SWORD
+#define TYPE_UID_T ELF_T_HALF
+#define TYPE_GID_T ELF_T_HALF
+
+static const Ebl_Register_Location fpregset_regs[] =
+ {
+ { .offset = 0, .regno = 16, .count = 8, .bits = 96 }, /* fp0-fp7 */
+ };
+#define FPREGSET_SIZE (27 * 4)
+
+#include "linux-core-note.c"
diff --git a/backends/m68k_init.c b/backends/m68k_init.c
new file mode 100644
index 00000000..943478fb
--- /dev/null
+++ b/backends/m68k_init.c
@@ -0,0 +1,60 @@
+/* Initialization of M68K 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND m68k_
+#define RELOC_PREFIX R_68K_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on m68k_reloc.def. */
+#include "common-reloc.c"
+
+
+const char *
+m68k_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 = "M68K";
+ m68k_init_reloc (eh);
+ HOOK (eh, gotpc_reloc_check);
+ HOOK (eh, reloc_simple_type);
+ HOOK (eh, return_value_location);
+ HOOK (eh, register_info);
+ HOOK (eh, core_note);
+
+ return MODVERSION;
+}
diff --git a/backends/m68k_regs.c b/backends/m68k_regs.c
new file mode 100644
index 00000000..cb99f552
--- /dev/null
+++ b/backends/m68k_regs.c
@@ -0,0 +1,96 @@
+/* Register names and numbers for M68K 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND m68k_
+#include "libebl_CPU.h"
+
+ssize_t
+m68k_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 25;
+
+ if (regno < 0 || regno > 24 || namelen < 5)
+ return -1;
+
+ *prefix = "%";
+ *setname = "integer";
+ *bits = 32;
+
+ switch (regno)
+ {
+ case 0 ... 7:
+ *type = DW_ATE_signed;
+ name[0] = 'd';
+ name[1] = regno + '0';
+ namelen = 2;
+ break;
+
+ case 8 ... 15:
+ *type = DW_ATE_address;
+ name[0] = 'a';
+ name[1] = regno - 8 + '0';
+ namelen = 2;
+ break;
+
+ case 16 ... 23:
+ *type = DW_ATE_float;
+ *setname = "FPU";
+ *bits = 96;
+ name[0] = 'f';
+ name[1] = 'p';
+ name[2] = regno - 16 + '0';
+ namelen = 3;
+ break;
+
+ case 24:
+ *type = DW_ATE_address;
+ name[0] = 'p';
+ name[1] = 'c';
+ namelen = 2;
+ break;
+
+ /* Can't happen. */
+ default:
+ *setname = NULL;
+ return 0;
+ }
+
+ name[namelen++] = '\0';
+ return namelen;
+}
diff --git a/backends/m68k_reloc.def b/backends/m68k_reloc.def
new file mode 100644
index 00000000..b7cc4df8
--- /dev/null
+++ b/backends/m68k_reloc.def
@@ -0,0 +1,70 @@
+/* List the relocation types for m68k. -*- 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 <http://www.gnu.org/licenses/>. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, EXEC|DYN)
+RELOC_TYPE (32, REL|EXEC|DYN)
+RELOC_TYPE (16, REL|EXEC|DYN)
+RELOC_TYPE (8, REL|EXEC|DYN)
+RELOC_TYPE (PC32, REL|EXEC|DYN)
+RELOC_TYPE (PC16, REL|EXEC|DYN)
+RELOC_TYPE (PC8, REL|EXEC|DYN)
+RELOC_TYPE (GOT32, REL)
+RELOC_TYPE (GOT16, REL)
+RELOC_TYPE (GOT8, REL)
+RELOC_TYPE (GOT32O, REL)
+RELOC_TYPE (GOT16O, REL)
+RELOC_TYPE (GOT8O, REL)
+RELOC_TYPE (PLT32, REL)
+RELOC_TYPE (PLT16, REL)
+RELOC_TYPE (PLT8, REL)
+RELOC_TYPE (PLT32O, REL)
+RELOC_TYPE (PLT16O, REL)
+RELOC_TYPE (PLT8O, REL)
+RELOC_TYPE (COPY, EXEC|DYN)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (TLS_GD32, REL)
+RELOC_TYPE (TLS_GD16, REL)
+RELOC_TYPE (TLS_GD8, REL)
+RELOC_TYPE (TLS_LDM32, REL)
+RELOC_TYPE (TLS_LDM16, REL)
+RELOC_TYPE (TLS_LDM8, REL)
+RELOC_TYPE (TLS_LDO32, REL)
+RELOC_TYPE (TLS_LDO16, REL)
+RELOC_TYPE (TLS_LDO8, REL)
+RELOC_TYPE (TLS_IE32, REL)
+RELOC_TYPE (TLS_IE16, REL)
+RELOC_TYPE (TLS_IE8, REL)
+RELOC_TYPE (TLS_LE32, REL)
+RELOC_TYPE (TLS_LE16, REL)
+RELOC_TYPE (TLS_LE8, REL)
+RELOC_TYPE (TLS_DTPMOD32, EXEC|DYN)
+RELOC_TYPE (TLS_DTPREL32, EXEC|DYN)
+RELOC_TYPE (TLS_TPREL32, EXEC|DYN)
diff --git a/backends/m68k_retval.c b/backends/m68k_retval.c
new file mode 100644
index 00000000..2dd285a0
--- /dev/null
+++ b/backends/m68k_retval.c
@@ -0,0 +1,153 @@
+/* Function return value location for Linux/m68k ABI.
+ 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>
+
+#define BACKEND m68k_
+#include "libebl_CPU.h"
+
+
+/* %d0, or pair %d0, %d1. */
+static const Dwarf_Op loc_intreg[] =
+ {
+ { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 },
+ { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 4 },
+ };
+#define nloc_intreg 1
+#define nloc_intregpair 4
+
+/* %a0. */
+static const Dwarf_Op loc_ptrreg[] =
+ {
+ { .atom = DW_OP_reg8 }
+ };
+#define nloc_ptrreg 1
+
+/* %fp0. */
+static const Dwarf_Op loc_fpreg[] =
+ {
+ { .atom = DW_OP_reg16 }
+ };
+#define nloc_fpreg 1
+
+/* 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 %a0. */
+static const Dwarf_Op loc_aggregate[] =
+ {
+ { .atom = DW_OP_reg8 }
+ };
+#define nloc_aggregate 1
+
+int
+m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+ /* Start with the function's type, and get the DW_AT_type attribute,
+ which is the type of the return value. */
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
+
+ switch (tag)
+ {
+ case -1:
+ return -1;
+
+ case DW_TAG_subrange_type:
+ if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+ {
+ Dwarf_Attribute attr_mem, *attr;
+ attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+ typedie = dwarf_formref_die (attr, &die_mem);
+ tag = DWARF_TAG_OR_RETURN (typedie);
+ }
+ /* Fall through. */
+
+ case DW_TAG_base_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_ptr_to_member_type:
+ {
+ Dwarf_Word size;
+ Dwarf_Attribute attr_mem;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+ &attr_mem), &size) != 0)
+ {
+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ size = 4;
+ 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;
+ if (encoding == DW_ATE_float)
+ {
+ if (size > 12)
+ return -2;
+ *locp = loc_fpreg;
+ return nloc_fpreg;
+ }
+ }
+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ {
+ *locp = loc_ptrreg;
+ return nloc_ptrreg;
+ }
+ *locp = loc_intreg;
+ if (size <= 4)
+ return nloc_intreg;
+ if (size <= 8)
+ return nloc_intregpair;
+
+ /* Else fall through. */
+ }
+
+ case DW_TAG_structure_type:
+ case DW_TAG_class_type:
+ case DW_TAG_union_type:
+ case DW_TAG_array_type:
+ *locp = loc_aggregate;
+ return nloc_aggregate;
+ }
+
+ /* 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;
+}
diff --git a/backends/m68k_symbol.c b/backends/m68k_symbol.c
new file mode 100644
index 00000000..269d12e5
--- /dev/null
+++ b/backends/m68k_symbol.c
@@ -0,0 +1,70 @@
+/* m68k specific symbolic name handling.
+ 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 <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND m68k_
+#include "libebl_CPU.h"
+
+
+/* Return true if the symbol type is that referencing the GOT. */
+bool
+m68k_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_68K_GOT32:
+ case R_68K_GOT16:
+ case R_68K_GOT8:
+ return true;
+ }
+ return false;
+}
+
+/* Check for the simple reloc types. */
+Elf_Type
+m68k_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_68K_32:
+ return ELF_T_SWORD;
+ case R_68K_16:
+ return ELF_T_HALF;
+ case R_68K_8:
+ return ELF_T_BYTE;
+ default:
+ return ELF_T_NUM;
+ }
+}
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index 26a4f941..97a9b897 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,7 @@
+2016-05-20 Andreas Schwab <schwab@linux-m68k.org>
+
+ * eblopenbackend.c (machines) [EM_68K]: Set class and data.
+
2016-02-12 Mark Wielaard <mjw@redhat.com>
* eblobjnotetypename.c (ebl_object_note_type_name): Check name is
diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
index 372ef2a4..2b922543 100644
--- a/libebl/eblopenbackend.c
+++ b/libebl/eblopenbackend.c
@@ -73,7 +73,7 @@ static const struct
{ "s390", "ebl_s390", "s390", 4, EM_S390, 0, 0 },
{ "m32", "elf_m32", "m32", 3, EM_M32, 0, 0 },
- { "m68k", "elf_m68k", "m68k", 4, EM_68K, 0, 0 },
+ { "m68k", "elf_m68k", "m68k", 4, EM_68K, ELFCLASS32, ELFDATA2MSB },
{ "m88k", "elf_m88k", "m88k", 4, EM_88K, 0, 0 },
{ "i860", "elf_i860", "i860", 4, EM_860, 0, 0 },
{ "s370", "ebl_s370", "s370", 4, EM_S370, 0, 0 },