xref: /haiku/src/system/runtime_loader/elf_symbol_lookup.h (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 /*
2  * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef ELF_SYMBOL_LOOKUP_H
6 #define ELF_SYMBOL_LOOKUP_H
7 
8 
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include <runtime_loader.h>
13 
14 
15 // values for SymbolLookupInfo::flags
16 #define LOOKUP_FLAG_DEFAULT_VERSION	0x01
17 
18 
19 uint32 elf_hash(const char* name);
20 
21 
22 struct SymbolLookupInfo {
23 	const char*				name;
24 	int32					type;
25 	uint32					hash;
26 	uint32					flags;
27 	const elf_version_info*	version;
28 	elf_sym*				requestingSymbol;
29 
30 	SymbolLookupInfo(const char* name, int32 type, uint32 hash,
31 		const elf_version_info* version = NULL, uint32 flags = 0,
32 		elf_sym* requestingSymbol = NULL)
33 		:
34 		name(name),
35 		type(type),
36 		hash(hash),
37 		flags(flags),
38 		version(version),
39 		requestingSymbol(requestingSymbol)
40 	{
41 	}
42 
43 	SymbolLookupInfo(const char* name, int32 type,
44 		const elf_version_info* version = NULL, uint32 flags = 0,
45 		elf_sym* requestingSymbol = NULL)
46 		:
47 		name(name),
48 		type(type),
49 		hash(elf_hash(name)),
50 		flags(flags),
51 		version(version),
52 		requestingSymbol(requestingSymbol)
53 	{
54 	}
55 };
56 
57 
58 struct SymbolLookupCache {
59 	SymbolLookupCache(image_t* image)
60 		:
61 		fTableSize(image->symhash != NULL ? image->symhash[1] : 0),
62 		fValues(NULL),
63 		fDSOs(NULL),
64 		fValuesResolved(NULL)
65 	{
66 		if (fTableSize > 0) {
67 			fValues = (addr_t*)malloc(sizeof(addr_t) * fTableSize);
68 			fDSOs = (image_t**)malloc(sizeof(image_t*) * fTableSize);
69 
70 			size_t elementCount = (fTableSize + 31) / 32;
71 			fValuesResolved = (uint32*)malloc(4 * elementCount);
72 
73 			if (fValues == NULL || fDSOs == NULL || fValuesResolved == NULL) {
74 				free(fValuesResolved);
75 				fValuesResolved = NULL;
76 				free(fValues);
77 				fValues = NULL;
78 				free(fDSOs);
79 				fDSOs = NULL;
80 				fTableSize = 0;
81 			} else {
82 				memset(fValuesResolved, 0, 4 * elementCount);
83 			}
84 		}
85 	}
86 
87 	~SymbolLookupCache()
88 	{
89 		free(fValuesResolved);
90 		free(fValues);
91 		free(fDSOs);
92 	}
93 
94 	bool IsSymbolValueCached(size_t index) const
95 	{
96 		return index < fTableSize
97 			&& (fValuesResolved[index / 32] & (1 << (index % 32))) != 0;
98 	}
99 
100 	addr_t SymbolValueAt(size_t index) const
101 	{
102 		return fValues[index];
103 	}
104 
105 	addr_t SymbolValueAt(size_t index, image_t** image) const
106 	{
107 		if (image)
108 			*image = fDSOs[index];
109 		return fValues[index];
110 	}
111 
112 	void SetSymbolValueAt(size_t index, addr_t value, image_t* image)
113 	{
114 		if (index < fTableSize) {
115 			fValues[index] = value;
116 			fDSOs[index] = image;
117 			fValuesResolved[index / 32] |= 1 << (index % 32);
118 		}
119 	}
120 
121 private:
122 	size_t		fTableSize;
123 	addr_t*		fValues;
124 	image_t**	fDSOs;
125 	uint32*		fValuesResolved;
126 };
127 
128 
129 void		patch_defined_symbol(image_t* image, const char* name,
130 				void** symbol, int32* type);
131 void		patch_undefined_symbol(image_t* rootImage, image_t* image,
132 				const char* name, image_t** foundInImage, void** symbol,
133 				int32* type);
134 
135 elf_sym*	find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo,
136 				bool allowLocal = false);
137 status_t	find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo,
138 				void** _location);
139 status_t	find_symbol_breadth_first(image_t* image,
140 				const SymbolLookupInfo& lookupInfo, image_t** _foundInImage,
141 				void** _location);
142 elf_sym*	find_undefined_symbol_beos(image_t* rootImage, image_t* image,
143 				const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
144 elf_sym*	find_undefined_symbol_global(image_t* rootImage, image_t* image,
145 				const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
146 elf_sym*	find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
147 				const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
148 
149 
150 #endif	// ELF_SYMBOL_LOOKUP_H
151