Home | History | Annotate | Download | only in ppc
      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