blob: d73855b601922aa49e75bf751107ed8beec34fce [file] [log] [blame]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001From: Kurt Roeckx <kurt@roeckx.be>
2From: Thorsten Glaser <tg@mirbsd.de>
3Subject: m68k support
4
5Written by Kurt Roeckx, except for the retval support which was written
6by Thorsten Glaser
7
8
9Index: elfutils-0.164/backends/m68k_init.c
10===================================================================
11--- /dev/null
12+++ elfutils-0.164/backends/m68k_init.c
13@@ -0,0 +1,49 @@
14+/* Initialization of m68k specific backend library.
15+ Copyright (C) 2007 Kurt Roeckx <kurt@roeckx.be>
16+
17+ This software is free software; you can redistribute it and/or modify
18+ it under the terms of the GNU General Public License as published by the
19+ Free Software Foundation; version 2 of the License.
20+
21+ This softare is distributed in the hope that it will be useful, but
22+ WITHOUT ANY WARRANTY; without even the implied warranty of
23+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24+ General Public License for more details.
25+
26+ You should have received a copy of the GNU General Public License along
27+ with this software; if not, write to the Free Software Foundation,
28+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
29+
30+*/
31+
32+#ifdef HAVE_CONFIG_H
33+# include <config.h>
34+#endif
35+
36+#define BACKEND m68k_
37+#define RELOC_PREFIX R_68K_
38+#include "libebl_CPU.h"
39+
40+/* This defines the common reloc hooks based on m68k_reloc.def. */
41+#include "common-reloc.c"
42+
43+
44+const char *
45+m68k_init (Elf *elf __attribute__ ((unused)),
46+ GElf_Half machine __attribute__ ((unused)),
47+ Ebl *eh,
48+ size_t ehlen)
49+{
50+ /* Check whether the Elf_BH object has a sufficent size. */
51+ if (ehlen < sizeof (Ebl))
52+ return NULL;
53+
54+ /* We handle it. */
55+ eh->name = "m68k";
56+ m68k_init_reloc (eh);
57+ HOOK (eh, reloc_simple_type);
58+ HOOK (eh, return_value_location);
59+ HOOK (eh, register_info);
60+
61+ return MODVERSION;
62+}
63Index: elfutils-0.164/backends/m68k_regs.c
64===================================================================
65--- /dev/null
66+++ elfutils-0.164/backends/m68k_regs.c
67@@ -0,0 +1,106 @@
68+/* Register names and numbers for m68k DWARF.
69+ Copyright (C) 2007 Kurt Roeckx <kurt@roeckx.be>
70+
71+ This software is free software; you can redistribute it and/or modify
72+ it under the terms of the GNU General Public License as published by the
73+ Free Software Foundation; version 2 of the License.
74+
75+ This software is distributed in the hope that it will be useful, but
76+ WITHOUT ANY WARRANTY; without even the implied warranty of
77+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
78+ General Public License for more details.
79+
80+ You should have received a copy of the GNU General Public License along
81+ with this software; if not, write to the Free Software Foundation,
82+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
83+
84+ */
85+
86+#ifdef HAVE_CONFIG_H
87+# include <config.h>
88+#endif
89+
90+#include <string.h>
91+#include <dwarf.h>
92+
93+#define BACKEND m68k_
94+#include "libebl_CPU.h"
95+
96+ssize_t
97+m68k_register_info (Ebl *ebl __attribute__ ((unused)),
98+ int regno, char *name, size_t namelen,
99+ const char **prefix, const char **setname,
100+ int *bits, int *type)
101+{
102+ if (name == NULL)
103+ return 25;
104+
105+ if (regno < 0 || regno > 24 || namelen < 5)
106+ return -1;
107+
108+ *prefix = "%";
109+ *bits = 32;
110+ *type = (regno < 8 ? DW_ATE_signed
111+ : regno < 16 ? DW_ATE_address : DW_ATE_float);
112+
113+ if (regno < 8)
114+ {
115+ *setname = "integer";
116+ }
117+ else if (regno < 16)
118+ {
119+ *setname = "address";
120+ }
121+ else if (regno < 24)
122+ {
123+ *setname = "FPU";
124+ }
125+ else
126+ {
127+ *setname = "address";
128+ *type = DW_ATE_address;
129+ }
130+
131+ switch (regno)
132+ {
133+ case 0 ... 7:
134+ name[0] = 'd';
135+ name[1] = regno + '0';
136+ namelen = 2;
137+ break;
138+
139+ case 8 ... 13:
140+ name[0] = 'a';
141+ name[1] = regno - 8 + '0';
142+ namelen = 2;
143+ break;
144+
145+ case 14:
146+ name[0] = 'f';
147+ name[1] = 'p';
148+ namelen = 2;
149+ break;
150+
151+ case 15:
152+ name[0] = 's';
153+ name[1] = 'p';
154+ namelen = 2;
155+ break;
156+
157+ case 16 ... 23:
158+ name[0] = 'f';
159+ name[1] = 'p';
160+ name[2] = regno - 16 + '0';
161+ namelen = 3;
162+ break;
163+
164+ case 24:
165+ name[0] = 'p';
166+ name[1] = 'c';
167+ namelen = 2;
168+ }
169+
170+ name[namelen++] = '\0';
171+ return namelen;
172+}
173+
174Index: elfutils-0.164/backends/m68k_reloc.def
175===================================================================
176--- /dev/null
177+++ elfutils-0.164/backends/m68k_reloc.def
178@@ -0,0 +1,45 @@
179+/* List the relocation types for m68k. -*- C -*-
180+ Copyright (C) 2007 Kurt Roeckx <kurt@roeckx.be>
181+
182+ This software is free software; you can redistribute it and/or modify
183+ it under the terms of the GNU General Public License as published by the
184+ Free Software Foundation; version 2 of the License.
185+
186+ This software is distributed in the hope that it will be useful, but
187+ WITHOUT ANY WARRANTY; without even the implied warranty of
188+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
189+ General Public License for more details.
190+
191+ You should have received a copy of the GNU General Public License along
192+ with this software; if not, write to the Free Software Foundation,
193+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
194+*/
195+
196+/* NAME, REL|EXEC|DYN */
197+
198+RELOC_TYPE (NONE, 0)
199+RELOC_TYPE (32, REL|EXEC|DYN)
200+RELOC_TYPE (16, REL)
201+RELOC_TYPE (8, REL)
202+RELOC_TYPE (PC32, REL|EXEC|DYN)
203+RELOC_TYPE (PC16, REL)
204+RELOC_TYPE (PC8, REL)
205+RELOC_TYPE (GOT32, REL)
206+RELOC_TYPE (GOT16, REL)
207+RELOC_TYPE (GOT8, REL)
208+RELOC_TYPE (GOT32O, REL)
209+RELOC_TYPE (GOT16O, REL)
210+RELOC_TYPE (GOT8O, REL)
211+RELOC_TYPE (PLT32, REL)
212+RELOC_TYPE (PLT16, REL)
213+RELOC_TYPE (PLT8, REL)
214+RELOC_TYPE (PLT32O, REL)
215+RELOC_TYPE (PLT16O, REL)
216+RELOC_TYPE (PLT8O, REL)
217+RELOC_TYPE (COPY, EXEC)
218+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
219+RELOC_TYPE (JMP_SLOT, EXEC|DYN)
220+RELOC_TYPE (RELATIVE, EXEC|DYN)
221+RELOC_TYPE (GNU_VTINHERIT, REL)
222+RELOC_TYPE (GNU_VTENTRY, REL)
223+
224Index: elfutils-0.164/libelf/elf.h
225===================================================================
226--- elfutils-0.164.orig/libelf/elf.h
227+++ elfutils-0.164/libelf/elf.h
228@@ -1158,6 +1158,9 @@ typedef struct
229 #define R_68K_GLOB_DAT 20 /* Create GOT entry */
230 #define R_68K_JMP_SLOT 21 /* Create PLT entry */
231 #define R_68K_RELATIVE 22 /* Adjust by program base */
232+/* The next 2 are GNU extensions to enable C++ vtable garbage collection. */
233+#define R_68K_GNU_VTINHERIT 23
234+#define R_68K_GNU_VTENTRY 24
235 #define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */
236 #define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */
237 #define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */
238Index: elfutils-0.164/backends/Makefile.am
239===================================================================
240--- elfutils-0.164.orig/backends/Makefile.am
241+++ elfutils-0.164/backends/Makefile.am
242@@ -33,12 +33,12 @@ AM_CPPFLAGS += -I$(top_srcdir)/libebl -I
243
244
245 modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \
246- tilegx parisc mips
247+ tilegx parisc mips m68k
248 libebl_pic = libebl_i386_pic.a libebl_sh_pic.a libebl_x86_64_pic.a \
249 libebl_ia64_pic.a libebl_alpha_pic.a libebl_arm_pic.a \
250 libebl_aarch64_pic.a libebl_sparc_pic.a libebl_ppc_pic.a \
251 libebl_ppc64_pic.a libebl_s390_pic.a libebl_tilegx_pic.a \
252- libebl_parisc_pic.a libebl_mips_pic.a
253+ libebl_parisc_pic.a libebl_mips_pic.a libebl_m68k_pic.a
254 noinst_LIBRARIES = $(libebl_pic)
255 noinst_DATA = $(libebl_pic:_pic.a=.so)
256
257@@ -120,6 +120,10 @@ mips_SRCS = mips_init.c mips_symbol.c mi
258 libebl_mips_pic_a_SOURCES = $(mips_SRCS)
259 am_libebl_mips_pic_a_OBJECTS = $(mips_SRCS:.c=.os)
260
261+m68k_SRCS = m68k_init.c m68k_symbol.c m68k_regs.c m68k_retval.c
262+libebl_m68k_pic_a_SOURCES = $(m68k_SRCS)
263+am_libebl_m68k_pic_a_OBJECTS = $(m68k_SRCS:.c=.os)
264+
265 libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw)
266 @rm -f $(@:.so=.map)
267 $(AM_V_at)echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' \
268Index: elfutils-0.164/backends/m68k_symbol.c
269===================================================================
270--- /dev/null
271+++ elfutils-0.164/backends/m68k_symbol.c
272@@ -0,0 +1,43 @@
273+/* m68k specific symbolic name handling.
274+ Copyright (C) 2007 Kurt Roeckx <kurt@roeckx.be>
275+
276+ This software is free software; you can redistribute it and/or modify
277+ it under the terms of the GNU General Public License as published by the
278+ Free Software Foundation; version 2 of the License.
279+
280+ This software distributed in the hope that it will be useful, but
281+ WITHOUT ANY WARRANTY; without even the implied warranty of
282+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
283+ General Public License for more details.
284+
285+ You should have received a copy of the GNU General Public License along
286+ with this software; if not, write to the Free Software Foundation,
287+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
288+*/
289+
290+#ifdef HAVE_CONFIG_H
291+# include <config.h>
292+#endif
293+
294+#include <elf.h>
295+#include <stddef.h>
296+
297+#define BACKEND m68k_
298+#include "libebl_CPU.h"
299+
300+/* Check for the simple reloc types. */
301+Elf_Type
302+m68k_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
303+{
304+ switch (type)
305+ {
306+ case R_68K_32:
307+ return ELF_T_SWORD;
308+ case R_68K_16:
309+ return ELF_T_HALF;
310+ case R_68K_8:
311+ return ELF_T_BYTE;
312+ default:
313+ return ELF_T_NUM;
314+ }
315+}
316Index: elfutils-0.164/backends/m68k_retval.c
317===================================================================
318--- /dev/null
319+++ elfutils-0.164/backends/m68k_retval.c
320@@ -0,0 +1,172 @@
321+/* Function return value location for Linux/m68k ABI.
322+ Copyright (C) 2005-2010 Red Hat, Inc.
323+ Copyright (c) 2011 Thorsten Glaser, Debian.
324+ This file is part of Red Hat elfutils.
325+
326+ Red Hat elfutils is free software; you can redistribute it and/or modify
327+ it under the terms of the GNU General Public License as published by the
328+ Free Software Foundation; version 2 of the License.
329+
330+ Red Hat elfutils is distributed in the hope that it will be useful, but
331+ WITHOUT ANY WARRANTY; without even the implied warranty of
332+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
333+ General Public License for more details.
334+
335+ You should have received a copy of the GNU General Public License along
336+ with Red Hat elfutils; if not, write to the Free Software Foundation,
337+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
338+
339+ Red Hat elfutils is an included package of the Open Invention Network.
340+ An included package of the Open Invention Network is a package for which
341+ Open Invention Network licensees cross-license their patents. No patent
342+ license is granted, either expressly or impliedly, by designation as an
343+ included package. Should you wish to participate in the Open Invention
344+ Network licensing program, please visit www.openinventionnetwork.com
345+ <http://www.openinventionnetwork.com>. */
346+
347+#ifdef HAVE_CONFIG_H
348+# include <config.h>
349+#endif
350+
351+#include <assert.h>
352+#include <dwarf.h>
353+
354+#define BACKEND m68k_
355+#include "libebl_CPU.h"
356+
357+
358+/* %d0, or pair %d0, %d1, or %a0 */
359+static const Dwarf_Op loc_intreg[] =
360+ {
361+ { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 },
362+ { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 4 },
363+ };
364+static const Dwarf_Op loc_ptrreg[] =
365+ {
366+ { .atom = DW_OP_reg8 },
367+ };
368+#define nloc_intreg 1
369+#define nloc_intregpair 4
370+#define nloc_ptrreg 1
371+
372+/* %f0 */
373+static const Dwarf_Op loc_fpreg[] =
374+ {
375+ { .atom = DW_OP_reg16 }
376+ };
377+#define nloc_fpreg 1
378+
379+/* Structures are a bit more complicated - small structures are returned
380+ in %d0 / %d1 (-freg-struct-return which is enabled by default), large
381+ structures use %a1 (in constrast to the SYSV psABI which says %a0) as
382+ reentrant storage space indicator. */
383+static const Dwarf_Op loc_aggregate[] =
384+ {
385+ { .atom = DW_OP_breg9, .number = 0 }
386+ };
387+#define nloc_aggregate 1
388+
389+int
390+m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
391+{
392+ Dwarf_Word size;
393+
394+ /* Start with the function's type, and get the DW_AT_type attribute,
395+ which is the type of the return value. */
396+
397+ Dwarf_Attribute attr_mem;
398+ Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
399+ &attr_mem);
400+ if (attr == NULL)
401+ /* The function has no return value, like a `void' function in C. */
402+ return 0;
403+
404+ Dwarf_Die die_mem;
405+ Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
406+ int tag = dwarf_tag (typedie);
407+
408+ /* Follow typedefs and qualifiers to get to the actual type. */
409+ while (tag == DW_TAG_typedef
410+ || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
411+ || tag == DW_TAG_restrict_type)
412+ {
413+ attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
414+ typedie = dwarf_formref_die (attr, &die_mem);
415+ tag = dwarf_tag (typedie);
416+ }
417+
418+ switch (tag)
419+ {
420+ case -1:
421+ return -1;
422+
423+ case DW_TAG_subrange_type:
424+ if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
425+ {
426+ attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
427+ typedie = dwarf_formref_die (attr, &die_mem);
428+ tag = dwarf_tag (typedie);
429+ }
430+ /* Fall through. */
431+
432+ case DW_TAG_base_type:
433+ case DW_TAG_enumeration_type:
434+ case DW_TAG_pointer_type:
435+ case DW_TAG_ptr_to_member_type:
436+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
437+ &attr_mem), &size) != 0)
438+ {
439+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
440+ size = 4;
441+ else
442+ return -1;
443+ }
444+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
445+ {
446+ *locp = loc_ptrreg;
447+ return nloc_ptrreg;
448+ }
449+ if (tag == DW_TAG_base_type)
450+ {
451+ Dwarf_Word encoding;
452+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
453+ &attr_mem),
454+ &encoding) != 0)
455+ return -1;
456+ if (encoding == DW_ATE_float)
457+ {
458+ /* XXX really 10? */
459+ if (size > 10)
460+ return -2;
461+ *locp = loc_fpreg;
462+ return nloc_fpreg;
463+ }
464+ }
465+ if (size <= 8)
466+ {
467+ intreg:
468+ /* XXX check endianness of dword pair, int64 vs aggregate */
469+ *locp = loc_intreg;
470+ return size <= 4 ? nloc_intreg : nloc_intregpair;
471+ }
472+
473+ aggregate:
474+ *locp = loc_aggregate;
475+ return nloc_aggregate;
476+
477+ case DW_TAG_structure_type:
478+ case DW_TAG_class_type:
479+ case DW_TAG_union_type:
480+ case DW_TAG_array_type:
481+ if (dwarf_aggregate_size (typedie, &size) == 0
482+ && size > 0 && size <= 8)
483+ /* not accurate for a struct whose only member is a float */
484+ goto intreg;
485+ goto aggregate;
486+ }
487+
488+ /* XXX We don't have a good way to return specific errors from ebl calls.
489+ This value means we do not understand the type, but it is well-formed
490+ DWARF and might be valid. */
491+ return -2;
492+}