plt.c revision e99af270a60891e68d465c4cd97dbe29cd1a05e4
1/* 2 * This file is part of ltrace. 3 * Copyright (C) 2008,2009 Juan Cespedes 4 * Copyright (C) 2006 Ian Wienand 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of the 9 * License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 19 * 02110-1301 USA 20 */ 21 22#include <gelf.h> 23 24#include "proc.h" 25#include "common.h" 26#include "library.h" 27 28/* A bundle is 128 bits */ 29#define BUNDLE_SIZE 16 30 31/* 32 33 The PLT has 34 35 ] 3 bundles as a header 36 37 ] The special reserved entry 38 39 ] Following that, each PLT entry has it's initial code that the GOT entry 40 points to. Each PLT entry has one bundle allocated. 41 42 ] Following that, each PLT entry has two bundles of actual PLT code, 43 i.e. load up the address from the GOT and jump to it. This is the 44 point we want to insert the breakpoint, as this will be captured 45 every time we jump to the PLT entry in the code. 46 47*/ 48 49GElf_Addr 50arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { 51 /* Find number of entires by removing header and special 52 * entry, dividing total size by three, since each PLT entry 53 * will have 3 bundles (1 for inital entry and two for the PLT 54 * code). */ 55 int entries = (lte->plt_size - 4 * BUNDLE_SIZE) / (3 * BUNDLE_SIZE); 56 57 /* Now the point we want to break on is the PLT entry after 58 * all the header stuff */ 59 unsigned long addr = 60 lte->plt_addr + (4 * BUNDLE_SIZE) + (BUNDLE_SIZE * entries) + 61 (2 * ndx * BUNDLE_SIZE); 62 debug(3, "Found PLT %zd entry at %lx\n", ndx, addr); 63 64 return addr; 65} 66 67void * 68sym2addr(Process *proc, struct library_symbol *sym) { 69 return sym->enter_addr; 70} 71