executable.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. #include <bootexec.h>
  13. #include <mach.h>
  14. #include "elf.h"
  15. /*
  16. * All a.out header types. The dummy entry allows canonical
  17. * processing of the union as a sequence of longs
  18. */
  19. typedef struct {
  20. union{
  21. struct {
  22. Exec; /* a.out.h */
  23. uint64_t hdr[1];
  24. };
  25. #ifdef HARVEY32
  26. Ehdr; /* elf.h */
  27. #endif
  28. E64hdr;
  29. struct mipsexec; /* bootexec.h */
  30. struct mips4kexec; /* bootexec.h */
  31. struct sparcexec; /* bootexec.h */
  32. struct nextexec; /* bootexec.h */
  33. } e;
  34. int32_t dummy; /* padding to ensure extra long */
  35. } ExecHdr;
  36. #ifdef HARVEYNEXT
  37. static int nextboot(int, Fhdr*, ExecHdr*);
  38. #elif HARVEYSPARC
  39. static int sparcboot(int, Fhdr*, ExecHdr*);
  40. #elif HARVEYMIPS
  41. static int mipsboot(int, Fhdr*, ExecHdr*);
  42. static int mips4kboot(int, Fhdr*, ExecHdr*);
  43. #endif
  44. static int common(int, Fhdr*, ExecHdr*);
  45. static int commonllp64(int, Fhdr*, ExecHdr*);
  46. static int adotout(int, Fhdr*, ExecHdr*);
  47. static int elfdotout(int, Fhdr*, ExecHdr*);
  48. static int armdotout(int, Fhdr*, ExecHdr*);
  49. static void setsym(Fhdr*, int32_t, int32_t, int32_t, int64_t);
  50. static void setdata(Fhdr*, uint64_t, int32_t, int64_t,
  51. int32_t);
  52. static void settext(Fhdr*, uint64_t, uint64_t, int32_t,
  53. int64_t);
  54. static void hswal(void*, int, uint32_t(*)(uint32_t));
  55. static uint64_t _round(uint64_t, uint32_t);
  56. /*
  57. * definition of per-executable file type structures
  58. */
  59. typedef struct Exectable{
  60. int32_t magic; /* big-endian magic number of file */
  61. char *name; /* executable identifier */
  62. char *dlmname; /* dynamically loadable module identifier */
  63. uint8_t type; /* Internal code */
  64. uint8_t _magic; /* _MAGIC() magic */
  65. Mach *mach; /* Per-machine data */
  66. int32_t hsize; /* header size */
  67. uint32_t (*swal)(uint32_t); /* beswal or leswal */
  68. int (*hparse)(int, Fhdr*, ExecHdr*);
  69. } ExecTable;
  70. #ifdef HARVEYMIPS
  71. extern Mach mmips;
  72. extern Mach mmips2le;
  73. extern Mach mmips2be;
  74. #elif HARVEYSPARC
  75. extern Mach msparc;
  76. extern Mach msparc64;
  77. extern Mach m68020;
  78. #elif HARVEY32
  79. extern Mach mi386;
  80. #endif
  81. extern Mach mamd64;
  82. #ifdef HARVEYARM
  83. extern Mach marm;
  84. #elif HARVEYPPC
  85. extern Mach mpower;
  86. extern Mach mpower64;
  87. #elif HARVEYALPHA
  88. extern Mach malpha;
  89. #endif
  90. ExecTable exectab[] =
  91. {
  92. #ifdef HARVEYMIPS
  93. { V_MAGIC, /* Mips v.out */
  94. "mips plan 9 executable BE",
  95. "mips plan 9 dlm BE",
  96. FMIPS,
  97. 1,
  98. &mmips,
  99. sizeof(Exec),
  100. beswal,
  101. adotout },
  102. { P_MAGIC, /* Mips 0.out (r3k le) */
  103. "mips plan 9 executable LE",
  104. "mips plan 9 dlm LE",
  105. FMIPSLE,
  106. 1,
  107. &mmips,
  108. sizeof(Exec),
  109. beswal,
  110. adotout },
  111. { M_MAGIC, /* Mips 4.out */
  112. "mips 4k plan 9 executable BE",
  113. "mips 4k plan 9 dlm BE",
  114. FMIPS2BE,
  115. 1,
  116. &mmips2be,
  117. sizeof(Exec),
  118. beswal,
  119. adotout },
  120. { N_MAGIC, /* Mips 0.out */
  121. "mips 4k plan 9 executable LE",
  122. "mips 4k plan 9 dlm LE",
  123. FMIPS2LE,
  124. 1,
  125. &mmips2le,
  126. sizeof(Exec),
  127. beswal,
  128. adotout },
  129. { 0x160<<16, /* Mips boot image */
  130. "mips plan 9 boot image",
  131. nil,
  132. FMIPSB,
  133. 0,
  134. &mmips,
  135. sizeof(struct mipsexec),
  136. beswal,
  137. mipsboot },
  138. { (0x160<<16)|3, /* Mips boot image */
  139. "mips 4k plan 9 boot image",
  140. nil,
  141. FMIPSB,
  142. 0,
  143. &mmips2be,
  144. sizeof(struct mips4kexec),
  145. beswal,
  146. mips4kboot },
  147. #elif HARVEYSPARC
  148. { K_MAGIC, /* Sparc k.out */
  149. "sparc plan 9 executable",
  150. "sparc plan 9 dlm",
  151. FSPARC,
  152. 1,
  153. &msparc,
  154. sizeof(Exec),
  155. beswal,
  156. adotout },
  157. { 0x01030107, /* Sparc boot image */
  158. "sparc plan 9 boot image",
  159. nil,
  160. FSPARCB,
  161. 0,
  162. &msparc,
  163. sizeof(struct sparcexec),
  164. beswal,
  165. sparcboot },
  166. { U_MAGIC, /* Sparc64 u.out */
  167. "sparc64 plan 9 executable",
  168. "sparc64 plan 9 dlm",
  169. FSPARC64,
  170. 1,
  171. &msparc64,
  172. sizeof(Exec),
  173. beswal,
  174. adotout },
  175. { A_MAGIC, /* 68020 2.out & boot image */
  176. "68020 plan 9 executable",
  177. "68020 plan 9 dlm",
  178. F68020,
  179. 1,
  180. &m68020,
  181. sizeof(Exec),
  182. beswal,
  183. common },
  184. #elif HARVEYNEXT
  185. { 0xFEEDFACE, /* Next boot image */
  186. "next plan 9 boot image",
  187. nil,
  188. FNEXTB,
  189. 0,
  190. &m68020,
  191. sizeof(struct nextexec),
  192. beswal,
  193. nextboot },
  194. #elif HARVEY32
  195. { I_MAGIC, /* I386 8.out & boot image */
  196. "386 plan 9 executable",
  197. "386 plan 9 dlm",
  198. FI386,
  199. 1,
  200. &mi386,
  201. sizeof(Exec),
  202. beswal,
  203. common },
  204. #endif
  205. { S_MAGIC, /* amd64 6.out & boot image */
  206. "amd64 plan 9 executable",
  207. "amd64 plan 9 dlm",
  208. FAMD64,
  209. 1,
  210. &mamd64,
  211. sizeof(Exec)+8,
  212. nil,
  213. commonllp64 },
  214. #ifdef HARVEYPPC
  215. { Q_MAGIC, /* PowerPC q.out & boot image */
  216. "power plan 9 executable",
  217. "power plan 9 dlm",
  218. FPOWER,
  219. 1,
  220. &mpower,
  221. sizeof(Exec),
  222. beswal,
  223. common },
  224. { T_MAGIC, /* power64 9.out & boot image */
  225. "power64 plan 9 executable",
  226. "power64 plan 9 dlm",
  227. FPOWER64,
  228. 1,
  229. &mpower64,
  230. sizeof(Exec)+8,
  231. nil,
  232. commonllp64 },
  233. #endif
  234. { ELF_MAG, /* any ELF */
  235. "elf executable",
  236. nil,
  237. FNONE,
  238. 0,
  239. /* &mi386,
  240. sizeof(Ehdr), */
  241. &mamd64,
  242. sizeof(E64hdr),
  243. nil,
  244. elfdotout },
  245. #ifdef HARVEYARM
  246. { E_MAGIC, /* Arm 5.out and boot image */
  247. "arm plan 9 executable",
  248. "arm plan 9 dlm",
  249. FARM,
  250. 1,
  251. &marm,
  252. sizeof(Exec),
  253. beswal,
  254. common },
  255. { (143<<16)|0413, /* (Free|Net)BSD Arm */
  256. "arm *bsd executable",
  257. nil,
  258. FARM,
  259. 0,
  260. &marm,
  261. sizeof(Exec),
  262. leswal,
  263. armdotout },
  264. #elif HARVEYALPHA
  265. { L_MAGIC, /* alpha 7.out */
  266. "alpha plan 9 executable",
  267. "alpha plan 9 dlm",
  268. FALPHA,
  269. 1,
  270. &malpha,
  271. sizeof(Exec),
  272. beswal,
  273. common },
  274. { 0x0700e0c3, /* alpha boot image */
  275. "alpha plan 9 boot image",
  276. nil,
  277. FALPHA,
  278. 0,
  279. &malpha,
  280. sizeof(Exec),
  281. beswal,
  282. common },
  283. #endif
  284. { 0 },
  285. };
  286. #ifdef HARVEY32
  287. Mach *mach = &mi386; /* Global current machine table */
  288. #endif
  289. Mach *mach = &mamd64;
  290. static ExecTable*
  291. couldbe4k(ExecTable *mp)
  292. {
  293. // Dir *d;
  294. ExecTable *f;
  295. /* undefined for use with kernel
  296. if((d=dirstat("/proc/1/regs")) == nil)
  297. return mp;
  298. if(d->length < 32*8){ / * R3000 * /
  299. free(d);
  300. return mp;
  301. }
  302. free(d); */
  303. for (f = exectab; f->magic; f++)
  304. if(f->magic == M_MAGIC) {
  305. f->name = "mips plan 9 executable on mips2 kernel";
  306. return f;
  307. }
  308. return mp;
  309. }
  310. int
  311. crackhdr(int fd, Fhdr *fp)
  312. {
  313. ExecTable *mp;
  314. ExecHdr d;
  315. int nb, ret;
  316. uint32_t magic;
  317. fp->type = FNONE;
  318. nb = read(fd, (char *)&d.e, sizeof(d.e));
  319. if (nb <= 0)
  320. return 0;
  321. ret = 0;
  322. magic = beswal(d.e.magic); /* big-endian */
  323. for (mp = exectab; mp->magic; mp++) {
  324. if (nb < mp->hsize)
  325. continue;
  326. /*
  327. * The magic number has morphed into something
  328. * with fields (the straw was DYN_MAGIC) so now
  329. * a flag is needed in Fhdr to distinguish _MAGIC()
  330. * magic numbers from foreign magic numbers.
  331. *
  332. * This code is creaking a bit and if it has to
  333. * be modified/extended much more it's probably
  334. * time to step back and redo it all.
  335. */
  336. if(mp->_magic){
  337. if(mp->magic != (magic & ~DYN_MAGIC))
  338. continue;
  339. if(mp->magic == V_MAGIC)
  340. mp = couldbe4k(mp);
  341. if ((magic & DYN_MAGIC) && mp->dlmname != nil)
  342. fp->name = mp->dlmname;
  343. else
  344. fp->name = mp->name;
  345. }
  346. else{
  347. if(mp->magic != magic)
  348. continue;
  349. fp->name = mp->name;
  350. }
  351. fp->type = mp->type;
  352. fp->hdrsz = mp->hsize; /* will be zero on bootables */
  353. fp->_magic = mp->_magic;
  354. fp->magic = magic;
  355. mach = mp->mach;
  356. if(mp->swal != nil)
  357. hswal(&d, sizeof(d.e)/sizeof(uint32_t), mp->swal);
  358. ret = mp->hparse(fd, fp, &d);
  359. seek(fd, mp->hsize, 0); /* seek to end of header */
  360. break;
  361. }
  362. if(mp->magic == 0)
  363. werrstr("unknown header type");
  364. return ret;
  365. }
  366. /*
  367. * Convert header to canonical form
  368. */
  369. static void
  370. hswal(void *v, int n, uint32_t (*swap)(uint32_t))
  371. {
  372. uint32_t *ulp;
  373. for(ulp = v; n--; ulp++)
  374. *ulp = (*swap)(*ulp);
  375. }
  376. /*
  377. * Crack a normal a.out-type header
  378. */
  379. static int
  380. adotout(int fd, Fhdr *fp, ExecHdr *hp)
  381. {
  382. int32_t pgsize;
  383. USED(fd);
  384. pgsize = mach->pgsize;
  385. settext(fp, hp->e.entry, pgsize+sizeof(Exec),
  386. hp->e.text, sizeof(Exec));
  387. setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize),
  388. hp->e.data, fp->txtsz+sizeof(Exec), hp->e.bss);
  389. setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz);
  390. return 1;
  391. }
  392. static void
  393. commonboot(Fhdr *fp)
  394. {
  395. if (!(fp->entry & mach->ktmask))
  396. return;
  397. switch(fp->type) { /* boot image */
  398. case F68020:
  399. fp->type = F68020B;
  400. fp->name = "68020 plan 9 boot image";
  401. break;
  402. case FI386:
  403. fp->type = FI386B;
  404. fp->txtaddr = (uint32_t)fp->entry;
  405. fp->name = "386 plan 9 boot image";
  406. fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
  407. break;
  408. case FARM:
  409. fp->type = FARMB;
  410. fp->txtaddr = (uint32_t)fp->entry;
  411. fp->name = "ARM plan 9 boot image";
  412. fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
  413. return;
  414. case FALPHA:
  415. fp->type = FALPHAB;
  416. fp->txtaddr = (uint32_t)fp->entry;
  417. fp->name = "alpha plan 9 boot image";
  418. fp->dataddr = fp->txtaddr+fp->txtsz;
  419. break;
  420. case FPOWER:
  421. fp->type = FPOWERB;
  422. fp->txtaddr = (uint32_t)fp->entry;
  423. fp->name = "power plan 9 boot image";
  424. fp->dataddr = fp->txtaddr+fp->txtsz;
  425. break;
  426. case FAMD64:
  427. fp->type = FAMD64B;
  428. fp->txtaddr = fp->entry;
  429. fp->name = "amd64 plan 9 boot image";
  430. fp->dataddr = _round(fp->txtaddr+fp->txtsz, 4096);
  431. break;
  432. case FPOWER64:
  433. fp->type = FPOWER64B;
  434. fp->txtaddr = fp->entry;
  435. fp->name = "power64 plan 9 boot image";
  436. fp->dataddr = fp->txtaddr+fp->txtsz;
  437. break;
  438. default:
  439. return;
  440. }
  441. fp->hdrsz = 0; /* header stripped */
  442. }
  443. /*
  444. * _MAGIC() style headers and
  445. * alpha plan9-style bootable images for axp "headerless" boot
  446. *
  447. */
  448. static int
  449. common(int fd, Fhdr *fp, ExecHdr *hp)
  450. {
  451. adotout(fd, fp, hp);
  452. if(hp->e.magic & DYN_MAGIC) {
  453. fp->txtaddr = 0;
  454. fp->dataddr = fp->txtsz;
  455. return 1;
  456. }
  457. commonboot(fp);
  458. return 1;
  459. }
  460. static int
  461. commonllp64(int i, Fhdr *fp, ExecHdr *hp)
  462. {
  463. int32_t pgsize;
  464. uint64_t entry;
  465. hswal(&hp->e, sizeof(Exec)/sizeof(int32_t), beswal);
  466. if(!(hp->e.magic & HDR_MAGIC))
  467. return 0;
  468. /*
  469. * There can be more magic here if the
  470. * header ever needs more expansion.
  471. * For now just catch use of any of the
  472. * unused bits.
  473. */
  474. if((hp->e.magic & ~DYN_MAGIC)>>16)
  475. return 0;
  476. entry = beswav(hp->e.hdr[0]);
  477. pgsize = mach->pgsize;
  478. settext(fp, entry, pgsize+fp->hdrsz, hp->e.text, fp->hdrsz);
  479. setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize),
  480. hp->e.data, fp->txtsz+fp->hdrsz, hp->e.bss);
  481. setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz);
  482. if(hp->e.magic & DYN_MAGIC) {
  483. fp->txtaddr = 0;
  484. fp->dataddr = fp->txtsz;
  485. return 1;
  486. }
  487. commonboot(fp);
  488. return 1;
  489. }
  490. #ifdef HARVEYMIPS
  491. /*
  492. * mips bootable image.
  493. */
  494. static int
  495. mipsboot(int fd, Fhdr *fp, ExecHdr *hp)
  496. {
  497. USED(fd);
  498. fp->type = FMIPSB;
  499. switch(hp->e.amagic) {
  500. default:
  501. case 0407: /* some kind of mips */
  502. settext(fp, (uint32_t)hp->e.mentry,
  503. (uint32_t)hp->e.text_start,
  504. hp->e.tsize, sizeof(struct mipsexec)+4);
  505. setdata(fp, (uint32_t)hp->e.data_start, hp->e.dsize,
  506. fp->txtoff+hp->e.tsize, hp->e.bsize);
  507. break;
  508. case 0413: /* some kind of mips */
  509. settext(fp, (uint32_t)hp->e.mentry,
  510. (uint32_t)hp->e.text_start,
  511. hp->e.tsize, 0);
  512. setdata(fp, (uint32_t)hp->e.data_start, hp->e.dsize,
  513. hp->e.tsize, hp->e.bsize);
  514. break;
  515. }
  516. setsym(fp, hp->e.nsyms, 0, hp->e.pcsize, hp->e.symptr);
  517. fp->hdrsz = 0; /* header stripped */
  518. return 1;
  519. }
  520. /*
  521. * mips4k bootable image.
  522. */
  523. static int
  524. mips4kboot(int fd, Fhdr *fp, ExecHdr *hp)
  525. {
  526. USED(fd);
  527. fp->type = FMIPSB;
  528. switch(hp->e.h.amagic) {
  529. default:
  530. case 0407: /* some kind of mips */
  531. settext(fp, (uint32_t)hp->e.h.mentry,
  532. (uint32_t)hp->e.h.text_start,
  533. hp->e.h.tsize, sizeof(struct mips4kexec));
  534. setdata(fp, (uint32_t)hp->e.h.data_start, hp->e.h.dsize,
  535. fp->txtoff+hp->e.h.tsize, hp->e.h.bsize);
  536. break;
  537. case 0413: /* some kind of mips */
  538. settext(fp, (uint32_t)hp->e.h.mentry,
  539. (uint32_t)hp->e.h.text_start,
  540. hp->e.h.tsize, 0);
  541. setdata(fp, (uint32_t)hp->e.h.data_start, hp->e.h.dsize,
  542. hp->e.h.tsize, hp->e.h.bsize);
  543. break;
  544. }
  545. setsym(fp, hp->e.h.nsyms, 0, hp->e.h.pcsize, hp->e.h.symptr);
  546. fp->hdrsz = 0; /* header stripped */
  547. return 1;
  548. }
  549. #endif
  550. #ifdef HARVEYSPARC
  551. /*
  552. * sparc bootable image
  553. */
  554. static int
  555. sparcboot(int fd, Fhdr *fp, ExecHdr *hp)
  556. {
  557. USED(fd);
  558. fp->type = FSPARCB;
  559. settext(fp, hp->e.sentry, hp->e.sentry, hp->e.stext,
  560. sizeof(struct sparcexec));
  561. setdata(fp, hp->e.sentry+hp->e.stext, hp->e.sdata,
  562. fp->txtoff+hp->e.stext, hp->e.sbss);
  563. setsym(fp, hp->e.ssyms, 0, hp->e.sdrsize, fp->datoff+hp->e.sdata);
  564. fp->hdrsz = 0; /* header stripped */
  565. return 1;
  566. }
  567. #endif
  568. #ifdef HARVEYNEXT
  569. /*
  570. * next bootable image
  571. */
  572. static int
  573. nextboot(int fd, Fhdr *fp, ExecHdr *hp)
  574. {
  575. USED(fd);
  576. fp->type = FNEXTB;
  577. settext(fp, hp->e.textc.vmaddr, hp->e.textc.vmaddr,
  578. hp->e.texts.size, hp->e.texts.offset);
  579. setdata(fp, hp->e.datac.vmaddr, hp->e.datas.size,
  580. hp->e.datas.offset, hp->e.bsss.size);
  581. setsym(fp, hp->e.symc.nsyms, hp->e.symc.spoff, hp->e.symc.pcoff,
  582. hp->e.symc.symoff);
  583. fp->hdrsz = 0; /* header stripped */
  584. return 1;
  585. }
  586. #endif
  587. /*
  588. * ELF64 binaries.
  589. */
  590. static int
  591. elf64dotout(int fd, Fhdr *fp, ExecHdr *hp)
  592. {
  593. E64hdr *ep;
  594. P64hdr *ph;
  595. uint16_t (*swab)(uint16_t);
  596. uint32_t (*swal)(uint32_t);
  597. uint64_t (*swav)(uint64_t);
  598. int i, it, id, is, phsz;
  599. uint64_t uvl;
  600. ep = &hp->e;
  601. if(ep->ident[DATA] == ELFDATA2LSB) {
  602. swab = leswab;
  603. swal = leswal;
  604. swav = leswav;
  605. } else if(ep->ident[DATA] == ELFDATA2MSB) {
  606. swab = beswab;
  607. swal = beswal;
  608. swav = beswav;
  609. } else {
  610. werrstr("bad ELF64 encoding - not big or little endian");
  611. return 0;
  612. }
  613. ep->type = swab(ep->type);
  614. ep->machine = swab(ep->machine);
  615. ep->version = swal(ep->version);
  616. if(ep->type != EXEC || ep->version != CURRENT)
  617. return 0;
  618. ep->elfentry = swav(ep->elfentry);
  619. ep->phoff = swav(ep->phoff);
  620. ep->shoff = swav(ep->shoff);
  621. ep->flags = swal(ep->flags);
  622. ep->ehsize = swab(ep->ehsize);
  623. ep->phentsize = swab(ep->phentsize);
  624. ep->phnum = swab(ep->phnum);
  625. ep->shentsize = swab(ep->shentsize);
  626. ep->shnum = swab(ep->shnum);
  627. ep->shstrndx = swab(ep->shstrndx);
  628. fp->magic = ELF_MAG;
  629. fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
  630. switch(ep->machine) {
  631. default:
  632. return 0;
  633. case AMD64:
  634. mach = &mamd64;
  635. fp->type = FAMD64;
  636. fp->name = "amd64 ELF64 executable";
  637. break;
  638. case POWER64:
  639. #ifdef HARVEYPPC
  640. mach = &mpower64;
  641. #endif
  642. fp->type = FPOWER64;
  643. fp->name = "power64 ELF64 executable";
  644. break;
  645. }
  646. if(ep->phentsize != sizeof(P64hdr)) {
  647. werrstr("bad ELF64 header size");
  648. return 0;
  649. }
  650. phsz = sizeof(P64hdr)*ep->phnum;
  651. ph = malloc(phsz);
  652. if(!ph)
  653. return 0;
  654. seek(fd, ep->phoff, 0);
  655. if(read(fd, ph, phsz) < 0) {
  656. free(ph);
  657. return 0;
  658. }
  659. for(i = 0; i < ep->phnum; i++) {
  660. ph[i].type = swal(ph[i].type);
  661. ph[i].flags = swal(ph[i].flags);
  662. ph[i].offset = swav(ph[i].offset);
  663. ph[i].vaddr = swav(ph[i].vaddr);
  664. ph[i].paddr = swav(ph[i].paddr);
  665. ph[i].filesz = swav(ph[i].filesz);
  666. ph[i].memsz = swav(ph[i].memsz);
  667. ph[i].align = swav(ph[i].align);
  668. }
  669. /* find text, data and symbols and install them */
  670. it = id = is = -1;
  671. for(i = 0; i < ep->phnum; i++) {
  672. if(ph[i].type == LOAD
  673. && (ph[i].flags & (R|X)) == (R|X) && it == -1)
  674. it = i;
  675. else if(ph[i].type == LOAD
  676. && (ph[i].flags & (R|W)) == (R|W) && id == -1)
  677. id = i;
  678. else if(ph[i].type == NOPTYPE && is == -1)
  679. is = i;
  680. }
  681. if(it == -1 || id == -1) {
  682. werrstr("No ELF64 TEXT or DATA sections");
  683. free(ph);
  684. return 0;
  685. }
  686. settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
  687. /* 8c: out of fixed registers */
  688. uvl = ph[id].memsz - ph[id].filesz;
  689. setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, uvl);
  690. if(is != -1)
  691. setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset);
  692. free(ph);
  693. return 1;
  694. }
  695. #ifdef HARVEY32
  696. /*
  697. * ELF32 binaries.
  698. */
  699. static int
  700. elf32dotout(int fd, Fhdr *fp, ExecHdr *hp)
  701. {
  702. uint32_t (*swal)(uint32_t);
  703. uint16_t (*swab)(uint16_t);
  704. Ehdr *ep;
  705. Phdr *ph;
  706. int i, it, id, is, phsz;
  707. /* bitswap the header according to the DATA format */
  708. ep = &hp->e;
  709. if(ep->ident[DATA] == ELFDATA2LSB) {
  710. swab = leswab;
  711. swal = leswal;
  712. } else if(ep->ident[DATA] == ELFDATA2MSB) {
  713. swab = beswab;
  714. swal = beswal;
  715. } else {
  716. werrstr("bad ELF32 encoding - not big or little endian");
  717. return 0;
  718. }
  719. ep->type = swab(ep->type);
  720. ep->machine = swab(ep->machine);
  721. ep->version = swal(ep->version);
  722. ep->elfentry = swal(ep->elfentry);
  723. ep->phoff = swal(ep->phoff);
  724. ep->shoff = swal(ep->shoff);
  725. ep->flags = swal(ep->flags);
  726. ep->ehsize = swab(ep->ehsize);
  727. ep->phentsize = swab(ep->phentsize);
  728. ep->phnum = swab(ep->phnum);
  729. ep->shentsize = swab(ep->shentsize);
  730. ep->shnum = swab(ep->shnum);
  731. ep->shstrndx = swab(ep->shstrndx);
  732. if(ep->type != EXEC || ep->version != CURRENT)
  733. return 0;
  734. /* we could definitely support a lot more machines here */
  735. fp->magic = ELF_MAG;
  736. fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
  737. switch(ep->machine) {
  738. case I386:
  739. mach = &mi386;
  740. fp->type = FI386;
  741. fp->name = "386 ELF32 executable";
  742. break;
  743. case MIPS:
  744. mach = &mmips;
  745. fp->type = FMIPS;
  746. fp->name = "mips ELF32 executable";
  747. break;
  748. case SPARC64:
  749. mach = &msparc64;
  750. fp->type = FSPARC64;
  751. fp->name = "sparc64 ELF32 executable";
  752. break;
  753. case POWER:
  754. mach = &mpower;
  755. fp->type = FPOWER;
  756. fp->name = "power ELF32 executable";
  757. break;
  758. case POWER64:
  759. mach = &mpower64;
  760. fp->type = FPOWER64;
  761. fp->name = "power64 ELF32 executable";
  762. break;
  763. case AMD64:
  764. mach = &mamd64;
  765. fp->type = FAMD64;
  766. fp->name = "amd64 ELF32 executable";
  767. break;
  768. case ARM:
  769. mach = &marm;
  770. fp->type = FARM;
  771. fp->name = "arm ELF32 executable";
  772. break;
  773. default:
  774. return 0;
  775. }
  776. if(ep->phentsize != sizeof(Phdr)) {
  777. werrstr("bad ELF32 header size");
  778. return 0;
  779. }
  780. phsz = sizeof(Phdr)*ep->phnum;
  781. ph = malloc(phsz);
  782. if(!ph)
  783. return 0;
  784. seek(fd, ep->phoff, 0);
  785. if(read(fd, ph, phsz) < 0) {
  786. free(ph);
  787. return 0;
  788. }
  789. hswal(ph, phsz/sizeof(uint32_t), swal);
  790. /* find text, data and symbols and install them */
  791. it = id = is = -1;
  792. for(i = 0; i < ep->phnum; i++) {
  793. if(ph[i].type == LOAD
  794. && (ph[i].flags & (R|X)) == (R|X) && it == -1)
  795. it = i;
  796. else if(ph[i].type == LOAD
  797. && (ph[i].flags & (R|W)) == (R|W) && id == -1)
  798. id = i;
  799. else if(ph[i].type == NOPTYPE && is == -1)
  800. is = i;
  801. }
  802. if(it == -1 || id == -1) {
  803. /*
  804. * The SPARC64 boot image is something of an ELF hack.
  805. * Text+Data+BSS are represented by ph[0]. Symbols
  806. * are represented by ph[1]:
  807. *
  808. * filesz, memsz, vaddr, paddr, off
  809. * ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff
  810. * ph[1] : symsz, lcsz, 0, 0, symoff
  811. */
  812. if(ep->machine == SPARC64 && ep->phnum == 2) {
  813. uint32_t txtaddr, txtsz, dataddr, bsssz;
  814. txtaddr = ph[0].vaddr | 0x80000000;
  815. txtsz = ph[0].filesz - ph[0].paddr;
  816. dataddr = txtaddr + txtsz;
  817. bsssz = ph[0].memsz - ph[0].filesz;
  818. settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset);
  819. setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz);
  820. setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset);
  821. free(ph);
  822. return 1;
  823. }
  824. werrstr("No ELF32 TEXT or DATA sections");
  825. free(ph);
  826. return 0;
  827. }
  828. settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
  829. setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz);
  830. if(is != -1)
  831. setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset);
  832. free(ph);
  833. return 1;
  834. }
  835. #endif
  836. /*
  837. * Elf binaries.
  838. */
  839. static int
  840. elfdotout(int fd, Fhdr *fp, ExecHdr *hp)
  841. {
  842. // Ehdr *ep;
  843. E64hdr *ep;
  844. /* bitswap the header according to the DATA format */
  845. ep = &hp->e;
  846. // if(ep->ident[CLASS] == ELFCLASS32)
  847. // return elf32dotout(fd, fp, hp);
  848. // else if(ep->ident[CLASS] == ELFCLASS64)
  849. if(ep->ident[CLASS] == ELFCLASS64)
  850. return elf64dotout(fd, fp, hp);
  851. // werrstr("bad ELF class - not 32- nor 64-bit");
  852. werrstr("bad ELF class - not 64-bit");
  853. return 0;
  854. }
  855. /*
  856. * (Free|Net)BSD ARM header.
  857. */
  858. static int
  859. armdotout(int fd, Fhdr *fp, ExecHdr *hp)
  860. {
  861. uint64_t kbase;
  862. USED(fd);
  863. settext(fp, hp->e.entry, sizeof(Exec), hp->e.text, sizeof(Exec));
  864. setdata(fp, fp->txtsz, hp->e.data, fp->txtsz, hp->e.bss);
  865. setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz);
  866. kbase = 0xF0000000;
  867. if ((fp->entry & kbase) == kbase) { /* Boot image */
  868. fp->txtaddr = kbase+sizeof(Exec);
  869. fp->name = "ARM *BSD boot image";
  870. fp->hdrsz = 0; /* header stripped */
  871. fp->dataddr = kbase+fp->txtsz;
  872. }
  873. return 1;
  874. }
  875. static void
  876. settext(Fhdr *fp, uint64_t e, uint64_t a, int32_t s, int64_t off)
  877. {
  878. fp->txtaddr = a;
  879. fp->entry = e;
  880. fp->txtsz = s;
  881. fp->txtoff = off;
  882. }
  883. static void
  884. setdata(Fhdr *fp, uint64_t a, int32_t s, int64_t off, int32_t bss)
  885. {
  886. fp->dataddr = a;
  887. fp->datsz = s;
  888. fp->datoff = off;
  889. fp->bsssz = bss;
  890. }
  891. static void
  892. setsym(Fhdr *fp, int32_t symsz, int32_t sppcsz, int32_t lnpcsz,
  893. int64_t symoff)
  894. {
  895. fp->symsz = symsz;
  896. fp->symoff = symoff;
  897. fp->sppcsz = sppcsz;
  898. fp->sppcoff = fp->symoff+fp->symsz;
  899. fp->lnpcsz = lnpcsz;
  900. fp->lnpcoff = fp->sppcoff+fp->sppcsz;
  901. }
  902. static uint64_t
  903. _round(uint64_t a, uint32_t b)
  904. {
  905. uint64_t w;
  906. w = (a/b)*b;
  907. if (a!=w)
  908. w += b;
  909. return(w);
  910. }