gelftrans.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. /*
  2. gelftrans.c - gelf_* translation functions.
  3. Copyright (C) 2000 - 2001 Michael Riepe
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  15. */
  16. #include <private.h>
  17. #if __LIBELF64
  18. #ifndef lint
  19. static const char rcsid[] = "@(#) $Id: gelftrans.c,v 1.10 2008/05/23 08:15:34 michael Exp $";
  20. #endif /* lint */
  21. #define check_and_copy(type, d, s, name, eret) \
  22. do { \
  23. if (sizeof((d)->name) < sizeof((s)->name) \
  24. && (type)(s)->name != (s)->name) { \
  25. seterr(ERROR_BADVALUE); \
  26. return (eret); \
  27. } \
  28. (d)->name = (type)(s)->name; \
  29. } while (0)
  30. /*
  31. * These macros are missing on some Linux systems
  32. */
  33. #if !defined(ELF32_R_SYM) || !defined(ELF32_R_TYPE) || !defined(ELF32_R_INFO)
  34. # undef ELF32_R_SYM
  35. # undef ELF32_R_TYPE
  36. # undef ELF32_R_INFO
  37. # define ELF32_R_SYM(i) ((i)>>8)
  38. # define ELF32_R_TYPE(i) ((unsigned char)(i))
  39. # define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t))
  40. #endif /* !defined(...) */
  41. #if !defined(ELF64_R_SYM) || !defined(ELF64_R_TYPE) || !defined(ELF64_R_INFO)
  42. # undef ELF64_R_SYM
  43. # undef ELF64_R_TYPE
  44. # undef ELF64_R_INFO
  45. # define ELF64_R_SYM(i) ((i)>>32)
  46. # define ELF64_R_TYPE(i) ((i)&0xffffffffL)
  47. # define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL))
  48. #endif /* !defined(...) */
  49. static char*
  50. get_addr_and_class(const Elf_Data *data, int ndx, Elf_Type type, unsigned *cls) {
  51. Scn_Data *sd = (Scn_Data*)data;
  52. Elf_Scn *scn;
  53. Elf *elf;
  54. size_t n;
  55. if (!sd) {
  56. return NULL;
  57. }
  58. elf_assert(sd->sd_magic == DATA_MAGIC);
  59. scn = sd->sd_scn;
  60. elf_assert(scn);
  61. elf_assert(scn->s_magic == SCN_MAGIC);
  62. elf = scn->s_elf;
  63. elf_assert(elf);
  64. elf_assert(elf->e_magic == ELF_MAGIC);
  65. if (elf->e_kind != ELF_K_ELF) {
  66. seterr(ERROR_NOTELF);
  67. return NULL;
  68. }
  69. if (!valid_class(elf->e_class)) {
  70. seterr(ERROR_UNKNOWN_CLASS);
  71. return NULL;
  72. }
  73. if (data->d_type != type) {
  74. seterr(ERROR_BADTYPE);
  75. return NULL;
  76. }
  77. n = _msize(elf->e_class, data->d_version, type);
  78. if (n == 0) {
  79. seterr(ERROR_UNIMPLEMENTED);
  80. return NULL;
  81. }
  82. if (ndx < 0 || data->d_size < (ndx + 1) * n) {
  83. seterr(ERROR_BADINDEX);
  84. return NULL;
  85. }
  86. if (!data->d_buf) {
  87. seterr(ERROR_NULLBUF);
  88. return NULL;
  89. }
  90. if (cls) {
  91. *cls = elf->e_class;
  92. }
  93. return (char*)data->d_buf + n * ndx;
  94. }
  95. GElf_Sym*
  96. gelf_getsym(Elf_Data *src, int ndx, GElf_Sym *dst) {
  97. GElf_Sym buf;
  98. unsigned cls;
  99. char *tmp;
  100. if (!dst) {
  101. dst = &buf;
  102. }
  103. tmp = get_addr_and_class(src, ndx, ELF_T_SYM, &cls);
  104. if (!tmp) {
  105. return NULL;
  106. }
  107. if (cls == ELFCLASS64) {
  108. *dst = *(Elf64_Sym*)tmp;
  109. }
  110. else if (cls == ELFCLASS32) {
  111. Elf32_Sym *src = (Elf32_Sym*)tmp;
  112. check_and_copy(GElf_Word, dst, src, st_name, NULL);
  113. check_and_copy(unsigned char, dst, src, st_info, NULL);
  114. check_and_copy(unsigned char, dst, src, st_other, NULL);
  115. check_and_copy(GElf_Half, dst, src, st_shndx, NULL);
  116. check_and_copy(GElf_Addr, dst, src, st_value, NULL);
  117. check_and_copy(GElf_Xword, dst, src, st_size, NULL);
  118. }
  119. else {
  120. seterr(ERROR_UNIMPLEMENTED);
  121. return NULL;
  122. }
  123. if (dst == &buf) {
  124. dst = (GElf_Sym*)malloc(sizeof(GElf_Sym));
  125. if (!dst) {
  126. seterr(ERROR_MEM_SYM);
  127. return NULL;
  128. }
  129. *dst = buf;
  130. }
  131. return dst;
  132. }
  133. int
  134. gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src) {
  135. unsigned cls;
  136. char *tmp;
  137. tmp = get_addr_and_class(dst, ndx, ELF_T_SYM, &cls);
  138. if (!tmp) {
  139. return 0;
  140. }
  141. if (cls == ELFCLASS64) {
  142. *(Elf64_Sym*)tmp = *src;
  143. }
  144. else if (cls == ELFCLASS32) {
  145. Elf32_Sym *dst = (Elf32_Sym*)tmp;
  146. check_and_copy(Elf32_Word, dst, src, st_name, 0);
  147. check_and_copy(Elf32_Addr, dst, src, st_value, 0);
  148. check_and_copy(Elf32_Word, dst, src, st_size, 0);
  149. check_and_copy(unsigned char, dst, src, st_info, 0);
  150. check_and_copy(unsigned char, dst, src, st_other, 0);
  151. check_and_copy(Elf32_Half, dst, src, st_shndx, 0);
  152. }
  153. else {
  154. seterr(ERROR_UNIMPLEMENTED);
  155. return 0;
  156. }
  157. return 1;
  158. }
  159. GElf_Dyn*
  160. gelf_getdyn(Elf_Data *src, int ndx, GElf_Dyn *dst) {
  161. GElf_Dyn buf;
  162. unsigned cls;
  163. char *tmp;
  164. if (!dst) {
  165. dst = &buf;
  166. }
  167. tmp = get_addr_and_class(src, ndx, ELF_T_DYN, &cls);
  168. if (!tmp) {
  169. return NULL;
  170. }
  171. if (cls == ELFCLASS64) {
  172. *dst = *(Elf64_Dyn*)tmp;
  173. }
  174. else if (cls == ELFCLASS32) {
  175. Elf32_Dyn *src = (Elf32_Dyn*)tmp;
  176. check_and_copy(GElf_Sxword, dst, src, d_tag, NULL);
  177. check_and_copy(GElf_Xword, dst, src, d_un.d_val, NULL);
  178. }
  179. else {
  180. seterr(ERROR_UNIMPLEMENTED);
  181. return NULL;
  182. }
  183. if (dst == &buf) {
  184. dst = (GElf_Dyn*)malloc(sizeof(GElf_Dyn));
  185. if (!dst) {
  186. seterr(ERROR_MEM_DYN);
  187. return NULL;
  188. }
  189. *dst = buf;
  190. }
  191. return dst;
  192. }
  193. int
  194. gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src) {
  195. unsigned cls;
  196. char *tmp;
  197. tmp = get_addr_and_class(dst, ndx, ELF_T_DYN, &cls);
  198. if (!tmp) {
  199. return 0;
  200. }
  201. if (cls == ELFCLASS64) {
  202. *(Elf64_Dyn*)tmp = *src;
  203. }
  204. else if (cls == ELFCLASS32) {
  205. Elf32_Dyn *dst = (Elf32_Dyn*)tmp;
  206. check_and_copy(Elf32_Sword, dst, src, d_tag, 0);
  207. check_and_copy(Elf32_Word, dst, src, d_un.d_val, 0);
  208. }
  209. else {
  210. seterr(ERROR_UNIMPLEMENTED);
  211. return 0;
  212. }
  213. return 1;
  214. }
  215. GElf_Rela*
  216. gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst) {
  217. GElf_Rela buf;
  218. unsigned cls;
  219. char *tmp;
  220. if (!dst) {
  221. dst = &buf;
  222. }
  223. tmp = get_addr_and_class(src, ndx, ELF_T_RELA, &cls);
  224. if (!tmp) {
  225. return NULL;
  226. }
  227. if (cls == ELFCLASS64) {
  228. *dst = *(Elf64_Rela*)tmp;
  229. }
  230. else if (cls == ELFCLASS32) {
  231. Elf32_Rela *src = (Elf32_Rela*)tmp;
  232. check_and_copy(GElf_Addr, dst, src, r_offset, NULL);
  233. dst->r_info = ELF64_R_INFO((Elf64_Xword)ELF32_R_SYM(src->r_info),
  234. (Elf64_Xword)ELF32_R_TYPE(src->r_info));
  235. check_and_copy(GElf_Sxword, dst, src, r_addend, NULL);
  236. }
  237. else {
  238. seterr(ERROR_UNIMPLEMENTED);
  239. return NULL;
  240. }
  241. if (dst == &buf) {
  242. dst = (GElf_Rela*)malloc(sizeof(GElf_Rela));
  243. if (!dst) {
  244. seterr(ERROR_MEM_RELA);
  245. return NULL;
  246. }
  247. *dst = buf;
  248. }
  249. return dst;
  250. }
  251. int
  252. gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src) {
  253. unsigned cls;
  254. char *tmp;
  255. tmp = get_addr_and_class(dst, ndx, ELF_T_RELA, &cls);
  256. if (!tmp) {
  257. return 0;
  258. }
  259. if (cls == ELFCLASS64) {
  260. *(Elf64_Rela*)tmp = *src;
  261. }
  262. else if (cls == ELFCLASS32) {
  263. Elf32_Rela *dst = (Elf32_Rela*)tmp;
  264. check_and_copy(Elf32_Addr, dst, src, r_offset, 0);
  265. if (ELF64_R_SYM(src->r_info) > 0xffffffUL
  266. || ELF64_R_TYPE(src->r_info) > 0xffUL) {
  267. seterr(ERROR_BADVALUE);
  268. return 0;
  269. }
  270. dst->r_info = ELF32_R_INFO((Elf32_Word)ELF64_R_SYM(src->r_info),
  271. (Elf32_Word)ELF64_R_TYPE(src->r_info));
  272. check_and_copy(Elf32_Sword, dst, src, r_addend, 0);
  273. }
  274. else {
  275. seterr(ERROR_UNIMPLEMENTED);
  276. return 0;
  277. }
  278. return 1;
  279. }
  280. GElf_Rel*
  281. gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst) {
  282. GElf_Rel buf;
  283. unsigned cls;
  284. char *tmp;
  285. if (!dst) {
  286. dst = &buf;
  287. }
  288. tmp = get_addr_and_class(src, ndx, ELF_T_REL, &cls);
  289. if (!tmp) {
  290. return NULL;
  291. }
  292. if (cls == ELFCLASS64) {
  293. *dst = *(Elf64_Rel*)tmp;
  294. }
  295. else if (cls == ELFCLASS32) {
  296. Elf32_Rel *src = (Elf32_Rel*)tmp;
  297. check_and_copy(GElf_Addr, dst, src, r_offset, NULL);
  298. dst->r_info = ELF64_R_INFO((Elf64_Xword)ELF32_R_SYM(src->r_info),
  299. (Elf64_Xword)ELF32_R_TYPE(src->r_info));
  300. }
  301. else {
  302. seterr(ERROR_UNIMPLEMENTED);
  303. return NULL;
  304. }
  305. if (dst == &buf) {
  306. dst = (GElf_Rel*)malloc(sizeof(GElf_Rel));
  307. if (!dst) {
  308. seterr(ERROR_MEM_REL);
  309. return NULL;
  310. }
  311. *dst = buf;
  312. }
  313. return dst;
  314. }
  315. int
  316. gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src) {
  317. unsigned cls;
  318. char *tmp;
  319. tmp = get_addr_and_class(dst, ndx, ELF_T_REL, &cls);
  320. if (!tmp) {
  321. return 0;
  322. }
  323. if (cls == ELFCLASS64) {
  324. *(Elf64_Rel*)tmp = *src;
  325. }
  326. else if (cls == ELFCLASS32) {
  327. Elf32_Rel *dst = (Elf32_Rel*)tmp;
  328. check_and_copy(Elf32_Addr, dst, src, r_offset, 0);
  329. if (ELF64_R_SYM(src->r_info) > 0xffffffUL
  330. || ELF64_R_TYPE(src->r_info) > 0xffUL) {
  331. seterr(ERROR_BADVALUE);
  332. return 0;
  333. }
  334. dst->r_info = ELF32_R_INFO((Elf32_Word)ELF64_R_SYM(src->r_info),
  335. (Elf32_Word)ELF64_R_TYPE(src->r_info));
  336. }
  337. else {
  338. seterr(ERROR_UNIMPLEMENTED);
  339. return 0;
  340. }
  341. return 1;
  342. }
  343. #if 0
  344. GElf_Syminfo*
  345. gelf_getsyminfo(Elf_Data *src, int ndx, GElf_Syminfo *dst) {
  346. seterr(ERROR_UNIMPLEMENTED);
  347. return NULL;
  348. }
  349. int
  350. gelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src) {
  351. seterr(ERROR_UNIMPLEMENTED);
  352. return 0;
  353. }
  354. GElf_Move*
  355. gelf_getmove(Elf_Data *src, int ndx, GElf_Move *src) {
  356. seterr(ERROR_UNIMPLEMENTED);
  357. return NULL;
  358. }
  359. int
  360. gelf_update_move(Elf_Data *dst, int ndx, GElf_Move *src) {
  361. seterr(ERROR_UNIMPLEMENTED);
  362. return 0;
  363. }
  364. #endif
  365. #endif /* __LIBELF64 */