1
0

64.xlatetof.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. /*
  2. * 64.xlatetof.c - implementation of the elf64_xlateto[fm](3) functions.
  3. * Copyright (C) 1995 - 2006 Michael Riepe
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Library General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Library General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Library General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  18. */
  19. #include <private.h>
  20. #include <ext_types.h>
  21. #include <byteswap.h>
  22. #if __LIBELF64
  23. #ifndef lint
  24. static const char rcsid[] = "@(#) $Id: 64.xlatetof.c,v 1.27 2008/05/23 08:15:34 michael Exp $";
  25. #endif /* lint */
  26. /*
  27. * Ugly, ugly
  28. */
  29. #ifdef _WIN32
  30. # define Cat2(a,b)a##b
  31. # define Cat3(a,b,c)a##b##c
  32. # define Ex1(m1,m2,a,b)m1##m2(a##b)
  33. # define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
  34. #else /* _WIN32 */
  35. # define x
  36. # if defined/**/x
  37. # define Cat2(a,b)a##b
  38. # define Cat3(a,b,c)a##b##c
  39. # define Ex1(m1,m2,a,b)m1##m2(a##b)
  40. # define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
  41. # else
  42. # define Cat2(a,b)a/**/b
  43. # define Cat3(a,b,c)a/**/b/**/c
  44. # define Ex1(m1,m2,a,b)m1/**/m2(a/**/b)
  45. # define Ex2(m1,m2,a,b,c)m1/**/m2(a,b/**/c)
  46. # endif
  47. # undef x
  48. #endif /* _WIN32 */
  49. /*
  50. * auxiliary macros for execution order reversal
  51. */
  52. #define seq_forw(a,b) a b
  53. #define seq_back(a,b) b a
  54. /*
  55. * function instantiator
  56. */
  57. #define copy_type_e_io(name,e,io,tfrom,tto,copy) \
  58. static size_t \
  59. Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) { \
  60. n /= sizeof(tfrom); \
  61. if (n && dst) { \
  62. const tfrom *from = (const tfrom*)src; \
  63. tto *to = (tto*)dst; \
  64. size_t i; \
  65. \
  66. if (sizeof(tfrom) < sizeof(tto)) { \
  67. from += n; \
  68. to += n; \
  69. for (i = 0; i < n; i++) { \
  70. --from; \
  71. --to; \
  72. copy(e,io,seq_back) \
  73. } \
  74. } \
  75. else { \
  76. for (i = 0; i < n; i++) { \
  77. copy(e,io,seq_forw) \
  78. from++; \
  79. to++; \
  80. } \
  81. } \
  82. } \
  83. return n * sizeof(tto); \
  84. }
  85. #define copy_type_e(name,e,type,copy) \
  86. copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy) \
  87. copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy)
  88. /*
  89. * master function instantiator
  90. */
  91. #define copy_type(name,version,type,copy) \
  92. copy_type_e(Cat3(name,L,version),L,type,copy) \
  93. copy_type_e(Cat3(name,M,version),M,type,copy)
  94. /*
  95. * scalar copying
  96. */
  97. #define copy_scalar_tom(type) *to = Cat2(__load_,type)(*from);
  98. #define copy_scalar_tof(type) Cat2(__store_,type)(*to, *from);
  99. /*
  100. * structure member copying
  101. */
  102. #define copy_tom(mb,type) to->mb = Cat2(__load_,type)(from->mb);
  103. #define copy_tof(mb,type) Cat2(__store_,type)(to->mb, from->mb);
  104. /*
  105. * structure member copying (direction independent)
  106. */
  107. #define copy_byte(e,io,mb) to->mb = from->mb;
  108. #define copy_addr(e,io,mb) Ex2(copy_,io,mb,u64,e)
  109. #define copy_half(e,io,mb) Ex2(copy_,io,mb,u16,e)
  110. #define copy_off(e,io,mb) Ex2(copy_,io,mb,u64,e)
  111. #define copy_sword(e,io,mb) Ex2(copy_,io,mb,i32,e)
  112. #define copy_word(e,io,mb) Ex2(copy_,io,mb,u32,e)
  113. #define copy_sxword(e,io,mb) Ex2(copy_,io,mb,i64,e)
  114. #define copy_xword(e,io,mb) Ex2(copy_,io,mb,u64,e)
  115. #define copy_arr(e,io,mb) \
  116. array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb));
  117. /*
  118. * scalar copying (direction independent)
  119. * these macros are used as `copy' arguments to copy_type()
  120. */
  121. #define copy_addr_11(e,io,seq) Ex1(copy_scalar_,io,u64,e)
  122. #define copy_half_11(e,io,seq) Ex1(copy_scalar_,io,u16,e)
  123. #define copy_off_11(e,io,seq) Ex1(copy_scalar_,io,u64,e)
  124. #define copy_sword_11(e,io,seq) Ex1(copy_scalar_,io,i32,e)
  125. #define copy_word_11(e,io,seq) Ex1(copy_scalar_,io,u32,e)
  126. #define copy_sxword_11(e,io,seq)Ex1(copy_scalar_,io,i64,e)
  127. #define copy_xword_11(e,io,seq) Ex1(copy_scalar_,io,u64,e)
  128. /*
  129. * structure copying (direction independent)
  130. * these macros are used as `copy' arguments to copy_type()
  131. */
  132. #define copy_dyn_11(e,io,seq) \
  133. seq(copy_xword(e,io,d_tag), \
  134. seq(copy_addr(e,io,d_un.d_ptr), \
  135. nullcopy))
  136. #define copy_ehdr_11(e,io,seq) \
  137. seq(copy_arr(e,io,e_ident), \
  138. seq(copy_half(e,io,e_type), \
  139. seq(copy_half(e,io,e_machine), \
  140. seq(copy_word(e,io,e_version), \
  141. seq(copy_addr(e,io,e_entry), \
  142. seq(copy_off(e,io,e_phoff), \
  143. seq(copy_off(e,io,e_shoff), \
  144. seq(copy_word(e,io,e_flags), \
  145. seq(copy_half(e,io,e_ehsize), \
  146. seq(copy_half(e,io,e_phentsize), \
  147. seq(copy_half(e,io,e_phnum), \
  148. seq(copy_half(e,io,e_shentsize), \
  149. seq(copy_half(e,io,e_shnum), \
  150. seq(copy_half(e,io,e_shstrndx), \
  151. nullcopy))))))))))))))
  152. #define copy_phdr_11(e,io,seq) \
  153. seq(copy_word(e,io,p_type), \
  154. seq(copy_word(e,io,p_flags), \
  155. seq(copy_off(e,io,p_offset), \
  156. seq(copy_addr(e,io,p_vaddr), \
  157. seq(copy_addr(e,io,p_paddr), \
  158. seq(copy_xword(e,io,p_filesz), \
  159. seq(copy_xword(e,io,p_memsz), \
  160. seq(copy_xword(e,io,p_align), \
  161. nullcopy))))))))
  162. #if __LIBELF64_IRIX
  163. #define copy_rela_11(e,io,seq) \
  164. seq(copy_addr(e,io,r_offset), \
  165. seq(copy_word(e,io,r_sym), \
  166. seq(copy_byte(e,io,r_ssym), \
  167. seq(copy_byte(e,io,r_type3), \
  168. seq(copy_byte(e,io,r_type2), \
  169. seq(copy_byte(e,io,r_type), \
  170. seq(copy_sxword(e,io,r_addend), \
  171. nullcopy)))))))
  172. #define copy_rel_11(e,io,seq) \
  173. seq(copy_addr(e,io,r_offset), \
  174. seq(copy_word(e,io,r_sym), \
  175. seq(copy_byte(e,io,r_ssym), \
  176. seq(copy_byte(e,io,r_type3), \
  177. seq(copy_byte(e,io,r_type2), \
  178. seq(copy_byte(e,io,r_type), \
  179. nullcopy))))))
  180. #else /* __LIBELF64_IRIX */
  181. #define copy_rela_11(e,io,seq) \
  182. seq(copy_addr(e,io,r_offset), \
  183. seq(copy_xword(e,io,r_info), \
  184. seq(copy_sxword(e,io,r_addend), \
  185. nullcopy)))
  186. #define copy_rel_11(e,io,seq) \
  187. seq(copy_addr(e,io,r_offset), \
  188. seq(copy_xword(e,io,r_info), \
  189. nullcopy))
  190. #endif /* __LIBELF64_IRIX */
  191. #define copy_shdr_11(e,io,seq) \
  192. seq(copy_word(e,io,sh_name), \
  193. seq(copy_word(e,io,sh_type), \
  194. seq(copy_xword(e,io,sh_flags), \
  195. seq(copy_addr(e,io,sh_addr), \
  196. seq(copy_off(e,io,sh_offset), \
  197. seq(copy_xword(e,io,sh_size), \
  198. seq(copy_word(e,io,sh_link), \
  199. seq(copy_word(e,io,sh_info), \
  200. seq(copy_xword(e,io,sh_addralign), \
  201. seq(copy_xword(e,io,sh_entsize), \
  202. nullcopy))))))))))
  203. #define copy_sym_11(e,io,seq) \
  204. seq(copy_word(e,io,st_name), \
  205. seq(copy_byte(e,io,st_info), \
  206. seq(copy_byte(e,io,st_other), \
  207. seq(copy_half(e,io,st_shndx), \
  208. seq(copy_addr(e,io,st_value), \
  209. seq(copy_xword(e,io,st_size), \
  210. nullcopy))))))
  211. #define nullcopy /**/
  212. static size_t
  213. byte_copy(unsigned char *dst, const unsigned char *src, size_t n) {
  214. if (n && dst && dst != src) {
  215. #if HAVE_BROKEN_MEMMOVE
  216. size_t i;
  217. if (dst >= src + n || dst + n <= src) {
  218. memcpy(dst, src, n);
  219. }
  220. else if (dst < src) {
  221. for (i = 0; i < n; i++) {
  222. dst[i] = src[i];
  223. }
  224. }
  225. else {
  226. for (i = n; --i; ) {
  227. dst[i] = src[i];
  228. }
  229. }
  230. #else /* HAVE_BROKEN_MEMMOVE */
  231. memmove(dst, src, n);
  232. #endif /* HAVE_BROKEN_MEMMOVE */
  233. }
  234. return n;
  235. }
  236. static void
  237. array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) {
  238. byte_copy(dst, src, dlen < slen ? dlen : slen);
  239. if (dlen > slen) {
  240. memset(dst + slen, 0, dlen - slen);
  241. }
  242. }
  243. /*
  244. * instantiate copy functions
  245. */
  246. copy_type(addr_64,_,Elf64_Addr,copy_addr_11)
  247. copy_type(half_64,_,Elf64_Half,copy_half_11)
  248. copy_type(off_64,_,Elf64_Off,copy_off_11)
  249. copy_type(sword_64,_,Elf64_Sword,copy_sword_11)
  250. copy_type(word_64,_,Elf64_Word,copy_word_11)
  251. copy_type(sxword_64,_,Elf64_Sxword,copy_sxword_11)
  252. copy_type(xword_64,_,Elf64_Xword,copy_xword_11)
  253. copy_type(dyn_64,11,Elf64_Dyn,copy_dyn_11)
  254. copy_type(ehdr_64,11,Elf64_Ehdr,copy_ehdr_11)
  255. copy_type(phdr_64,11,Elf64_Phdr,copy_phdr_11)
  256. copy_type(rela_64,11,Elf64_Rela,copy_rela_11)
  257. copy_type(rel_64,11,Elf64_Rel,copy_rel_11)
  258. copy_type(shdr_64,11,Elf64_Shdr,copy_shdr_11)
  259. copy_type(sym_64,11,Elf64_Sym,copy_sym_11)
  260. typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t);
  261. typedef xlator xltab[ELF_T_NUM][2];
  262. /*
  263. * translation table (64-bit, version 1 -> version 1)
  264. */
  265. #if PIC
  266. static xltab
  267. #else /* PIC */
  268. static const xltab
  269. #endif /* PIC */
  270. xlate64_11[/*encoding*/] = {
  271. {
  272. { byte_copy, byte_copy },
  273. { addr_64L__tom, addr_64L__tof },
  274. { dyn_64L11_tom, dyn_64L11_tof },
  275. { ehdr_64L11_tom, ehdr_64L11_tof },
  276. { half_64L__tom, half_64L__tof },
  277. { off_64L__tom, off_64L__tof },
  278. { phdr_64L11_tom, phdr_64L11_tof },
  279. { rela_64L11_tom, rela_64L11_tof },
  280. { rel_64L11_tom, rel_64L11_tof },
  281. { shdr_64L11_tom, shdr_64L11_tof },
  282. { sword_64L__tom, sword_64L__tof },
  283. { sym_64L11_tom, sym_64L11_tof },
  284. { word_64L__tom, word_64L__tof },
  285. { sxword_64L__tom, sxword_64L__tof },
  286. { xword_64L__tom, xword_64L__tof },
  287. #if __LIBELF_SYMBOL_VERSIONS
  288. { _elf_verdef_64L11_tom, _elf_verdef_64L11_tof },
  289. { _elf_verneed_64L11_tom, _elf_verneed_64L11_tof },
  290. #else /* __LIBELF_SYMBOL_VERSIONS */
  291. { 0, 0 },
  292. { 0, 0 },
  293. #endif /* __LIBELF_SYMBOL_VERSIONS */
  294. },
  295. {
  296. { byte_copy, byte_copy },
  297. { addr_64M__tom, addr_64M__tof },
  298. { dyn_64M11_tom, dyn_64M11_tof },
  299. { ehdr_64M11_tom, ehdr_64M11_tof },
  300. { half_64M__tom, half_64M__tof },
  301. { off_64M__tom, off_64M__tof },
  302. { phdr_64M11_tom, phdr_64M11_tof },
  303. { rela_64M11_tom, rela_64M11_tof },
  304. { rel_64M11_tom, rel_64M11_tof },
  305. { shdr_64M11_tom, shdr_64M11_tof },
  306. { sword_64M__tom, sword_64M__tof },
  307. { sym_64M11_tom, sym_64M11_tof },
  308. { word_64M__tom, word_64M__tof },
  309. { sxword_64M__tom, sxword_64M__tof },
  310. { xword_64M__tom, xword_64M__tof },
  311. #if __LIBELF_SYMBOL_VERSIONS
  312. { _elf_verdef_64M11_tom, _elf_verdef_64M11_tof },
  313. { _elf_verneed_64M11_tom, _elf_verneed_64M11_tof },
  314. #else /* __LIBELF_SYMBOL_VERSIONS */
  315. { 0, 0 },
  316. { 0, 0 },
  317. #endif /* __LIBELF_SYMBOL_VERSIONS */
  318. },
  319. };
  320. /*
  321. * main translation table (64-bit)
  322. */
  323. #if PIC
  324. static xltab*
  325. #else /* PIC */
  326. static const xltab *const
  327. #endif /* PIC */
  328. xlate64[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = {
  329. { xlate64_11, },
  330. };
  331. #define translator(sv,dv,enc,type,d) \
  332. (xlate64[(sv) - EV_NONE - 1] \
  333. [(dv) - EV_NONE - 1] \
  334. [(enc) - ELFDATA2LSB] \
  335. [(type) - ELF_T_BYTE] \
  336. [d])
  337. /*
  338. * destination buffer size
  339. */
  340. size_t
  341. _elf64_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) {
  342. Elf_Type type = src->d_type;
  343. unsigned sv = src->d_version;
  344. xlator op;
  345. if (!valid_version(sv) || !valid_version(dv)) {
  346. seterr(ERROR_UNKNOWN_VERSION);
  347. return (size_t)-1;
  348. }
  349. if (tof) {
  350. /*
  351. * Encoding doesn't really matter (the translator only looks at
  352. * the source, which resides in memory), but we need a proper
  353. * encoding to select a translator...
  354. */
  355. encode = ELFDATA2LSB;
  356. }
  357. else if (!valid_encoding(encode)) {
  358. seterr(ERROR_UNKNOWN_ENCODING);
  359. return (size_t)-1;
  360. }
  361. if (!valid_type(type)) {
  362. seterr(ERROR_UNKNOWN_TYPE);
  363. return (size_t)-1;
  364. }
  365. if (!(op = translator(sv, dv, encode, type, tof))) {
  366. seterr(ERROR_UNKNOWN_TYPE);
  367. return (size_t)-1;
  368. }
  369. return (*op)(NULL, src->d_buf, src->d_size);
  370. }
  371. /*
  372. * direction-independent translation
  373. */
  374. static Elf_Data*
  375. elf64_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) {
  376. Elf_Type type;
  377. int dv;
  378. int sv;
  379. size_t dsize;
  380. size_t tmp;
  381. xlator op;
  382. if (!src || !dst) {
  383. return NULL;
  384. }
  385. if (!src->d_buf || !dst->d_buf) {
  386. seterr(ERROR_NULLBUF);
  387. return NULL;
  388. }
  389. if (!valid_encoding(encode)) {
  390. seterr(ERROR_UNKNOWN_ENCODING);
  391. return NULL;
  392. }
  393. sv = src->d_version;
  394. dv = dst->d_version;
  395. if (!valid_version(sv) || !valid_version(dv)) {
  396. seterr(ERROR_UNKNOWN_VERSION);
  397. return NULL;
  398. }
  399. type = src->d_type;
  400. if (!valid_type(type)) {
  401. seterr(ERROR_UNKNOWN_TYPE);
  402. return NULL;
  403. }
  404. op = translator(sv, dv, encode, type, tof);
  405. if (!op) {
  406. seterr(ERROR_UNKNOWN_TYPE);
  407. return NULL;
  408. }
  409. dsize = (*op)(NULL, src->d_buf, src->d_size);
  410. if (dsize == (size_t)-1) {
  411. return NULL;
  412. }
  413. if (dst->d_size < dsize) {
  414. seterr(ERROR_DST2SMALL);
  415. return NULL;
  416. }
  417. if (dsize) {
  418. tmp = (*op)(dst->d_buf, src->d_buf, src->d_size);
  419. if (tmp == (size_t)-1) {
  420. return NULL;
  421. }
  422. elf_assert(tmp == dsize);
  423. }
  424. dst->d_size = dsize;
  425. dst->d_type = type;
  426. return dst;
  427. }
  428. /*
  429. * finally, the "official" translation functions
  430. */
  431. Elf_Data*
  432. elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
  433. return elf64_xlate(dst, src, encode, 0);
  434. }
  435. Elf_Data*
  436. elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
  437. return elf64_xlate(dst, src, encode, 1);
  438. }
  439. Elf_Data*
  440. gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) {
  441. if (elf) {
  442. if (elf->e_kind != ELF_K_ELF) {
  443. seterr(ERROR_NOTELF);
  444. }
  445. else if (elf->e_class == ELFCLASS32) {
  446. return elf32_xlatetom(dst, src, encode);
  447. }
  448. else if (elf->e_class == ELFCLASS64) {
  449. return elf64_xlatetom(dst, src, encode);
  450. }
  451. else if (valid_class(elf->e_class)) {
  452. seterr(ERROR_UNIMPLEMENTED);
  453. }
  454. else {
  455. seterr(ERROR_UNKNOWN_CLASS);
  456. }
  457. }
  458. return NULL;
  459. }
  460. Elf_Data*
  461. gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) {
  462. if (elf) {
  463. if (elf->e_kind != ELF_K_ELF) {
  464. seterr(ERROR_NOTELF);
  465. }
  466. else if (elf->e_class == ELFCLASS32) {
  467. return elf32_xlatetof(dst, src, encode);
  468. }
  469. else if (elf->e_class == ELFCLASS64) {
  470. return elf64_xlatetof(dst, src, encode);
  471. }
  472. else if (valid_class(elf->e_class)) {
  473. seterr(ERROR_UNIMPLEMENTED);
  474. }
  475. else {
  476. seterr(ERROR_UNKNOWN_CLASS);
  477. }
  478. }
  479. return NULL;
  480. }
  481. #endif /* __LIBELF64__ */