32and64bit.patch 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. Upstream-Status: Inappropriate [embedded specific]
  2. We run the ldconfig in the cross fashion. make the code bitsize aware so that
  3. we can cross build ldconfig cache for various architectures.
  4. Richard Purdie <richard.purdie@linuxfoundation.org> 2009/05/19
  5. Nitin A Kamble <nitin.a.kamble@intel.com> 2009/03/29
  6. Index: ldconfig-native-2.12.1/readelflib.c
  7. ===================================================================
  8. --- ldconfig-native-2.12.1.orig/readelflib.c
  9. +++ ldconfig-native-2.12.1/readelflib.c
  10. @@ -40,39 +40,212 @@ do \
  11. /* Returns 0 if everything is ok, != 0 in case of error. */
  12. int
  13. -process_elf_file (const char *file_name, const char *lib, int *flag,
  14. +process_elf_file32 (const char *file_name, const char *lib, int *flag,
  15. unsigned int *osversion, char **soname, void *file_contents,
  16. size_t file_length)
  17. {
  18. int i;
  19. unsigned int j;
  20. - ElfW(Addr) loadaddr;
  21. + Elf32_Addr loadaddr;
  22. unsigned int dynamic_addr;
  23. size_t dynamic_size;
  24. char *program_interpreter;
  25. - ElfW(Ehdr) *elf_header;
  26. - ElfW(Phdr) *elf_pheader, *segment;
  27. - ElfW(Dyn) *dynamic_segment, *dyn_entry;
  28. + Elf32_Ehdr *elf_header;
  29. + Elf32_Phdr *elf_pheader, *segment;
  30. + Elf32_Dyn *dynamic_segment, *dyn_entry;
  31. char *dynamic_strings;
  32. - elf_header = (ElfW(Ehdr) *) file_contents;
  33. + elf_header = (Elf32_Ehdr *) file_contents;
  34. *osversion = 0;
  35. - if (elf_header->e_ident [EI_CLASS] != ElfW (CLASS))
  36. + if (elf_header->e_type != ET_DYN)
  37. {
  38. - if (opt_verbose)
  39. + error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name,
  40. + elf_header->e_type);
  41. + return 1;
  42. + }
  43. +
  44. + /* Get information from elf program header. */
  45. + elf_pheader = (Elf32_Phdr *) (elf_header->e_phoff + file_contents);
  46. + check_ptr (elf_pheader);
  47. +
  48. + /* The library is an elf library, now search for soname and
  49. + libc5/libc6. */
  50. + *flag = FLAG_ELF;
  51. +
  52. + loadaddr = -1;
  53. + dynamic_addr = 0;
  54. + dynamic_size = 0;
  55. + program_interpreter = NULL;
  56. + for (i = 0, segment = elf_pheader;
  57. + i < elf_header->e_phnum; i++, segment++)
  58. + {
  59. + check_ptr (segment);
  60. +
  61. + switch (segment->p_type)
  62. {
  63. - if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
  64. - error (0, 0, _("%s is a 32 bit ELF file.\n"), file_name);
  65. - else if (elf_header->e_ident [EI_CLASS] == ELFCLASS64)
  66. - error (0, 0, _("%s is a 64 bit ELF file.\n"), file_name);
  67. - else
  68. - error (0, 0, _("Unknown ELFCLASS in file %s.\n"), file_name);
  69. + case PT_LOAD:
  70. + if (loadaddr == (Elf32_Addr) -1)
  71. + loadaddr = segment->p_vaddr - segment->p_offset;
  72. + break;
  73. +
  74. + case PT_DYNAMIC:
  75. + if (dynamic_addr)
  76. + error (0, 0, _("more than one dynamic segment\n"));
  77. +
  78. + dynamic_addr = segment->p_offset;
  79. + dynamic_size = segment->p_filesz;
  80. + break;
  81. +
  82. + case PT_INTERP:
  83. + program_interpreter = (char *) (file_contents + segment->p_offset);
  84. + check_ptr (program_interpreter);
  85. +
  86. + /* Check if this is enough to classify the binary. */
  87. + for (j = 0; j < sizeof (interpreters) / sizeof (interpreters [0]);
  88. + ++j)
  89. + if (strcmp (program_interpreter, interpreters[j].soname) == 0)
  90. + {
  91. + *flag = interpreters[j].flag;
  92. + break;
  93. + }
  94. + break;
  95. +
  96. + case PT_NOTE:
  97. + if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4)
  98. + {
  99. + Elf32_Word *abi_note = (Elf32_Word *) (file_contents
  100. + + segment->p_offset);
  101. + Elf32_Addr size = segment->p_filesz;
  102. +
  103. + while (abi_note [0] != 4 || abi_note [1] != 16
  104. + || abi_note [2] != 1
  105. + || memcmp (abi_note + 3, "GNU", 4) != 0)
  106. + {
  107. +#define ROUND(len) (((len) + sizeof (Elf32_Word)) - 1) & -sizeof (Elf32_Word)))
  108. + Elf32_Addr) note_size = 3 * sizeof (Elf32_Word))
  109. + + ROUND (abi_note[0])
  110. + + ROUND (abi_note[1]);
  111. +
  112. + if (size - 32 < note_size || note_size == 0)
  113. + {
  114. + size = 0;
  115. + break;
  116. + }
  117. + size -= note_size;
  118. + abi_note = (void *) abi_note + note_size;
  119. + }
  120. +
  121. + if (size == 0)
  122. + break;
  123. +
  124. + *osversion = (abi_note [4] << 24) |
  125. + ((abi_note [5] & 0xff) << 16) |
  126. + ((abi_note [6] & 0xff) << 8) |
  127. + (abi_note [7] & 0xff);
  128. + }
  129. + break;
  130. +
  131. + default:
  132. + break;
  133. + }
  134. +
  135. + }
  136. + if (loadaddr == (Elf32_Addr) -1)
  137. + {
  138. + /* Very strange. */
  139. + loadaddr = 0;
  140. + }
  141. +
  142. + /* Now we can read the dynamic sections. */
  143. + if (dynamic_size == 0)
  144. + return 1;
  145. +
  146. + dynamic_segment = (Elf32_Dyn *) (file_contents + dynamic_addr);
  147. + check_ptr (dynamic_segment);
  148. +
  149. + /* Find the string table. */
  150. + dynamic_strings = NULL;
  151. + for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
  152. + ++dyn_entry)
  153. + {
  154. + check_ptr (dyn_entry);
  155. + if (dyn_entry->d_tag == DT_STRTAB)
  156. + {
  157. + dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
  158. + check_ptr (dynamic_strings);
  159. + break;
  160. }
  161. - return 1;
  162. }
  163. + if (dynamic_strings == NULL)
  164. + return 1;
  165. +
  166. + /* Now read the DT_NEEDED and DT_SONAME entries. */
  167. + for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
  168. + ++dyn_entry)
  169. + {
  170. + if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME)
  171. + {
  172. + char *name = dynamic_strings + dyn_entry->d_un.d_val;
  173. + check_ptr (name);
  174. +
  175. + if (dyn_entry->d_tag == DT_NEEDED)
  176. + {
  177. +
  178. + if (*flag == FLAG_ELF)
  179. + {
  180. + /* Check if this is enough to classify the binary. */
  181. + for (j = 0;
  182. + j < sizeof (known_libs) / sizeof (known_libs [0]);
  183. + ++j)
  184. + if (strcmp (name, known_libs [j].soname) == 0)
  185. + {
  186. + *flag = known_libs [j].flag;
  187. + break;
  188. + }
  189. + }
  190. + }
  191. +
  192. + else if (dyn_entry->d_tag == DT_SONAME)
  193. + *soname = xstrdup (name);
  194. +
  195. + /* Do we have everything we need? */
  196. + if (*soname && *flag != FLAG_ELF)
  197. + return 0;
  198. + }
  199. + }
  200. +
  201. + /* We reach this point only if the file doesn't contain a DT_SONAME
  202. + or if we can't classify the library. If it doesn't have a
  203. + soname, return the name of the library. */
  204. + if (*soname == NULL)
  205. + *soname = xstrdup (lib);
  206. +
  207. + return 0;
  208. +}
  209. +
  210. +int
  211. +process_elf_file64 (const char *file_name, const char *lib, int *flag,
  212. + unsigned int *osversion, char **soname, void *file_contents,
  213. + size_t file_length)
  214. +{
  215. + int i;
  216. + unsigned int j;
  217. + Elf64_Addr loadaddr;
  218. + unsigned int dynamic_addr;
  219. + size_t dynamic_size;
  220. + char *program_interpreter;
  221. +
  222. + Elf64_Ehdr *elf_header;
  223. + Elf64_Phdr *elf_pheader, *segment;
  224. + Elf64_Dyn *dynamic_segment, *dyn_entry;
  225. + char *dynamic_strings;
  226. +
  227. + elf_header = (Elf64_Ehdr *) file_contents;
  228. + *osversion = 0;
  229. +
  230. if (elf_header->e_type != ET_DYN)
  231. {
  232. error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name,
  233. @@ -81,7 +254,7 @@ process_elf_file (const char *file_name,
  234. }
  235. /* Get information from elf program header. */
  236. - elf_pheader = (ElfW(Phdr) *) (elf_header->e_phoff + file_contents);
  237. + elf_pheader = (Elf64_Phdr *) (elf_header->e_phoff + file_contents);
  238. check_ptr (elf_pheader);
  239. /* The library is an elf library, now search for soname and
  240. @@ -100,7 +273,7 @@ process_elf_file (const char *file_name,
  241. switch (segment->p_type)
  242. {
  243. case PT_LOAD:
  244. - if (loadaddr == (ElfW(Addr)) -1)
  245. + if (loadaddr == (Elf64_Addr) -1)
  246. loadaddr = segment->p_vaddr - segment->p_offset;
  247. break;
  248. @@ -129,16 +302,16 @@ process_elf_file (const char *file_name,
  249. case PT_NOTE:
  250. if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4)
  251. {
  252. - ElfW(Word) *abi_note = (ElfW(Word) *) (file_contents
  253. + Elf64_Word *abi_note = (Elf64_Word *) (file_contents
  254. + segment->p_offset);
  255. - ElfW(Addr) size = segment->p_filesz;
  256. + Elf64_Addr size = segment->p_filesz;
  257. while (abi_note [0] != 4 || abi_note [1] != 16
  258. || abi_note [2] != 1
  259. || memcmp (abi_note + 3, "GNU", 4) != 0)
  260. {
  261. -#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
  262. - ElfW(Addr) note_size = 3 * sizeof (ElfW(Word))
  263. +#define ROUND(len) (((len) + sizeof (Elf64_Word) - 1) & -sizeof (Elf64_Word))
  264. + Elf64_Addr note_size = 3 * sizeof (Elf64_Word)
  265. + ROUND (abi_note[0])
  266. + ROUND (abi_note[1]);
  267. @@ -166,7 +339,7 @@ process_elf_file (const char *file_name,
  268. }
  269. }
  270. - if (loadaddr == (ElfW(Addr)) -1)
  271. + if (loadaddr == (Elf64_Addr) -1)
  272. {
  273. /* Very strange. */
  274. loadaddr = 0;
  275. @@ -176,7 +349,7 @@ process_elf_file (const char *file_name,
  276. if (dynamic_size == 0)
  277. return 1;
  278. - dynamic_segment = (ElfW(Dyn) *) (file_contents + dynamic_addr);
  279. + dynamic_segment = (Elf64_Dyn *) (file_contents + dynamic_addr);
  280. check_ptr (dynamic_segment);
  281. /* Find the string table. */
  282. @@ -233,3 +406,33 @@ process_elf_file (const char *file_name,
  283. return 0;
  284. }
  285. +/* Returns 0 if everything is ok, != 0 in case of error. */
  286. +int
  287. +process_elf_file (const char *file_name, const char *lib, int *flag,
  288. + unsigned int *osversion, char **soname, void *file_contents,
  289. + size_t file_length)
  290. +{
  291. + int i;
  292. + unsigned int j;
  293. + ElfW(Addr) loadaddr;
  294. + unsigned int dynamic_addr;
  295. + size_t dynamic_size;
  296. + char *program_interpreter;
  297. +
  298. + ElfW(Ehdr) *elf_header;
  299. + ElfW(Phdr) *elf_pheader, *segment;
  300. + ElfW(Dyn) *dynamic_segment, *dyn_entry;
  301. + char *dynamic_strings;
  302. +
  303. + elf_header = (ElfW(Ehdr) *) file_contents;
  304. + *osversion = 0;
  305. +
  306. + if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
  307. + return process_elf_file32(file_name, lib,flag, osversion, soname, file_contents, file_length);
  308. + else if (elf_header->e_ident [EI_CLASS] == ELFCLASS64)
  309. + return process_elf_file64(file_name, lib,flag, osversion, soname, file_contents, file_length);
  310. + error (0, 0, _("Unknown ELFCLASS in file %s.\n"), file_name);
  311. + return 1;
  312. +}
  313. +
  314. +