blob: 2e0e54b0c7f5427616a324c67d00a8cd50fc8b5b [file] [log] [blame]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001From 46d0d0ca718093486eeeedf1b44134e9e29b56f7 Mon Sep 17 00:00:00 2001
2From: Hongxu Jia <hongxu.jia@windriver.com>
3Date: Wed, 16 Aug 2017 09:18:59 +0800
4Subject: [PATCH] mips backends
5
6Upstream-Status: Backport [from debian]
7
8Rebase to 0.170
9Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
10---
11 backends/Makefile.am | 8 +-
12 backends/mips_init.c | 59 +++++++++
13 backends/mips_regs.c | 104 ++++++++++++++++
14 backends/mips_reloc.def | 79 ++++++++++++
15 backends/mips_retval.c | 321 ++++++++++++++++++++++++++++++++++++++++++++++++
16 backends/mips_symbol.c | 52 ++++++++
17 libebl/eblopenbackend.c | 2 +
18 7 files changed, 623 insertions(+), 2 deletions(-)
19 create mode 100644 backends/mips_init.c
20 create mode 100644 backends/mips_regs.c
21 create mode 100644 backends/mips_reloc.def
22 create mode 100644 backends/mips_retval.c
23 create mode 100644 backends/mips_symbol.c
24
25diff --git a/backends/Makefile.am b/backends/Makefile.am
26index 7f1f5d4..91baf6e 100644
27--- a/backends/Makefile.am
28+++ b/backends/Makefile.am
29@@ -33,12 +33,12 @@ AM_CPPFLAGS += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \
30
31
32 modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \
33- tilegx m68k bpf parisc
34+ tilegx m68k bpf parisc mips
35 libebl_pic = libebl_i386_pic.a libebl_sh_pic.a libebl_x86_64_pic.a \
36 libebl_ia64_pic.a libebl_alpha_pic.a libebl_arm_pic.a \
37 libebl_aarch64_pic.a libebl_sparc_pic.a libebl_ppc_pic.a \
38 libebl_ppc64_pic.a libebl_s390_pic.a libebl_tilegx_pic.a \
39- libebl_m68k_pic.a libebl_bpf_pic.a libebl_parisc_pic.a
40+ libebl_m68k_pic.a libebl_bpf_pic.a libebl_parisc_pic.a libebl_mips_pic.a
41 noinst_LIBRARIES = $(libebl_pic)
42 noinst_DATA = $(libebl_pic:_pic.a=.so)
43
44@@ -128,6 +128,10 @@ parisc_SRCS = parisc_init.c parisc_symbol.c parisc_regs.c parisc_retval.c
45 libebl_parisc_pic_a_SOURCES = $(parisc_SRCS)
46 am_libebl_parisc_pic_a_OBJECTS = $(parisc_SRCS:.c=.os)
47
48+mips_SRCS = mips_init.c mips_symbol.c mips_regs.c mips_retval.c
49+libebl_mips_pic_a_SOURCES = $(mips_SRCS)
50+am_libebl_mips_pic_a_OBJECTS = $(mips_SRCS:.c=.os)
51+
52 libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw) $(libeu)
53 @rm -f $(@:.so=.map)
54 $(AM_V_at)echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' \
55diff --git a/backends/mips_init.c b/backends/mips_init.c
56new file mode 100644
57index 0000000..975c04e
58--- /dev/null
59+++ b/backends/mips_init.c
60@@ -0,0 +1,59 @@
61+/* Initialization of mips specific backend library.
62+ Copyright (C) 2006 Red Hat, Inc.
63+ This file is part of Red Hat elfutils.
64+
65+ Red Hat elfutils is free software; you can redistribute it and/or modify
66+ it under the terms of the GNU General Public License as published by the
67+ Free Software Foundation; version 2 of the License.
68+
69+ Red Hat elfutils is distributed in the hope that it will be useful, but
70+ WITHOUT ANY WARRANTY; without even the implied warranty of
71+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
72+ General Public License for more details.
73+
74+ You should have received a copy of the GNU General Public License along
75+ with Red Hat elfutils; if not, write to the Free Software Foundation,
76+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
77+
78+ Red Hat elfutils is an included package of the Open Invention Network.
79+ An included package of the Open Invention Network is a package for which
80+ Open Invention Network licensees cross-license their patents. No patent
81+ license is granted, either expressly or impliedly, by designation as an
82+ included package. Should you wish to participate in the Open Invention
83+ Network licensing program, please visit www.openinventionnetwork.com
84+ <http://www.openinventionnetwork.com>. */
85+
86+#ifdef HAVE_CONFIG_H
87+# include <config.h>
88+#endif
89+
90+#define BACKEND mips_
91+#define RELOC_PREFIX R_MIPS_
92+#include "libebl_CPU.h"
93+
94+/* This defines the common reloc hooks based on mips_reloc.def. */
95+#include "common-reloc.c"
96+
97+const char *
98+mips_init (Elf *elf __attribute__ ((unused)),
99+ GElf_Half machine __attribute__ ((unused)),
100+ Ebl *eh,
101+ size_t ehlen)
102+{
103+ /* Check whether the Elf_BH object has a sufficent size. */
104+ if (ehlen < sizeof (Ebl))
105+ return NULL;
106+
107+ /* We handle it. */
108+ if (machine == EM_MIPS)
109+ eh->name = "MIPS R3000 big-endian";
110+ else if (machine == EM_MIPS_RS3_LE)
111+ eh->name = "MIPS R3000 little-endian";
112+
113+ mips_init_reloc (eh);
114+ HOOK (eh, reloc_simple_type);
115+ HOOK (eh, return_value_location);
116+ HOOK (eh, register_info);
117+
118+ return MODVERSION;
119+}
120diff --git a/backends/mips_regs.c b/backends/mips_regs.c
121new file mode 100644
122index 0000000..44f86cb
123--- /dev/null
124+++ b/backends/mips_regs.c
125@@ -0,0 +1,104 @@
126+/* Register names and numbers for MIPS DWARF.
127+ Copyright (C) 2006 Red Hat, Inc.
128+ This file is part of Red Hat elfutils.
129+
130+ Red Hat elfutils is free software; you can redistribute it and/or modify
131+ it under the terms of the GNU General Public License as published by the
132+ Free Software Foundation; version 2 of the License.
133+
134+ Red Hat elfutils is distributed in the hope that it will be useful, but
135+ WITHOUT ANY WARRANTY; without even the implied warranty of
136+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
137+ General Public License for more details.
138+
139+ You should have received a copy of the GNU General Public License along
140+ with Red Hat elfutils; if not, write to the Free Software Foundation,
141+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
142+
143+ Red Hat elfutils is an included package of the Open Invention Network.
144+ An included package of the Open Invention Network is a package for which
145+ Open Invention Network licensees cross-license their patents. No patent
146+ license is granted, either expressly or impliedly, by designation as an
147+ included package. Should you wish to participate in the Open Invention
148+ Network licensing program, please visit www.openinventionnetwork.com
149+ <http://www.openinventionnetwork.com>. */
150+
151+#ifdef HAVE_CONFIG_H
152+# include <config.h>
153+#endif
154+
155+#include <string.h>
156+#include <dwarf.h>
157+
158+#define BACKEND mips_
159+#include "libebl_CPU.h"
160+
161+ssize_t
162+mips_register_info (Ebl *ebl __attribute__((unused)),
163+ int regno, char *name, size_t namelen,
164+ const char **prefix, const char **setname,
165+ int *bits, int *type)
166+{
167+ if (name == NULL)
168+ return 66;
169+
170+ if (regno < 0 || regno > 65 || namelen < 4)
171+ return -1;
172+
173+ *prefix = "$";
174+
175+ if (regno < 32)
176+ {
177+ *setname = "integer";
178+ *type = DW_ATE_signed;
179+ *bits = 32;
180+ if (regno < 32 + 10)
181+ {
182+ name[0] = regno + '0';
183+ namelen = 1;
184+ }
185+ else
186+ {
187+ name[0] = (regno / 10) + '0';
188+ name[1] = (regno % 10) + '0';
189+ namelen = 2;
190+ }
191+ }
192+ else if (regno < 64)
193+ {
194+ *setname = "FPU";
195+ *type = DW_ATE_float;
196+ *bits = 32;
197+ name[0] = 'f';
198+ if (regno < 32 + 10)
199+ {
200+ name[1] = (regno - 32) + '0';
201+ namelen = 2;
202+ }
203+ else
204+ {
205+ name[1] = (regno - 32) / 10 + '0';
206+ name[2] = (regno - 32) % 10 + '0';
207+ namelen = 3;
208+ }
209+ }
210+ else if (regno == 64)
211+ {
212+ *type = DW_ATE_signed;
213+ *bits = 32;
214+ name[0] = 'h';
215+ name[1] = 'i';
216+ namelen = 2;
217+ }
218+ else
219+ {
220+ *type = DW_ATE_signed;
221+ *bits = 32;
222+ name[0] = 'l';
223+ name[1] = 'o';
224+ namelen = 2;
225+ }
226+
227+ name[namelen++] = '\0';
228+ return namelen;
229+}
230diff --git a/backends/mips_reloc.def b/backends/mips_reloc.def
231new file mode 100644
232index 0000000..4579970
233--- /dev/null
234+++ b/backends/mips_reloc.def
235@@ -0,0 +1,79 @@
236+/* List the relocation types for mips. -*- C -*-
237+ Copyright (C) 2006 Red Hat, Inc.
238+ This file is part of Red Hat elfutils.
239+
240+ Red Hat elfutils is free software; you can redistribute it and/or modify
241+ it under the terms of the GNU General Public License as published by the
242+ Free Software Foundation; version 2 of the License.
243+
244+ Red Hat elfutils is distributed in the hope that it will be useful, but
245+ WITHOUT ANY WARRANTY; without even the implied warranty of
246+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
247+ General Public License for more details.
248+
249+ You should have received a copy of the GNU General Public License along
250+ with Red Hat elfutils; if not, write to the Free Software Foundation,
251+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
252+
253+ Red Hat elfutils is an included package of the Open Invention Network.
254+ An included package of the Open Invention Network is a package for which
255+ Open Invention Network licensees cross-license their patents. No patent
256+ license is granted, either expressly or impliedly, by designation as an
257+ included package. Should you wish to participate in the Open Invention
258+ Network licensing program, please visit www.openinventionnetwork.com
259+ <http://www.openinventionnetwork.com>. */
260+
261+/* NAME, REL|EXEC|DYN */
262+
263+RELOC_TYPE (NONE, 0)
264+RELOC_TYPE (16, 0)
265+RELOC_TYPE (32, 0)
266+RELOC_TYPE (REL32, 0)
267+RELOC_TYPE (26, 0)
268+RELOC_TYPE (HI16, 0)
269+RELOC_TYPE (LO16, 0)
270+RELOC_TYPE (GPREL16, 0)
271+RELOC_TYPE (LITERAL, 0)
272+RELOC_TYPE (GOT16, 0)
273+RELOC_TYPE (PC16, 0)
274+RELOC_TYPE (CALL16, 0)
275+RELOC_TYPE (GPREL32, 0)
276+
277+RELOC_TYPE (SHIFT5, 0)
278+RELOC_TYPE (SHIFT6, 0)
279+RELOC_TYPE (64, 0)
280+RELOC_TYPE (GOT_DISP, 0)
281+RELOC_TYPE (GOT_PAGE, 0)
282+RELOC_TYPE (GOT_OFST, 0)
283+RELOC_TYPE (GOT_HI16, 0)
284+RELOC_TYPE (GOT_LO16, 0)
285+RELOC_TYPE (SUB, 0)
286+RELOC_TYPE (INSERT_A, 0)
287+RELOC_TYPE (INSERT_B, 0)
288+RELOC_TYPE (DELETE, 0)
289+RELOC_TYPE (HIGHER, 0)
290+RELOC_TYPE (HIGHEST, 0)
291+RELOC_TYPE (CALL_HI16, 0)
292+RELOC_TYPE (CALL_LO16, 0)
293+RELOC_TYPE (SCN_DISP, 0)
294+RELOC_TYPE (REL16, 0)
295+RELOC_TYPE (ADD_IMMEDIATE, 0)
296+RELOC_TYPE (PJUMP, 0)
297+RELOC_TYPE (RELGOT, 0)
298+RELOC_TYPE (JALR, 0)
299+RELOC_TYPE (TLS_DTPMOD32, 0)
300+RELOC_TYPE (TLS_DTPREL32, 0)
301+RELOC_TYPE (TLS_DTPMOD64, 0)
302+RELOC_TYPE (TLS_DTPREL64, 0)
303+RELOC_TYPE (TLS_GD, 0)
304+RELOC_TYPE (TLS_LDM, 0)
305+RELOC_TYPE (TLS_DTPREL_HI16, 0)
306+RELOC_TYPE (TLS_DTPREL_LO16, 0)
307+RELOC_TYPE (TLS_GOTTPREL, 0)
308+RELOC_TYPE (TLS_TPREL32, 0)
309+RELOC_TYPE (TLS_TPREL64, 0)
310+RELOC_TYPE (TLS_TPREL_HI16, 0)
311+RELOC_TYPE (TLS_TPREL_LO16, 0)
312+
313+#define NO_COPY_RELOC 1
314+#define NO_RELATIVE_RELOC 1
315diff --git a/backends/mips_retval.c b/backends/mips_retval.c
316new file mode 100644
317index 0000000..656cd1f
318--- /dev/null
319+++ b/backends/mips_retval.c
320@@ -0,0 +1,321 @@
321+/* Function return value location for Linux/mips ABI.
322+ Copyright (C) 2005 Red Hat, Inc.
323+ This file is part of Red Hat elfutils.
324+
325+ Red Hat elfutils is free software; you can redistribute it and/or modify
326+ it under the terms of the GNU General Public License as published by the
327+ Free Software Foundation; version 2 of the License.
328+
329+ Red Hat elfutils is distributed in the hope that it will be useful, but
330+ WITHOUT ANY WARRANTY; without even the implied warranty of
331+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
332+ General Public License for more details.
333+
334+ You should have received a copy of the GNU General Public License along
335+ with Red Hat elfutils; if not, write to the Free Software Foundation,
336+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
337+
338+ Red Hat elfutils is an included package of the Open Invention Network.
339+ An included package of the Open Invention Network is a package for which
340+ Open Invention Network licensees cross-license their patents. No patent
341+ license is granted, either expressly or impliedly, by designation as an
342+ included package. Should you wish to participate in the Open Invention
343+ Network licensing program, please visit www.openinventionnetwork.com
344+ <http://www.openinventionnetwork.com>. */
345+
346+#ifdef HAVE_CONFIG_H
347+# include <config.h>
348+#endif
349+
350+#include <string.h>
351+#include <assert.h>
352+#include <dwarf.h>
353+#include <elf.h>
354+
355+#include "../libebl/libeblP.h"
356+#include "../libdw/libdwP.h"
357+
358+#define BACKEND mips_
359+#include "libebl_CPU.h"
360+
361+/* The ABI of the file. Also see EF_MIPS_ABI2 above. */
362+#define EF_MIPS_ABI 0x0000F000
363+
364+/* The original o32 abi. */
365+#define E_MIPS_ABI_O32 0x00001000
366+
367+/* O32 extended to work on 64 bit architectures */
368+#define E_MIPS_ABI_O64 0x00002000
369+
370+/* EABI in 32 bit mode */
371+#define E_MIPS_ABI_EABI32 0x00003000
372+
373+/* EABI in 64 bit mode */
374+#define E_MIPS_ABI_EABI64 0x00004000
375+
376+/* All the possible MIPS ABIs. */
377+enum mips_abi
378+ {
379+ MIPS_ABI_UNKNOWN = 0,
380+ MIPS_ABI_N32,
381+ MIPS_ABI_O32,
382+ MIPS_ABI_N64,
383+ MIPS_ABI_O64,
384+ MIPS_ABI_EABI32,
385+ MIPS_ABI_EABI64,
386+ MIPS_ABI_LAST
387+ };
388+
389+/* Find the mips ABI of the current file */
390+enum mips_abi find_mips_abi(Elf *elf)
391+{
392+ GElf_Ehdr ehdr_mem;
393+ GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
394+
395+ if (ehdr == NULL)
396+ return MIPS_ABI_LAST;
397+
398+ GElf_Word elf_flags = ehdr->e_flags;
399+
400+ /* Check elf_flags to see if it specifies the ABI being used. */
401+ switch ((elf_flags & EF_MIPS_ABI))
402+ {
403+ case E_MIPS_ABI_O32:
404+ return MIPS_ABI_O32;
405+ case E_MIPS_ABI_O64:
406+ return MIPS_ABI_O64;
407+ case E_MIPS_ABI_EABI32:
408+ return MIPS_ABI_EABI32;
409+ case E_MIPS_ABI_EABI64:
410+ return MIPS_ABI_EABI64;
411+ default:
412+ if ((elf_flags & EF_MIPS_ABI2))
413+ return MIPS_ABI_N32;
414+ }
415+
416+ /* GCC creates a pseudo-section whose name describes the ABI. */
417+ size_t shstrndx;
418+ if (elf_getshdrstrndx (elf, &shstrndx) < 0)
419+ return MIPS_ABI_LAST;
420+
421+ const char *name;
422+ Elf_Scn *scn = NULL;
423+ while ((scn = elf_nextscn (elf, scn)) != NULL)
424+ {
425+ GElf_Shdr shdr_mem;
426+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
427+ if (shdr == NULL)
428+ return MIPS_ABI_LAST;
429+
430+ name = elf_strptr (elf, shstrndx, shdr->sh_name) ?: "";
431+ if (strncmp (name, ".mdebug.", 8) != 0)
432+ continue;
433+
434+ if (strcmp (name, ".mdebug.abi32") == 0)
435+ return MIPS_ABI_O32;
436+ else if (strcmp (name, ".mdebug.abiN32") == 0)
437+ return MIPS_ABI_N32;
438+ else if (strcmp (name, ".mdebug.abi64") == 0)
439+ return MIPS_ABI_N64;
440+ else if (strcmp (name, ".mdebug.abiO64") == 0)
441+ return MIPS_ABI_O64;
442+ else if (strcmp (name, ".mdebug.eabi32") == 0)
443+ return MIPS_ABI_EABI32;
444+ else if (strcmp (name, ".mdebug.eabi64") == 0)
445+ return MIPS_ABI_EABI64;
446+ else
447+ return MIPS_ABI_UNKNOWN;
448+ }
449+
450+ return MIPS_ABI_UNKNOWN;
451+}
452+
453+unsigned int
454+mips_abi_regsize (enum mips_abi abi)
455+{
456+ switch (abi)
457+ {
458+ case MIPS_ABI_EABI32:
459+ case MIPS_ABI_O32:
460+ return 4;
461+ case MIPS_ABI_N32:
462+ case MIPS_ABI_N64:
463+ case MIPS_ABI_O64:
464+ case MIPS_ABI_EABI64:
465+ return 8;
466+ case MIPS_ABI_UNKNOWN:
467+ case MIPS_ABI_LAST:
468+ default:
469+ return 0;
470+ }
471+}
472+
473+
474+/* $v0 or pair $v0, $v1 */
475+static const Dwarf_Op loc_intreg_o32[] =
476+ {
477+ { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 4 },
478+ { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 },
479+ };
480+
481+static const Dwarf_Op loc_intreg[] =
482+ {
483+ { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 8 },
484+ { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 8 },
485+ };
486+#define nloc_intreg 1
487+#define nloc_intregpair 4
488+
489+/* $f0 (float), or pair $f0, $f1 (double).
490+ * f2/f3 are used for COMPLEX (= 2 doubles) returns in Fortran */
491+static const Dwarf_Op loc_fpreg_o32[] =
492+ {
493+ { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 4 },
494+ { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 4 },
495+ { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 4 },
496+ { .atom = DW_OP_regx, .number = 35 }, { .atom = DW_OP_piece, .number = 4 },
497+ };
498+
499+/* $f0, or pair $f0, $f2. */
500+static const Dwarf_Op loc_fpreg[] =
501+ {
502+ { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 8 },
503+ { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 8 },
504+ };
505+#define nloc_fpreg 1
506+#define nloc_fpregpair 4
507+#define nloc_fpregquad 8
508+
509+/* The return value is a structure and is actually stored in stack space
510+ passed in a hidden argument by the caller. But, the compiler
511+ helpfully returns the address of that space in $v0. */
512+static const Dwarf_Op loc_aggregate[] =
513+ {
514+ { .atom = DW_OP_breg2, .number = 0 }
515+ };
516+#define nloc_aggregate 1
517+
518+int
519+mips_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
520+{
521+ /* First find the ABI used by the elf object */
522+ enum mips_abi abi = find_mips_abi(functypedie->cu->dbg->elf);
523+
524+ /* Something went seriously wrong while trying to figure out the ABI */
525+ if (abi == MIPS_ABI_LAST)
526+ return -1;
527+
528+ /* We couldn't identify the ABI, but the file seems valid */
529+ if (abi == MIPS_ABI_UNKNOWN)
530+ return -2;
531+
532+ /* Can't handle EABI variants */
533+ if ((abi == MIPS_ABI_EABI32) || (abi == MIPS_ABI_EABI64))
534+ return -2;
535+
536+ unsigned int regsize = mips_abi_regsize (abi);
537+ if (!regsize)
538+ return -2;
539+
540+ /* Start with the function's type, and get the DW_AT_type attribute,
541+ which is the type of the return value. */
542+
543+ Dwarf_Attribute attr_mem;
544+ Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type, &attr_mem);
545+ if (attr == NULL)
546+ /* The function has no return value, like a `void' function in C. */
547+ return 0;
548+
549+ Dwarf_Die die_mem;
550+ Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
551+ int tag = dwarf_tag (typedie);
552+
553+ /* Follow typedefs and qualifiers to get to the actual type. */
554+ while (tag == DW_TAG_typedef
555+ || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
556+ || tag == DW_TAG_restrict_type)
557+ {
558+ attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
559+ typedie = dwarf_formref_die (attr, &die_mem);
560+ tag = dwarf_tag (typedie);
561+ }
562+
563+ switch (tag)
564+ {
565+ case -1:
566+ return -1;
567+
568+ case DW_TAG_subrange_type:
569+ if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
570+ {
571+ attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
572+ typedie = dwarf_formref_die (attr, &die_mem);
573+ tag = dwarf_tag (typedie);
574+ }
575+ /* Fall through. */
576+
577+ case DW_TAG_base_type:
578+ case DW_TAG_enumeration_type:
579+ case DW_TAG_pointer_type:
580+ case DW_TAG_ptr_to_member_type:
581+ {
582+ Dwarf_Word size;
583+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
584+ &attr_mem), &size) != 0)
585+ {
586+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
587+ size = regsize;
588+ else
589+ return -1;
590+ }
591+ if (tag == DW_TAG_base_type)
592+ {
593+ Dwarf_Word encoding;
594+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
595+ &attr_mem), &encoding) != 0)
596+ return -1;
597+
598+#define ABI_LOC(loc, regsize) ((regsize) == 4 ? (loc ## _o32) : (loc))
599+
600+ if (encoding == DW_ATE_float)
601+ {
602+ *locp = ABI_LOC(loc_fpreg, regsize);
603+ if (size <= regsize)
604+ return nloc_fpreg;
605+
606+ if (size <= 2*regsize)
607+ return nloc_fpregpair;
608+
609+ if (size <= 4*regsize && abi == MIPS_ABI_O32)
610+ return nloc_fpregquad;
611+
612+ goto aggregate;
613+ }
614+ }
615+ *locp = ABI_LOC(loc_intreg, regsize);
616+ if (size <= regsize)
617+ return nloc_intreg;
618+ if (size <= 2*regsize)
619+ return nloc_intregpair;
620+
621+ /* Else fall through. Shouldn't happen though (at least with gcc) */
622+ }
623+
624+ case DW_TAG_structure_type:
625+ case DW_TAG_class_type:
626+ case DW_TAG_union_type:
627+ case DW_TAG_array_type:
628+ aggregate:
629+ /* XXX TODO: Can't handle structure return with other ABI's yet :-/ */
630+ if ((abi != MIPS_ABI_O32) && (abi != MIPS_ABI_O64))
631+ return -2;
632+
633+ *locp = loc_aggregate;
634+ return nloc_aggregate;
635+ }
636+
637+ /* XXX We don't have a good way to return specific errors from ebl calls.
638+ This value means we do not understand the type, but it is well-formed
639+ DWARF and might be valid. */
640+ return -2;
641+}
642diff --git a/backends/mips_symbol.c b/backends/mips_symbol.c
643new file mode 100644
644index 0000000..ba465fe
645--- /dev/null
646+++ b/backends/mips_symbol.c
647@@ -0,0 +1,52 @@
648+/* MIPS specific symbolic name handling.
649+ Copyright (C) 2002, 2003, 2005 Red Hat, Inc.
650+ This file is part of Red Hat elfutils.
651+ Written by Jakub Jelinek <jakub@redhat.com>, 2002.
652+
653+ Red Hat elfutils is free software; you can redistribute it and/or modify
654+ it under the terms of the GNU General Public License as published by the
655+ Free Software Foundation; version 2 of the License.
656+
657+ Red Hat elfutils is distributed in the hope that it will be useful, but
658+ WITHOUT ANY WARRANTY; without even the implied warranty of
659+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
660+ General Public License for more details.
661+
662+ You should have received a copy of the GNU General Public License along
663+ with Red Hat elfutils; if not, write to the Free Software Foundation,
664+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
665+
666+ Red Hat elfutils is an included package of the Open Invention Network.
667+ An included package of the Open Invention Network is a package for which
668+ Open Invention Network licensees cross-license their patents. No patent
669+ license is granted, either expressly or impliedly, by designation as an
670+ included package. Should you wish to participate in the Open Invention
671+ Network licensing program, please visit www.openinventionnetwork.com
672+ <http://www.openinventionnetwork.com>. */
673+
674+#ifdef HAVE_CONFIG_H
675+# include <config.h>
676+#endif
677+
678+#include <elf.h>
679+#include <stddef.h>
680+
681+#define BACKEND mips_
682+#include "libebl_CPU.h"
683+
684+/* Check for the simple reloc types. */
685+Elf_Type
686+mips_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
687+{
688+ switch (type)
689+ {
690+ case R_MIPS_16:
691+ return ELF_T_HALF;
692+ case R_MIPS_32:
693+ return ELF_T_WORD;
694+ case R_MIPS_64:
695+ return ELF_T_XWORD;
696+ default:
697+ return ELF_T_NUM;
698+ }
699+}
700diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
701index 1f81477..5371396 100644
702--- a/libebl/eblopenbackend.c
703+++ b/libebl/eblopenbackend.c
704@@ -72,6 +72,8 @@ static const struct
705 { "sparc", "elf_sparc", "sparc", 5, EM_SPARC, 0, 0 },
706 { "sparc", "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS, 0, 0 },
707 { "s390", "ebl_s390", "s390", 4, EM_S390, 0, 0 },
708+ { "mips", "elf_mips", "mips", 4, EM_MIPS, 0, 0 },
709+ { "mips", "elf_mipsel", "mipsel", 4, EM_MIPS_RS3_LE, 0, 0 },
710
711 { "m32", "elf_m32", "m32", 3, EM_M32, 0, 0 },
712 { "m68k", "elf_m68k", "m68k", 4, EM_68K, ELFCLASS32, ELFDATA2MSB },
713--
7141.8.3.1
715