1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 ## 12_ELF64_on_M32.dpatch by <jblache@debian.org>
4 ## All lines beginning with `## DP:' are a description of the patch.
5 ## DP: Add support for loading ELF64 kernels on 32bit PROMs.
6 ## DP: (some code shamelessly stolen from arcboot)
9 diff -urNad arcload-0.5~
/loader
/main.c arcload-0.5
/loader
/main.c
10 --- arcload-0.5~
/loader
/main.c
2007-09-11 16:17:27.000000000 +0000
11 +++ arcload-0.5
/loader
/main.c
2007-09-11 16:18:32.000000000 +0000
18 + unsigned char e_ident
[EI_NIDENT
];
27 INT checkmemmap
(ULONG elf_start
, ULONG elf_size
)
34 -ULONG load_elf
(CHAR
*fname
)
40 +Elf64_Addr load_elf32
(Elf32_Ehdr
*hdr
, BDEV
*file)
42 Elf32_Phdr ph
[N_PHDR
];
43 - ULONG elf_ehdr_size
= sizeof
(Elf32_Ehdr
);
44 - ULONG elf_phdr_size
= sizeof
(Elf32_Phdr
);
47 - Elf64_Phdr ph
[N_PHDR
];
48 - ULONG elf_ehdr_size
= sizeof
(Elf64_Ehdr
);
49 - ULONG elf_phdr_size
= sizeof
(Elf64_Phdr
);
56 - if(bopen
(&file, fname
)) {
57 - printf("Opening %s failed.\n\r", fname
);
58 + /* Not Relocatable?
*/
59 + if(hdr-
>e_type
!= ET_EXEC
) {
60 + printf("ELF file is not executable.\n\r");
61 + printf("Relocatable files are not supported, sorry.\n\r");
65 - printf("Loading %s...\n\r", fname
);
67 - /* Read ELF Header
*/
68 - if(bread
(&file, elf_ehdr_size
, &hdr
)<0) {
69 - printf("Error reading ELF header.\n\r");
71 + /* Does the ELF have any Program Headers?
*/
72 + if(hdr-
>e_phnum
== 0) {
73 + printf("ELF file contains no Program Headers.\n\r");
77 - /* Is is an ELF binary?
*/
78 - if((hdr.e_ident
[0] != 0x7f) ||
79 - (hdr.e_ident
[1] != 'E') ||
80 - (hdr.e_ident
[2] != 'L') ||
81 - (hdr.e_ident
[3] != 'F'))
83 - printf("ELF magic invalid.\n\r");
85 + /* Save LOAD headers
*/
86 + for(i
= 0; i
< hdr-
>e_phnum
; i
++) {
87 + bseek
(file, (hdr-
>e_phoff
+ (i
* hdr-
>e_phentsize
)));
88 + if(bread
(file, sizeof
(Elf32_Phdr
), ph
+nph
)<0) {
89 + printf("Can't read program header %u at 0x%x!\n\r", i
, hdr-
>e_phoff
+ (i
* hdr-
>e_phentsize
));
93 + if(ph
[nph
].p_type
!= PT_LOAD
)
98 + printf("ELF file has too many LOAD headers (over N_PHDR).\n\r");
103 - /* 32 or
64 bit?
*/
105 - if(hdr.e_ident
[EI_CLASS
] != ELFCLASS32
) {
106 - printf("ELF file is not 32-bit.\n\r");
108 - if(hdr.e_ident
[EI_CLASS
] != ELFCLASS64
) {
109 - printf("ELF file is not 64-bit.\n\r");
112 + /* Was a LOAD header found?
*/
114 + printf("ELF file contains no LOAD header.\n\r");
119 - if(hdr.e_ident
[EI_DATA
] != ELFDATA2MSB
) {
120 - printf("ELF file is not big-endian.\n\r");
122 + /* Realize LOAD headers
*/
123 + for(i
= 0; i
< nph
; i
++) {
124 + /* Check the Memory Map
*/
125 + if(checkmemmap
(vtophys
(ph
[i
].p_vaddr
), ph
[i
].p_memsz
)) {
126 + printf("File can't be loaded into current memory map.\n\r");
130 + /* Load the ELF into memory
*/
131 + printf("Reading %u bytes... ", (ULONG
)ph
[i
].p_filesz
);
132 + left
= ph
[i
].p_filesz
;
134 + ptr
= (UCHAR
*)ph
[i
].p_vaddr
;
135 + bseek
(file, ph
[i
].p_offset
);
137 + j
= ((left
> READBLOCK
) ? READBLOCK
: left
);
138 + if(bread
(file, j
, ptr
)<0) {
139 + printf("failed at %u!\n\r", (ULONG
)pos
);
147 + ptr
= (UCHAR
*)(ph
[i
].p_vaddr
+ ph
[i
].p_filesz
);
148 + for(pos
= ph
[i
].p_filesz
; pos
< ph
[i
].p_memsz
; pos
++)
152 + return (Elf64_Addr
) hdr-
>e_entry
;
156 +Elf64_Addr load_elf64
(Elf64_Ehdr
*hdr
, BDEV
*file)
158 + Elf64_Phdr ph
[N_PHDR
];
163 /* Not Relocatable?
*/
164 - if(hdr.e_ident
[EI_DATA
] != ET_EXEC
) {
165 + if(hdr-
>e_type
!= ET_EXEC
) {
166 printf("ELF file is not executable.\n\r");
167 printf("Relocatable files are not supported, sorry.\n\r");
172 /* Does the ELF have any Program Headers?
*/
173 - if(hdr.e_phnum
== 0) {
174 + if(hdr-
>e_phnum
== 0) {
175 printf("ELF file contains no Program Headers.\n\r");
180 /* Save LOAD headers
*/
181 - for(i
= 0; i
< hdr.e_phnum
; i
++) {
182 - bseek
(&file, (hdr.e_phoff
+ (i
* hdr.e_phentsize
)));
183 - if(bread
(&file, elf_phdr_size
, ph
+nph
)<0) {
184 - printf("Can't read program header %u at 0x%x!\n\r", i
, hdr.e_phoff
+ (i
* hdr.e_phentsize
));
186 + for(i
= 0; i
< hdr-
>e_phnum
; i
++) {
187 + bseek
(file, (hdr-
>e_phoff
+ (i
* hdr-
>e_phentsize
)));
188 + if(bread
(file, sizeof
(Elf64_Phdr
), ph
+nph
)<0) {
189 + printf("Can't read program header %u at 0x%x!\n\r", i
, hdr-
>e_phoff
+ (i
* hdr-
>e_phentsize
));
193 if(ph
[nph
].p_type
!= PT_LOAD
)
194 @@
-170,14 +209,14 @@
197 printf("ELF file has too many LOAD headers (over N_PHDR).\n\r");
203 /* Was a LOAD header found?
*/
205 printf("ELF file contains no LOAD header.\n\r");
210 /* Realize LOAD headers
*/
211 @@
-185,34 +224,96 @@
212 /* Check the Memory Map
*/
213 if(checkmemmap
(vtophys
(ph
[i
].p_vaddr
), ph
[i
].p_memsz
)) {
214 printf("File can't be loaded into current memory map.\n\r");
219 /* Load the ELF into memory
*/
220 printf("Reading %u bytes... ", (ULONG
)ph
[i
].p_filesz
);
221 left
= ph
[i
].p_filesz
;
224 + ptr
= (UCHAR
*)(Elf32_Addr
)ph
[i
].p_vaddr
;
226 ptr
= (UCHAR
*)ph
[i
].p_vaddr
;
227 - bseek
(&file, ph
[i
].p_offset
);
229 + bseek
(file, ph
[i
].p_offset
);
231 j
= ((left
> READBLOCK
) ? READBLOCK
: left
);
232 - if(bread
(&file, j
, ptr
)<0) {
233 + if(bread
(file, j
, ptr
)<0) {
234 printf("failed at %u!\n\r", (ULONG
)pos
);
244 + ptr
= (UCHAR
*)(Elf32_Addr
)(ph
[i
].p_vaddr
+ ph
[i
].p_filesz
);
246 ptr
= (UCHAR
*)(ph
[i
].p_vaddr
+ ph
[i
].p_filesz
);
248 for(pos
= ph
[i
].p_filesz
; pos
< ph
[i
].p_memsz
; pos
++)
252 + return hdr-
>e_entry
;
255 +Elf64_Addr load_elf
(CHAR
*fname
)
262 + if(bopen
(&file, fname
)) {
263 + printf("Opening %s failed.\n\r", fname
);
267 + printf("Loading %s...\n\r", fname
);
269 + /* Read ELF Header
*/
270 + if(bread
(&file, sizeof
(hdr
), &hdr
)<0) {
271 + printf("Error reading ELF header.\n\r");
275 + /* Is is an ELF binary?
*/
276 + if((hdr.e_ident
[0] != 0x7f) ||
277 + (hdr.e_ident
[1] != 'E') ||
278 + (hdr.e_ident
[2] != 'L') ||
279 + (hdr.e_ident
[3] != 'F'))
281 + printf("ELF magic invalid.\n\r");
286 + if(hdr.e_ident
[EI_DATA
] != ELFDATA2MSB
) {
287 + printf("ELF file is not big-endian.\n\r");
291 + /* 32 or
64 bit?
*/
292 + if(hdr.e_ident
[EI_CLASS
] == ELFCLASS64
) {
293 + kentry
= load_elf64
(&hdr.e64
, &file);
296 + else if(hdr.e_ident
[EI_CLASS
] == ELFCLASS32
) {
298 + kentry
= load_elf32
(&hdr.e32
, &file);
302 + printf("ELF file cannot be loaded.\n\r");
308 - return hdr.e_entry
;
311 /* Failed to
do something
, close and
return */
319 unsigned fixup_trampolines_data
[]={
320 0x03e00821, 0x04110001, 0x00000000, 0xdfe30014,
321 @@
-248,12 +350,31 @@
322 "Patched %u occurrences of the wrong trampoline.\n"
323 "-- WARNING --\n", stat
);
329 +void _start64
(LONG argc
, CHAR
* argv
[], CHAR
* envp
[],
330 + unsigned long long
*addr
)
332 + __asm__ __volatile__
(
335 + "\t.set noreorder\n"
345 LONG main
(INT argc
, CHAR
**argv
, CHAR
**envp
)
350 + Elf32_Addr entry32
= (Elf32_Addr
)entry
;
352 VOID
(*kernel_entry
)(INT argc
, CHAR
**argv
, CHAR
**envp
);
355 @@
-318,10 +439,25 @@
361 + kernel_entry
= (VOID
(*)(INT
, CHAR
**, CHAR
**))entry32
;
363 + printf("Entering 32bit kernel.\n\r");
364 + ArcFlushAllCaches
();
365 + kernel_entry
(append_count
, append
, envp
);
367 + printf("Entering 64bit kernel.\n\r");
368 + ArcFlushAllCaches
();
369 + _start64
(append_count
, append
, envp
, &entry
);
372 kernel_entry
= (VOID
(*)(INT
, CHAR
**, CHAR
**))entry
;
374 printf("Entering kernel.\n\r");
375 + ArcFlushAllCaches
();
376 kernel_entry
(append_count
, append
, envp
);