xref: /haiku/src/system/runtime_loader/elf_symbol_lookup.h (revision caed67a8cba83913b9c21ac2b06ebc6bd1cb3111)
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 uint32 elf_gnuhash(const char* name);
21 
22 
23 struct SymbolLookupInfo {
24 	const char*				name;
25 	int32					type;
26 	uint32					hash, gnuhash;
27 	uint32					flags;
28 	const elf_version_info*	version;
29 	elf_sym*				requestingSymbol;
30 
31 	SymbolLookupInfo(const char* name, int32 type,
32 		const elf_version_info* version = NULL, uint32 flags = 0,
33 		elf_sym* requestingSymbol = NULL)
34 		:
35 		name(name),
36 		type(type),
37 		hash(0),
38 		gnuhash(0),
39 		flags(flags),
40 		version(version),
41 		requestingSymbol(requestingSymbol)
42 	{
43 	}
44 };
45 
46 
47 struct SymbolLookupCache {
48 	SymbolLookupCache(image_t* image)
49 		:
50 		fTableSize(image->symhash != NULL ? image->symhash[1] : 0),
51 		fValues(NULL),
52 		fDSOs(NULL),
53 		fValuesResolved(NULL)
54 	{
55 		if (fTableSize > 0) {
56 			fValues = (addr_t*)malloc(sizeof(addr_t) * fTableSize);
57 			fDSOs = (image_t**)malloc(sizeof(image_t*) * fTableSize);
58 
59 			size_t elementCount = (fTableSize + 31) / 32;
60 			fValuesResolved = (uint32*)malloc(4 * elementCount);
61 
62 			if (fValues == NULL || fDSOs == NULL || fValuesResolved == NULL) {
63 				free(fValuesResolved);
64 				fValuesResolved = NULL;
65 				free(fValues);
66 				fValues = NULL;
67 				free(fDSOs);
68 				fDSOs = NULL;
69 				fTableSize = 0;
70 			} else {
71 				memset(fValuesResolved, 0, 4 * elementCount);
72 			}
73 		}
74 	}
75 
76 	~SymbolLookupCache()
77 	{
78 		free(fValuesResolved);
79 		free(fValues);
80 		free(fDSOs);
81 	}
82 
83 	bool IsSymbolValueCached(size_t index) const
84 	{
85 		return index < fTableSize
86 			&& (fValuesResolved[index / 32] & (1 << (index % 32))) != 0;
87 	}
88 
89 	addr_t SymbolValueAt(size_t index) const
90 	{
91 		return fValues[index];
92 	}
93 
94 	addr_t SymbolValueAt(size_t index, image_t** image) const
95 	{
96 		if (image)
97 			*image = fDSOs[index];
98 		return fValues[index];
99 	}
100 
101 	void SetSymbolValueAt(size_t index, addr_t value, image_t* image)
102 	{
103 		if (index < fTableSize) {
104 			fValues[index] = value;
105 			fDSOs[index] = image;
106 			fValuesResolved[index / 32] |= 1 << (index % 32);
107 		}
108 	}
109 
110 private:
111 	size_t		fTableSize;
112 	addr_t*		fValues;
113 	image_t**	fDSOs;
114 	uint32*		fValuesResolved;
115 };
116 
117 
118 void		patch_defined_symbol(image_t* image, const char* name,
119 				void** symbol, int32* type);
120 void		patch_undefined_symbol(image_t* rootImage, image_t* image,
121 				const char* name, image_t** foundInImage, void** symbol,
122 				int32* type);
123 
124 elf_sym*	find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo);
125 status_t	find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo,
126 				void** _location);
127 status_t	find_symbol_breadth_first(image_t* image,
128 				const SymbolLookupInfo& lookupInfo, image_t** _foundInImage,
129 				void** _location);
130 elf_sym*	find_undefined_symbol_beos(image_t* rootImage, image_t* image,
131 				const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
132 elf_sym*	find_undefined_symbol_global(image_t* rootImage, image_t* image,
133 				const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
134 elf_sym*	find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
135 				const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
136 
137 
138 #endif	// ELF_SYMBOL_LOOKUP_H
139