Add support for m68k

Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
This commit is contained in:
Andreas Schwab
2016-05-20 19:37:29 +02:00
committed by Mark Wielaard
parent 239cd48bc8
commit 37bb3fcd90
11 changed files with 550 additions and 4 deletions
+14
View File
@@ -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
+8 -2
View File
@@ -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)
+3 -1
View File
@@ -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
+71
View File
@@ -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"
+60
View File
@@ -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;
}
+96
View File
@@ -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;
}
+70
View File
@@ -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)
+153
View File
@@ -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;
}
+70
View File
@@ -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;
}
}
+4
View File
@@ -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
+1 -1
View File
@@ -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 },