diff options
author | Petr Machata <pmachata@redhat.com> | 2013-10-15 13:54:55 +0200 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2013-10-23 01:00:03 +0200 |
commit | 1e4b8c8d93606721c8728c6cacb8c9921353049b (patch) | |
tree | 83ff546ae54b8e5ec249a42c40950fcfb14a01bf /sysdeps | |
parent | b420a226cd2fc5d6028adcaf236c512a1f1fb437 (diff) | |
download | ltrace-1e4b8c8d93606721c8728c6cacb8c9921353049b.tar.gz |
Enable IRELATIVE tracing on x86 and x86_64
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/linux-gnu/x86/arch.h | 4 | ||||
-rw-r--r-- | sysdeps/linux-gnu/x86/plt.c | 30 |
2 files changed, 32 insertions, 2 deletions
diff --git a/sysdeps/linux-gnu/x86/arch.h b/sysdeps/linux-gnu/x86/arch.h index 329cfba..da5bd33 100644 --- a/sysdeps/linux-gnu/x86/arch.h +++ b/sysdeps/linux-gnu/x86/arch.h @@ -1,6 +1,6 @@ /* * This file is part of ltrace. - * Copyright (C) 2011, 2012 Petr Machata + * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc. * Copyright (C) 2006 Ian Wienand * Copyright (C) 2004 Juan Cespedes * @@ -28,6 +28,8 @@ #define ARCH_HAVE_ALIGNOF #define ARCH_ENDIAN_LITTLE +#define ARCH_HAVE_ADD_PLT_ENTRY + #ifdef __x86_64__ #define LT_ELFCLASS ELFCLASS64 #define LT_ELF_MACHINE EM_X86_64 diff --git a/sysdeps/linux-gnu/x86/plt.c b/sysdeps/linux-gnu/x86/plt.c index c2a4151..6d11987 100644 --- a/sysdeps/linux-gnu/x86/plt.c +++ b/sysdeps/linux-gnu/x86/plt.c @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 2004,2008,2009 Juan Cespedes * * This program is free software; you can redistribute it and/or @@ -19,12 +20,15 @@ */ #include <gelf.h> +#include <stdbool.h> + #include "proc.h" #include "common.h" #include "library.h" +#include "trace.h" GElf_Addr -arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) +arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) { return lte->plt_addr + (ndx + 1) * 16; } @@ -34,3 +38,27 @@ sym2addr(struct process *proc, struct library_symbol *sym) { return sym->enter_addr; } + +enum plt_status +arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte, + const char *a_name, GElf_Rela *rela, size_t ndx, + struct library_symbol **ret) +{ + bool irelative = false; + if (lte->ehdr.e_machine == EM_X86_64) { +#ifdef R_X86_64_IRELATIVE + irelative = GELF_R_TYPE(rela->r_info) == R_X86_64_IRELATIVE; +#endif + } else { + assert(lte->ehdr.e_machine == EM_386); +#ifdef R_386_IRELATIVE + irelative = GELF_R_TYPE(rela->r_info) == R_386_IRELATIVE; +#endif + } + + if (irelative) + return linux_elf_add_plt_entry_irelative(proc, lte, rela, + ndx, ret); + + return PLT_DEFAULT; +} |