executable.c 21 KB

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