elf32_machdep.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /*-
  2. * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
  3. *
  4. * Copyright 1996-1998 John D. Polstra.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  19. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  25. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. *
  27. * $FreeBSD$
  28. */
  29. #include <sys/param.h>
  30. #include <sys/kernel.h>
  31. #include <sys/systm.h>
  32. #define __ELF_WORD_SIZE 32
  33. #include <sys/exec.h>
  34. #include <sys/imgact.h>
  35. #include <sys/malloc.h>
  36. #include <sys/proc.h>
  37. #include <sys/namei.h>
  38. #include <sys/fcntl.h>
  39. #include <sys/sysent.h>
  40. #include <sys/imgact_elf.h>
  41. #include <sys/jail.h>
  42. #include <sys/smp.h>
  43. #include <sys/syscall.h>
  44. #include <sys/sysctl.h>
  45. #include <sys/signalvar.h>
  46. #include <sys/vnode.h>
  47. #include <sys/linker.h>
  48. #include <vm/vm.h>
  49. #include <vm/vm_param.h>
  50. #include <machine/altivec.h>
  51. #include <machine/cpu.h>
  52. #include <machine/fpu.h>
  53. #include <machine/elf.h>
  54. #include <machine/reg.h>
  55. #include <machine/md_var.h>
  56. #include <powerpc/powerpc/elf_common.c>
  57. #ifdef __powerpc64__
  58. #include <compat/freebsd32/freebsd32_proto.h>
  59. #include <compat/freebsd32/freebsd32_util.h>
  60. extern const char *freebsd32_syscallnames[];
  61. static void ppc32_fixlimit(struct rlimit *rl, int which);
  62. static SYSCTL_NODE(_compat, OID_AUTO, ppc32, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
  63. "32-bit mode");
  64. #define PPC32_MAXDSIZ (1024*1024*1024)
  65. static u_long ppc32_maxdsiz = PPC32_MAXDSIZ;
  66. SYSCTL_ULONG(_compat_ppc32, OID_AUTO, maxdsiz, CTLFLAG_RWTUN, &ppc32_maxdsiz,
  67. 0, "");
  68. #define PPC32_MAXSSIZ (64*1024*1024)
  69. u_long ppc32_maxssiz = PPC32_MAXSSIZ;
  70. SYSCTL_ULONG(_compat_ppc32, OID_AUTO, maxssiz, CTLFLAG_RWTUN, &ppc32_maxssiz,
  71. 0, "");
  72. #else
  73. static void ppc32_runtime_resolve(void);
  74. #endif
  75. struct sysentvec elf32_freebsd_sysvec = {
  76. .sv_size = SYS_MAXSYSCALL,
  77. #ifdef __powerpc64__
  78. .sv_table = freebsd32_sysent,
  79. #else
  80. .sv_table = sysent,
  81. #endif
  82. .sv_transtrap = NULL,
  83. .sv_fixup = __elfN(freebsd_fixup),
  84. .sv_copyout_auxargs = __elfN(powerpc_copyout_auxargs),
  85. .sv_sendsig = sendsig,
  86. .sv_sigcode = sigcode32,
  87. .sv_szsigcode = &szsigcode32,
  88. .sv_name = "FreeBSD ELF32",
  89. .sv_coredump = __elfN(coredump),
  90. .sv_imgact_try = NULL,
  91. .sv_minsigstksz = MINSIGSTKSZ,
  92. .sv_minuser = VM_MIN_ADDRESS,
  93. .sv_stackprot = VM_PROT_ALL,
  94. #ifdef __powerpc64__
  95. .sv_maxuser = VM_MAXUSER_ADDRESS32,
  96. .sv_usrstack = FREEBSD32_USRSTACK,
  97. .sv_psstrings = FREEBSD32_PS_STRINGS,
  98. .sv_copyout_strings = freebsd32_copyout_strings,
  99. .sv_setregs = ppc32_setregs,
  100. .sv_syscallnames = freebsd32_syscallnames,
  101. .sv_fixlimit = ppc32_fixlimit,
  102. #else
  103. .sv_maxuser = VM_MAXUSER_ADDRESS,
  104. .sv_usrstack = USRSTACK,
  105. .sv_psstrings = PS_STRINGS,
  106. .sv_copyout_strings = exec_copyout_strings,
  107. .sv_setregs = exec_setregs,
  108. .sv_syscallnames = syscallnames,
  109. .sv_fixlimit = NULL,
  110. #endif
  111. .sv_maxssiz = NULL,
  112. .sv_flags = SV_ABI_FREEBSD | SV_ILP32 | SV_SHP | SV_ASLR |
  113. SV_TIMEKEEP | SV_RNG_SEED_VER,
  114. .sv_set_syscall_retval = cpu_set_syscall_retval,
  115. .sv_fetch_syscall_args = cpu_fetch_syscall_args,
  116. .sv_shared_page_base = FREEBSD32_SHAREDPAGE,
  117. .sv_shared_page_len = PAGE_SIZE,
  118. .sv_schedtail = NULL,
  119. .sv_thread_detach = NULL,
  120. .sv_trap = NULL,
  121. .sv_hwcap = &cpu_features,
  122. .sv_hwcap2 = &cpu_features2,
  123. };
  124. INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
  125. static Elf32_Brandinfo freebsd_brand_info = {
  126. .brand = ELFOSABI_FREEBSD,
  127. .machine = EM_PPC,
  128. .compat_3_brand = "FreeBSD",
  129. .emul_path = NULL,
  130. .interp_path = "/libexec/ld-elf.so.1",
  131. .sysvec = &elf32_freebsd_sysvec,
  132. #ifdef __powerpc64__
  133. .interp_newpath = "/libexec/ld-elf32.so.1",
  134. #else
  135. .interp_newpath = NULL,
  136. #endif
  137. .brand_note = &elf32_freebsd_brandnote,
  138. .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
  139. };
  140. SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST,
  141. (sysinit_cfunc_t) elf32_insert_brand_entry,
  142. &freebsd_brand_info);
  143. static Elf32_Brandinfo freebsd_brand_oinfo = {
  144. .brand = ELFOSABI_FREEBSD,
  145. .machine = EM_PPC,
  146. .compat_3_brand = "FreeBSD",
  147. .emul_path = NULL,
  148. .interp_path = "/usr/libexec/ld-elf.so.1",
  149. .sysvec = &elf32_freebsd_sysvec,
  150. .interp_newpath = NULL,
  151. .brand_note = &elf32_freebsd_brandnote,
  152. .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
  153. };
  154. SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
  155. (sysinit_cfunc_t) elf32_insert_brand_entry,
  156. &freebsd_brand_oinfo);
  157. void elf_reloc_self(Elf_Dyn *dynp, Elf_Addr relocbase);
  158. void
  159. elf32_dump_thread(struct thread *td, void *dst, size_t *off)
  160. {
  161. size_t len;
  162. struct pcb *pcb;
  163. uint64_t vshr[32];
  164. uint64_t *vsr_dw1;
  165. int vsr_idx;
  166. len = 0;
  167. pcb = td->td_pcb;
  168. if (pcb->pcb_flags & PCB_VEC) {
  169. save_vec_nodrop(td);
  170. if (dst != NULL) {
  171. len += elf32_populate_note(NT_PPC_VMX,
  172. &pcb->pcb_vec, (char *)dst + len,
  173. sizeof(pcb->pcb_vec), NULL);
  174. } else
  175. len += elf32_populate_note(NT_PPC_VMX, NULL, NULL,
  176. sizeof(pcb->pcb_vec), NULL);
  177. }
  178. if (pcb->pcb_flags & PCB_VSX) {
  179. save_fpu_nodrop(td);
  180. if (dst != NULL) {
  181. /*
  182. * Doubleword 0 of VSR0-VSR31 overlap with FPR0-FPR31 and
  183. * VSR32-VSR63 overlap with VR0-VR31, so we only copy
  184. * the non-overlapping data, which is doubleword 1 of VSR0-VSR31.
  185. */
  186. for (vsr_idx = 0; vsr_idx < nitems(vshr); vsr_idx++) {
  187. vsr_dw1 = (uint64_t *)&pcb->pcb_fpu.fpr[vsr_idx].vsr[2];
  188. vshr[vsr_idx] = *vsr_dw1;
  189. }
  190. len += elf32_populate_note(NT_PPC_VSX,
  191. vshr, (char *)dst + len,
  192. sizeof(vshr), NULL);
  193. } else
  194. len += elf32_populate_note(NT_PPC_VSX, NULL, NULL,
  195. sizeof(vshr), NULL);
  196. }
  197. *off = len;
  198. }
  199. #ifndef __powerpc64__
  200. bool
  201. elf_is_ifunc_reloc(Elf_Size r_info)
  202. {
  203. return (ELF_R_TYPE(r_info) == R_PPC_IRELATIVE);
  204. }
  205. /* Process one elf relocation with addend. */
  206. static int
  207. elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
  208. int type, int local, elf_lookup_fn lookup)
  209. {
  210. Elf_Addr *where;
  211. Elf_Half *hwhere;
  212. Elf_Addr addr;
  213. Elf_Addr addend, val;
  214. Elf_Word rtype, symidx;
  215. const Elf_Rela *rela;
  216. int error;
  217. switch (type) {
  218. case ELF_RELOC_REL:
  219. panic("PPC only supports RELA relocations");
  220. break;
  221. case ELF_RELOC_RELA:
  222. rela = (const Elf_Rela *)data;
  223. where = (Elf_Addr *) ((uintptr_t)relocbase + rela->r_offset);
  224. hwhere = (Elf_Half *) ((uintptr_t)relocbase + rela->r_offset);
  225. addend = rela->r_addend;
  226. rtype = ELF_R_TYPE(rela->r_info);
  227. symidx = ELF_R_SYM(rela->r_info);
  228. break;
  229. default:
  230. panic("elf_reloc: unknown relocation mode %d\n", type);
  231. }
  232. switch (rtype) {
  233. case R_PPC_NONE:
  234. break;
  235. case R_PPC_ADDR32: /* word32 S + A */
  236. error = lookup(lf, symidx, 1, &addr);
  237. if (error != 0)
  238. return (-1);
  239. *where = elf_relocaddr(lf, addr + addend);
  240. break;
  241. case R_PPC_ADDR16_LO: /* #lo(S) */
  242. error = lookup(lf, symidx, 1, &addr);
  243. if (error != 0)
  244. return (-1);
  245. /*
  246. * addend values are sometimes relative to sections
  247. * (i.e. .rodata) in rela, where in reality they
  248. * are relative to relocbase. Detect this condition.
  249. */
  250. if (addr > relocbase && addr <= (relocbase + addend))
  251. addr = relocbase;
  252. addr = elf_relocaddr(lf, addr + addend);
  253. *hwhere = addr & 0xffff;
  254. break;
  255. case R_PPC_ADDR16_HA: /* #ha(S) */
  256. error = lookup(lf, symidx, 1, &addr);
  257. if (error != 0)
  258. return (-1);
  259. /*
  260. * addend values are sometimes relative to sections
  261. * (i.e. .rodata) in rela, where in reality they
  262. * are relative to relocbase. Detect this condition.
  263. */
  264. if (addr > relocbase && addr <= (relocbase + addend))
  265. addr = relocbase;
  266. addr = elf_relocaddr(lf, addr + addend);
  267. *hwhere = ((addr >> 16) + ((addr & 0x8000) ? 1 : 0))
  268. & 0xffff;
  269. break;
  270. case R_PPC_RELATIVE: /* word32 B + A */
  271. *where = elf_relocaddr(lf, relocbase + addend);
  272. break;
  273. case R_PPC_JMP_SLOT: /* PLT jump slot entry */
  274. /*
  275. * We currently only support Secure-PLT jump slots.
  276. * Given that we reject BSS-PLT modules during load, we
  277. * don't need to check again.
  278. * The method we are using here is equivilent to
  279. * LD_BIND_NOW.
  280. */
  281. error = lookup(lf, symidx, 1, &addr);
  282. if (error != 0)
  283. return (-1);
  284. *where = elf_relocaddr(lf, addr + addend);
  285. break;
  286. case R_PPC_IRELATIVE:
  287. addr = relocbase + addend;
  288. val = ((Elf32_Addr (*)(void))addr)();
  289. if (*where != val)
  290. *where = val;
  291. break;
  292. default:
  293. printf("kldload: unexpected relocation type %d, "
  294. "symbol index %d\n", (int)rtype, symidx);
  295. return (-1);
  296. }
  297. return (0);
  298. }
  299. void
  300. elf_reloc_self(Elf_Dyn *dynp, Elf_Addr relocbase)
  301. {
  302. Elf_Rela *rela = NULL, *relalim;
  303. Elf_Addr relasz = 0;
  304. Elf_Addr *where;
  305. /*
  306. * Extract the rela/relasz values from the dynamic section
  307. */
  308. for (; dynp->d_tag != DT_NULL; dynp++) {
  309. switch (dynp->d_tag) {
  310. case DT_RELA:
  311. rela = (Elf_Rela *)(relocbase+dynp->d_un.d_ptr);
  312. break;
  313. case DT_RELASZ:
  314. relasz = dynp->d_un.d_val;
  315. break;
  316. }
  317. }
  318. /*
  319. * Relocate these values
  320. */
  321. relalim = (Elf_Rela *)((caddr_t)rela + relasz);
  322. for (; rela < relalim; rela++) {
  323. if (ELF_R_TYPE(rela->r_info) != R_PPC_RELATIVE)
  324. continue;
  325. where = (Elf_Addr *)(relocbase + rela->r_offset);
  326. *where = (Elf_Addr)(relocbase + rela->r_addend);
  327. }
  328. }
  329. int
  330. elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
  331. elf_lookup_fn lookup)
  332. {
  333. return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
  334. }
  335. int
  336. elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
  337. int type, elf_lookup_fn lookup)
  338. {
  339. return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
  340. }
  341. int
  342. elf_cpu_load_file(linker_file_t lf)
  343. {
  344. /* Only sync the cache for non-kernel modules */
  345. if (lf->id != 1)
  346. __syncicache(lf->address, lf->size);
  347. return (0);
  348. }
  349. int
  350. elf_cpu_unload_file(linker_file_t lf __unused)
  351. {
  352. return (0);
  353. }
  354. static void
  355. ppc32_runtime_resolve()
  356. {
  357. /*
  358. * Since we don't support lazy binding, panic immediately if anyone
  359. * manages to call the runtime resolver.
  360. */
  361. panic("kldload: Runtime resolver was called unexpectedly!");
  362. }
  363. int
  364. elf_cpu_parse_dynamic(caddr_t loadbase, Elf_Dyn *dynamic)
  365. {
  366. Elf_Dyn *dp;
  367. bool has_plt = false;
  368. bool secure_plt = false;
  369. Elf_Addr *got;
  370. for (dp = dynamic; dp->d_tag != DT_NULL; dp++) {
  371. switch (dp->d_tag) {
  372. case DT_PPC_GOT:
  373. secure_plt = true;
  374. got = (Elf_Addr *)(loadbase + dp->d_un.d_ptr);
  375. /* Install runtime resolver canary. */
  376. got[1] = (Elf_Addr)ppc32_runtime_resolve;
  377. got[2] = (Elf_Addr)0;
  378. break;
  379. case DT_PLTGOT:
  380. has_plt = true;
  381. break;
  382. }
  383. }
  384. if (has_plt && !secure_plt) {
  385. printf("kldload: BSS-PLT modules are not supported.\n");
  386. return (-1);
  387. }
  388. return (0);
  389. }
  390. #endif
  391. #ifdef __powerpc64__
  392. static void
  393. ppc32_fixlimit(struct rlimit *rl, int which)
  394. {
  395. switch (which) {
  396. case RLIMIT_DATA:
  397. if (ppc32_maxdsiz != 0) {
  398. if (rl->rlim_cur > ppc32_maxdsiz)
  399. rl->rlim_cur = ppc32_maxdsiz;
  400. if (rl->rlim_max > ppc32_maxdsiz)
  401. rl->rlim_max = ppc32_maxdsiz;
  402. }
  403. break;
  404. case RLIMIT_STACK:
  405. if (ppc32_maxssiz != 0) {
  406. if (rl->rlim_cur > ppc32_maxssiz)
  407. rl->rlim_cur = ppc32_maxssiz;
  408. if (rl->rlim_max > ppc32_maxssiz)
  409. rl->rlim_max = ppc32_maxssiz;
  410. }
  411. break;
  412. }
  413. }
  414. #endif