1e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata/*
2e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This file is part of ltrace.
399b19eb1bb736d7066026894aa69e70de8a03094Petr Machata * Copyright (C) 2006,2010,2012,2013 Petr Machata, Red Hat Inc.
4e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2010 Zachary T Welch
5e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2001,2004,2007,2009 Juan Cespedes
6e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2006 Ian Wienand
7e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
8e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is free software; you can redistribute it and/or
9e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * modify it under the terms of the GNU General Public License as
10e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * published by the Free Software Foundation; either version 2 of the
11e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * License, or (at your option) any later version.
12e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
13e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is distributed in the hope that it will be useful, but
14e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of
15e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * General Public License for more details.
17e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
18e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * You should have received a copy of the GNU General Public License
19e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * along with this program; if not, write to the Free Software
20e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 02110-1301 USA
22e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata */
23e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata
241cd999a32728f41208dc30f38a125d7bb7063625Juan Cespedes#ifndef LTRACE_ELF_H
251cd999a32728f41208dc30f38a125d7bb7063625Juan Cespedes#define LTRACE_ELF_H
261cd999a32728f41208dc30f38a125d7bb7063625Juan Cespedes
27d914a206a11cc1011a45f00674b1e16988fae77fJuan Cespedes#include <gelf.h>
28d914a206a11cc1011a45f00674b1e16988fae77fJuan Cespedes#include <stdlib.h>
297a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata#include <callback.h>
30e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
31929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata#include "forward.h"
32929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata#include "sysdep.h"
33673ff510953b65b844a58478aa434120f457c014Petr Machata#include "vect.h"
342b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata
352b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata/* XXX Ok, the original idea was to separate the low-level ELF data
362b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata * from the abstract "struct library" object, but we use some of the
372b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata * following extensively in the back end.  Not all though.  So what we
382b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata * use should be move to struct library, and the rest of this
392b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata * structure maybe could be safely hidden in .c.  How to integrate the
402b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata * arch-specific bits into struct library is unclear as of now.  */
412d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienandstruct ltelf {
422d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	int fd;
432d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	Elf *elf;
442d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	GElf_Ehdr ehdr;
452d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	Elf_Data *dynsym;
462d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	size_t dynsym_count;
472d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	const char *dynstr;
482d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	GElf_Addr plt_addr;
4918c801c3f29081d9de517815df89bc1bbf8e2188Petr Machata	GElf_Word plt_flags;
502d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	size_t plt_size;
51e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	Elf_Data *plt_data;
52673ff510953b65b844a58478aa434120f457c014Petr Machata
53673ff510953b65b844a58478aa434120f457c014Petr Machata	/* Vector of GElf_Rela with PLT relocations.  */
54673ff510953b65b844a58478aa434120f457c014Petr Machata	struct vect plt_relocs;
55673ff510953b65b844a58478aa434120f457c014Petr Machata
562d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	Elf_Data *symtab;
572d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	const char *strtab;
582b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	const char *soname;
592d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	size_t symtab_count;
602d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	Elf_Data *opd;
612d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	GElf_Addr *opd_addr;
622d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	size_t opd_size;
6387f4f58320226cd20d317f488c7e6a92a3efa2ddJoe Damato	GElf_Addr dyn_addr;
6487f4f58320226cd20d317f488c7e6a92a3efa2ddJoe Damato	size_t dyn_sz;
6529add4fdf852b10ddd22cac0d1390f6d01577bc2Petr Machata	GElf_Addr bias;
662b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	GElf_Addr entry_addr;
6729add4fdf852b10ddd22cac0d1390f6d01577bc2Petr Machata	GElf_Addr base_addr;
68e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata	struct arch_ltelf_data arch;
691cd999a32728f41208dc30f38a125d7bb7063625Juan Cespedes};
701cd999a32728f41208dc30f38a125d7bb7063625Juan Cespedes
71673ff510953b65b844a58478aa434120f457c014Petr Machataint ltelf_init(struct ltelf *lte, const char *filename);
72673ff510953b65b844a58478aa434120f457c014Petr Machatavoid ltelf_destroy(struct ltelf *lte);
731cd999a32728f41208dc30f38a125d7bb7063625Juan Cespedes
742b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata/* XXX is it possible to put breakpoints in VDSO and VSYSCALL
752b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata * pseudo-libraries?  For now we assume that all libraries can be
762b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata * opened via a filesystem.  BASE is ignored for ET_EXEC files.  */
77929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataint ltelf_read_library(struct library *lib, struct process *proc,
78b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		       const char *filename, GElf_Addr bias);
79d914a206a11cc1011a45f00674b1e16988fae77fJuan Cespedes
802b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata/* Create a library object representing the main binary.  The entry
812b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata * point address is stored to *ENTRYP.  */
82929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatastruct library *ltelf_read_main_binary(struct process *proc, const char *path);
8396935a9fe2af57e089cbd2e32a69caba5b3f2458Juan Cespedes
8497d13666cd84589135ba593fa43a800d098026d0Petr Machata/* This is called for every PLT relocation R in ELF file LTE, that
8597d13666cd84589135ba593fa43a800d098026d0Petr Machata * ltrace is about to add to a library constructed in process PROC.
8697d13666cd84589135ba593fa43a800d098026d0Petr Machata * The corresponding PLT entry is for symbol called NAME, and it's
8797d13666cd84589135ba593fa43a800d098026d0Petr Machata * I-th relocation in the file.  *RET shall be initialized and
8897d13666cd84589135ba593fa43a800d098026d0Petr Machata * symbol(s) corresponding to the given PLT entry will be added to the
8997d13666cd84589135ba593fa43a800d098026d0Petr Machata * front.  Returns 0 for success, or a negative value for failures.
9097d13666cd84589135ba593fa43a800d098026d0Petr Machata *
9197d13666cd84589135ba593fa43a800d098026d0Petr Machata * This calls os_elf_add_plt_entry and arch_elf_add_plt_entry in the
9297d13666cd84589135ba593fa43a800d098026d0Petr Machata * background (see backend.h for documentation).  The arch callback is
9397d13666cd84589135ba593fa43a800d098026d0Petr Machata * called first.  If it returns PLT_DEFAULT, the os callback is called
9497d13666cd84589135ba593fa43a800d098026d0Petr Machata * next.  If that returns PLT_DEFAULT, default_elf_add_plt_entry is
9597d13666cd84589135ba593fa43a800d098026d0Petr Machata * called.  */
9697d13666cd84589135ba593fa43a800d098026d0Petr Machataint elf_add_plt_entry(struct process *proc, struct ltelf *lte,
9797d13666cd84589135ba593fa43a800d098026d0Petr Machata		      const char *name, GElf_Rela *rela, size_t idx,
9897d13666cd84589135ba593fa43a800d098026d0Petr Machata		      struct library_symbol **ret);
9997d13666cd84589135ba593fa43a800d098026d0Petr Machata
1006db61f509eb7537ca64873b0c8c1955e2293db9fPetr Machata/* Create a default PLT entry.  This can be used instead (or in
101ade3b9798fbc62becbe1b4854f7a2d106498167aPetr Machata * addition to) returning PLT_DEFAULT from arch_elf_add_plt_entry.
1026db61f509eb7537ca64873b0c8c1955e2293db9fPetr Machata * RET shall be initialized, the created symbol will be added to the
1036db61f509eb7537ca64873b0c8c1955e2293db9fPetr Machata * beginning of the linked list at *RET.  This function doesn't add
1046db61f509eb7537ca64873b0c8c1955e2293db9fPetr Machata * the symbol to LTE.  arch_elf_add_plt_entry has the chance to adjust
105ade3b9798fbc62becbe1b4854f7a2d106498167aPetr Machata * symbol internals to its liking, and then return either PLT_DEFAULT
106ade3b9798fbc62becbe1b4854f7a2d106498167aPetr Machata * or PLT_OK.  */
107929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataint default_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
1086db61f509eb7537ca64873b0c8c1955e2293db9fPetr Machata			      const char *a_name, GElf_Rela *rela, size_t ndx,
1096db61f509eb7537ca64873b0c8c1955e2293db9fPetr Machata			      struct library_symbol **ret);
1106db61f509eb7537ca64873b0c8c1955e2293db9fPetr Machata
111e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr MachataElf_Data *elf_loaddata(Elf_Scn *scn, GElf_Shdr *shdr);
11299b19eb1bb736d7066026894aa69e70de8a03094Petr Machata
11399b19eb1bb736d7066026894aa69e70de8a03094Petr Machata/* The following three look for sections based on various criteria.
11499b19eb1bb736d7066026894aa69e70de8a03094Petr Machata * They return 0 if there was no error, or a negative value if there
11599b19eb1bb736d7066026894aa69e70de8a03094Petr Machata * was.  If the section was found, it is returned in *TGT_SEC, and the
116a9a12bdd7d73c01d5ee88aed7e34bf2a9772e94dPetr Machata * header is stored to TGT_SHDR.  If it wasn't found, *TGT_SEC is set
11799b19eb1bb736d7066026894aa69e70de8a03094Petr Machata * to NULL.  */
118e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machataint elf_get_section_covering(struct ltelf *lte, GElf_Addr addr,
119e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata			     Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr);
120ffd5aab0bddbbb7c650c2f5c12a48e0298f82516Petr Machataint elf_get_section_type(struct ltelf *lte, GElf_Word type,
121ffd5aab0bddbbb7c650c2f5c12a48e0298f82516Petr Machata			 Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr);
1225b3e26acd50d74e8b7c007f8b5dfb1a825ef9affPetr Machataint elf_get_section_named(struct ltelf *lte, const char *name,
1235b3e26acd50d74e8b7c007f8b5dfb1a825ef9affPetr Machata			  Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr);
124e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
1257a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata/* Iterate through all symbols in LTE.  See callback.h for notes on
1267a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata * iteration interfaces.  START_AFTER is 0 in initial call.  */
1277a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machatastruct elf_each_symbol_t {
1287a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata	unsigned restart;
1297a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata	int status;
1307a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata} elf_each_symbol(struct ltelf *lte, unsigned start_after,
1317a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata		  enum callback_status (*cb)(GElf_Sym *symbol,
1327a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata					     const char *name,
1337a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata					     void *data),
1347a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata		  void *data);
1357a29f9e7a2bd5849886519eb82e9c043d24c6a40Petr Machata
1360ed5399f5cbb2b505a95bcac634c0ad5d7bbd6b8Petr Machata/* Read relocations from relocation section SCN with header SHDR and
1370ed5399f5cbb2b505a95bcac634c0ad5d7bbd6b8Petr Machata * add them to RELA_VEC, which is a vector of GElf_Rela.  Return 0 on
1380ed5399f5cbb2b505a95bcac634c0ad5d7bbd6b8Petr Machata * success, or a negative value on failure.  */
1390ed5399f5cbb2b505a95bcac634c0ad5d7bbd6b8Petr Machataint elf_read_relocs(struct ltelf *lte, Elf_Scn *scn, GElf_Shdr *shdr,
1400ed5399f5cbb2b505a95bcac634c0ad5d7bbd6b8Petr Machata		    struct vect *rela_vec);
1410ed5399f5cbb2b505a95bcac634c0ad5d7bbd6b8Petr Machata
1424f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machata/* Read a given DT_ TAG from LTE.  Value is returned in *VALUEP.
1434f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machata * Returns 0 on success or a negative value on failure.  */
1444f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machataint elf_load_dynamic_entry(struct ltelf *lte, int tag, GElf_Addr *valuep);
1454f2f66e6abc7fedf3a5d04fab7cc00e5f82b37cfPetr Machata
1463c636fb789a29cac0c8f7f0982fb17afeee489dcPetr Machata/* Read, respectively, 1, 2, 4, or 8 bytes from Elf data at given
1473c636fb789a29cac0c8f7f0982fb17afeee489dcPetr Machata * OFFSET, and store it in *RETP.  Returns 0 on success or a negative
1483c636fb789a29cac0c8f7f0982fb17afeee489dcPetr Machata * value if there's not enough data.  */
1493c636fb789a29cac0c8f7f0982fb17afeee489dcPetr Machataint elf_read_u8(Elf_Data *data, GElf_Xword offset, uint8_t *retp);
1503a01cd7a2fcf200cedd0770e137a28764f679c3cPetr Machataint elf_read_u16(Elf_Data *data, GElf_Xword offset, uint16_t *retp);
1513a01cd7a2fcf200cedd0770e137a28764f679c3cPetr Machataint elf_read_u32(Elf_Data *data, GElf_Xword offset, uint32_t *retp);
1523a01cd7a2fcf200cedd0770e137a28764f679c3cPetr Machataint elf_read_u64(Elf_Data *data, GElf_Xword offset, uint64_t *retp);
153e67635d6dcecb0f44448a5329d69fd0de74ebabaPetr Machata
154184779e4e8a42f2e9e7f3cee4bf4eb31e8c84ee4Petr Machata/* Read at most 64-bit quantity recorded in an ULEB128 variable-length
155184779e4e8a42f2e9e7f3cee4bf4eb31e8c84ee4Petr Machata * encoding.  */
156184779e4e8a42f2e9e7f3cee4bf4eb31e8c84ee4Petr Machataint elf_read_uleb128(Elf_Data *data, GElf_Xword offset, uint64_t *retp);
157184779e4e8a42f2e9e7f3cee4bf4eb31e8c84ee4Petr Machata
158439ab5bfac8588e52c77e22c96fb397787512d0ePetr Machata/* These are same as above, but update *OFFSET with the width
159439ab5bfac8588e52c77e22c96fb397787512d0ePetr Machata * of read datum.  */
160439ab5bfac8588e52c77e22c96fb397787512d0ePetr Machataint elf_read_next_u8(Elf_Data *data, GElf_Xword *offset, uint8_t *retp);
161439ab5bfac8588e52c77e22c96fb397787512d0ePetr Machataint elf_read_next_u16(Elf_Data *data, GElf_Xword *offset, uint16_t *retp);
162439ab5bfac8588e52c77e22c96fb397787512d0ePetr Machataint elf_read_next_u32(Elf_Data *data, GElf_Xword *offset, uint32_t *retp);
163439ab5bfac8588e52c77e22c96fb397787512d0ePetr Machataint elf_read_next_u64(Elf_Data *data, GElf_Xword *offset, uint64_t *retp);
164184779e4e8a42f2e9e7f3cee4bf4eb31e8c84ee4Petr Machataint elf_read_next_uleb128(Elf_Data *data, GElf_Xword *offset, uint64_t *retp);
165439ab5bfac8588e52c77e22c96fb397787512d0ePetr Machata
1665c37171a18bddfbc716d4f3da8b008a844eea4f7Petr Machata/* Return whether there's AMOUNT more bytes after OFFSET in DATA.  */
1675c37171a18bddfbc716d4f3da8b008a844eea4f7Petr Machataint elf_can_read_next(Elf_Data *data, GElf_Xword offset, GElf_Xword amount);
1685c37171a18bddfbc716d4f3da8b008a844eea4f7Petr Machata
1693ba522fed3d34f476090da9349be96e15e0652cbZachary T Welch#if __WORDSIZE == 32
1703ba522fed3d34f476090da9349be96e15e0652cbZachary T Welch#define PRI_ELF_ADDR		PRIx32
1713ba522fed3d34f476090da9349be96e15e0652cbZachary T Welch#define GELF_ADDR_CAST(x)	(void *)(uint32_t)(x)
1723ba522fed3d34f476090da9349be96e15e0652cbZachary T Welch#else
1733ba522fed3d34f476090da9349be96e15e0652cbZachary T Welch#define PRI_ELF_ADDR		PRIx64
1743ba522fed3d34f476090da9349be96e15e0652cbZachary T Welch#define GELF_ADDR_CAST(x)	(void *)(x)
1753ba522fed3d34f476090da9349be96e15e0652cbZachary T Welch#endif
1763ba522fed3d34f476090da9349be96e15e0652cbZachary T Welch
1771cd999a32728f41208dc30f38a125d7bb7063625Juan Cespedes#endif
178