update.c 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. /*
  2. * update.c - implementation of the elf_update(3) function.
  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. #ifndef lint
  21. static const char rcsid[] = "@(#) $Id: update.c,v 1.34 2009/05/22 17:08:09 michael Exp $";
  22. #endif /* lint */
  23. #include <errno.h>
  24. #if HAVE_MMAP
  25. #include <sys/mman.h>
  26. #endif /* HAVE_MMAP */
  27. static const unsigned short __encoding = ELFDATA2LSB + (ELFDATA2MSB << 8);
  28. #define native_encoding (*(unsigned char*)&__encoding)
  29. #define rewrite(var,val,f) \
  30. do{if((var)!=(val)){(var)=(val);(f)|=ELF_F_DIRTY;}}while(0)
  31. #define align(var,val) \
  32. do{if((val)>1){(var)+=(val)-1;(var)-=(var)%(val);}}while(0)
  33. #undef max
  34. #define max(a,b) ((a)>(b)?(a):(b))
  35. static off_t
  36. scn_data_layout(Elf_Scn *scn, unsigned v, unsigned type, size_t *algn, unsigned *flag) {
  37. Elf *elf = scn->s_elf;
  38. Elf_Data *data;
  39. int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
  40. size_t scn_align = 1;
  41. size_t len = 0;
  42. Scn_Data *sd;
  43. size_t fsize;
  44. if (!(sd = scn->s_data_1)) {
  45. /* no data in section */
  46. *algn = scn_align;
  47. return (off_t)len;
  48. }
  49. /* load data from file, if any */
  50. if (!(data = elf_getdata(scn, NULL))) {
  51. return (off_t)-1;
  52. }
  53. elf_assert(data == &sd->sd_data);
  54. for (; sd; sd = sd->sd_link) {
  55. elf_assert(sd->sd_magic == DATA_MAGIC);
  56. elf_assert(sd->sd_scn == scn);
  57. if (!valid_version(sd->sd_data.d_version)) {
  58. return (off_t)-1;
  59. }
  60. fsize = sd->sd_data.d_size;
  61. if (fsize && type != SHT_NOBITS && valid_type(sd->sd_data.d_type)) {
  62. if (elf->e_class == ELFCLASS32) {
  63. fsize = _elf32_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1);
  64. }
  65. #if __LIBELF64
  66. else if (elf->e_class == ELFCLASS64) {
  67. fsize = _elf64_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1);
  68. }
  69. #endif /* __LIBELF64 */
  70. else {
  71. elf_assert(valid_class(elf->e_class));
  72. seterr(ERROR_UNIMPLEMENTED);
  73. return (off_t)-1;
  74. }
  75. if (fsize == (size_t)-1) {
  76. return (off_t)-1;
  77. }
  78. }
  79. if (layout) {
  80. align(len, sd->sd_data.d_align);
  81. scn_align = max(scn_align, sd->sd_data.d_align);
  82. rewrite(sd->sd_data.d_off, (off_t)len, sd->sd_data_flags);
  83. len += fsize;
  84. }
  85. else {
  86. len = max(len, sd->sd_data.d_off + fsize);
  87. }
  88. *flag |= sd->sd_data_flags;
  89. }
  90. *algn = scn_align;
  91. return (off_t)len;
  92. }
  93. static size_t
  94. scn_entsize(const Elf *elf, unsigned version, unsigned stype) {
  95. Elf_Type type;
  96. switch ((type = _elf_scn_type(stype))) {
  97. case ELF_T_BYTE:
  98. return 0;
  99. case ELF_T_VDEF:
  100. case ELF_T_VNEED:
  101. return 0; /* What else can I do? Thank you, Sun! */
  102. default:
  103. return _fsize(elf->e_class, version, type);
  104. }
  105. }
  106. static off_t
  107. _elf32_layout(Elf *elf, unsigned *flag) {
  108. int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
  109. int allow_overlap = (elf->e_elf_flags & ELF_F_LAYOUT_OVERLAP) != 0;
  110. Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf->e_ehdr;
  111. size_t off = 0;
  112. unsigned version;
  113. unsigned encoding;
  114. size_t align_addr;
  115. size_t entsize;
  116. unsigned phnum;
  117. unsigned shnum;
  118. Elf_Scn *scn;
  119. *flag = elf->e_elf_flags | elf->e_phdr_flags;
  120. if ((version = ehdr->e_version) == EV_NONE) {
  121. version = EV_CURRENT;
  122. }
  123. if (!valid_version(version)) {
  124. seterr(ERROR_UNKNOWN_VERSION);
  125. return -1;
  126. }
  127. if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) {
  128. encoding = native_encoding;
  129. }
  130. if (!valid_encoding(encoding)) {
  131. seterr(ERROR_UNKNOWN_ENCODING);
  132. return -1;
  133. }
  134. entsize = _fsize(ELFCLASS32, version, ELF_T_EHDR);
  135. elf_assert(entsize);
  136. rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags);
  137. off = entsize;
  138. align_addr = _fsize(ELFCLASS32, version, ELF_T_ADDR);
  139. elf_assert(align_addr);
  140. if ((phnum = elf->e_phnum)) {
  141. entsize = _fsize(ELFCLASS32, version, ELF_T_PHDR);
  142. elf_assert(entsize);
  143. if (layout) {
  144. align(off, align_addr);
  145. rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags);
  146. off += phnum * entsize;
  147. }
  148. else {
  149. off = max(off, ehdr->e_phoff + phnum * entsize);
  150. }
  151. }
  152. else {
  153. entsize = 0;
  154. if (layout) {
  155. rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags);
  156. }
  157. }
  158. if (phnum >= PN_XNUM) {
  159. Elf_Scn *scn = elf->e_scn_1;
  160. Elf32_Shdr *shdr = &scn->s_shdr32;
  161. elf_assert(scn);
  162. elf_assert(scn->s_index == 0);
  163. rewrite(shdr->sh_info, phnum, scn->s_shdr_flags);
  164. *flag |= scn->s_shdr_flags;
  165. phnum = PN_XNUM;
  166. }
  167. rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags);
  168. rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags);
  169. for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) {
  170. Elf32_Shdr *shdr = &scn->s_shdr32;
  171. size_t scn_align = 1;
  172. off_t len;
  173. elf_assert(scn->s_index == shnum);
  174. *flag |= scn->s_scn_flags;
  175. if (scn->s_index == SHN_UNDEF) {
  176. rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags);
  177. if (layout) {
  178. rewrite(shdr->sh_offset, 0, scn->s_shdr_flags);
  179. rewrite(shdr->sh_size, 0, scn->s_shdr_flags);
  180. rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags);
  181. }
  182. *flag |= scn->s_shdr_flags;
  183. continue;
  184. }
  185. if (shdr->sh_type == SHT_NULL) {
  186. *flag |= scn->s_shdr_flags;
  187. continue;
  188. }
  189. len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag);
  190. if (len == -1) {
  191. return -1;
  192. }
  193. /*
  194. * Never override the program's choice.
  195. */
  196. if (shdr->sh_entsize == 0) {
  197. entsize = scn_entsize(elf, version, shdr->sh_type);
  198. if (entsize > 1) {
  199. rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags);
  200. }
  201. }
  202. if (layout) {
  203. align(off, scn_align);
  204. rewrite(shdr->sh_offset, off, scn->s_shdr_flags);
  205. rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags);
  206. rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags);
  207. if (shdr->sh_type != SHT_NOBITS) {
  208. off += (size_t)len;
  209. }
  210. }
  211. else if ((size_t)len > shdr->sh_size) {
  212. seterr(ERROR_SCN2SMALL);
  213. return -1;
  214. }
  215. else {
  216. Elf_Scn *scn2;
  217. size_t end1, end2;
  218. end1 = shdr->sh_offset;
  219. if (shdr->sh_type != SHT_NOBITS) {
  220. end1 += shdr->sh_size;
  221. }
  222. if (!allow_overlap && shdr->sh_offset < off) {
  223. /*
  224. * check for overlapping sections
  225. */
  226. for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) {
  227. if (scn2 == scn) {
  228. break;
  229. }
  230. end2 = scn2->s_shdr32.sh_offset;
  231. if (scn2->s_shdr32.sh_type != SHT_NOBITS) {
  232. end2 += scn2->s_shdr32.sh_size;
  233. }
  234. if (end1 > scn2->s_shdr32.sh_offset
  235. && end2 > shdr->sh_offset) {
  236. seterr(ERROR_SCN_OVERLAP);
  237. return -1;
  238. }
  239. }
  240. }
  241. if (off < end1) {
  242. off = end1;
  243. }
  244. }
  245. *flag |= scn->s_shdr_flags;
  246. }
  247. if (shnum) {
  248. entsize = _fsize(ELFCLASS32, version, ELF_T_SHDR);
  249. elf_assert(entsize);
  250. if (layout) {
  251. align(off, align_addr);
  252. rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags);
  253. off += shnum * entsize;
  254. }
  255. else {
  256. off = max(off, ehdr->e_shoff + shnum * entsize);
  257. }
  258. }
  259. else {
  260. entsize = 0;
  261. if (layout) {
  262. rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags);
  263. }
  264. }
  265. if (shnum >= SHN_LORESERVE) {
  266. Elf_Scn *scn = elf->e_scn_1;
  267. Elf32_Shdr *shdr = &scn->s_shdr32;
  268. elf_assert(scn->s_index == 0);
  269. rewrite(shdr->sh_size, shnum, scn->s_shdr_flags);
  270. *flag |= scn->s_shdr_flags;
  271. shnum = 0;
  272. }
  273. rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags);
  274. rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags);
  275. rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags);
  276. rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags);
  277. rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags);
  278. rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags);
  279. rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS32, elf->e_ehdr_flags);
  280. rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags);
  281. rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags);
  282. rewrite(ehdr->e_version, version, elf->e_ehdr_flags);
  283. *flag |= elf->e_ehdr_flags;
  284. return off;
  285. }
  286. #if __LIBELF64
  287. static off_t
  288. _elf64_layout(Elf *elf, unsigned *flag) {
  289. int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
  290. int allow_overlap = (elf->e_elf_flags & ELF_F_LAYOUT_OVERLAP) != 0;
  291. Elf64_Ehdr *ehdr = (Elf64_Ehdr*)elf->e_ehdr;
  292. size_t off = 0;
  293. unsigned version;
  294. unsigned encoding;
  295. size_t align_addr;
  296. size_t entsize;
  297. unsigned phnum;
  298. unsigned shnum;
  299. Elf_Scn *scn;
  300. *flag = elf->e_elf_flags | elf->e_phdr_flags;
  301. if ((version = ehdr->e_version) == EV_NONE) {
  302. version = EV_CURRENT;
  303. }
  304. if (!valid_version(version)) {
  305. seterr(ERROR_UNKNOWN_VERSION);
  306. return -1;
  307. }
  308. if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) {
  309. encoding = native_encoding;
  310. }
  311. if (!valid_encoding(encoding)) {
  312. seterr(ERROR_UNKNOWN_ENCODING);
  313. return -1;
  314. }
  315. entsize = _fsize(ELFCLASS64, version, ELF_T_EHDR);
  316. elf_assert(entsize);
  317. rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags);
  318. off = entsize;
  319. align_addr = _fsize(ELFCLASS64, version, ELF_T_ADDR);
  320. elf_assert(align_addr);
  321. if ((phnum = elf->e_phnum)) {
  322. entsize = _fsize(ELFCLASS64, version, ELF_T_PHDR);
  323. elf_assert(entsize);
  324. if (layout) {
  325. align(off, align_addr);
  326. rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags);
  327. off += phnum * entsize;
  328. }
  329. else {
  330. off = max(off, ehdr->e_phoff + phnum * entsize);
  331. }
  332. }
  333. else {
  334. entsize = 0;
  335. if (layout) {
  336. rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags);
  337. }
  338. }
  339. if (phnum >= PN_XNUM) {
  340. Elf_Scn *scn = elf->e_scn_1;
  341. Elf32_Shdr *shdr = &scn->s_shdr32;
  342. /* modify first section header, too! */
  343. elf_assert(scn);
  344. elf_assert(scn->s_index == 0);
  345. rewrite(shdr->sh_info, phnum, scn->s_shdr_flags);
  346. *flag |= scn->s_shdr_flags;
  347. phnum = PN_XNUM;
  348. }
  349. rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags);
  350. rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags);
  351. for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) {
  352. Elf64_Shdr *shdr = &scn->s_shdr64;
  353. size_t scn_align = 1;
  354. off_t len;
  355. elf_assert(scn->s_index == shnum);
  356. *flag |= scn->s_scn_flags;
  357. if (scn->s_index == SHN_UNDEF) {
  358. rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags);
  359. if (layout) {
  360. rewrite(shdr->sh_offset, 0, scn->s_shdr_flags);
  361. rewrite(shdr->sh_size, 0, scn->s_shdr_flags);
  362. rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags);
  363. }
  364. *flag |= scn->s_shdr_flags;
  365. continue;
  366. }
  367. if (shdr->sh_type == SHT_NULL) {
  368. *flag |= scn->s_shdr_flags;
  369. continue;
  370. }
  371. len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag);
  372. if (len == -1) {
  373. return -1;
  374. }
  375. /*
  376. * Never override the program's choice.
  377. */
  378. if (shdr->sh_entsize == 0) {
  379. entsize = scn_entsize(elf, version, shdr->sh_type);
  380. if (entsize > 1) {
  381. rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags);
  382. }
  383. }
  384. if (layout) {
  385. align(off, scn_align);
  386. rewrite(shdr->sh_offset, off, scn->s_shdr_flags);
  387. rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags);
  388. rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags);
  389. if (shdr->sh_type != SHT_NOBITS) {
  390. off += (size_t)len;
  391. }
  392. }
  393. else if ((size_t)len > shdr->sh_size) {
  394. seterr(ERROR_SCN2SMALL);
  395. return -1;
  396. }
  397. else {
  398. Elf_Scn *scn2;
  399. size_t end1, end2;
  400. end1 = shdr->sh_offset;
  401. if (shdr->sh_type != SHT_NOBITS) {
  402. end1 += shdr->sh_size;
  403. }
  404. if (!allow_overlap && shdr->sh_offset < off) {
  405. /*
  406. * check for overlapping sections
  407. */
  408. for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) {
  409. if (scn2 == scn) {
  410. break;
  411. }
  412. end2 = scn2->s_shdr64.sh_offset;
  413. if (scn2->s_shdr64.sh_type != SHT_NOBITS) {
  414. end2 += scn2->s_shdr64.sh_size;
  415. }
  416. if (end1 > scn2->s_shdr64.sh_offset
  417. && end2 > shdr->sh_offset) {
  418. seterr(ERROR_SCN_OVERLAP);
  419. return -1;
  420. }
  421. }
  422. }
  423. if (off < end1) {
  424. off = end1;
  425. }
  426. }
  427. *flag |= scn->s_shdr_flags;
  428. }
  429. if (shnum) {
  430. entsize = _fsize(ELFCLASS64, version, ELF_T_SHDR);
  431. elf_assert(entsize);
  432. if (layout) {
  433. align(off, align_addr);
  434. rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags);
  435. off += shnum * entsize;
  436. }
  437. else {
  438. off = max(off, ehdr->e_shoff + shnum * entsize);
  439. }
  440. }
  441. else {
  442. entsize = 0;
  443. if (layout) {
  444. rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags);
  445. }
  446. }
  447. if (shnum >= SHN_LORESERVE) {
  448. Elf_Scn *scn = elf->e_scn_1;
  449. Elf64_Shdr *shdr = &scn->s_shdr64;
  450. elf_assert(scn->s_index == 0);
  451. rewrite(shdr->sh_size, shnum, scn->s_shdr_flags);
  452. *flag |= scn->s_shdr_flags;
  453. shnum = 0;
  454. }
  455. rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags);
  456. rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags);
  457. rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags);
  458. rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags);
  459. rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags);
  460. rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags);
  461. rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS64, elf->e_ehdr_flags);
  462. rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags);
  463. rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags);
  464. rewrite(ehdr->e_version, version, elf->e_ehdr_flags);
  465. *flag |= elf->e_ehdr_flags;
  466. return off;
  467. }
  468. #endif /* __LIBELF64 */
  469. #define ptrinside(p,a,l) ((p)>=(a)&&(p)<(a)+(l))
  470. #define newptr(p,o,n) ((p)=((p)-(o))+(n))
  471. static int
  472. _elf_update_pointers(Elf *elf, char *outbuf, size_t len) {
  473. Elf_Scn *scn;
  474. Scn_Data *sd;
  475. char *data, *rawdata;
  476. elf_assert(elf);
  477. elf_assert(elf->e_data);
  478. elf_assert(!elf->e_parent);
  479. elf_assert(!elf->e_unmap_data);
  480. elf_assert(elf->e_kind == ELF_K_ELF);
  481. elf_assert(len >= EI_NIDENT);
  482. /* resize memory images */
  483. if (len <= elf->e_dsize) {
  484. /* don't shorten the memory image */
  485. data = elf->e_data;
  486. }
  487. else if ((data = (char*)realloc(elf->e_data, len))) {
  488. elf->e_dsize = len;
  489. }
  490. else {
  491. seterr(ERROR_IO_2BIG);
  492. return -1;
  493. }
  494. if (elf->e_rawdata == elf->e_data) {
  495. /* update frozen raw image */
  496. memcpy(data, outbuf, len);
  497. elf->e_data = elf->e_rawdata = data;
  498. /* cooked data is stored outside the raw image */
  499. return 0;
  500. }
  501. if (elf->e_rawdata) {
  502. /* update raw image */
  503. if (!(rawdata = (char*)realloc(elf->e_rawdata, len))) {
  504. seterr(ERROR_IO_2BIG);
  505. return -1;
  506. }
  507. memcpy(rawdata, outbuf, len);
  508. elf->e_rawdata = rawdata;
  509. }
  510. if (data == elf->e_data) {
  511. /* nothing more to do */
  512. return 0;
  513. }
  514. /* adjust internal pointers */
  515. for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
  516. elf_assert(scn->s_magic == SCN_MAGIC);
  517. elf_assert(scn->s_elf == elf);
  518. if ((sd = scn->s_data_1)) {
  519. elf_assert(sd->sd_magic == DATA_MAGIC);
  520. elf_assert(sd->sd_scn == scn);
  521. if (sd->sd_memdata && !sd->sd_free_data) {
  522. elf_assert(ptrinside(sd->sd_memdata, elf->e_data, elf->e_dsize));
  523. if (sd->sd_data.d_buf == sd->sd_memdata) {
  524. newptr(sd->sd_memdata, elf->e_data, data);
  525. sd->sd_data.d_buf = sd->sd_memdata;
  526. }
  527. else {
  528. newptr(sd->sd_memdata, elf->e_data, data);
  529. }
  530. }
  531. }
  532. if ((sd = scn->s_rawdata)) {
  533. elf_assert(sd->sd_magic == DATA_MAGIC);
  534. elf_assert(sd->sd_scn == scn);
  535. if (sd->sd_memdata && sd->sd_free_data) {
  536. size_t off, len;
  537. if (elf->e_class == ELFCLASS32) {
  538. off = scn->s_shdr32.sh_offset;
  539. len = scn->s_shdr32.sh_size;
  540. }
  541. #if __LIBELF64
  542. else if (elf->e_class == ELFCLASS64) {
  543. off = scn->s_shdr64.sh_offset;
  544. len = scn->s_shdr64.sh_size;
  545. }
  546. #endif /* __LIBELF64 */
  547. else {
  548. seterr(ERROR_UNIMPLEMENTED);
  549. return -1;
  550. }
  551. if (!(rawdata = (char*)realloc(sd->sd_memdata, len))) {
  552. seterr(ERROR_IO_2BIG);
  553. return -1;
  554. }
  555. memcpy(rawdata, outbuf + off, len);
  556. if (sd->sd_data.d_buf == sd->sd_memdata) {
  557. sd->sd_data.d_buf = rawdata;
  558. }
  559. sd->sd_memdata = rawdata;
  560. }
  561. }
  562. }
  563. elf->e_data = data;
  564. return 0;
  565. }
  566. #undef ptrinside
  567. #undef newptr
  568. static off_t
  569. _elf32_write(Elf *elf, char *outbuf, size_t len) {
  570. Elf32_Ehdr *ehdr;
  571. Elf32_Shdr *shdr;
  572. Elf_Scn *scn;
  573. Scn_Data *sd;
  574. Elf_Data src;
  575. Elf_Data dst;
  576. unsigned encode;
  577. elf_assert(len);
  578. elf_assert(elf->e_ehdr);
  579. ehdr = (Elf32_Ehdr*)elf->e_ehdr;
  580. encode = ehdr->e_ident[EI_DATA];
  581. src.d_buf = ehdr;
  582. src.d_type = ELF_T_EHDR;
  583. src.d_size = _msize(ELFCLASS32, _elf_version, ELF_T_EHDR);
  584. src.d_version = _elf_version;
  585. dst.d_buf = outbuf;
  586. dst.d_size = ehdr->e_ehsize;
  587. dst.d_version = ehdr->e_version;
  588. if (!elf32_xlatetof(&dst, &src, encode)) {
  589. return -1;
  590. }
  591. if (elf->e_phnum) {
  592. src.d_buf = elf->e_phdr;
  593. src.d_type = ELF_T_PHDR;
  594. src.d_size = elf->e_phnum * _msize(ELFCLASS32, _elf_version, ELF_T_PHDR);
  595. src.d_version = _elf_version;
  596. dst.d_buf = outbuf + ehdr->e_phoff;
  597. dst.d_size = elf->e_phnum * ehdr->e_phentsize;
  598. dst.d_version = ehdr->e_version;
  599. if (!elf32_xlatetof(&dst, &src, encode)) {
  600. return -1;
  601. }
  602. }
  603. for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
  604. elf_assert(scn->s_magic == SCN_MAGIC);
  605. elf_assert(scn->s_elf == elf);
  606. src.d_buf = &scn->s_uhdr;
  607. src.d_type = ELF_T_SHDR;
  608. src.d_size = _msize(ELFCLASS32, EV_CURRENT, ELF_T_SHDR);
  609. src.d_version = EV_CURRENT;
  610. dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize;
  611. dst.d_size = ehdr->e_shentsize;
  612. dst.d_version = ehdr->e_version;
  613. if (!elf32_xlatetof(&dst, &src, encode)) {
  614. return -1;
  615. }
  616. if (scn->s_index == SHN_UNDEF) {
  617. continue;
  618. }
  619. shdr = &scn->s_shdr32;
  620. if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) {
  621. continue;
  622. }
  623. /* XXX: this is probably no longer necessary */
  624. if (scn->s_data_1 && !elf_getdata(scn, NULL)) {
  625. return -1;
  626. }
  627. for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
  628. elf_assert(sd->sd_magic == DATA_MAGIC);
  629. elf_assert(sd->sd_scn == scn);
  630. src = sd->sd_data;
  631. if (!src.d_size) {
  632. continue;
  633. }
  634. if (!src.d_buf) {
  635. seterr(ERROR_NULLBUF);
  636. return -1;
  637. }
  638. dst.d_buf = outbuf + shdr->sh_offset + src.d_off;
  639. dst.d_size = src.d_size;
  640. dst.d_version = ehdr->e_version;
  641. if (valid_type(src.d_type)) {
  642. size_t tmp;
  643. tmp = _elf32_xltsize(&src, dst.d_version, ELFDATA2LSB, 1);
  644. if (tmp == (size_t)-1) {
  645. return -1;
  646. }
  647. dst.d_size = tmp;
  648. }
  649. else {
  650. src.d_type = ELF_T_BYTE;
  651. }
  652. if (!elf32_xlatetof(&dst, &src, encode)) {
  653. return -1;
  654. }
  655. }
  656. }
  657. /* cleanup */
  658. if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) {
  659. return -1;
  660. }
  661. /* NOTE: ehdr is no longer valid! */
  662. ehdr = (Elf32_Ehdr*)elf->e_ehdr; elf_assert(ehdr);
  663. elf->e_encoding = ehdr->e_ident[EI_DATA];
  664. elf->e_version = ehdr->e_ident[EI_VERSION];
  665. elf->e_elf_flags &= ~ELF_F_DIRTY;
  666. elf->e_ehdr_flags &= ~ELF_F_DIRTY;
  667. elf->e_phdr_flags &= ~ELF_F_DIRTY;
  668. for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
  669. scn->s_scn_flags &= ~ELF_F_DIRTY;
  670. scn->s_shdr_flags &= ~ELF_F_DIRTY;
  671. for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
  672. sd->sd_data_flags &= ~ELF_F_DIRTY;
  673. }
  674. if (elf->e_readable) {
  675. shdr = &scn->s_shdr32;
  676. scn->s_type = shdr->sh_type;
  677. scn->s_size = shdr->sh_size;
  678. scn->s_offset = shdr->sh_offset;
  679. }
  680. }
  681. elf->e_size = len;
  682. return len;
  683. }
  684. #if __LIBELF64
  685. static off_t
  686. _elf64_write(Elf *elf, char *outbuf, size_t len) {
  687. Elf64_Ehdr *ehdr;
  688. Elf64_Shdr *shdr;
  689. Elf_Scn *scn;
  690. Scn_Data *sd;
  691. Elf_Data src;
  692. Elf_Data dst;
  693. unsigned encode;
  694. elf_assert(len);
  695. elf_assert(elf->e_ehdr);
  696. ehdr = (Elf64_Ehdr*)elf->e_ehdr;
  697. encode = ehdr->e_ident[EI_DATA];
  698. src.d_buf = ehdr;
  699. src.d_type = ELF_T_EHDR;
  700. src.d_size = _msize(ELFCLASS64, _elf_version, ELF_T_EHDR);
  701. src.d_version = _elf_version;
  702. dst.d_buf = outbuf;
  703. dst.d_size = ehdr->e_ehsize;
  704. dst.d_version = ehdr->e_version;
  705. if (!elf64_xlatetof(&dst, &src, encode)) {
  706. return -1;
  707. }
  708. if (elf->e_phnum) {
  709. src.d_buf = elf->e_phdr;
  710. src.d_type = ELF_T_PHDR;
  711. src.d_size = elf->e_phnum * _msize(ELFCLASS64, _elf_version, ELF_T_PHDR);
  712. src.d_version = _elf_version;
  713. dst.d_buf = outbuf + ehdr->e_phoff;
  714. dst.d_size = elf->e_phnum * ehdr->e_phentsize;
  715. dst.d_version = ehdr->e_version;
  716. if (!elf64_xlatetof(&dst, &src, encode)) {
  717. return -1;
  718. }
  719. }
  720. for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
  721. elf_assert(scn->s_magic == SCN_MAGIC);
  722. elf_assert(scn->s_elf == elf);
  723. src.d_buf = &scn->s_uhdr;
  724. src.d_type = ELF_T_SHDR;
  725. src.d_size = _msize(ELFCLASS64, EV_CURRENT, ELF_T_SHDR);
  726. src.d_version = EV_CURRENT;
  727. dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize;
  728. dst.d_size = ehdr->e_shentsize;
  729. dst.d_version = ehdr->e_version;
  730. if (!elf64_xlatetof(&dst, &src, encode)) {
  731. return -1;
  732. }
  733. if (scn->s_index == SHN_UNDEF) {
  734. continue;
  735. }
  736. shdr = &scn->s_shdr64;
  737. if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) {
  738. continue;
  739. }
  740. /* XXX: this is probably no longer necessary */
  741. if (scn->s_data_1 && !elf_getdata(scn, NULL)) {
  742. return -1;
  743. }
  744. for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
  745. elf_assert(sd->sd_magic == DATA_MAGIC);
  746. elf_assert(sd->sd_scn == scn);
  747. src = sd->sd_data;
  748. if (!src.d_size) {
  749. continue;
  750. }
  751. if (!src.d_buf) {
  752. seterr(ERROR_NULLBUF);
  753. return -1;
  754. }
  755. dst.d_buf = outbuf + shdr->sh_offset + src.d_off;
  756. dst.d_size = src.d_size;
  757. dst.d_version = ehdr->e_version;
  758. if (valid_type(src.d_type)) {
  759. size_t tmp;
  760. tmp = _elf64_xltsize(&src, dst.d_version, ELFDATA2LSB, 1);
  761. if (tmp == (size_t)-1) {
  762. return -1;
  763. }
  764. dst.d_size = tmp;
  765. }
  766. else {
  767. src.d_type = ELF_T_BYTE;
  768. }
  769. if (!elf64_xlatetof(&dst, &src, encode)) {
  770. return -1;
  771. }
  772. }
  773. }
  774. /* cleanup */
  775. if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) {
  776. return -1;
  777. }
  778. /* NOTE: ehdr is no longer valid! */
  779. ehdr = (Elf64_Ehdr*)elf->e_ehdr; elf_assert(ehdr);
  780. elf->e_encoding = ehdr->e_ident[EI_DATA];
  781. elf->e_version = ehdr->e_ident[EI_VERSION];
  782. elf->e_elf_flags &= ~ELF_F_DIRTY;
  783. elf->e_ehdr_flags &= ~ELF_F_DIRTY;
  784. elf->e_phdr_flags &= ~ELF_F_DIRTY;
  785. for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
  786. scn->s_scn_flags &= ~ELF_F_DIRTY;
  787. scn->s_shdr_flags &= ~ELF_F_DIRTY;
  788. for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
  789. sd->sd_data_flags &= ~ELF_F_DIRTY;
  790. }
  791. if (elf->e_readable) {
  792. shdr = &scn->s_shdr64;
  793. scn->s_type = shdr->sh_type;
  794. scn->s_size = shdr->sh_size;
  795. scn->s_offset = shdr->sh_offset;
  796. }
  797. }
  798. elf->e_size = len;
  799. return len;
  800. }
  801. #endif /* __LIBELF64 */
  802. static int
  803. xwrite(int fd, char *buffer, size_t len) {
  804. size_t done = 0;
  805. size_t n;
  806. while (done < len) {
  807. n = write(fd, buffer + done, len - done);
  808. if (n == 0) {
  809. /* file system full */
  810. return -1;
  811. }
  812. else if (n != (size_t)-1) {
  813. /* some bytes written, continue */
  814. done += n;
  815. }
  816. else if (errno != EAGAIN && errno != EINTR) {
  817. /* real error */
  818. return -1;
  819. }
  820. }
  821. return 0;
  822. }
  823. static off_t
  824. _elf_output(Elf *elf, int fd, size_t len, off_t (*_elf_write)(Elf*, char*, size_t)) {
  825. char *buf;
  826. off_t err;
  827. elf_assert(len);
  828. #if HAVE_FTRUNCATE
  829. if (ftruncate(fd, 0)) {
  830. seterr(ERROR_IO_WRITE);
  831. return -1;
  832. }
  833. #endif /* HAVE_FTRUNCATE */
  834. #if HAVE_MMAP
  835. /*
  836. * Make sure the file is (at least) len bytes long
  837. */
  838. #if HAVE_FTRUNCATE
  839. lseek(fd, (off_t)len, SEEK_SET);
  840. if (ftruncate(fd, len)) {
  841. #else /* HAVE_FTRUNCATE */
  842. {
  843. #endif /* HAVE_FTRUNCATE */
  844. if (lseek(fd, (off_t)len - 1, SEEK_SET) != (off_t)len - 1) {
  845. seterr(ERROR_IO_SEEK);
  846. return -1;
  847. }
  848. if (xwrite(fd, "", 1)) {
  849. seterr(ERROR_IO_WRITE);
  850. return -1;
  851. }
  852. }
  853. buf = (void*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  854. if (buf != (char*)-1) {
  855. if ((char)_elf_fill && !(elf->e_elf_flags & ELF_F_LAYOUT)) {
  856. memset(buf, _elf_fill, len);
  857. }
  858. err = _elf_write(elf, buf, len);
  859. munmap(buf, len);
  860. return err;
  861. }
  862. #endif /* HAVE_MMAP */
  863. if (!(buf = (char*)malloc(len))) {
  864. seterr(ERROR_MEM_OUTBUF);
  865. return -1;
  866. }
  867. memset(buf, _elf_fill, len);
  868. err = _elf_write(elf, buf, len);
  869. if (err != -1 && (size_t)err == len) {
  870. if (lseek(fd, (off_t)0, SEEK_SET)) {
  871. seterr(ERROR_IO_SEEK);
  872. err = -1;
  873. }
  874. else if (xwrite(fd, buf, len)) {
  875. seterr(ERROR_IO_WRITE);
  876. err = -1;
  877. }
  878. }
  879. free(buf);
  880. return err;
  881. }
  882. off_t
  883. elf_update(Elf *elf, Elf_Cmd cmd) {
  884. unsigned flag;
  885. off_t len;
  886. if (!elf) {
  887. return -1;
  888. }
  889. elf_assert(elf->e_magic == ELF_MAGIC);
  890. if (cmd == ELF_C_WRITE) {
  891. if (!elf->e_writable) {
  892. seterr(ERROR_RDONLY);
  893. return -1;
  894. }
  895. if (elf->e_disabled) {
  896. seterr(ERROR_FDDISABLED);
  897. return -1;
  898. }
  899. }
  900. else if (cmd != ELF_C_NULL) {
  901. seterr(ERROR_INVALID_CMD);
  902. return -1;
  903. }
  904. if (!elf->e_ehdr) {
  905. seterr(ERROR_NOEHDR);
  906. }
  907. else if (elf->e_kind != ELF_K_ELF) {
  908. seterr(ERROR_NOTELF);
  909. }
  910. else if (elf->e_class == ELFCLASS32) {
  911. len = _elf32_layout(elf, &flag);
  912. if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) {
  913. len = _elf_output(elf, elf->e_fd, (size_t)len, _elf32_write);
  914. }
  915. return len;
  916. }
  917. #if __LIBELF64
  918. else if (elf->e_class == ELFCLASS64) {
  919. len = _elf64_layout(elf, &flag);
  920. if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) {
  921. len = _elf_output(elf, elf->e_fd, (size_t)len, _elf64_write);
  922. }
  923. return len;
  924. }
  925. #endif /* __LIBELF64 */
  926. else if (valid_class(elf->e_class)) {
  927. seterr(ERROR_UNIMPLEMENTED);
  928. }
  929. else {
  930. seterr(ERROR_UNKNOWN_CLASS);
  931. }
  932. return -1;
  933. }