aboutsummaryrefslogtreecommitdiff
path: root/library.h
blob: 876a533b079579e09e6bedd6f90f071d8313bf77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
 * This file is part of ltrace.
 * Copyright (C) 2012 Petr Machata, Red Hat Inc.
 * Copyright (C) 2006 Paul Gilliam
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#ifndef _LIBRARY_H_
#define _LIBRARY_H_

#include <stdint.h>
#include "sysdep.h"

struct Process;
struct library;

enum toplt {
	LS_TOPLT_NONE = 0,	/* PLT not used for this symbol. */
	LS_TOPLT_EXEC,		/* PLT for this symbol is executable. */
};

/* Dict interface.  */
unsigned int target_address_hash(const void *key);
int target_address_cmp(const void *key1, const void *key2);

struct library_symbol {
	struct library_symbol *next;
	struct library *lib;
	const char *name;
	arch_addr_t enter_addr;
	enum toplt plt_type;
	char own_name;
	struct arch_library_symbol_data arch;
};

/* Init LIBSYM.  NAME will be freed when LIBSYM is destroyed if
 * OWN_NAME.  ARCH has to be initialized by a separate call.  */
int library_symbol_init(struct library_symbol *libsym,
			arch_addr_t addr, const char *name, int own_name,
			enum toplt type_of_plt);

/* Copy library symbol SYM into the area pointed-to by RETP.  Return 0
 * on success or a negative value on failure.  */
int library_symbol_clone(struct library_symbol *retp,
			 struct library_symbol *sym);

/* Destroy library symbol.  This essentially just frees name if it's
 * owned.  It doesn't free the memory associated with SYM pointer
 * itself.  Returns 0 on success or a negative value in case of an
 * error (which would be an out of memory condition).  */
void library_symbol_destroy(struct library_symbol *sym);

/* Compare two library symbols.  Returns a negative value, 0, or a
 * positive value, much like strcmp.  The function compares symbol
 * addresses, and if those are equal, it compares symbol names.  If
 * those are equal, too, the symbols are considered equal.  */
int library_symbol_cmp(struct library_symbol *a, struct library_symbol *b);

/* Set a name for library symbol.  This frees the old name, if
 * that is owned.  */
void library_symbol_set_name(struct library_symbol *libsym,
			     const char *name, int own_name);

/* A function that can be used as library_each_symbol callback.  Looks
 * for a symbol SYM for which library_symbol_cmp(SYM, STANDARD)
 * returns 0.  */
enum callback_status library_symbol_equal_cb(struct library_symbol *libsym,
					     void *standard);

enum library_type {
	LT_LIBTYPE_MAIN,
	LT_LIBTYPE_DSO,
};

/* XXX we might consider sharing libraries across processes.  Things
 * like libc will be opened by every single process, no point cloning
 * these everywhere.  But for now, keep the ownership structure
 * simple.  */
struct library {
	struct library *next;

	/* Unique key. Two library objects are considered equal, if
	 * they have the same key.  */
	arch_addr_t key;

	/* Address where the library is mapped.  Two library objects
	 * are considered equal, if they have the same base.  */
	arch_addr_t base;

	/* Absolute address of the entry point.  Useful for main
	 * binary, though I suppose the value might be useful for the
	 * dynamic linker, too (in case we ever want to do early
	 * process tracing).  */
	arch_addr_t entry;

	/* Address of PT_DYNAMIC segment.  */
	arch_addr_t dyn_addr;

	/* Symbols associated with the library.  */
	struct library_symbol *symbols;

	const char *soname;
	const char *pathname;

	enum library_type type;

	char own_soname : 1;
	char own_pathname : 1;

	struct arch_library_data arch;
};

/* Init LIB.  */
void library_init(struct library *lib, enum library_type type);

/* Initialize RETP to a library identical to LIB.  Symbols are not
 * shared, but copied over.  Returns 0 on success and a negative value
 * in case of failure.  */
int library_clone(struct library *retp, struct library *lib);

/* Destroy library.  Doesn't free LIB itself.  Symbols are destroyed
 * and freed.  */
void library_destroy(struct library *lib);

/* Set library soname.  Frees the old name if necessary.  */
void library_set_soname(struct library *lib,
			const char *new_name, int own_name);

/* Set library pathname.  Frees the old name if necessary.  */
void library_set_pathname(struct library *lib,
			  const char *new_name, int own_name);

/* Iterate through list of symbols of library LIB.  Restarts are
 * supported via START_AFTER (see each_process for details of
 * iteration interface).  */
struct library_symbol *library_each_symbol
	(struct library *lib, struct library_symbol *start_after,
	 enum callback_status (*cb)(struct library_symbol *, void *),
	 void *data);

/* Add a new symbol SYM to LIB.  SYM is assumed owned, we need to
 * overwrite SYM->next.  */
void library_add_symbol(struct library *lib, struct library_symbol *sym);

/* A function that can be used as proc_each_library callback.  Looks
 * for a library with the name passed in DATA.  PROC is ignored.  */
enum callback_status library_named_cb(struct Process *proc,
				      struct library *lib, void *name);

/* A function that can be used as proc_each_library callback.  Looks
 * for a library with given base.
 *
 * NOTE: The key is passed as a POINTER to arch_addr_t (that
 * because in general, arch_addr_t doesn't fit in void*).  */
enum callback_status library_with_key_cb(struct Process *proc,
					 struct library *lib, void *keyp);

/* XXX this should really be in backend.h (as on pmachata/revamp
 * branch), or, on this branch, in common.h.  But we need
 * arch_addr_t (which should also be in backend.h, I reckon), so
 * stuff it here for the time being.  */
/* This function is implemented in the back end.  It is called for all
 * raw addresses as read from symbol tables etc.  If necessary on
 * given architecture, this function should translate the address
 * according to .opd or other indirection mechanism.  Returns 0 on
 * success and a negative value on failure.  */
struct ltelf;
int arch_translate_address(struct ltelf *lte,
			   arch_addr_t addr, arch_addr_t *ret);
/* This is the same function as arch_translate_address, except it's
 * used at the point that we don't have ELF available anymore.  */
int arch_translate_address_dyn(struct Process *proc,
			       arch_addr_t addr, arch_addr_t *ret);

#endif /* _LIBRARY_H_ */