PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/netbsd/xsrc/xfree/xc/programs/Xserver/hw/xfree86/loader/hash.c

https://bitbucket.org/killerpenguinassassins/open_distrib_devel
C | 351 lines | 264 code | 47 blank | 40 comment | 43 complexity | 88b688a32deb7136f1debbebb06d2358 MD5 | raw file
Possible License(s): CC0-1.0, MIT, LGPL-2.0, LGPL-3.0, WTFPL, GPL-2.0, BSD-2-Clause, AGPL-3.0, CC-BY-SA-3.0, MPL-2.0, JSON, BSD-3-Clause-No-Nuclear-License-2014, LGPL-2.1, CPL-1.0, AGPL-1.0, 0BSD, ISC, Apache-2.0, GPL-3.0, IPL-1.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. /* $XFree86: xc/programs/Xserver/hw/xfree86/loader/hash.c,v 1.25 2003/11/23 00:57:56 dawes Exp $ */
  2. /*
  3. *
  4. * Copyright 1995-1998 by Metro Link, Inc.
  5. *
  6. * Permission to use, copy, modify, distribute, and sell this software and its
  7. * documentation for any purpose is hereby granted without fee, provided that
  8. * the above copyright notice appear in all copies and that both that
  9. * copyright notice and this permission notice appear in supporting
  10. * documentation, and that the name of Metro Link, Inc. not be used in
  11. * advertising or publicity pertaining to distribution of the software without
  12. * specific, written prior permission. Metro Link, Inc. makes no
  13. * representations about the suitability of this software for any purpose.
  14. * It is provided "as is" without express or implied warranty.
  15. *
  16. * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  17. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  18. * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  19. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  20. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  21. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  22. * PERFORMANCE OF THIS SOFTWARE.
  23. */
  24. #include "os.h"
  25. #include "Xos.h"
  26. #undef abs
  27. #include <stdlib.h>
  28. #include "sym.h"
  29. #include "loader.h"
  30. #include "hash.h"
  31. #if defined(Lynx)
  32. #define MAXINT 32000
  33. #else
  34. #include <limits.h>
  35. #undef MAXINT
  36. #define MAXINT INT_MAX
  37. #endif
  38. /* Prototypes for static functions. */
  39. static unsigned int hashFunc(const char *);
  40. static itemPtr LoaderHashFindNearest(unsigned long);
  41. static itemPtr LoaderhashTable[HASHSIZE];
  42. #ifdef DEBUG
  43. static int hashhits[HASHSIZE];
  44. void
  45. DumpHashHits(void)
  46. {
  47. int i;
  48. int depth = 0;
  49. int dev = 0;
  50. for (i = 0; i < HASHSIZE; i++) {
  51. ErrorF("hashhits[%d]=%d\n", i, hashhits[i]);
  52. depth += hashhits[i];
  53. }
  54. depth /= HASHSIZE;
  55. ErrorF("Average hash depth=%d\n", depth);
  56. for (i = 0; i < HASHSIZE; i++) {
  57. if (hashhits[i] < depth)
  58. dev += depth - hashhits[i];
  59. else
  60. dev += hashhits[i] - depth;
  61. }
  62. dev /= HASHSIZE;
  63. ErrorF("Average hash deviation=%d\n", dev);
  64. }
  65. #endif
  66. static unsigned int
  67. hashFunc(const char *string)
  68. {
  69. int i = 0;
  70. while (i < 10 && string[i])
  71. i++;
  72. if (i < 5) {
  73. #ifdef DEBUG
  74. hashhits[i]++;
  75. #endif
  76. return i;
  77. }
  78. /*
  79. * Original has function
  80. #define HASH ((string[ i-4 ] * string[i-3] + string[i-2] ) & (HASHSIZE-1))
  81. */
  82. #define HASH ((string[i-5] * string[ i-4 ] + string[i-3] * string[i-2] ) & (HASHSIZE-1))
  83. #ifdef DEBUG
  84. hashhits[HASH]++;
  85. #endif
  86. return HASH;
  87. }
  88. void
  89. LoaderHashAdd(itemPtr entry)
  90. {
  91. int bucket = hashFunc(entry->name);
  92. itemPtr oentry;
  93. if ((oentry = LoaderHashFind(entry->name)) != NULL)
  94. LoaderDuplicateSymbol(entry->name, oentry->handle);
  95. entry->next = LoaderhashTable[bucket];
  96. LoaderhashTable[bucket] = entry;
  97. return;
  98. }
  99. void
  100. LoaderAddSymbols(int handle, int module, LOOKUP *list)
  101. {
  102. LOOKUP *l = list, *exports = NULL;
  103. itemPtr i, exportsItem = NULL;
  104. char *modname;
  105. if (!list)
  106. return;
  107. /*
  108. * First look for a symbol called <name>ExportedSymbols. If it exists,
  109. * only export the symbols that are listed in that array. Otherwise
  110. * export all of the external symbols.
  111. */
  112. modname = _LoaderHandleToCanonicalName(handle);
  113. if (modname) {
  114. char *exportname;
  115. exportname = xf86loadermalloc(strlen("ExportedSymbols") +
  116. strlen(modname) + 1);
  117. if (exportname) {
  118. sprintf(exportname, "%sExportedSymbols", modname);
  119. while (l->symName) {
  120. if (strcmp(l->symName, exportname) == 0) {
  121. exports = l;
  122. ErrorF("LoaderAddSymbols: %s: %s found\n", modname,
  123. exportname);
  124. break;
  125. }
  126. l++;
  127. }
  128. xf86loaderfree(exportname);
  129. }
  130. }
  131. /*
  132. * Allocate the exports list item first.
  133. */
  134. if (exports) {
  135. exportsItem = xf86loadermalloc(sizeof(itemRec));
  136. exportsItem->name = exports->symName;
  137. exportsItem->address = (char *)exports->offset;
  138. exportsItem->handle = handle;
  139. exportsItem->module = module;
  140. exportsItem->exports = NULL;
  141. LoaderHashAdd(exportsItem);
  142. }
  143. /*
  144. * Visit every symbol in the lookup table, tagging it with the
  145. * reference to the export list, if present.
  146. */
  147. l = list;
  148. while (l->symName) {
  149. if (l != exports) {
  150. i = xf86loadermalloc(sizeof(itemRec));
  151. i->name = l->symName;
  152. i->address = (char *)l->offset;
  153. i->handle = handle;
  154. i->module = module;
  155. i->exports = exportsItem;
  156. LoaderHashAdd(i);
  157. }
  158. l++;
  159. }
  160. }
  161. itemPtr
  162. LoaderHashDelete(const char *string)
  163. {
  164. int bucket = hashFunc(string);
  165. itemPtr entry;
  166. itemPtr *entry2;
  167. entry = LoaderhashTable[bucket];
  168. entry2 = &(LoaderhashTable[bucket]);
  169. while (entry) {
  170. if (!strcmp(entry->name, string)) {
  171. *entry2 = entry->next;
  172. xf86loaderfree(entry->name);
  173. xf86loaderfree(entry);
  174. return 0;
  175. }
  176. entry2 = &(entry->next);
  177. entry = entry->next;
  178. }
  179. return 0;
  180. }
  181. itemPtr
  182. LoaderHashFind(const char *string)
  183. {
  184. int bucket = hashFunc(string);
  185. itemPtr entry;
  186. entry = LoaderhashTable[bucket];
  187. while (entry) {
  188. if (!strcmp(entry->name, string)) {
  189. return entry;
  190. }
  191. entry = entry->next;
  192. }
  193. return 0;
  194. }
  195. static itemPtr
  196. LoaderHashFindNearest(unsigned long address)
  197. {
  198. int i;
  199. itemPtr entry, best_entry = 0;
  200. long best_difference = MAXINT;
  201. for (i = 0; i < HASHSIZE; i++) {
  202. entry = LoaderhashTable[i];
  203. while (entry) {
  204. long difference = (long)address - (long)entry->address;
  205. if (difference >= 0) {
  206. if (best_entry) {
  207. if (difference < best_difference) {
  208. best_entry = entry;
  209. best_difference = difference;
  210. }
  211. } else {
  212. best_entry = entry;
  213. best_difference = difference;
  214. }
  215. }
  216. entry = entry->next;
  217. }
  218. }
  219. return best_entry;
  220. }
  221. void
  222. LoaderPrintSymbol(unsigned long address)
  223. {
  224. itemPtr entry;
  225. entry = LoaderHashFindNearest(address);
  226. if (entry) {
  227. const char *module, *section;
  228. #if defined(__alpha__) || defined(__ia64__)
  229. ErrorF("0x%016lx %s+%lx\n", (unsigned long)entry->address,
  230. entry->name, address - (unsigned long)entry->address);
  231. #else
  232. ErrorF("0x%lx %s+%lx\n", (unsigned long)entry->address, entry->name,
  233. address - (unsigned long)entry->address);
  234. #endif
  235. if (_LoaderAddressToSection(address, &module, &section))
  236. ErrorF("\tModule \"%s\"\n\tSection \"%s\"\n", module, section);
  237. } else {
  238. ErrorF("(null)\n");
  239. }
  240. }
  241. void
  242. LoaderPrintItem(itemPtr pItem)
  243. {
  244. if (pItem) {
  245. const char *module, *section;
  246. #if defined(__alpha__) || defined(__ia64__)
  247. ErrorF("0x%016lx %s\n", (unsigned long)pItem->address, pItem->name);
  248. #else
  249. ErrorF("0x%lx %s\n", (unsigned long)pItem->address, pItem->name);
  250. #endif
  251. if (_LoaderAddressToSection((unsigned long)pItem->address,
  252. &module, &section))
  253. ErrorF("\tModule \"%s\"\n\tSection \"%s\"\n", module, section);
  254. } else
  255. ErrorF("(null)\n");
  256. }
  257. void
  258. LoaderPrintAddress(const char *symbol)
  259. {
  260. itemPtr entry;
  261. entry = LoaderHashFind(symbol);
  262. LoaderPrintItem(entry);
  263. }
  264. void
  265. LoaderHashTraverse(void *card, int (*fnp)(void *, itemPtr))
  266. {
  267. int i;
  268. itemPtr entry, last_entry = 0;
  269. for (i = 0; i < HASHSIZE; i++) {
  270. last_entry = 0;
  271. entry = LoaderhashTable[i];
  272. while (entry) {
  273. if ((*fnp) (card, entry)) {
  274. if (last_entry) {
  275. last_entry->next = entry->next;
  276. xf86loaderfree(entry->name);
  277. xf86loaderfree(entry);
  278. entry = last_entry->next;
  279. } else {
  280. LoaderhashTable[i] = entry->next;
  281. xf86loaderfree(entry->name);
  282. xf86loaderfree(entry);
  283. entry = LoaderhashTable[i];
  284. }
  285. } else {
  286. last_entry = entry;
  287. entry = entry->next;
  288. }
  289. }
  290. }
  291. }
  292. void
  293. LoaderDumpSymbols()
  294. {
  295. itemPtr entry;
  296. int j;
  297. for (j = 0; j < HASHSIZE; j++) {
  298. entry = LoaderhashTable[j];
  299. while (entry) {
  300. LoaderPrintItem(entry);
  301. entry = entry->next;
  302. }
  303. }
  304. }