diff options
author | Chih-hung Hsieh <chh@google.com> | 2016-01-05 17:44:12 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2016-01-05 17:44:12 +0000 |
commit | 97c644e689be3b7b3b7898513a38ead399d2285a (patch) | |
tree | bcd20af43068df2ab3c279089461ef1c69ca6ff6 /backends | |
parent | 611603536be3a6caaafb4289e2713cd117c70048 (diff) | |
parent | 645a828a7aef8113f07efae9b48e742bb65b712e (diff) | |
download | android_external_elfutils-97c644e689be3b7b3b7898513a38ead399d2285a.tar.gz android_external_elfutils-97c644e689be3b7b3b7898513a38ead399d2285a.tar.bz2 android_external_elfutils-97c644e689be3b7b3b7898513a38ead399d2285a.zip |
Merge "Merge upstream SHA '9d1e236'"
Diffstat (limited to 'backends')
-rw-r--r-- | backends/ChangeLog | 16 | ||||
-rw-r--r-- | backends/Makefile.am | 3 | ||||
-rw-r--r-- | backends/sparc_cfi.c | 83 | ||||
-rw-r--r-- | backends/sparc_corenote.c | 10 | ||||
-rw-r--r-- | backends/sparc_init.c | 8 | ||||
-rw-r--r-- | backends/sparc_initreg.c | 129 |
6 files changed, 247 insertions, 2 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog index 7f0d1c00..4b604fd2 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,19 @@ +2015-12-08 Jose E. Marchesi <jose.marchesi@oracle.com> + + * sparc_init.c (sparc_init): Hook sparc_set_initial_registers_tid. + * sparc_initreg.c: New file. + * Makefile.am (sparc_SRCS): Added sparc_initreg.c. + +2015-12-08 Jose E. Marchesi <jose.marchesi@oracle.com> + + * sparc_corenote.c: Header comment typo fixed. + (PRSTATUS_REGSET_ITEMS): Defined, so the PC can be fetched from + core files. + * Makefile.am (sparc_SRCS): Added sparc_cfi.c + * sparc_cfi.c: New file. + * sparc_init.c (sparc_init): Set eh->frame_nregs, eh->ra_offset + and hook sparc_abi_cfi. + 2015-10-21 Chih-Hung Hsieh <chh@google.com> * ia64_retval.c (hfa_type): Move nested function 'hfa' to file scope. diff --git a/backends/Makefile.am b/backends/Makefile.am index f7002fb5..b16f9486 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -84,7 +84,8 @@ libebl_aarch64_pic_a_SOURCES = $(aarch64_SRCS) am_libebl_aarch64_pic_a_OBJECTS = $(aarch64_SRCS:.c=.os) sparc_SRCS = sparc_init.c sparc_symbol.c sparc_regs.c sparc_retval.c \ - sparc_corenote.c sparc64_corenote.c sparc_auxv.c sparc_attrs.c + sparc_corenote.c sparc64_corenote.c sparc_auxv.c sparc_attrs.c \ + sparc_cfi.c sparc_initreg.c libebl_sparc_pic_a_SOURCES = $(sparc_SRCS) am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os) diff --git a/backends/sparc_cfi.c b/backends/sparc_cfi.c new file mode 100644 index 00000000..dcc17bd6 --- /dev/null +++ b/backends/sparc_cfi.c @@ -0,0 +1,83 @@ +/* SPARC defaults for DWARF CFI. + Copyright (C) 2015 Oracle Inc. + 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 <dwarf.h> + +#define BACKEND sparc_ +#include "libebl_CPU.h" + +int +sparc_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { +#define SV(n) DW_CFA_same_value, ULEB128_7 (n) + /* %g0 .. %g7 */ + SV (0), SV (1), SV (2), SV (3), SV (4), SV (5), SV (6), SV (7), + /* %o0 .. %o7 */ + SV (8), SV (9), SV (10), SV (11), SV (12), SV (13), SV (14), SV (15), + /* %l0 .. %l7 */ + SV (16), SV (17), SV (18), SV (19), SV (20), SV (21), SV (22), SV (23), + /* %i0 .. %i7 */ + SV (24), SV (25), SV (26), SV (27), SV (28), SV (29), SV (30), SV (31), + /* %f0 .. %f32 */ + SV (32), SV (33), SV (34), SV (35), SV (36), SV (37), SV (38), SV (39), + SV (40), SV (41), SV (42), SV (43), SV (44), SV (45), SV (46), SV (47), + SV (48), SV (49), SV (50), SV (51), SV (52), SV (53), SV (54), SV (55), + SV (56), SV (57), SV (58), SV (59), SV (60), SV (61), SV (52), SV (63), + /* %f33 .. %63 + Note that there are DWARF columns for the odd registers, even + if they don't exist in hardware) */ + SV (64), SV (65), SV (66), SV (67), SV (68), SV (69), SV (70), SV (71), + SV (72), SV (73), SV (74), SV (75), SV (76), SV (77), SV (78), SV (79), + SV (80), SV (81), SV (82), SV (83), SV (84), SV (85), SV (86), SV (87), + SV (88), SV (89), SV (90), SV (91), SV (92), SV (93), SV (94), SV (95), + /* %fcc[0123] */ + SV (96), SV (97), SV (98), SV (99), + /* %icc/%xcc */ + SV (100), + /* Soft frame-pointer */ + SV (101), + /* %gsr */ + SV (102) +#undef SV + }; + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = 4; + + abi_info->return_address_register = 31; /* %i7 */ + + return 0; +} + diff --git a/backends/sparc_corenote.c b/backends/sparc_corenote.c index 7912539b..c9b6ff3d 100644 --- a/backends/sparc_corenote.c +++ b/backends/sparc_corenote.c @@ -1,5 +1,6 @@ -/* PowerPC specific core note handling. +/* SPARC specific core note handling. Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2015 Oracle, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -109,4 +110,11 @@ static const Ebl_Register_Location fpregset_regs[] = #define ALIGN_PID_T 4 #define TYPE_PID_T ELF_T_SWORD +#define PRSTATUS_REGSET_ITEMS \ + { \ + .name = "pc", .type = ELF_T_ADDR, .format = 'x', \ + .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[33]), \ + .group = "register", .pc_register = true \ + } + #include "linux-core-note.c" diff --git a/backends/sparc_init.c b/backends/sparc_init.c index f8a7cfbd..8e946fb2 100644 --- a/backends/sparc_init.c +++ b/backends/sparc_init.c @@ -76,6 +76,14 @@ sparc_init (Elf *elf __attribute__ ((unused)), HOOK (eh, register_info); HOOK (eh, return_value_location); HOOK (eh, check_object_attribute); + HOOK (eh, abi_cfi); + /* gcc/config/sparc.h define FIRST_PSEUDO_REGISTER */ + eh->frame_nregs = 103; + /* The CFI Dwarf register with the "return address" in sparc + actually contains the call address. The return address is + located 8 bytes after it. */ + eh->ra_offset = 8; + HOOK (eh, set_initial_registers_tid); return MODVERSION; } diff --git a/backends/sparc_initreg.c b/backends/sparc_initreg.c new file mode 100644 index 00000000..c2a9b32a --- /dev/null +++ b/backends/sparc_initreg.c @@ -0,0 +1,129 @@ +/* Fetch live process registers from TID. + Copyright (C) 2015 Oracle, In + 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 "system.h" +#include <stdlib.h> +#ifdef __sparc__ +# include <asm/ptrace.h> +# include <sys/ptrace.h> +#endif + +#define BACKEND sparc_ +#include "libebl_CPU.h" + +bool +EBLHOOK (set_initial_registers_tid) (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#ifndef __sparc__ + return false; +#else /* __sparc__ */ + + + /* The pt_regs structure filled in by PTRACE_GETREGS provides the + PC, the global registers and the output registers. Note how the + %g0 register is not explicitly provided in the structure (it's + value is always 0) and the resulting weird packing in the u_regs + array: the last element is not used. */ + + struct pt_regs regs; + if (ptrace (PTRACE_GETREGS, tid, ®s, 0) == -1) + return false; + + /* PC: no DWARF number */ + if (!setfunc (-1, 1, (Dwarf_Word *) ®s.tpc, arg)) + return false; + + /* Global registers: DWARF 0 .. 7 */ + Dwarf_Word zero = 0; + if (!setfunc (0, 1, &zero, arg)) + return false; + if (!setfunc (1, 7, (Dwarf_Word *) ®s.u_regs[0], arg)) + return false; + + /* Output registers: DWARF 8 .. 15 */ + if (!setfunc (8, 8, (Dwarf_Word *) ®s.u_regs[7], arg)) + return false; + + /* Local and input registers must be read from the stack. They are + saved in the previous stack frame. The stack pointer is %o6, + read above. */ + + Dwarf_Word locals_outs[16]; + Dwarf_Word sp = regs.u_regs[13]; + + if (sp & 1) + { + /* Registers are 64 bits, and we need to apply the 2047 stack + bias in order to get the real stack pointer. */ + + sp += 2047; + + for (unsigned i = 0; i < 16; i++) + { + locals_outs[i] = ptrace (PTRACE_PEEKDATA, tid, + (void *) (uintptr_t) (sp + (i * 8)), + NULL); + if (errno != 0) + return false; + } + } + else + { + /* Registers are 32 bits. */ + + for (unsigned i = 0; i < 8; i++) + { + Dwarf_Word tuple = ptrace (PTRACE_PEEKDATA, tid, + (void *) (uintptr_t) (sp + (i * 8)), + NULL); + if (errno != 0) + return false; + + locals_outs[2*i] = (tuple >> 32) & 0xffffffff; + locals_outs[2*i+1] = tuple & 0xffffffff; + } + } + + + /* Local registers: DWARF 16 .. 23 */ + if (!setfunc (16, 8, &locals_outs[0], arg)) + return false; + + /* Input registers: DWARF 24 .. 31 */ + if (!setfunc (24, 8, &locals_outs[8], arg)) + return false; + + return true; +#endif +} |