1e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata/*
2e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This file is part of ltrace.
335742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata * Copyright (C) 2012,2013,2014 Petr Machata, Red Hat Inc.
4e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2004,2008,2009 Juan Cespedes
5e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2006 Paul Gilliam
6e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
7e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is free software; you can redistribute it and/or
8e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * modify it under the terms of the GNU General Public License as
9e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * published by the Free Software Foundation; either version 2 of the
10e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * License, or (at your option) any later version.
11e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
12e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is distributed in the hope that it will be useful, but
13e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of
14e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * General Public License for more details.
16e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
17e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * You should have received a copy of the GNU General Public License
18e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * along with this program; if not, write to the Free Software
19e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 02110-1301 USA
21e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata */
22e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata
23d914a206a11cc1011a45f00674b1e16988fae77fJuan Cespedes#include <gelf.h>
24a7af00db2231e99a4506e4f5587f9dd00b9d1175Juan Cespedes#include <sys/ptrace.h>
25e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata#include <errno.h>
26e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata#include <inttypes.h>
27e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata#include <assert.h>
2873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata#include <stdbool.h>
2937d368e49f2d757484252a060d3021de96998e0dPetr Machata#include <string.h>
30e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
31366c2f46d844f040458df9b7e35fc3b8527ed2d3Petr Machata#include "proc.h"
32f728123bd75a65a6a1536e198c3c30719e494e71Juan Cespedes#include "common.h"
337e26bd32a1a2269c193a6ef100ed8cd3127f3dc2Petr Machata#include "insn.h"
34e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata#include "library.h"
35b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata#include "breakpoint.h"
3658b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata#include "linux-gnu/trace.h"
3798d319eb9654ce903c751405535ebcd7077be887Petr Machata#include "backend.h"
38e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
3937d368e49f2d757484252a060d3021de96998e0dPetr Machata/* There are two PLT types on 32-bit PPC: old-style, BSS PLT, and
4037d368e49f2d757484252a060d3021de96998e0dPetr Machata * new-style "secure" PLT.  We can tell one from the other by the
4137d368e49f2d757484252a060d3021de96998e0dPetr Machata * flags on the .plt section.  If it's +X (executable), it's BSS PLT,
4237d368e49f2d757484252a060d3021de96998e0dPetr Machata * otherwise it's secure.
4337d368e49f2d757484252a060d3021de96998e0dPetr Machata *
4437d368e49f2d757484252a060d3021de96998e0dPetr Machata * BSS PLT works the same way as most architectures: the .plt section
459a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * contains trampolines and we put breakpoints to those.  If not
469a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * prelinked, .plt contains zeroes, and dynamic linker fills in the
479a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * initial set of trampolines, which means that we need to delay
489a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * enabling breakpoints until after binary entry point is hit.
499a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * Additionally, after first call, dynamic linker updates .plt with
509a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * branch to resolved address.  That means that on first hit, we must
519a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * do something similar to the PPC64 gambit described below.
5237d368e49f2d757484252a060d3021de96998e0dPetr Machata *
539a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * With secure PLT, the .plt section doesn't contain instructions but
549a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * addresses.  The real PLT table is stored in .text.  Addresses of
559a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * those PLT entries can be computed, and apart from the fact that
569a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata * they are in .text, they are ordinary PLT entries.
5737d368e49f2d757484252a060d3021de96998e0dPetr Machata *
5837d368e49f2d757484252a060d3021de96998e0dPetr Machata * 64-bit PPC is more involved.  Program linker creates for each
5937d368e49f2d757484252a060d3021de96998e0dPetr Machata * library call a _stub_ symbol named xxxxxxxx.plt_call.<callee>
6037d368e49f2d757484252a060d3021de96998e0dPetr Machata * (where xxxxxxxx is a hexadecimal number).  That stub does the call
6137d368e49f2d757484252a060d3021de96998e0dPetr Machata * dispatch: it loads an address of a function to call from the
6237d368e49f2d757484252a060d3021de96998e0dPetr Machata * section .plt, and branches.  PLT entries themselves are essentially
6337d368e49f2d757484252a060d3021de96998e0dPetr Machata * a curried call to the resolver.  When the symbol is resolved, the
6437d368e49f2d757484252a060d3021de96998e0dPetr Machata * resolver updates the value stored in .plt, and the next time
6537d368e49f2d757484252a060d3021de96998e0dPetr Machata * around, the stub calls the library function directly.  So we make
6637d368e49f2d757484252a060d3021de96998e0dPetr Machata * at most one trip (none if the binary is prelinked) through each PLT
6737d368e49f2d757484252a060d3021de96998e0dPetr Machata * entry, and correspondingly that is useless as a breakpoint site.
6837d368e49f2d757484252a060d3021de96998e0dPetr Machata *
6937d368e49f2d757484252a060d3021de96998e0dPetr Machata * Note the three confusing terms: stubs (that play the role of PLT
7037d368e49f2d757484252a060d3021de96998e0dPetr Machata * entries), PLT entries, .plt section.
7137d368e49f2d757484252a060d3021de96998e0dPetr Machata *
7237d368e49f2d757484252a060d3021de96998e0dPetr Machata * We first check symbol tables and see if we happen to have stub
7337d368e49f2d757484252a060d3021de96998e0dPetr Machata * symbols available.  If yes we just put breakpoints to those, and
7437d368e49f2d757484252a060d3021de96998e0dPetr Machata * treat them as usual breakpoints.  The only tricky part is realizing
7537d368e49f2d757484252a060d3021de96998e0dPetr Machata * that there can be more than one breakpoint per symbol.
7637d368e49f2d757484252a060d3021de96998e0dPetr Machata *
7737d368e49f2d757484252a060d3021de96998e0dPetr Machata * The case that we don't have the stub symbols available is harder.
7837d368e49f2d757484252a060d3021de96998e0dPetr Machata * The following scheme uses two kinds of PLT breakpoints: unresolved
7937d368e49f2d757484252a060d3021de96998e0dPetr Machata * and resolved (to some address).  When the process starts (or when
8037d368e49f2d757484252a060d3021de96998e0dPetr Machata * we attach), we distribute unresolved PLT breakpoints to the PLT
8137d368e49f2d757484252a060d3021de96998e0dPetr Machata * entries (not stubs).  Then we look in .plt, and for each entry
8237d368e49f2d757484252a060d3021de96998e0dPetr Machata * whose value is different than the corresponding PLT entry address,
8337d368e49f2d757484252a060d3021de96998e0dPetr Machata * we assume it was already resolved, and convert the breakpoint to
8437d368e49f2d757484252a060d3021de96998e0dPetr Machata * resolved.  We also rewrite the resolved value in .plt back to the
8537d368e49f2d757484252a060d3021de96998e0dPetr Machata * PLT address.
8637d368e49f2d757484252a060d3021de96998e0dPetr Machata *
8737d368e49f2d757484252a060d3021de96998e0dPetr Machata * When a PLT entry hits a resolved breakpoint (which happens because
8819c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * we rewrite .plt with the original unresolved addresses), we move
8919c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * the instruction pointer to the corresponding address and continue
9019c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * the process as if nothing happened.
9137d368e49f2d757484252a060d3021de96998e0dPetr Machata *
9237d368e49f2d757484252a060d3021de96998e0dPetr Machata * When unresolved PLT entry is called for the first time, we need to
9337d368e49f2d757484252a060d3021de96998e0dPetr Machata * catch the new value that the resolver will write to a .plt slot.
9437d368e49f2d757484252a060d3021de96998e0dPetr Machata * We also need to prevent another thread from racing through and
9537d368e49f2d757484252a060d3021de96998e0dPetr Machata * taking the branch without ltrace noticing.  So when unresolved PLT
9637d368e49f2d757484252a060d3021de96998e0dPetr Machata * entry hits, we have to stop all threads.  We then single-step
9737d368e49f2d757484252a060d3021de96998e0dPetr Machata * through the resolver, until the .plt slot changes.  When it does,
9837d368e49f2d757484252a060d3021de96998e0dPetr Machata * we treat it the same way as above: convert the PLT breakpoint to
9937d368e49f2d757484252a060d3021de96998e0dPetr Machata * resolved, and rewrite the .plt value back to PLT address.  We then
10037d368e49f2d757484252a060d3021de96998e0dPetr Machata * start all threads again.
10137d368e49f2d757484252a060d3021de96998e0dPetr Machata *
10219c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * As an optimization, we remember the address where the address was
10319c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * resolved, and put a breakpoint there.  The next time around (when
10419c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * the next PLT entry is to be resolved), instead of single-stepping
10519c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * through half the dynamic linker, we just let the thread run and hit
10619c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * this breakpoint.  When it hits, we know the PLT entry was resolved.
10758b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata *
10873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * Another twist comes from tracing slots corresponding to
10973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * R_PPC64_JMP_IREL relocations.  These have no dedicated PLT entry.
11073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * The calls are done directly from stubs, and the .plt entry
11173b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * (actually .iplt entry, these live in a special section) is resolved
11273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * in advance before the binary starts.  Because there's no PLT entry,
11373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * we put the PLT breakpoints directly to the IFUNC resolver code, and
11473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * then would like them to behave like ordinary PLT slots, including
11573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * catching the point where these get resolved to unresolve them.  So
11673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * for the first call (which is the actual resolver call), we pretend
11773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * that this breakpoint is artificial and has no associated symbol,
11873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * and turn it on fully only after the first hit.  Ideally we would
11973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * trace that first call as well, but then the stepper, which tries to
12073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * catch the point where the slot is resolved, would hit the return
12173b85aadbf377541ac336914e5ff8ec521226a97Petr Machata * breakpoint and that's not currently handled well.
12273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata *
123fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata * On PPC32 with secure PLT, the address of IFUNC symbols in main
124fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata * binary actually isn't of the resolver, but of a PLT slot.  We
125fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata * therefore have to locate the corresponding PLT relocation (which is
126fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata * of type R_PPC_IRELATIVE) and request that it be traced.  The addend
127fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata * of that relocation is an address of resolver, and we request
128fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata * tracing of the xyz.IFUNC symbol there.
12954bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata *
13019c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * XXX TODO If we have hardware watch point, we might put a read watch
13119c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * on .plt slot, and discover the offenders this way.  I don't know
13219c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * the details, but I assume at most a handful (like, one or two, if
13319c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * available at all) addresses may be watched at a time, and thus this
13419c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * would be used as an amendment of the above rather than full-on
13519c0f295a1a923b923e1083e480496c1454a2e0ePetr Machata * solution to PLT tracing on PPC.
13637d368e49f2d757484252a060d3021de96998e0dPetr Machata */
13737d368e49f2d757484252a060d3021de96998e0dPetr Machata
138e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata#define PPC_PLT_STUB_SIZE 16
139b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata#define PPC64_PLT_STUB_SIZE 8 //xxx
140e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
141e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machatastatic inline int
1424e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machatahost_powerpc64()
143e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata{
144e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata#ifdef __powerpc64__
145e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	return 1;
146e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata#else
147e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	return 0;
148e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata#endif
149e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata}
150e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
15113e68683414450f3bf7256e1cf09c0220325399fPetr Machatastatic void
15213e68683414450f3bf7256e1cf09c0220325399fPetr Machatamark_as_resolved(struct library_symbol *libsym, GElf_Addr value)
15313e68683414450f3bf7256e1cf09c0220325399fPetr Machata{
15413e68683414450f3bf7256e1cf09c0220325399fPetr Machata	libsym->arch.type = PPC_PLT_RESOLVED;
15513e68683414450f3bf7256e1cf09c0220325399fPetr Machata	libsym->arch.resolved_value = value;
15613e68683414450f3bf7256e1cf09c0220325399fPetr Machata}
15713e68683414450f3bf7256e1cf09c0220325399fPetr Machata
15873b85aadbf377541ac336914e5ff8ec521226a97Petr Machatastatic void
15973b85aadbf377541ac336914e5ff8ec521226a97Petr Machatappc32_delayed_symbol(struct library_symbol *libsym)
16073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata{
16173b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	/* arch_dynlink_done is called on attach as well.  In that
16273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * case some slots will have been resolved already.
16373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * Unresolved PLT looks like this:
16473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *
16573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *    <sleep@plt>:	li      r11,0
16673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *    <sleep@plt+4>:	b       "resolve"
16773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *
16873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * "resolve" is another address in PLTGOT (the same block that
16973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * all the PLT slots are it).  When resolved, it looks either
17073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * this way:
17173b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *
17273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *    <sleep@plt>:	b       0xfea88d0 <sleep>
17373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *
17473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * Which is easy to detect.  It can also look this way:
17573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *
17673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *    <sleep@plt>:	li      r11,0
17773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *    <sleep@plt+4>:	b       "dispatch"
17873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 *
17973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * The "dispatch" address lies in PLTGOT as well.  In current
18073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * GNU toolchain, "dispatch" address is the same as PLTGOT
18173b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * address.  We rely on this to figure out whether the address
18273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * is resolved or not.  */
18373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
18473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	uint32_t insn1 = libsym->arch.resolved_value >> 32;
18573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	uint32_t insn2 = (uint32_t) libsym->arch.resolved_value;
18673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	if ((insn1 & BRANCH_MASK) == B_INSN
18773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	    || ((insn2 & BRANCH_MASK) == B_INSN
18873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		/* XXX double cast  */
18973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		&& (ppc_branch_dest(libsym->enter_addr + 4, insn2)
19073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		    == (arch_addr_t) (long) libsym->lib->arch.pltgot_addr)))
19173b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	{
19273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		mark_as_resolved(libsym, libsym->arch.resolved_value);
19373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	}
19473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata}
19573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
1968ddf19a62a4521561ae4e4f118f0c364774ee2dbPetr Machatavoid
197929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_dynlink_done(struct process *proc)
198d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata{
19973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	/* We may need to activate delayed symbols.  */
2008ddf19a62a4521561ae4e4f118f0c364774ee2dbPetr Machata	struct library_symbol *libsym = NULL;
2018ddf19a62a4521561ae4e4f118f0c364774ee2dbPetr Machata	while ((libsym = proc_each_symbol(proc, libsym,
2028ddf19a62a4521561ae4e4f118f0c364774ee2dbPetr Machata					  library_symbol_delayed_cb, NULL))) {
203653085a32cdc89f5215c2d70249b58c9fe6aebb7Petr Machata		if (proc_read_64(proc, libsym->enter_addr,
204653085a32cdc89f5215c2d70249b58c9fe6aebb7Petr Machata				 &libsym->arch.resolved_value) < 0) {
205b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			fprintf(stderr,
206b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata				"couldn't read PLT value for %s(%p): %s\n",
207b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata				libsym->name, libsym->enter_addr,
208b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata				strerror(errno));
2098ddf19a62a4521561ae4e4f118f0c364774ee2dbPetr Machata			return;
210b8deb4d589d57c49d510b1b463b3904cb4964557Petr Machata		}
211d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata
21273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		if (proc->e_machine == EM_PPC)
21373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata			ppc32_delayed_symbol(libsym);
2147e26bd32a1a2269c193a6ef100ed8cd3127f3dc2Petr Machata
215b8deb4d589d57c49d510b1b463b3904cb4964557Petr Machata		if (proc_activate_delayed_symbol(proc, libsym) < 0)
2168ddf19a62a4521561ae4e4f118f0c364774ee2dbPetr Machata			return;
2177e26bd32a1a2269c193a6ef100ed8cd3127f3dc2Petr Machata
21873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		if (proc->e_machine == EM_PPC)
21973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata			/* XXX double cast  */
22073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata			libsym->arch.plt_slot_addr
22173b85aadbf377541ac336914e5ff8ec521226a97Petr Machata				= (GElf_Addr) (uintptr_t) libsym->enter_addr;
22273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	}
22373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata}
22473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
22573b85aadbf377541ac336914e5ff8ec521226a97Petr Machatastatic bool
22673b85aadbf377541ac336914e5ff8ec521226a97Petr Machatareloc_is_irelative(int machine, GElf_Rela *rela)
22773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata{
22873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	bool irelative = false;
22973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	if (machine == EM_PPC64) {
23073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata#ifdef R_PPC64_JMP_IREL
23173b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		irelative = GELF_R_TYPE(rela->r_info) == R_PPC64_JMP_IREL;
23273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata#endif
23373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	} else {
23473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		assert(machine == EM_PPC);
23573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata#ifdef R_PPC_IRELATIVE
23673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		irelative = GELF_R_TYPE(rela->r_info) == R_PPC_IRELATIVE;
23773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata#endif
2389a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	}
23973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	return irelative;
240d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata}
241d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata
242f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan CespedesGElf_Addr
2434e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machataarch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela)
2444e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machata{
2454e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machata	if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) {
2464e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machata		assert(lte->arch.plt_stub_vma != 0);
247e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		return lte->arch.plt_stub_vma + PPC_PLT_STUB_SIZE * ndx;
2484e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machata
2494e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machata	} else if (lte->ehdr.e_machine == EM_PPC) {
250e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		return rela->r_offset;
2514e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machata
25273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	/* Beyond this point, we are on PPC64, but don't have stub
25373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * symbols.  */
25473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
25573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	} else if (reloc_is_irelative(lte->ehdr.e_machine, rela)) {
25673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
25773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		/* Put JMP_IREL breakpoint to resolver, since there's
25873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		 * no dedicated PLT entry.  */
25973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
26073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		assert(rela->r_addend != 0);
26173b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		/* XXX double cast */
26273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		arch_addr_t res_addr = (arch_addr_t) (uintptr_t) rela->r_addend;
26373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		if (arch_translate_address(lte, res_addr, &res_addr) < 0) {
26473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata			fprintf(stderr, "Couldn't OPD-translate IRELATIVE "
26573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata				"resolver address.\n");
26673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata			return 0;
26773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		}
26873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		/* XXX double cast */
26973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		return (GElf_Addr) (uintptr_t) res_addr;
27073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
2714e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machata	} else {
27273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		/* We put brakpoints to PLT entries the same as the
27373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		 * PPC32 secure PLT case does. */
274b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata		assert(lte->arch.plt_stub_vma != 0);
275b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata		return lte->arch.plt_stub_vma + PPC64_PLT_STUB_SIZE * ndx;
2764e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machata	}
277e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata}
278e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
279b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata/* This entry point is called when ltelf is not available
280b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata * anymore--during runtime.  At that point we don't have to concern
281b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata * ourselves with bias, as the values in OPD have been resolved
282b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata * already.  */
283e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machataint
284929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_translate_address_dyn(struct process *proc,
285bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata			   arch_addr_t addr, arch_addr_t *ret)
286e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata{
287b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	if (proc->e_machine == EM_PPC64) {
2886ca19a3c08bc75fb451df30f4c6e6c1a128731fePetr Machata		uint64_t value;
289653085a32cdc89f5215c2d70249b58c9fe6aebb7Petr Machata		if (proc_read_64(proc, addr, &value) < 0) {
290b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			fprintf(stderr,
291b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata				"dynamic .opd translation of %p: %s\n",
292b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata				addr, strerror(errno));
293e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			return -1;
294e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		}
295a82d32209f276e10dd1f437b38b4b6e5de32b980Petr Machata		/* XXX The double cast should be removed when
296bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		 * arch_addr_t becomes integral type.  */
297bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		*ret = (arch_addr_t)(uintptr_t)value;
298e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		return 0;
299e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	}
300e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
301e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	*ret = addr;
302e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	return 0;
303d914a206a11cc1011a45f00674b1e16988fae77fJuan Cespedes}
3049a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand
305b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machataint
306b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machataarch_translate_address(struct ltelf *lte,
307bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		       arch_addr_t addr, arch_addr_t *ret)
308b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata{
3098bfb5734dfc5a82addc9db9d4c7642173bb4206bPetr Machata	if (lte->ehdr.e_machine == EM_PPC64) {
310a82d32209f276e10dd1f437b38b4b6e5de32b980Petr Machata		/* XXX The double cast should be removed when
311bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		 * arch_addr_t becomes integral type.  */
312a82d32209f276e10dd1f437b38b4b6e5de32b980Petr Machata		GElf_Xword offset
313a82d32209f276e10dd1f437b38b4b6e5de32b980Petr Machata			= (GElf_Addr)(uintptr_t)addr - lte->arch.opd_base;
3148bfb5734dfc5a82addc9db9d4c7642173bb4206bPetr Machata		uint64_t value;
3158bfb5734dfc5a82addc9db9d4c7642173bb4206bPetr Machata		if (elf_read_u64(lte->arch.opd_data, offset, &value) < 0) {
316b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			fprintf(stderr, "static .opd translation of %p: %s\n",
317b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata				addr, elf_errmsg(-1));
3188bfb5734dfc5a82addc9db9d4c7642173bb4206bPetr Machata			return -1;
3198bfb5734dfc5a82addc9db9d4c7642173bb4206bPetr Machata		}
320bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		*ret = (arch_addr_t)(uintptr_t)(value + lte->bias);
3218bfb5734dfc5a82addc9db9d4c7642173bb4206bPetr Machata		return 0;
322b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	}
3238bfb5734dfc5a82addc9db9d4c7642173bb4206bPetr Machata
3248bfb5734dfc5a82addc9db9d4c7642173bb4206bPetr Machata	*ret = addr;
325b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	return 0;
326b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata}
327b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata
328b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machatastatic int
329b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machataload_opd_data(struct ltelf *lte, struct library *lib)
330b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata{
331b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	Elf_Scn *sec;
332b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	GElf_Shdr shdr;
33399b19eb1bb736d7066026894aa69e70de8a03094Petr Machata	if (elf_get_section_named(lte, ".opd", &sec, &shdr) < 0
33499b19eb1bb736d7066026894aa69e70de8a03094Petr Machata	    || sec == NULL) {
335b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	fail:
336b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata		fprintf(stderr, "couldn't find .opd data\n");
337b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata		return -1;
338b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	}
339b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata
340b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	lte->arch.opd_data = elf_rawdata(sec, NULL);
341b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	if (lte->arch.opd_data == NULL)
342b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata		goto fail;
343b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata
344b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	lte->arch.opd_base = shdr.sh_addr + lte->bias;
345b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	lte->arch.opd_size = shdr.sh_size;
346b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata
347b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	return 0;
348b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata}
349b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata
350f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid *
351929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatasym2addr(struct process *proc, struct library_symbol *sym)
35218c801c3f29081d9de517815df89bc1bbf8e2188Petr Machata{
35318c801c3f29081d9de517815df89bc1bbf8e2188Petr Machata	return sym->enter_addr;
3549a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand}
355e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
356e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machatastatic GElf_Addr
357e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machataget_glink_vma(struct ltelf *lte, GElf_Addr ppcgot, Elf_Data *plt_data)
358e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata{
359e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	Elf_Scn *ppcgot_sec = NULL;
360e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	GElf_Shdr ppcgot_shdr;
361e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	if (ppcgot != 0
36299b19eb1bb736d7066026894aa69e70de8a03094Petr Machata	    && (elf_get_section_covering(lte, ppcgot,
36399b19eb1bb736d7066026894aa69e70de8a03094Petr Machata					 &ppcgot_sec, &ppcgot_shdr) < 0
36499b19eb1bb736d7066026894aa69e70de8a03094Petr Machata		|| ppcgot_sec == NULL))
365b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata		fprintf(stderr,
366b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			"DT_PPC_GOT=%#"PRIx64", but no such section found\n",
367b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			ppcgot);
368e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
369e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	if (ppcgot_sec != NULL) {
370e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		Elf_Data *data = elf_loaddata(ppcgot_sec, &ppcgot_shdr);
371e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		if (data == NULL || data->d_size < 8 ) {
372b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			fprintf(stderr, "couldn't read GOT data\n");
373e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		} else {
374e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			// where PPCGOT begins in .got
375e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			size_t offset = ppcgot - ppcgot_shdr.sh_addr;
376e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			assert(offset % 4 == 0);
377e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			uint32_t glink_vma;
378e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			if (elf_read_u32(data, offset + 4, &glink_vma) < 0) {
379b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata				fprintf(stderr, "couldn't read glink VMA"
380b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata					" address at %zd@GOT\n", offset);
381e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata				return 0;
382e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			}
383e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			if (glink_vma != 0) {
384e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata				debug(1, "PPC GOT glink_vma address: %#" PRIx32,
385e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata				      glink_vma);
386e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata				return (GElf_Addr)glink_vma;
387e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			}
388e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		}
389e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	}
390e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
391e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	if (plt_data != NULL) {
392e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		uint32_t glink_vma;
393e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		if (elf_read_u32(plt_data, 0, &glink_vma) < 0) {
394b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			fprintf(stderr, "couldn't read glink VMA address\n");
395e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			return 0;
396e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		}
397e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		debug(1, ".plt glink_vma address: %#" PRIx32, glink_vma);
398e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		return (GElf_Addr)glink_vma;
399e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	}
400e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
401e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	return 0;
402e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata}
403e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
404644d669f96c0fe261fe938cecda41938e804c7d9Petr Machatastatic int
405d95733284377c0b186ba0c81a1158edc2b913e45Petr Machatanonzero_data(Elf_Data *data)
406d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata{
4079a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	/* We are not supposed to get here if there's no PLT.  */
408d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	assert(data != NULL);
409d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata
410d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	unsigned char *buf = data->d_buf;
411d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	if (buf == NULL)
412d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata		return 0;
413d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata
414d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	size_t i;
415d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	for (i = 0; i < data->d_size; ++i)
416d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata		if (buf[i] != 0)
417d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata			return 1;
418d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	return 0;
419d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata}
420d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata
42173b85aadbf377541ac336914e5ff8ec521226a97Petr Machatastatic enum callback_status
42273b85aadbf377541ac336914e5ff8ec521226a97Petr Machatareloc_copy_if_irelative(GElf_Rela *rela, void *data)
42373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata{
42473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	struct ltelf *lte = data;
42573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
42673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	return CBS_STOP_IF(reloc_is_irelative(lte->ehdr.e_machine, rela)
42773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata			   && VECT_PUSHBACK(&lte->plt_relocs, rela) < 0);
42873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata}
42973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
430e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machataint
431d95733284377c0b186ba0c81a1158edc2b913e45Petr Machataarch_elf_init(struct ltelf *lte, struct library *lib)
432e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata{
433b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	if (lte->ehdr.e_machine == EM_PPC64
434b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	    && load_opd_data(lte, lib) < 0)
435b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata		return -1;
436b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata
43718c801c3f29081d9de517815df89bc1bbf8e2188Petr Machata	lte->arch.secure_plt = !(lte->plt_flags & SHF_EXECINSTR);
438d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata
439d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	/* For PPC32 BSS, it is important whether the binary was
440d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	 * prelinked.  If .plt section is NODATA, or if it contains
441d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	 * zeroes, then this library is not prelinked, and we need to
442d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	 * delay breakpoints.  */
443d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	if (lte->ehdr.e_machine == EM_PPC && !lte->arch.secure_plt)
444d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata		lib->arch.bss_plt_prelinked = nonzero_data(lte->plt_data);
445d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata	else
446d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata		/* For cases where it's irrelevant, initialize the
447d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata		 * value to something conspicuous.  */
448d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata		lib->arch.bss_plt_prelinked = -1;
449d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata
45054bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	/* On PPC64 and PPC32 secure, IRELATIVE relocations actually
45154bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	 * relocate .iplt section, and as such are stored in .rela.dyn
45254bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	 * (where all non-PLT relocations are stored) instead of
45354bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	 * .rela.plt.  Add these to lte->plt_relocs.  */
45454bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata
45554bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	GElf_Addr rela, relasz;
45654bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	Elf_Scn *rela_sec;
45754bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	GElf_Shdr rela_shdr;
45854bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	if ((lte->ehdr.e_machine == EM_PPC64 || lte->arch.secure_plt)
4594f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machata	    && elf_load_dynamic_entry(lte, DT_RELA, &rela) == 0
4604f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machata	    && elf_load_dynamic_entry(lte, DT_RELASZ, &relasz) == 0
46154bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	    && elf_get_section_covering(lte, rela, &rela_sec, &rela_shdr) == 0
46254bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	    && rela_sec != NULL) {
46354bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata
46454bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		struct vect v;
46554bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		VECT_INIT(&v, GElf_Rela);
46654bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		int ret = elf_read_relocs(lte, rela_sec, &rela_shdr, &v);
46754bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		if (ret >= 0
46854bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		    && VECT_EACH(&v, GElf_Rela, NULL,
46954bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata				 reloc_copy_if_irelative, lte) != NULL)
47054bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata			ret = -1;
47154bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata
47254bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		VECT_DESTROY(&v, GElf_Rela, NULL, NULL);
47354bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata
47454bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		if (ret < 0)
47554bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata			return ret;
47654bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	}
47754bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata
4784e2073f64f9db2974d89064dcdc49b2ed7aa9006Petr Machata	if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) {
479644d669f96c0fe261fe938cecda41938e804c7d9Petr Machata		GElf_Addr ppcgot;
4804f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machata		if (elf_load_dynamic_entry(lte, DT_PPC_GOT, &ppcgot) < 0) {
481b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			fprintf(stderr, "couldn't find DT_PPC_GOT\n");
482644d669f96c0fe261fe938cecda41938e804c7d9Petr Machata			return -1;
483644d669f96c0fe261fe938cecda41938e804c7d9Petr Machata		}
484644d669f96c0fe261fe938cecda41938e804c7d9Petr Machata		GElf_Addr glink_vma = get_glink_vma(lte, ppcgot, lte->plt_data);
485e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
48673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		size_t count = vect_size(&lte->plt_relocs);
487e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		lte->arch.plt_stub_vma = glink_vma
488ba36f0ac51d194c599fd56457796e33e62c3220bPetr Machata			- (GElf_Addr) count * PPC_PLT_STUB_SIZE;
489e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata		debug(1, "stub_vma is %#" PRIx64, lte->arch.plt_stub_vma);
490b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
491b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	} else if (lte->ehdr.e_machine == EM_PPC64) {
492b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata		GElf_Addr glink_vma;
4934f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machata		if (elf_load_dynamic_entry(lte, DT_PPC64_GLINK,
4944f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machata					   &glink_vma) < 0) {
495b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			fprintf(stderr, "couldn't find DT_PPC64_GLINK\n");
496b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata			return -1;
497b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata		}
498b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
499b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata		/* The first glink stub starts at offset 32.  */
500b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata		lte->arch.plt_stub_vma = glink_vma + 32;
5017e26bd32a1a2269c193a6ef100ed8cd3127f3dc2Petr Machata
5027e26bd32a1a2269c193a6ef100ed8cd3127f3dc2Petr Machata	} else {
5037e26bd32a1a2269c193a6ef100ed8cd3127f3dc2Petr Machata		/* By exhaustion--PPC32 BSS.  */
5044f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machata		if (elf_load_dynamic_entry(lte, DT_PLTGOT,
5054f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machata					   &lib->arch.pltgot_addr) < 0) {
5067e26bd32a1a2269c193a6ef100ed8cd3127f3dc2Petr Machata			fprintf(stderr, "couldn't find DT_PLTGOT\n");
5077e26bd32a1a2269c193a6ef100ed8cd3127f3dc2Petr Machata			return -1;
5087e26bd32a1a2269c193a6ef100ed8cd3127f3dc2Petr Machata		}
509e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	}
510e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
51137d368e49f2d757484252a060d3021de96998e0dPetr Machata	/* On PPC64, look for stub symbols in symbol table.  These are
51237d368e49f2d757484252a060d3021de96998e0dPetr Machata	 * called: xxxxxxxx.plt_call.callee_name@version+addend.  */
51337d368e49f2d757484252a060d3021de96998e0dPetr Machata	if (lte->ehdr.e_machine == EM_PPC64
51437d368e49f2d757484252a060d3021de96998e0dPetr Machata	    && lte->symtab != NULL && lte->strtab != NULL) {
51537d368e49f2d757484252a060d3021de96998e0dPetr Machata
51637d368e49f2d757484252a060d3021de96998e0dPetr Machata		/* N.B. We can't simply skip the symbols that we fail
51737d368e49f2d757484252a060d3021de96998e0dPetr Machata		 * to read or malloc.  There may be more than one stub
51837d368e49f2d757484252a060d3021de96998e0dPetr Machata		 * per symbol name, and if we failed in one but
51937d368e49f2d757484252a060d3021de96998e0dPetr Machata		 * succeeded in another, the PLT enabling code would
52037d368e49f2d757484252a060d3021de96998e0dPetr Machata		 * have no way to tell that something is missing.  We
52137d368e49f2d757484252a060d3021de96998e0dPetr Machata		 * could work around that, of course, but it doesn't
5227b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata		 * seem worth the trouble.  So if anything fails, we
5237b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata		 * just pretend that we don't have stub symbols at
5247b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata		 * all, as if the binary is stripped.  */
52537d368e49f2d757484252a060d3021de96998e0dPetr Machata
52637d368e49f2d757484252a060d3021de96998e0dPetr Machata		size_t i;
52737d368e49f2d757484252a060d3021de96998e0dPetr Machata		for (i = 0; i < lte->symtab_count; ++i) {
52837d368e49f2d757484252a060d3021de96998e0dPetr Machata			GElf_Sym sym;
5297b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata			if (gelf_getsym(lte->symtab, i, &sym) == NULL) {
5307b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata				struct library_symbol *sym, *next;
5317b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata			fail:
5327b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata				for (sym = lte->arch.stubs; sym != NULL; ) {
5337b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata					next = sym->next;
5347b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata					library_symbol_destroy(sym);
5357b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata					free(sym);
5367b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata					sym = next;
5377b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata				}
5387b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata				lte->arch.stubs = NULL;
53937d368e49f2d757484252a060d3021de96998e0dPetr Machata				break;
5407b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata			}
54137d368e49f2d757484252a060d3021de96998e0dPetr Machata
54237d368e49f2d757484252a060d3021de96998e0dPetr Machata			const char *name = lte->strtab + sym.st_name;
54337d368e49f2d757484252a060d3021de96998e0dPetr Machata
54437d368e49f2d757484252a060d3021de96998e0dPetr Machata#define STUBN ".plt_call."
54537d368e49f2d757484252a060d3021de96998e0dPetr Machata			if ((name = strstr(name, STUBN)) == NULL)
54637d368e49f2d757484252a060d3021de96998e0dPetr Machata				continue;
54737d368e49f2d757484252a060d3021de96998e0dPetr Machata			name += sizeof(STUBN) - 1;
54837d368e49f2d757484252a060d3021de96998e0dPetr Machata#undef STUBN
54937d368e49f2d757484252a060d3021de96998e0dPetr Machata
55037d368e49f2d757484252a060d3021de96998e0dPetr Machata			size_t len;
55137d368e49f2d757484252a060d3021de96998e0dPetr Machata			const char *ver = strchr(name, '@');
55237d368e49f2d757484252a060d3021de96998e0dPetr Machata			if (ver != NULL) {
55337d368e49f2d757484252a060d3021de96998e0dPetr Machata				len = ver - name;
55437d368e49f2d757484252a060d3021de96998e0dPetr Machata
55537d368e49f2d757484252a060d3021de96998e0dPetr Machata			} else {
55637d368e49f2d757484252a060d3021de96998e0dPetr Machata				/* If there is "+" at all, check that
55737d368e49f2d757484252a060d3021de96998e0dPetr Machata				 * the symbol name ends in "+0".  */
55837d368e49f2d757484252a060d3021de96998e0dPetr Machata				const char *add = strrchr(name, '+');
55937d368e49f2d757484252a060d3021de96998e0dPetr Machata				if (add != NULL) {
56037d368e49f2d757484252a060d3021de96998e0dPetr Machata					assert(strcmp(add, "+0") == 0);
56137d368e49f2d757484252a060d3021de96998e0dPetr Machata					len = add - name;
56237d368e49f2d757484252a060d3021de96998e0dPetr Machata				} else {
56337d368e49f2d757484252a060d3021de96998e0dPetr Machata					len = strlen(name);
56437d368e49f2d757484252a060d3021de96998e0dPetr Machata				}
56537d368e49f2d757484252a060d3021de96998e0dPetr Machata			}
56637d368e49f2d757484252a060d3021de96998e0dPetr Machata
56737d368e49f2d757484252a060d3021de96998e0dPetr Machata			char *sym_name = strndup(name, len);
5687b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata			struct library_symbol *libsym = malloc(sizeof(*libsym));
5697b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata			if (sym_name == NULL || libsym == NULL) {
570e8d9076a97f6617868466a99bd18e11e3f6389acPetr Machata			fail2:
57137d368e49f2d757484252a060d3021de96998e0dPetr Machata				free(sym_name);
5727b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata				free(libsym);
5737b36114b46cf93aa2828de055e71ec57a801dfc1Petr Machata				goto fail;
57437d368e49f2d757484252a060d3021de96998e0dPetr Machata			}
57537d368e49f2d757484252a060d3021de96998e0dPetr Machata
576ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			/* XXX The double cast should be removed when
577bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata			 * arch_addr_t becomes integral type.  */
578bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata			arch_addr_t addr = (arch_addr_t)
579ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata				(uintptr_t)sym.st_value + lte->bias;
580e8d9076a97f6617868466a99bd18e11e3f6389acPetr Machata			if (library_symbol_init(libsym, addr, sym_name, 1,
581e8d9076a97f6617868466a99bd18e11e3f6389acPetr Machata						LS_TOPLT_EXEC) < 0)
582e8d9076a97f6617868466a99bd18e11e3f6389acPetr Machata				goto fail2;
583585f60f7b171a391fbd5149f3d397d192168a67cPetr Machata			libsym->arch.type = PPC64_PLT_STUB;
58437d368e49f2d757484252a060d3021de96998e0dPetr Machata			libsym->next = lte->arch.stubs;
58537d368e49f2d757484252a060d3021de96998e0dPetr Machata			lte->arch.stubs = libsym;
58637d368e49f2d757484252a060d3021de96998e0dPetr Machata		}
58737d368e49f2d757484252a060d3021de96998e0dPetr Machata	}
58837d368e49f2d757484252a060d3021de96998e0dPetr Machata
589e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	return 0;
590e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata}
59137d368e49f2d757484252a060d3021de96998e0dPetr Machata
59258b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machatastatic int
593929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataread_plt_slot_value(struct process *proc, GElf_Addr addr, GElf_Addr *valp)
59458b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata{
5959a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	/* On PPC64, we read from .plt, which contains 8 byte
5969a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	 * addresses.  On PPC32 we read from .plt, which contains 4
597d2fc09dccfc18680209a918dc8cbcc1f75e41118Petr Machata	 * byte instructions, but the PLT is two instructions, and
598d2fc09dccfc18680209a918dc8cbcc1f75e41118Petr Machata	 * either can change.  */
5999a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	uint64_t l;
600a753c98f0957df9d12d5ecf0607eef7033ab7745Petr Machata	/* XXX double cast.  */
601653085a32cdc89f5215c2d70249b58c9fe6aebb7Petr Machata	if (proc_read_64(proc, (arch_addr_t)(uintptr_t)addr, &l) < 0) {
602b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata		fprintf(stderr, "ptrace .plt slot value @%#" PRIx64": %s\n",
603b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			addr, strerror(errno));
60458b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata		return -1;
60558b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	}
60658b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata
60758b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	*valp = (GElf_Addr)l;
60858b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	return 0;
60958b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata}
61058b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata
61158b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machatastatic int
612929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataunresolve_plt_slot(struct process *proc, GElf_Addr addr, GElf_Addr value)
61358b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata{
61458b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	/* We only modify plt_entry[0], which holds the resolved
61558b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	 * address of the routine.  We keep the TOC and environment
61658b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	 * pointers intact.  Hence the only adjustment that we need to
61758b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	 * do is to IP.  */
61858b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	if (ptrace(PTRACE_POKETEXT, proc->pid, addr, value) < 0) {
619b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata		fprintf(stderr, "failed to unresolve .plt slot: %s\n",
620b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			strerror(errno));
62158b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata		return -1;
62258b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	}
62358b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	return 0;
62458b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata}
62558b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata
62637d368e49f2d757484252a060d3021de96998e0dPetr Machataenum plt_status
627fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machataarch_elf_add_func_entry(struct process *proc, struct ltelf *lte,
628fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			const GElf_Sym *sym,
629fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			arch_addr_t addr, const char *name,
630fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			struct library_symbol **ret)
631fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata{
632fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata	if (lte->ehdr.e_machine != EM_PPC || lte->ehdr.e_type == ET_DYN)
633fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata		return PLT_DEFAULT;
634fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata
635fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata	bool ifunc = false;
636fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata#ifdef STT_GNU_IFUNC
637fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata	ifunc = GELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC;
638fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata#endif
639fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata	if (! ifunc)
640fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata		return PLT_DEFAULT;
641fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata
642fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata	size_t len = vect_size(&lte->plt_relocs);
643fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata	size_t i;
644fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata	for (i = 0; i < len; ++i) {
645fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata		GElf_Rela *rela = VECT_ELEMENT(&lte->plt_relocs, GElf_Rela, i);
646fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata		if (sym->st_value == arch_plt_sym_val(lte, i, rela)) {
647fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata
648fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			char *tmp_name = linux_append_IFUNC_to_name(name);
649fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			struct library_symbol *libsym = malloc(sizeof *libsym);
650fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata
651fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			/* XXX double cast.  */
652fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			arch_addr_t resolver_addr
653fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata				= (arch_addr_t) (uintptr_t) rela->r_addend;
654fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata
655fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			if (tmp_name == NULL || libsym == NULL
656fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			    || 	library_symbol_init(libsym, resolver_addr,
657fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata						    tmp_name, 1,
658fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata						    LS_TOPLT_EXEC) < 0) {
659fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			fail:
660fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata				free(tmp_name);
661fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata				free(libsym);
662fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata				return PLT_FAIL;
663fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			}
664fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata
665fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			if (elf_add_plt_entry(proc, lte, name, rela,
666fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata					      i, ret) < 0) {
667fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata				library_symbol_destroy(libsym);
668fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata				goto fail;
669fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			}
670fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata
671fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			libsym->proto = linux_IFUNC_prototype();
672fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			libsym->next = *ret;
673fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			*ret = libsym;
674fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata			return PLT_OK;
675fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata		}
676fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata	}
677fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata
678fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata	*ret = NULL;
679fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata	return PLT_OK;
680fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata}
681fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machata
682a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machatastruct ppc_unresolve_data {
683a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	struct ppc_unresolve_data *self; /* A canary.  */
684a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	GElf_Addr plt_entry_addr;
685a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	GElf_Addr plt_slot_addr;
686a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	GElf_Addr plt_slot_value;
687a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	bool is_irelative;
688a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata};
689a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata
690fa844db00b61b9f61c9ae8c6f4165aa5fff3a5d7Petr Machataenum plt_status
691929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
692d1746d17eda0c4d2c1004c9deb8b229eb6fb1c78Petr Machata		       const char *a_name, GElf_Rela *rela, size_t ndx,
69337d368e49f2d757484252a060d3021de96998e0dPetr Machata		       struct library_symbol **ret)
69437d368e49f2d757484252a060d3021de96998e0dPetr Machata{
69573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	bool is_irelative = reloc_is_irelative(lte->ehdr.e_machine, rela);
69673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	char *name;
69754bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	if (! is_irelative) {
69873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		name = strdup(a_name);
69954bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	} else {
70054bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		GElf_Addr addr = lte->ehdr.e_machine == EM_PPC64
70154bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata			? (GElf_Addr) rela->r_addend
70254bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata			: arch_plt_sym_val(lte, ndx, rela);
70354bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		name = linux_elf_find_irelative_name(lte, addr);
70454bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	}
70573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
70654bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	if (name == NULL) {
70754bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	fail:
70854bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		free(name);
70973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		return PLT_FAIL;
71054bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	}
71154bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata
71254bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	struct library_symbol *chain = NULL;
71354bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	if (lte->ehdr.e_machine == EM_PPC) {
71454bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		if (default_elf_add_plt_entry(proc, lte, name, rela, ndx,
71554bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata					      &chain) < 0)
71654bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata			goto fail;
71754bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata
71854bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		if (! lte->arch.secure_plt) {
71954bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata			/* On PPC32 with BSS PLT, delay the symbol
72054bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata			 * until dynamic linker is done.  */
72154bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata			assert(!chain->delayed);
72254bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata			chain->delayed = 1;
72354bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		}
72454bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata
72554bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	ok:
72654bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		*ret = chain;
72754bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		free(name);
72854bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		return PLT_OK;
72954bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	}
73073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
73137d368e49f2d757484252a060d3021de96998e0dPetr Machata	/* PPC64.  If we have stubs, we return a chain of breakpoint
73237d368e49f2d757484252a060d3021de96998e0dPetr Machata	 * sites, one for each stub that corresponds to this PLT
73337d368e49f2d757484252a060d3021de96998e0dPetr Machata	 * entry.  */
73437d368e49f2d757484252a060d3021de96998e0dPetr Machata	struct library_symbol **symp;
73537d368e49f2d757484252a060d3021de96998e0dPetr Machata	for (symp = &lte->arch.stubs; *symp != NULL; ) {
73637d368e49f2d757484252a060d3021de96998e0dPetr Machata		struct library_symbol *sym = *symp;
73773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		if (strcmp(sym->name, name) != 0) {
73837d368e49f2d757484252a060d3021de96998e0dPetr Machata			symp = &(*symp)->next;
73937d368e49f2d757484252a060d3021de96998e0dPetr Machata			continue;
74037d368e49f2d757484252a060d3021de96998e0dPetr Machata		}
74137d368e49f2d757484252a060d3021de96998e0dPetr Machata
74237d368e49f2d757484252a060d3021de96998e0dPetr Machata		/* Re-chain the symbol from stubs to CHAIN.  */
74337d368e49f2d757484252a060d3021de96998e0dPetr Machata		*symp = sym->next;
74437d368e49f2d757484252a060d3021de96998e0dPetr Machata		sym->next = chain;
74537d368e49f2d757484252a060d3021de96998e0dPetr Machata		chain = sym;
74637d368e49f2d757484252a060d3021de96998e0dPetr Machata	}
74737d368e49f2d757484252a060d3021de96998e0dPetr Machata
74854bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	if (chain != NULL)
74954bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		goto ok;
75037d368e49f2d757484252a060d3021de96998e0dPetr Machata
751b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	/* We don't have stub symbols.  Find corresponding .plt slot,
752b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	 * and check whether it contains the corresponding PLT address
753b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	 * (or 0 if the dynamic linker hasn't run yet).  N.B. we don't
754b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	 * want read this from ELF file, but from process image.  That
755b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	 * makes a difference if we are attaching to a running
756b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	 * process.  */
757b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
758b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	GElf_Addr plt_entry_addr = arch_plt_sym_val(lte, ndx, rela);
759b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	GElf_Addr plt_slot_addr = rela->r_offset;
76073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
761b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	assert(plt_slot_addr >= lte->plt_addr
762b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	       || plt_slot_addr < lte->plt_addr + lte->plt_size);
763b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
76458b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	GElf_Addr plt_slot_value;
76554bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	if (read_plt_slot_value(proc, plt_slot_addr, &plt_slot_value) < 0)
76654bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		goto fail;
767b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
768b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	struct library_symbol *libsym = malloc(sizeof(*libsym));
76973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	if (libsym == NULL) {
770b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata		fprintf(stderr, "allocation for .plt slot: %s\n",
771b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			strerror(errno));
77254bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata	fail2:
773b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata		free(libsym);
77454bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		goto fail;
775b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	}
776b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
777ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	/* XXX The double cast should be removed when
778bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	 * arch_addr_t becomes integral type.  */
779ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	if (library_symbol_init(libsym,
78073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata				(arch_addr_t) (uintptr_t) plt_entry_addr,
781e8d9076a97f6617868466a99bd18e11e3f6389acPetr Machata				name, 1, LS_TOPLT_EXEC) < 0)
78254bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata		goto fail2;
78358b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	libsym->arch.plt_slot_addr = plt_slot_addr;
78458b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata
78573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	if (! is_irelative
78673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	    && (plt_slot_value == plt_entry_addr || plt_slot_value == 0)) {
787585f60f7b171a391fbd5149f3d397d192168a67cPetr Machata		libsym->arch.type = PPC_PLT_UNRESOLVED;
78858b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata		libsym->arch.resolved_value = plt_entry_addr;
789b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	} else {
790a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		/* Mark the symbol for later unresolving.  We may not
791a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * do this right away, as this is called by ltrace
792a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * core for all symbols, and only later filtered.  We
793a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * only unresolve the symbol before the breakpoint is
794a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * enabled.  */
795a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata
796a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		libsym->arch.type = PPC_PLT_NEED_UNRESOLVE;
797a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		libsym->arch.data = malloc(sizeof *libsym->arch.data);
798a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		if (libsym->arch.data == NULL)
79954bb64cf2eae7a0daa4d17e980b743b8ae69413bPetr Machata			goto fail2;
80073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
801a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		libsym->arch.data->self = libsym->arch.data;
802a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		libsym->arch.data->plt_entry_addr = plt_entry_addr;
803a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		libsym->arch.data->plt_slot_addr = plt_slot_addr;
804a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		libsym->arch.data->plt_slot_value = plt_slot_value;
805a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		libsym->arch.data->is_irelative = is_irelative;
806b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	}
807b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
808b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	*ret = libsym;
809ade3b9798fbc62becbe1b4854f7a2d106498167aPetr Machata	return PLT_OK;
81037d368e49f2d757484252a060d3021de96998e0dPetr Machata}
81137d368e49f2d757484252a060d3021de96998e0dPetr Machata
8124d9a91c5c677d6a6b2db21f00385bce5167373c4Petr Machatavoid
8134d9a91c5c677d6a6b2db21f00385bce5167373c4Petr Machataarch_elf_destroy(struct ltelf *lte)
8144d9a91c5c677d6a6b2db21f00385bce5167373c4Petr Machata{
81537d368e49f2d757484252a060d3021de96998e0dPetr Machata	struct library_symbol *sym;
81637d368e49f2d757484252a060d3021de96998e0dPetr Machata	for (sym = lte->arch.stubs; sym != NULL; ) {
81737d368e49f2d757484252a060d3021de96998e0dPetr Machata		struct library_symbol *next = sym->next;
81837d368e49f2d757484252a060d3021de96998e0dPetr Machata		library_symbol_destroy(sym);
81937d368e49f2d757484252a060d3021de96998e0dPetr Machata		free(sym);
82037d368e49f2d757484252a060d3021de96998e0dPetr Machata		sym = next;
82137d368e49f2d757484252a060d3021de96998e0dPetr Machata	}
8224d9a91c5c677d6a6b2db21f00385bce5167373c4Petr Machata}
823b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
8246b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machatastatic void
825929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatadl_plt_update_bp_on_hit(struct breakpoint *bp, struct process *proc)
8266b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata{
827b04b64b7285183ad5fbc011ee381613359c35a2bPetr Machata	debug(DEBUG_PROCESS, "pid=%d dl_plt_update_bp_on_hit %s(%p)",
828b04b64b7285183ad5fbc011ee381613359c35a2bPetr Machata	      proc->pid, breakpoint_name(bp), bp->addr);
8296b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	struct process_stopping_handler *self = proc->arch.handler;
8306b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	assert(self != NULL);
8316b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
8326b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	struct library_symbol *libsym = self->breakpoint_being_enabled->libsym;
8336b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	GElf_Addr value;
8346b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	if (read_plt_slot_value(proc, libsym->arch.plt_slot_addr, &value) < 0)
8356b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata		return;
8366b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
837f685a3d0b3aaf9cf2bda30937ddc1a55009ee01aPetr Machata	/* On PPC64, we rewrite the slot value.  */
838f685a3d0b3aaf9cf2bda30937ddc1a55009ee01aPetr Machata	if (proc->e_machine == EM_PPC64)
839f685a3d0b3aaf9cf2bda30937ddc1a55009ee01aPetr Machata		unresolve_plt_slot(proc, libsym->arch.plt_slot_addr,
840f685a3d0b3aaf9cf2bda30937ddc1a55009ee01aPetr Machata				   libsym->arch.resolved_value);
841f685a3d0b3aaf9cf2bda30937ddc1a55009ee01aPetr Machata	/* We mark the breakpoint as resolved on both arches.  */
8428d930e8f095d04d62705f35f5362a537b73ffefePetr Machata	mark_as_resolved(libsym, value);
84372b5ee8b5c795e88e090be6bc64492ec216d40cePetr Machata
8446b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	/* cb_on_all_stopped looks if HANDLER is set to NULL as a way
8456b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	 * to check that this was run.  It's an error if it
8466b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	 * wasn't.  */
8476b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	proc->arch.handler = NULL;
848b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata
849b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	breakpoint_turn_off(bp, proc);
8506b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata}
8516b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
8526b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machatastatic void
8536b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machatacb_on_all_stopped(struct process_stopping_handler *self)
8546b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata{
8556b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	/* Put that in for dl_plt_update_bp_on_hit to see.  */
8566b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	assert(self->task_enabling_breakpoint->arch.handler == NULL);
8576b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	self->task_enabling_breakpoint->arch.handler = self;
8586b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
8596b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	linux_ptrace_disable_and_continue(self);
8606b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata}
8616b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
86258b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machatastatic enum callback_status
8636b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machatacb_keep_stepping_p(struct process_stopping_handler *self)
86458b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata{
865929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata	struct process *proc = self->task_enabling_breakpoint;
86658b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	struct library_symbol *libsym = self->breakpoint_being_enabled->libsym;
867b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata
86858b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	GElf_Addr value;
86958b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	if (read_plt_slot_value(proc, libsym->arch.plt_slot_addr, &value) < 0)
87058b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata		return CBS_FAIL;
87158b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata
87258b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	/* In UNRESOLVED state, the RESOLVED_VALUE in fact contains
87358b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	 * the PLT entry value.  */
87458b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	if (value == libsym->arch.resolved_value)
87558b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata		return CBS_CONT;
87658b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata
877b04b64b7285183ad5fbc011ee381613359c35a2bPetr Machata	debug(DEBUG_PROCESS, "pid=%d PLT got resolved to value %#"PRIx64,
878b04b64b7285183ad5fbc011ee381613359c35a2bPetr Machata	      proc->pid, value);
879b04b64b7285183ad5fbc011ee381613359c35a2bPetr Machata
88058b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	/* The .plt slot got resolved!  We can migrate the breakpoint
88158b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	 * to RESOLVED and stop single-stepping.  */
882b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	if (proc->e_machine == EM_PPC64
883b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	    && unresolve_plt_slot(proc, libsym->arch.plt_slot_addr,
884b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata				  libsym->arch.resolved_value) < 0)
88558b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata		return CBS_FAIL;
8866b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
887b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	/* Resolving on PPC64 consists of overwriting a doubleword in
888b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * .plt.  That doubleword is than read back by a stub, and
889b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * jumped on.  Hopefully we can assume that double word update
890b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * is done on a single place only, as it contains a final
891b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * address.  We still need to look around for any sync
892b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * instruction, but essentially it is safe to optimize away
893b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * the single stepping next time and install a post-update
894b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * breakpoint.
895b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 *
896b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * The situation on PPC32 BSS is more complicated.  The
897b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * dynamic linker here updates potentially several
898b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * instructions (XXX currently we assume two) and the rules
899b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * are more complicated.  Sometimes it's enough to adjust just
900b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * one of the addresses--the logic for generating optimal
901b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * dispatch depends on relative addresses of the .plt entry
902b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * and the jump destination.  We can't assume that the some
903b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * instruction block does the update every time.  So on PPC32,
904b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * we turn the optimization off and just step through it each
905b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	 * time.  */
906b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	if (proc->e_machine == EM_PPC)
907b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata		goto done;
908b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata
9096b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	/* Install breakpoint to the address where the change takes
9106b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	 * place.  If we fail, then that just means that we'll have to
9116b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	 * singlestep the next time around as well.  */
912929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata	struct process *leader = proc->leader;
9136b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	if (leader == NULL || leader->arch.dl_plt_update_bp != NULL)
9148557b4a1a6f2a6d12867ee57b417e3e941963721Petr Machata		goto done;
9156b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
9166b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	/* We need to install to the next instruction.  ADDR points to
9176b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	 * a store instruction, so moving the breakpoint one
9186b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	 * instruction forward is safe.  */
919bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	arch_addr_t addr = get_instruction_pointer(proc) + 4;
92002a796e5e49c147982020c78b0066930e979f3e4Petr Machata	leader->arch.dl_plt_update_bp = insert_breakpoint_at(proc, addr, NULL);
9218557b4a1a6f2a6d12867ee57b417e3e941963721Petr Machata	if (leader->arch.dl_plt_update_bp == NULL)
9228557b4a1a6f2a6d12867ee57b417e3e941963721Petr Machata		goto done;
9236b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
924b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	static struct bp_callbacks dl_plt_update_cbs = {
925b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata		.on_hit = dl_plt_update_bp_on_hit,
926b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	};
927b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata	leader->arch.dl_plt_update_bp->cbs = &dl_plt_update_cbs;
928b556058c2126fd69dfe03d1187429d98b5636d61Petr Machata
9296b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	/* Turn it off for now.  We will turn it on again when we hit
9306b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	 * the PLT entry that needs this.  */
9316b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	breakpoint_turn_off(leader->arch.dl_plt_update_bp, proc);
9326b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
9338557b4a1a6f2a6d12867ee57b417e3e941963721Petr Machatadone:
9348557b4a1a6f2a6d12867ee57b417e3e941963721Petr Machata	mark_as_resolved(libsym, value);
93558b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata
93658b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	return CBS_STOP;
93758b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata}
93858b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata
939b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machatastatic void
940929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatajump_to_entry_point(struct process *proc, struct breakpoint *bp)
941d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata{
942d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	/* XXX The double cast should be removed when
943bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	 * arch_addr_t becomes integral type.  */
944bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	arch_addr_t rv = (arch_addr_t)
945d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata		(uintptr_t)bp->libsym->arch.resolved_value;
946d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	set_instruction_pointer(proc, rv);
947d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata}
948d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata
949d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machatastatic void
950929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatappc_plt_bp_continue(struct breakpoint *bp, struct process *proc)
951b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata{
95273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	/* If this is a first call through IREL breakpoint, enable the
95373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * symbol so that it doesn't look like an artificial
95473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * breakpoint anymore.  */
95573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	if (bp->libsym == NULL) {
95673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		assert(bp->arch.irel_libsym != NULL);
95773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		bp->libsym = bp->arch.irel_libsym;
95873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		bp->arch.irel_libsym = NULL;
95973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	}
96073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
96158b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	switch (bp->libsym->arch.type) {
962929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata		struct process *leader;
9636b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata		void (*on_all_stopped)(struct process_stopping_handler *);
9646b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata		enum callback_status (*keep_stepping_p)
9656b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata			(struct process_stopping_handler *);
9666b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
9679a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	case PPC_DEFAULT:
9689a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata		assert(proc->e_machine == EM_PPC);
9699a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata		assert(bp->libsym != NULL);
9709a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata		assert(bp->libsym->lib->arch.bss_plt_prelinked == 0);
971b8deb4d589d57c49d510b1b463b3904cb4964557Petr Machata		/* Fall through.  */
9729a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata
97373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	case PPC_PLT_IRELATIVE:
974585f60f7b171a391fbd5149f3d397d192168a67cPetr Machata	case PPC_PLT_UNRESOLVED:
9756b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata		on_all_stopped = NULL;
9766b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata		keep_stepping_p = NULL;
9776b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata		leader = proc->leader;
9786b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
97905058b79e6f995e4d328952ecd73cf090d89cb13Petr Machata		if (leader != NULL && leader->arch.dl_plt_update_bp != NULL
98005058b79e6f995e4d328952ecd73cf090d89cb13Petr Machata		    && breakpoint_turn_on(leader->arch.dl_plt_update_bp,
98105058b79e6f995e4d328952ecd73cf090d89cb13Petr Machata					  proc) >= 0)
9826b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata			on_all_stopped = cb_on_all_stopped;
98305058b79e6f995e4d328952ecd73cf090d89cb13Petr Machata		else
9846b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata			keep_stepping_p = cb_keep_stepping_p;
9856b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
9866b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata		if (process_install_stopping_handler
9876b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata		    (proc, bp, on_all_stopped, keep_stepping_p, NULL) < 0) {
988b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata			fprintf(stderr,	"ppc_plt_bp_continue: "
989b5fd53993b71d0301b3547287f1a978679b21be2Petr Machata				"couldn't install event handler\n");
99058b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata			continue_after_breakpoint(proc, bp);
99158b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata		}
99258b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata		return;
99358b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata
994585f60f7b171a391fbd5149f3d397d192168a67cPetr Machata	case PPC_PLT_RESOLVED:
995f685a3d0b3aaf9cf2bda30937ddc1a55009ee01aPetr Machata		if (proc->e_machine == EM_PPC) {
996f685a3d0b3aaf9cf2bda30937ddc1a55009ee01aPetr Machata			continue_after_breakpoint(proc, bp);
997f685a3d0b3aaf9cf2bda30937ddc1a55009ee01aPetr Machata			return;
998f685a3d0b3aaf9cf2bda30937ddc1a55009ee01aPetr Machata		}
999f685a3d0b3aaf9cf2bda30937ddc1a55009ee01aPetr Machata
1000d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata		jump_to_entry_point(proc, bp);
100158b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata		continue_process(proc->pid);
100250969624d377d485c6d9638a4b00a0b02022d635Petr Machata		return;
100350969624d377d485c6d9638a4b00a0b02022d635Petr Machata
1004585f60f7b171a391fbd5149f3d397d192168a67cPetr Machata	case PPC64_PLT_STUB:
1005a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	case PPC_PLT_NEED_UNRESOLVE:
1006fbd9742d03154ca842eeae8f6a32e35c1e3c8326Petr Machata		/* These should never hit here.  */
100750969624d377d485c6d9638a4b00a0b02022d635Petr Machata		break;
100858b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	}
100950969624d377d485c6d9638a4b00a0b02022d635Petr Machata
101050969624d377d485c6d9638a4b00a0b02022d635Petr Machata	assert(bp->libsym->arch.type != bp->libsym->arch.type);
101150969624d377d485c6d9638a4b00a0b02022d635Petr Machata	abort();
1012b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata}
1013b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
1014d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata/* When a process is in a PLT stub, it may have already read the data
1015d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata * in .plt that we changed.  If we detach now, it will jump to PLT
1016d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata * entry and continue to the dynamic linker, where it will SIGSEGV,
1017d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata * because zeroth .plt slot is not filled in prelinked binaries, and
1018d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata * the dynamic linker needs that data.  Moreover, the process may
1019d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata * actually have hit the breakpoint already.  This functions tries to
1020d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata * detect both cases and do any fix-ups necessary to mend this
1021d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata * situation.  */
1022d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machatastatic enum callback_status
1023929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatadetach_task_cb(struct process *task, void *data)
1024d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata{
1025d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	struct breakpoint *bp = data;
1026d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata
1027d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	if (get_instruction_pointer(task) == bp->addr) {
1028d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata		debug(DEBUG_PROCESS, "%d at %p, which is PLT slot",
1029d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata		      task->pid, bp->addr);
1030d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata		jump_to_entry_point(task, bp);
1031d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata		return CBS_CONT;
1032d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	}
1033917725c482d4857561fbb1e6a9ca8a964549a22bPetr Machata
1034917725c482d4857561fbb1e6a9ca8a964549a22bPetr Machata	/* XXX There's still a window of several instructions where we
1035917725c482d4857561fbb1e6a9ca8a964549a22bPetr Machata	 * might catch the task inside a stub such that it has already
1036917725c482d4857561fbb1e6a9ca8a964549a22bPetr Machata	 * read destination address from .plt, but hasn't jumped yet,
1037917725c482d4857561fbb1e6a9ca8a964549a22bPetr Machata	 * thus avoiding the breakpoint.  */
1038917725c482d4857561fbb1e6a9ca8a964549a22bPetr Machata
1039d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	return CBS_CONT;
1040d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata}
1041d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata
1042d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machatastatic void
1043929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatappc_plt_bp_retract(struct breakpoint *bp, struct process *proc)
1044d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata{
1045d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	/* On PPC64, we rewrite .plt with PLT entry addresses.  This
1046d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	 * needs to be undone.  Unfortunately, the program may have
1047d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	 * made decisions based on that value */
1048d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	if (proc->e_machine == EM_PPC64
1049d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	    && bp->libsym != NULL
1050d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	    && bp->libsym->arch.type == PPC_PLT_RESOLVED) {
1051d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata		each_task(proc->leader, NULL, detach_task_cb, bp);
1052d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata		unresolve_plt_slot(proc, bp->libsym->arch.plt_slot_addr,
1053d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata				   bp->libsym->arch.resolved_value);
1054d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata	}
1055d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata}
1056d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata
1057a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machatastatic void
1058a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machatappc_plt_bp_install(struct breakpoint *bp, struct process *proc)
1059a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata{
1060a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	/* This should not be an artificial breakpoint.  */
1061a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	struct library_symbol *libsym = bp->libsym;
1062a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	if (libsym == NULL)
1063a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		libsym = bp->arch.irel_libsym;
1064a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	assert(libsym != NULL);
1065a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata
1066a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	if (libsym->arch.type == PPC_PLT_NEED_UNRESOLVE) {
1067a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		/* Unresolve the .plt slot.  If the binary was
1068a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * prelinked, this makes the code invalid, because in
1069a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * case of prelinked binary, the dynamic linker
1070a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * doesn't update .plt[0] and .plt[1] with addresses
1071a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * of the resover.  But we don't care, we will never
1072a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * need to enter the resolver.  That just means that
1073a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * we have to un-un-resolve this back before we
1074a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		 * detach.  */
1075a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata
1076a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		struct ppc_unresolve_data *data = libsym->arch.data;
1077a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		libsym->arch.data = NULL;
1078a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		assert(data->self == data);
1079a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata
1080a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		GElf_Addr plt_slot_addr = data->plt_slot_addr;
1081a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		GElf_Addr plt_slot_value = data->plt_slot_value;
1082a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		GElf_Addr plt_entry_addr = data->plt_entry_addr;
1083a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata
1084a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		if (unresolve_plt_slot(proc, plt_slot_addr,
1085a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata				       plt_entry_addr) == 0) {
1086a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata			if (! data->is_irelative) {
1087a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata				mark_as_resolved(libsym, plt_slot_value);
1088a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata			} else {
1089a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata				libsym->arch.type = PPC_PLT_IRELATIVE;
1090a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata				libsym->arch.resolved_value = plt_entry_addr;
1091a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata			}
1092a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		} else {
1093a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata			fprintf(stderr, "Couldn't unresolve %s@%p.  Not tracing"
1094a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata				" this symbol.\n",
1095a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata				breakpoint_name(bp), bp->addr);
1096a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata			proc_remove_breakpoint(proc, bp);
1097a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		}
1098a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata
1099a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		free(data);
1100a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	}
1101a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata}
1102a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata
11037287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machataint
1104d95733284377c0b186ba0c81a1158edc2b913e45Petr Machataarch_library_init(struct library *lib)
1105d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata{
11067287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machata	return 0;
1107d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata}
1108d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata
1109d95733284377c0b186ba0c81a1158edc2b913e45Petr Machatavoid
1110d95733284377c0b186ba0c81a1158edc2b913e45Petr Machataarch_library_destroy(struct library *lib)
1111d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata{
1112d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata}
1113d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata
11147287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machataint
1115d95733284377c0b186ba0c81a1158edc2b913e45Petr Machataarch_library_clone(struct library *retp, struct library *lib)
1116d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata{
11177287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machata	return 0;
1118d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata}
1119d95733284377c0b186ba0c81a1158edc2b913e45Petr Machata
112024c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machataint
112124c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machataarch_library_symbol_init(struct library_symbol *libsym)
112224c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata{
112324c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata	/* We set type explicitly in the code above, where we have the
112424c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata	 * necessary context.  This is for calls from ltrace-elf.c and
112524c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata	 * such.  */
1126fbd9742d03154ca842eeae8f6a32e35c1e3c8326Petr Machata	libsym->arch.type = PPC_DEFAULT;
112724c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata	return 0;
112824c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata}
112924c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata
113024c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machatavoid
113124c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machataarch_library_symbol_destroy(struct library_symbol *libsym)
113224c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata{
1133a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	if (libsym->arch.type == PPC_PLT_NEED_UNRESOLVE) {
1134a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		assert(libsym->arch.data->self == libsym->arch.data);
1135a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		free(libsym->arch.data);
1136a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		libsym->arch.data = NULL;
1137a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata	}
113824c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata}
113924c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata
114024c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machataint
114124c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machataarch_library_symbol_clone(struct library_symbol *retp,
114224c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata			  struct library_symbol *libsym)
114324c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata{
114424c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata	retp->arch = libsym->arch;
114524c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata	return 0;
114624c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata}
114724c6e9daa8d89e13c19fc3f9a475ba7913d7d9c8Petr Machata
114852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata/* For some symbol types, we need to set up custom callbacks.  XXX we
114952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * don't need PROC here, we can store the data in BP if it is of
115052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * interest to us.  */
1151b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machataint
1152929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_breakpoint_init(struct process *proc, struct breakpoint *bp)
1153b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata{
115473b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	bp->arch.irel_libsym = NULL;
115573b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
11569a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	/* Artificial and entry-point breakpoints are plain.  */
11579a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	if (bp->libsym == NULL || bp->libsym->plt_type != LS_TOPLT_EXEC)
11589a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata		return 0;
11599a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata
11609a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	/* On PPC, secure PLT and prelinked BSS PLT are plain.  */
1161b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	if (proc->e_machine == EM_PPC
11629a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	    && bp->libsym->lib->arch.bss_plt_prelinked != 0)
1163052b5f191ec00b7677c43278cb2ce886af1d0ef1Petr Machata		return 0;
1164052b5f191ec00b7677c43278cb2ce886af1d0ef1Petr Machata
11659a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	/* On PPC64, stub PLT breakpoints are plain.  */
11669a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata	if (proc->e_machine == EM_PPC64
1167585f60f7b171a391fbd5149f3d397d192168a67cPetr Machata	    && bp->libsym->arch.type == PPC64_PLT_STUB)
1168b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata		return 0;
1169b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
117058b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	static struct bp_callbacks cbs = {
11719a45d22e3b67a0d611675630cb7cd38e3895a1ffPetr Machata		.on_continue = ppc_plt_bp_continue,
1172d94108be1ae41b0ead839fb01cb0c1fd384ea65fPetr Machata		.on_retract = ppc_plt_bp_retract,
1173a0093ca43cf40d7e5f6cebeb64156062d2de46d9Petr Machata		.on_install = ppc_plt_bp_install,
117458b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	};
117558b2d0fd5deed5f33fbd47a6b6e5c109f43908b5Petr Machata	breakpoint_set_callbacks(bp, &cbs);
117673b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
117773b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	/* For JMP_IREL breakpoints, make the breakpoint look
117873b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	 * artificial by hiding the symbol.  */
117973b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	if (bp->libsym->arch.type == PPC_PLT_IRELATIVE) {
118073b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		bp->arch.irel_libsym = bp->libsym;
118173b85aadbf377541ac336914e5ff8ec521226a97Petr Machata		bp->libsym = NULL;
118273b85aadbf377541ac336914e5ff8ec521226a97Petr Machata	}
118373b85aadbf377541ac336914e5ff8ec521226a97Petr Machata
1184b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata	return 0;
1185b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata}
1186b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata
1187b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machatavoid
1188b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machataarch_breakpoint_destroy(struct breakpoint *bp)
1189b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata{
1190b64b5c7b6f4a368ccaf60507090192845221a3bePetr Machata}
1191d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata
1192d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataint
1193d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataarch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
1194d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{
1195d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	retp->arch = sbp->arch;
1196d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	return 0;
1197d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata}
11986b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
11996b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machataint
1200929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_process_init(struct process *proc)
12016b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata{
12026b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	proc->arch.dl_plt_update_bp = NULL;
12036b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	proc->arch.handler = NULL;
12046b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	return 0;
12056b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata}
12066b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
12076b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machatavoid
1208929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_process_destroy(struct process *proc)
12096b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata{
12106b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata}
12116b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
12126b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machataint
1213929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_process_clone(struct process *retp, struct process *proc)
12146b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata{
12156b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	retp->arch = proc->arch;
121635742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata
121735742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata	if (retp->arch.dl_plt_update_bp != NULL) {
121835742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata		/* Point it to the corresponding breakpoint in RETP.
121935742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata		 * It must be there, this part of PROC has already
122035742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata		 * been cloned to RETP.  */
122135742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata		retp->arch.dl_plt_update_bp
122235742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata			= address2bpstruct(retp,
122335742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata					   retp->arch.dl_plt_update_bp->addr);
122435742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata
122535742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata		assert(retp->arch.dl_plt_update_bp != NULL);
122635742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata	}
122735742523e3daa0e59de0c1c3fdd8e5ff52891967Petr Machata
12286b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	return 0;
12296b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata}
12306b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata
12316b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machataint
1232929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_process_exec(struct process *proc)
12336b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata{
12346b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata	return arch_process_init(proc);
12356b314183200b1462ef4aad6e04fda72f3f6b0d87Petr Machata}
1236