diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/parisc/kernel/binfmt_elf32.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/parisc/kernel/binfmt_elf32.c')
-rw-r--r-- | arch/parisc/kernel/binfmt_elf32.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c new file mode 100644 index 000000000000..d1833f164bbe --- /dev/null +++ b/arch/parisc/kernel/binfmt_elf32.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * Support for 32-bit Linux/Parisc ELF binaries on 64 bit kernels | ||
3 | * | ||
4 | * Copyright (C) 2000 John Marvin | ||
5 | * Copyright (C) 2000 Hewlett Packard Co. | ||
6 | * | ||
7 | * Heavily inspired from various other efforts to do the same thing | ||
8 | * (ia64,sparc64/mips64) | ||
9 | */ | ||
10 | |||
11 | /* Make sure include/asm-parisc/elf.h does the right thing */ | ||
12 | |||
13 | #define ELF_CLASS ELFCLASS32 | ||
14 | |||
15 | #define ELF_CORE_COPY_REGS(dst, pt) \ | ||
16 | memset(dst, 0, sizeof(dst)); /* don't leak any "random" bits */ \ | ||
17 | { int i; \ | ||
18 | for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \ | ||
19 | for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \ | ||
20 | } \ | ||
21 | dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \ | ||
22 | dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \ | ||
23 | dst[44] = (elf_greg_t) pt->sar; dst[45] = (elf_greg_t) pt->iir; \ | ||
24 | dst[46] = (elf_greg_t) pt->isr; dst[47] = (elf_greg_t) pt->ior; \ | ||
25 | dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \ | ||
26 | dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \ | ||
27 | dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \ | ||
28 | dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \ | ||
29 | dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \ | ||
30 | dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \ | ||
31 | dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \ | ||
32 | dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15); | ||
33 | |||
34 | |||
35 | typedef unsigned int elf_greg_t; | ||
36 | |||
37 | #include <linux/spinlock.h> | ||
38 | #include <asm/processor.h> | ||
39 | #include <linux/module.h> | ||
40 | #include <linux/elfcore.h> | ||
41 | #include <linux/compat.h> /* struct compat_timeval */ | ||
42 | |||
43 | #define elf_prstatus elf_prstatus32 | ||
44 | struct elf_prstatus32 | ||
45 | { | ||
46 | struct elf_siginfo pr_info; /* Info associated with signal */ | ||
47 | short pr_cursig; /* Current signal */ | ||
48 | unsigned int pr_sigpend; /* Set of pending signals */ | ||
49 | unsigned int pr_sighold; /* Set of held signals */ | ||
50 | pid_t pr_pid; | ||
51 | pid_t pr_ppid; | ||
52 | pid_t pr_pgrp; | ||
53 | pid_t pr_sid; | ||
54 | struct compat_timeval pr_utime; /* User time */ | ||
55 | struct compat_timeval pr_stime; /* System time */ | ||
56 | struct compat_timeval pr_cutime; /* Cumulative user time */ | ||
57 | struct compat_timeval pr_cstime; /* Cumulative system time */ | ||
58 | elf_gregset_t pr_reg; /* GP registers */ | ||
59 | int pr_fpvalid; /* True if math co-processor being used. */ | ||
60 | }; | ||
61 | |||
62 | #define elf_prpsinfo elf_prpsinfo32 | ||
63 | struct elf_prpsinfo32 | ||
64 | { | ||
65 | char pr_state; /* numeric process state */ | ||
66 | char pr_sname; /* char for pr_state */ | ||
67 | char pr_zomb; /* zombie */ | ||
68 | char pr_nice; /* nice val */ | ||
69 | unsigned int pr_flag; /* flags */ | ||
70 | u16 pr_uid; | ||
71 | u16 pr_gid; | ||
72 | pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; | ||
73 | /* Lots missing */ | ||
74 | char pr_fname[16]; /* filename of executable */ | ||
75 | char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ | ||
76 | }; | ||
77 | |||
78 | #define elf_addr_t unsigned int | ||
79 | #define init_elf_binfmt init_elf32_binfmt | ||
80 | |||
81 | #define ELF_PLATFORM ("PARISC32\0") | ||
82 | |||
83 | /* | ||
84 | * We should probably use this macro to set a flag somewhere to indicate | ||
85 | * this is a 32 on 64 process. We could use PER_LINUX_32BIT, or we | ||
86 | * could set a processor dependent flag in the thread_struct. | ||
87 | */ | ||
88 | |||
89 | #define SET_PERSONALITY(ex, ibcs2) \ | ||
90 | current->personality = PER_LINUX32; \ | ||
91 | current->thread.map_base = DEFAULT_MAP_BASE32; \ | ||
92 | current->thread.task_size = DEFAULT_TASK_SIZE32 \ | ||
93 | |||
94 | #undef cputime_to_timeval | ||
95 | #define cputime_to_timeval cputime_to_compat_timeval | ||
96 | static __inline__ void | ||
97 | cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) | ||
98 | { | ||
99 | unsigned long jiffies = cputime_to_jiffies(cputime); | ||
100 | value->tv_usec = (jiffies % HZ) * (1000000L / HZ); | ||
101 | value->tv_sec = jiffies / HZ; | ||
102 | } | ||
103 | |||
104 | #include "../../../fs/binfmt_elf.c" | ||
105 | |||
106 | /* Set up a separate execution domain for ELF32 binaries running | ||
107 | * on an ELF64 kernel */ | ||
108 | |||
109 | static struct exec_domain parisc32_exec_domain = { | ||
110 | .name = "Linux/ELF32", | ||
111 | .pers_low = PER_LINUX32, | ||
112 | .pers_high = PER_LINUX32, | ||
113 | }; | ||
114 | |||
115 | static int __init parisc32_exec_init(void) | ||
116 | { | ||
117 | /* steal the identity signal mappings from the default domain */ | ||
118 | parisc32_exec_domain.signal_map = default_exec_domain.signal_map; | ||
119 | parisc32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; | ||
120 | |||
121 | register_exec_domain(&parisc32_exec_domain); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | __initcall(parisc32_exec_init); | ||