1 /* 2 * This file is part of ltrace. 3 * Copyright (C) 2012,2013,2014 Petr Machata 4 * Copyright (C) 2006 Paul Gilliam 5 * Copyright (C) 2002,2004 Juan Cespedes 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of the 10 * License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 */ 22 #ifndef LTRACE_PPC_ARCH_H 23 #define LTRACE_PPC_ARCH_H 24 25 #include <gelf.h> 26 27 #define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 } 28 #define BREAKPOINT_LENGTH 4 29 #define DECR_PC_AFTER_BREAK 0 30 31 #define LT_ELFCLASS ELFCLASS32 32 #define LT_ELF_MACHINE EM_PPC 33 34 #ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target. 35 #define LT_ELFCLASS2 ELFCLASS64 36 #define LT_ELF_MACHINE2 EM_PPC64 37 #define ARCH_SUPPORTS_OPD 38 #endif 39 40 #define ARCH_HAVE_SW_SINGLESTEP 41 #define ARCH_HAVE_ADD_PLT_ENTRY 42 #define ARCH_HAVE_ADD_FUNC_ENTRY 43 #define ARCH_HAVE_TRANSLATE_ADDRESS 44 #define ARCH_HAVE_DYNLINK_DONE 45 #define ARCH_HAVE_FETCH_ARG 46 #define ARCH_ENDIAN_BIG 47 #define ARCH_HAVE_SIZEOF 48 #define ARCH_HAVE_ALIGNOF 49 50 struct library_symbol; 51 52 #define ARCH_HAVE_LTELF_DATA 53 struct arch_ltelf_data { 54 GElf_Addr plt_stub_vma; 55 struct library_symbol *stubs; 56 Elf_Data *opd_data; 57 GElf_Addr opd_base; 58 GElf_Xword opd_size; 59 int secure_plt; 60 61 Elf_Data *reladyn; 62 size_t reladyn_count; 63 }; 64 65 #define ARCH_HAVE_LIBRARY_DATA 66 struct arch_library_data { 67 GElf_Addr pltgot_addr; 68 int bss_plt_prelinked; 69 }; 70 71 enum ppc64_plt_type { 72 /* Either a non-PLT symbol, or PPC32 symbol. */ 73 PPC_DEFAULT = 0, 74 75 /* PPC64 STUB, never resolved. */ 76 PPC64_PLT_STUB, 77 78 /* Unresolved PLT symbol (.plt contains PLT address). */ 79 PPC_PLT_UNRESOLVED, 80 81 /* Resolved PLT symbol. The corresponding .plt slot contained 82 * target address, which was changed to the address of 83 * corresponding PLT entry. The original is now saved in 84 * RESOLVED_VALUE. */ 85 PPC_PLT_RESOLVED, 86 87 /* Very similar to PPC_PLT_UNRESOLVED, but for JMP_IREL 88 * slots. */ 89 PPC_PLT_IRELATIVE, 90 91 /* Transitional state before the breakpoint is enabled. */ 92 PPC_PLT_NEED_UNRESOLVE, 93 }; 94 95 #define ARCH_HAVE_LIBRARY_SYMBOL_DATA 96 struct ppc_unresolve_data; 97 struct arch_library_symbol_data { 98 enum ppc64_plt_type type; 99 100 /* State Contents 101 * 102 * PPC_DEFAULT N/A 103 * PPC64_PLT_STUB N/A 104 * PPC_PLT_UNRESOLVED PLT entry address. 105 * PPC_PLT_IRELATIVE Likewise. 106 * PPC_PLT_RESOLVED The original value the slot was resolved to. 107 * PPC_PLT_NEED_UNRESOLVE DATA. 108 */ 109 union { 110 GElf_Addr resolved_value; 111 struct ppc_unresolve_data *data; 112 }; 113 114 /* Address of corresponding slot in .plt. */ 115 GElf_Addr plt_slot_addr; 116 }; 117 118 #define ARCH_HAVE_BREAKPOINT_DATA 119 struct arch_breakpoint_data { 120 /* This is where we hide symbol for IRELATIVE breakpoint for 121 * the first time that it hits. This is NULL for normal 122 * breakpoints. */ 123 struct library_symbol *irel_libsym; 124 }; 125 126 #define ARCH_HAVE_PROCESS_DATA 127 struct arch_process_data { 128 /* Breakpoint that hits when the dynamic linker is about to 129 * update a .plt slot. NULL before that address is known. */ 130 struct breakpoint *dl_plt_update_bp; 131 132 /* PLT update breakpoint looks here for the handler. */ 133 struct process_stopping_handler *handler; 134 }; 135 136 #endif /* LTRACE_PPC_ARCH_H */ 137