Ticket #6307: haiku_loader.elf64support.txt

File haiku_loader.elf64support.txt, 35.8 KB (added by nmentley, 9 years ago)

elf64 haiku_loader loading support

Line 
1Index: src/system/boot/platform/bios_ia32/smp.cpp
2===================================================================
3--- src/system/boot/platform/bios_ia32/smp.cpp  (revision 37496)
4+++ src/system/boot/platform/bios_ia32/smp.cpp  (working copy)
5@@ -472,7 +472,7 @@
6        uint32 j;
7 
8        // set this stack up
9-       finalStack = (uint32 *)gKernelArgs.cpu_kstack[i].start;
10+       finalStack = (uint32 *)(addr_t)gKernelArgs.cpu_kstack[i].start;
11        memset((uint8*)finalStack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, 0,
12            KERNEL_STACK_SIZE);
13        tempStack = (finalStack
14Index: src/system/boot/loader/elf.cpp
15===================================================================
16--- src/system/boot/loader/elf.cpp  (revision 37496)
17+++ src/system/boot/loader/elf.cpp  (working copy)
18@@ -11,6 +11,7 @@
19 #include <boot/stage2.h>
20 #include <driver_settings.h>
21 #include <elf32.h>
22+#include <elf64.h>
23 #include <kernel.h>
24 
25 #include <unistd.h>
26@@ -60,6 +61,20 @@
27 
28 
29 static status_t
30+verify_elf64_header(struct Elf64_Ehdr &header)
31+{
32+   if (memcmp(header.e_ident, ELF_MAGIC, 4) != 0
33+       || header.e_ident[4] != ELFCLASS64
34+       || header.e_phoff == 0
35+       || !header.IsHostEndian()
36+       || header.e_phentsize != sizeof(struct Elf64_Phdr))
37+       return B_BAD_TYPE;
38+
39+   return B_OK;
40+}
41+
42+
43+static status_t
44 elf_parse_dynamic_section(struct preloaded_image *image)
45 {
46    image->syms = 0;
47@@ -71,7 +86,7 @@
48    image->pltrel_len = 0;
49    image->pltrel_type = 0;
50 
51-   struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_section.start;
52+   struct Elf32_Dyn *d = (struct Elf32_Dyn *)(addr_t)image->dynamic_section.start;
53    if (!d)
54        return B_ERROR;
55 
56@@ -123,6 +138,69 @@
57 
58 
59 static status_t
60+elf64_parse_dynamic_section(struct preloaded_image *image)
61+{
62+   image->syms64 = 0;
63+   image->rel64 = 0;
64+   image->rel_len = 0;
65+   image->rela64 = 0;
66+   image->rela_len = 0;
67+   image->pltrel64 = 0;
68+   image->pltrel_len = 0;
69+   image->pltrel_type = 0;
70+
71+   struct Elf64_Dyn *d = (struct Elf64_Dyn *)(addr_t)image->dynamic_section.start;
72+   if (!d)
73+       return B_ERROR;
74+
75+   for (int i = 0; d[i].d_tag != DT_NULL; i++) {
76+       switch (d[i].d_tag) {
77+           case DT_HASH:
78+           case DT_STRTAB:
79+               break;
80+           case DT_SYMTAB:
81+               image->syms64 = (struct Elf64_Sym *)(d[i].d_un.d_ptr
82+                   + image->text_region.delta);
83+               break;
84+           case DT_REL:
85+               image->rel64 = (struct Elf64_Rel *)(d[i].d_un.d_ptr
86+                   + image->text_region.delta);
87+               break;
88+           case DT_RELSZ:
89+               image->rel_len = d[i].d_un.d_val;
90+               break;
91+           case DT_RELA:
92+               image->rela64 = (struct Elf64_Rela *)(d[i].d_un.d_ptr
93+                   + image->text_region.delta);
94+               break;
95+           case DT_RELASZ:
96+               image->rela_len = d[i].d_un.d_val;
97+               break;
98+           case DT_JMPREL:
99+               image->pltrel64 = (struct Elf64_Rel *)(d[i].d_un.d_ptr
100+                   + image->text_region.delta);
101+               break;
102+           case DT_PLTRELSZ:
103+               image->pltrel_len = d[i].d_un.d_val;
104+               break;
105+           case DT_PLTREL:
106+               image->pltrel_type = d[i].d_un.d_val;
107+               break;
108+
109+           default:
110+               continue;
111+       }
112+   }
113+
114+   // lets make sure we found all the required sections
115+   if (image->syms64 == NULL)
116+       return B_ERROR;
117+
118+   return B_OK;
119+}
120+
121+
122+static status_t
123 load_elf_symbol_table(int fd, preloaded_image *image)
124 {
125    struct Elf32_Ehdr &elfHeader = image->elf_header;
126@@ -224,24 +302,116 @@
127 }
128 
129 
130+static status_t
131+load_elf64_symbol_table(int fd, preloaded_image *image)
132+{
133+   struct Elf64_Ehdr &elfHeader = image->elf_header64;
134+   Elf64_Sym *symbolTable = NULL;
135+   Elf64_Shdr *stringHeader = NULL;
136+   uint32 numSymbols = 0;
137+   char *stringTable;
138+   status_t status;
139+
140+   // get section headers
141+
142+   ssize_t size = elfHeader.e_shnum * elfHeader.e_shentsize;
143+   Elf64_Shdr *sectionHeaders = (struct Elf64_Shdr *)malloc(size);
144+   if (sectionHeaders == NULL) {
145+       dprintf("error allocating space for section headers\n");
146+       return B_NO_MEMORY;
147+   }
148+
149+   ssize_t length = read_pos(fd, elfHeader.e_shoff, sectionHeaders, size);
150+   if (length < size) {
151+       TRACE(("error reading in program headers\n"));
152+       status = B_ERROR;
153+       goto error1;
154+   }
155+
156+   // find symbol table in section headers
157+
158+   for (int32 i = 0; i < elfHeader.e_shnum; i++) {
159+       if (sectionHeaders[i].sh_type == SHT_SYMTAB) {
160+           stringHeader = &sectionHeaders[sectionHeaders[i].sh_link];
161+
162+           if (stringHeader->sh_type != SHT_STRTAB) {
163+               TRACE(("doesn't link to string table\n"));
164+               status = B_BAD_DATA;
165+               goto error1;
166+           }
167+
168+           // read in symbol table
169+           symbolTable = (Elf64_Sym *)kernel_args_malloc(
170+               size = sectionHeaders[i].sh_size);
171+           if (symbolTable == NULL) {
172+               status = B_NO_MEMORY;
173+               goto error1;
174+           }
175+
176+           length = read_pos(fd, sectionHeaders[i].sh_offset, symbolTable,
177+               size);
178+           if (length < size) {
179+               TRACE(("error reading in symbol table\n"));
180+               status = B_ERROR;
181+               goto error1;
182+           }
183+
184+           numSymbols = size / sizeof(Elf64_Sym);
185+           break;
186+       }
187+   }
188+
189+   if (symbolTable == NULL) {
190+       TRACE(("no symbol table\n"));
191+       status = B_BAD_VALUE;
192+       goto error1;
193+   }
194+
195+   // read in string table
196+
197+   stringTable = (char *)kernel_args_malloc(size = stringHeader->sh_size);
198+   if (stringTable == NULL) {
199+       status = B_NO_MEMORY;
200+       goto error2;
201+   }
202+
203+   length = read_pos(fd, stringHeader->sh_offset, stringTable, size);
204+   if (length < size) {
205+       TRACE(("error reading in string table\n"));
206+       status = B_ERROR;
207+       goto error3;
208+   }
209+
210+   TRACE(("loaded %ld debug symbols\n", numSymbols));
211+
212+   // insert tables into image
213+   image->debug_symbols64 = symbolTable;
214+   image->num_debug_symbols = numSymbols;
215+   image->debug_string_table = stringTable;
216+   image->debug_string_table_size = size;
217+
218+   free(sectionHeaders);
219+   return B_OK;
220+
221+error3:
222+   kernel_args_free(stringTable);
223+error2:
224+   kernel_args_free(symbolTable);
225+error1:
226+   free(sectionHeaders);
227+
228+   return status;
229+}
230+
231 status_t
232-elf_load_image(int fd, preloaded_image *image)
233+elf32_load_image(int fd, preloaded_image *image)
234 {
235    size_t totalSize;
236    status_t status;
237 
238-   TRACE(("elf_load_image(fd = %d, image = %p)\n", fd, image));
239-
240    struct Elf32_Ehdr &elfHeader = image->elf_header;
241-
242    ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf32_Ehdr));
243-   if (length < (ssize_t)sizeof(Elf32_Ehdr))
244-       return B_BAD_TYPE;
245 
246-   status = verify_elf_header(elfHeader);
247-   if (status < B_OK)
248-       return status;
249-
250    ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize;
251    Elf32_Phdr *programHeaders = (struct Elf32_Phdr *)malloc(size);
252    if (programHeaders == NULL) {
253@@ -407,8 +577,214 @@
254    return status;
255 }
256 
257+status_t
258+elf64_load_image(int fd, preloaded_image *image)
259+{
260+   size_t totalSize;
261+   status_t status;
262 
263+   struct Elf64_Ehdr &elfHeader = image->elf_header64;
264+   ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf64_Ehdr));
265+
266+   ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize;
267+   Elf64_Phdr *programHeaders = (struct Elf64_Phdr *)malloc(size);
268+   if (programHeaders == NULL) {
269+       dprintf("error allocating space for program headers\n");
270+       return B_NO_MEMORY;
271+   }
272+
273+   length = read_pos(fd, elfHeader.e_phoff, programHeaders, size);
274+   if (length < size) {
275+       TRACE(("error reading in program headers\n"));
276+       status = B_ERROR;
277+       goto error1;
278+   }
279+
280+   // create an area large enough to hold the image
281+
282+   image->data_region.size = 0;
283+   image->text_region.size = 0;
284+
285+   for (int32 i = 0; i < elfHeader.e_phnum; i++) {
286+       Elf64_Phdr &header = programHeaders[i];
287+
288+       switch (header.p_type) {
289+           case PT_LOAD:
290+               break;
291+           case PT_DYNAMIC:
292+               image->dynamic_section.start = header.p_vaddr;
293+               image->dynamic_section.size = header.p_memsz;
294+               continue;
295+           case PT_INTERP:
296+           case PT_PHDR:
297+               // known but unused type
298+               continue;
299+           default:
300+               dprintf("unhandled pheader type 0x%lx\n", header.p_type);
301+               continue;
302+       }
303+
304+       elf_region *region;
305+       if (header.IsReadWrite()) {
306+           if (image->data_region.size != 0) {
307+               dprintf("elf: rw already handled!\n");
308+               continue;
309+           }
310+           region = &image->data_region;
311+       } else if (header.IsExecutable()) {
312+           if (image->text_region.size != 0) {
313+               dprintf("elf: ro already handled!\n");
314+               continue;
315+           }
316+           region = &image->text_region;
317+       } else
318+           continue;
319+
320+       region->start = ROUNDDOWN(header.p_vaddr, B_PAGE_SIZE);
321+       region->size = ROUNDUP(header.p_memsz + (header.p_vaddr % B_PAGE_SIZE),
322+           B_PAGE_SIZE);
323+       region->delta = -region->start;
324+
325+       TRACE(("segment %d: start = %p, size = %lu, delta = %lx\n", i,
326+           region->start, region->size, region->delta));
327+   }
328+   image->text_region.size = 1;
329+   // found both, text and data?
330+   if (image->data_region.size == 0 || image->text_region.size == 0) {
331+       dprintf("Couldn't find both text and data segment!\n");
332+       status = B_BAD_DATA;
333+       goto error1;
334+   }
335+
336+   // get the segment order
337+   elf_region *firstRegion;
338+   elf_region *secondRegion;
339+   if (image->text_region.start < image->data_region.start) {
340+       firstRegion = &image->text_region;
341+       secondRegion = &image->data_region;
342+   } else {
343+       firstRegion = &image->data_region;
344+       secondRegion = &image->text_region;
345+   }
346+
347+   // Check whether the segments have an unreasonable amount of unused space
348+   // inbetween.
349+   totalSize = secondRegion->start + secondRegion->size - firstRegion->start;
350+/* if (totalSize > image->text_region.size + image->data_region.size
351+       + 8 * 1024) {
352+       status = B_BAD_DATA;
353+       goto error1;
354+   }
355+*/
356+   // The kernel and the modules are relocatable, thus
357+   // platform_allocate_region() can automatically allocate an address,
358+   // but shall prefer the specified base address.
359+   if (platform_allocate_region((void **)&firstRegion->start, totalSize,
360+           B_READ_AREA | B_WRITE_AREA, false) < B_OK) {
361+       status = B_NO_MEMORY;
362+       goto error1;
363+   }
364+
365+   // initialize the region pointers to the allocated region
366+   secondRegion->start += firstRegion->start + firstRegion->delta;
367+
368+   image->data_region.delta += image->data_region.start;
369+   image->text_region.delta += image->text_region.start;
370+
371+   // load program data
372+
373+   for (int i = 0; i < elfHeader.e_phnum; i++) {
374+       Elf64_Phdr &header = programHeaders[i];
375+
376+       if (header.p_type != PT_LOAD)
377+           continue;
378+
379+       elf_region *region;
380+       if (header.IsReadWrite())
381+           region = &image->data_region;
382+       else if (header.IsExecutable())
383+           region = &image->text_region;
384+       else
385+           continue;
386+
387+       TRACE(("load segment %d (%ld bytes)...\n", i, header.p_filesz));
388+
389+       length = read_pos(fd, header.p_offset,
390+           (void *)(region->start + (header.p_vaddr % B_PAGE_SIZE)),
391+           header.p_filesz);
392+       if (length < (ssize_t)header.p_filesz) {
393+           status = B_BAD_DATA;
394+           dprintf("error reading in seg %d\n", i);
395+           goto error2;
396+       }
397+
398+       // Clear anything above the file size (that may also contain the BSS
399+       // area)
400+
401+       uint32 offset = (header.p_vaddr % B_PAGE_SIZE) + header.p_filesz;
402+       if (offset < region->size)
403+           memset((void *)(region->start + offset), 0, region->size - offset);
404+   }
405+
406+   // offset dynamic section, and program entry addresses by the delta of the
407+   // regions
408+   image->dynamic_section.start += image->text_region.delta;
409+   image->elf_header.e_entry += image->text_region.delta;
410+
411+   image->num_debug_symbols = 0;
412+   image->debug_symbols = NULL;
413+   image->debug_string_table = NULL;
414+
415+   if (sLoadElfSymbols)
416+       load_elf64_symbol_table(fd, image);
417+
418+   free(programHeaders);
419+
420+   return B_OK;
421+
422+error2:
423+   if (image->text_region.start != 0)
424+       platform_free_region((void *)image->text_region.start, totalSize);
425+error1:
426+   free(programHeaders);
427+
428+   return status;
429+}
430+
431 status_t
432+elf_load_image(int fd, preloaded_image *image)
433+{
434+   status_t status;
435+
436+   TRACE(("elf_load_image(fd = %d, image = %p)\n", fd, image));
437+
438+   struct Elf32_Ehdr &elfHeader = image->elf_header;
439+   struct Elf64_Ehdr &elfHeader64 = image->elf_header64;
440+
441+   ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf32_Ehdr));
442+   if (length < (ssize_t)sizeof(Elf32_Ehdr))
443+       return B_BAD_TYPE;
444+
445+   status = verify_elf_header(elfHeader);
446+   if (status < B_OK) {    //not elf32. Check if elf64.
447+       ssize_t length = read_pos(fd, 0, &elfHeader64, sizeof(Elf64_Ehdr));
448+       if (length < (ssize_t)sizeof(Elf64_Ehdr))
449+           return B_BAD_TYPE;
450+
451+       status = verify_elf64_header(elfHeader64);
452+       if (status < B_OK)
453+           return status;
454+
455+       image->elf_size = 64;
456+       return elf64_load_image(fd, image);
457+   }
458+
459+   image->elf_size = 32;
460+   return elf32_load_image(fd, image);
461+}
462+
463+
464+status_t
465 elf_load_image(Directory *directory, const char *path)
466 {
467    preloaded_image *image;
468@@ -458,7 +834,7 @@
469 
470 
471 status_t
472-elf_relocate_image(struct preloaded_image *image)
473+elf32_relocate_image(struct preloaded_image *image)
474 {
475    status_t status = elf_parse_dynamic_section(image);
476    if (status != B_OK)
477@@ -503,6 +879,60 @@
478 
479 
480 status_t
481+elf64_relocate_image(struct preloaded_image *image)
482+{
483+   status_t status = elf64_parse_dynamic_section(image);
484+   if (status != B_OK)
485+       return status;
486+
487+   // deal with the rels first
488+   if (image->rel64) {
489+       TRACE(("total %i relocs\n",
490+           image->rel_len / (int)sizeof(struct Elf64_Rel)));
491+
492+       status = boot_arch_elf64_relocate_rel(image, image->rel64, image->rel_len);
493+       if (status < B_OK)
494+           return status;
495+   }
496+
497+   if (image->pltrel64) {
498+       TRACE(("total %i plt-relocs\n",
499+           image->pltrel_len / (int)sizeof(struct Elf64_Rel)));
500+
501+       if (image->pltrel_type == DT_REL) {
502+           status = boot_arch_elf64_relocate_rel(image, image->pltrel64,
503+               image->pltrel_len);
504+       } else {
505+           status = boot_arch_elf64_relocate_rela(image,
506+               (struct Elf64_Rela *)image->pltrel64, image->pltrel_len);
507+       }
508+       if (status < B_OK)
509+           return status;
510+   }
511+
512+   if (image->rela64) {
513+       TRACE(("total %i rela relocs\n",
514+           image->rela_len / (int)sizeof(struct Elf64_Rela)));
515+       status = boot_arch_elf64_relocate_rela(image, image->rela64,
516+           image->rela_len);
517+       if (status < B_OK)
518+           return status;
519+   }
520+   panic("relocate 4");
521+   return B_OK;
522+}
523+
524+status_t
525+elf_relocate_image(struct preloaded_image *image)
526+{
527+   if(image->elf_size == 32)
528+       return elf32_relocate_image(image);
529+
530+   return elf64_relocate_image(image);
531+}
532+
533+
534+status_t
535 boot_elf_resolve_symbol(struct preloaded_image *image,
536    struct Elf32_Sym *symbol, addr_t *symbolAddress)
537 {
538@@ -524,3 +954,26 @@
539            return B_NO_ERROR;
540    }
541 }
542+
543+status_t
544+boot_elf64_resolve_symbol(struct preloaded_image *image,
545+   struct Elf64_Sym *symbol, addr_t *symbolAddress)
546+{
547+   switch (symbol->st_shndx) {
548+       case SHN_UNDEF:
549+           // Since we do that only for the kernel, there shouldn't be
550+           // undefined symbols.
551+           return B_MISSING_SYMBOL;
552+       case SHN_ABS:
553+           *symbolAddress = symbol->st_value;
554+           return B_NO_ERROR;
555+       case SHN_COMMON:
556+           // ToDo: finish this
557+           TRACE(("elf_resolve_symbol: COMMON symbol, finish me!\n"));
558+           return B_ERROR;
559+       default:
560+           // standard symbol
561+           *symbolAddress = symbol->st_value + image->text_region.delta;
562+           return B_NO_ERROR;
563+   }
564+}
565Index: headers/private/system/elf32.h
566===================================================================
567--- headers/private/system/elf32.h  (revision 37496)
568+++ headers/private/system/elf32.h  (working copy)
569@@ -1,5 +1,5 @@
570 /*
571- * Copyright 2002-2009, Haiku Inc. All Rights Reserved.
572+ * Copyright 2002-2010, Haiku Inc. All Rights Reserved.
573  * Distributed under the terms of the MIT license.
574  *
575  * Copyright 2001, Travis Geiselbrecht. All rights reserved.
576@@ -8,13 +8,12 @@
577 #ifndef _ELF32_H
578 #define _ELF32_H
579 
580-
581 #include <SupportDefs.h>
582 #include <ByteOrder.h>
583 
584 #include <arch_elf.h>
585+#include <elf_common.h>
586 
587-
588 typedef uint32 Elf32_Addr;
589 typedef uint16 Elf32_Half;
590 typedef uint32 Elf32_Off;
591@@ -25,8 +24,6 @@
592 
593 /*** ELF header ***/
594 
595-#define EI_NIDENT  16
596-
597 struct Elf32_Ehdr {
598    uint8       e_ident[EI_NIDENT];
599    Elf32_Half  e_type;
600@@ -48,26 +45,6 @@
601 #endif
602 };
603 
604-#define ELF_MAGIC  "\x7f""ELF"
605-
606-// e_ident[] indices
607-#define EI_MAG0        0
608-#define EI_MAG1        1
609-#define EI_MAG2        2
610-#define EI_MAG3        3
611-#define EI_CLASS   4
612-#define EI_DATA        5
613-#define EI_VERSION 6
614-#define EI_PAD     7
615-
616-// architecture class (EI_CLASS)
617-#define ELFCLASS32 1
618-#define ELFCLASS64 2
619-// endian (EI_DATA)
620-#define ELFDATA2LSB    1   /* little endian */
621-#define ELFDATA2MSB    2   /* big endian */
622-
623-
624 /*** section header ***/
625 
626 struct Elf32_Shdr {
627@@ -83,46 +60,7 @@
628    Elf32_Word  sh_entsize;
629 };
630 
631-// special section indices
632-#define SHN_UNDEF      0
633-#define SHN_LORESERVE  0xff00
634-#define SHN_LOPROC     0xff00
635-#define SHN_HIPROC     0xff1f
636-#define SHN_ABS            0xfff1
637-#define SHN_COMMON     0xfff2
638-#define SHN_HIRESERVE  0xffff
639 
640-// section header type
641-#define SHT_NULL       0
642-#define SHT_PROGBITS   1
643-#define SHT_SYMTAB     2
644-#define SHT_STRTAB     3
645-#define SHT_RELA       4
646-#define SHT_HASH       5
647-#define SHT_DYNAMIC        6
648-#define SHT_NOTE       7
649-#define SHT_NOBITS     8
650-#define SHT_REL            9
651-#define SHT_SHLIB      10
652-#define SHT_DYNSYM     11
653-
654-#define SHT_GNU_verdef 0x6ffffffd    /* version definition section */
655-#define SHT_GNU_verneed    0x6ffffffe    /* version needs section */
656-#define SHT_GNU_versym 0x6fffffff    /* version symbol table */
657-
658-#define SHT_LOPROC     0x70000000
659-#define SHT_HIPROC     0x7fffffff
660-#define SHT_LOUSER     0x80000000
661-#define SHT_HIUSER     0xffffffff
662-
663-// section header flags
664-#define SHF_WRITE      1
665-#define SHF_ALLOC      2
666-#define SHF_EXECINSTR  4
667-
668-#define SHF_MASKPROC   0xf0000000
669-
670-
671 /*** program header ***/
672 
673 struct Elf32_Phdr {
674@@ -141,27 +79,6 @@
675 #endif
676 };
677 
678-// program header segment types
679-#define PT_NULL        0
680-#define PT_LOAD        1
681-#define PT_DYNAMIC 2
682-#define PT_INTERP  3
683-#define PT_NOTE        4
684-#define PT_SHLIB   5
685-#define PT_PHDR        6
686-#define PT_STACK   0x6474e551
687-
688-#define PT_LOPROC  0x70000000
689-#define PT_HIPROC  0x7fffffff
690-
691-// program header segment flags
692-#define PF_EXECUTE 0x1
693-#define PF_WRITE   0x2
694-#define PF_READ        0x4
695-#define PF_PROTECTION_MASK (PF_EXECUTE | PF_WRITE | PF_READ)
696-
697-#define PF_MASKPROC    0xf0000000
698-
699 struct Elf32_Sym {
700    Elf32_Word  st_name;
701    Elf32_Addr  st_value;
702@@ -180,22 +97,6 @@
703 #define ELF32_ST_TYPE(i) ((i) & 0xf)
704 #define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf))
705 
706-#define STT_NOTYPE 0
707-#define STT_OBJECT 1
708-#define STT_FUNC 2
709-#define STT_SECTION 3
710-#define STT_FILE 4
711-#define STT_LOPROC 13
712-#define STT_HIPROC 15
713-
714-#define STB_LOCAL 0
715-#define STB_GLOBAL 1
716-#define STB_WEAK 2
717-#define STB_LOPROC 13
718-#define STB_HIPROC 15
719-
720-#define STN_UNDEF 0
721-
722 struct Elf32_Rel {
723    Elf32_Addr r_offset;
724    Elf32_Word r_info;
725@@ -228,41 +129,6 @@
726    } d_un;
727 };
728 
729-#define DT_NULL        0
730-#define DT_NEEDED  1
731-#define DT_PLTRELSZ    2
732-#define DT_PLTGOT  3
733-#define DT_HASH        4
734-#define DT_STRTAB  5
735-#define DT_SYMTAB  6
736-#define DT_RELA        7
737-#define DT_RELASZ  8
738-#define DT_RELAENT 9
739-#define DT_STRSZ   10
740-#define DT_SYMENT  11
741-#define DT_INIT        12
742-#define DT_FINI        13
743-#define DT_SONAME  14
744-#define DT_RPATH   15
745-#define DT_SYMBOLIC    16
746-#define DT_REL     17
747-#define DT_RELSZ   18
748-#define DT_RELENT  19
749-#define DT_PLTREL  20
750-#define DT_DEBUG   21
751-#define DT_TEXTREL 22
752-#define DT_JMPREL  23
753-
754-#define DT_VERSYM       0x6ffffff0 /* symbol version table */
755-#define DT_VERDEF      0x6ffffffc  /* version definition table */
756-#define DT_VERDEFNUM   0x6ffffffd  /* number of version definitions */
757-#define DT_VERNEED     0x6ffffffe  /* table with needed versions */
758-#define DT_VERNEEDNUM  0x6fffffff  /* number of needed versions */
759-
760-#define DT_LOPROC      0x70000000
761-#define DT_HIPROC      0x7fffffff
762-
763-
764 /* version definition section */
765 
766 struct Elf32_Verdef {
767@@ -276,31 +142,6 @@
768    Elf32_Word  vd_next;        /* byte offset to next verdef entry */
769 };
770 
771-/* values for vd_version (version revision) */
772-#define VER_DEF_NONE       0       /* no version */
773-#define VER_DEF_CURRENT        1       /* current version */
774-#define VER_DEF_NUM            2       /* given version number */
775-
776-/* values for vd_flags (version information flags) */
777-#define VER_FLG_BASE       0x1     /* version definition of file itself */
778-#define VER_FLG_WEAK       0x2     /* weak version identifier */
779-
780-/* values for versym symbol index */
781-#define VER_NDX_LOCAL      0       /* symbol is local */
782-#define VER_NDX_GLOBAL     1       /* symbol is global/unversioned */
783-#define VER_NDX_INITIAL        2       /* initial version -- that's the one given
784-                                      to symbols when a library becomes
785-                                      versioned; handled by the linker (and
786-                                      runtime loader) similar to
787-                                      VER_NDX_GLOBAL */
788-#define VER_NDX_LORESERVE  0xff00  /* beginning of reserved entries */
789-#define VER_NDX_ELIMINATE  0xff01  /* symbol is to be eliminated */
790-
791-#define VER_NDX_FLAG_HIDDEN    0x8000  /* flag: version is hidden */
792-#define VER_NDX_MASK       0x7fff  /* mask to get the actual version index */
793-#define VER_NDX(x)         ((x) & VER_NDX_MASK)
794-
795-
796 /* auxiliary version information */
797 
798 struct Elf32_Verdaux {
799@@ -321,12 +162,6 @@
800    Elf32_Word  vn_next;        /* byte offset to next verneed entry */
801 };
802 
803-/* values for vn_version (version revision) */
804-#define VER_NEED_NONE      0   /* no version */
805-#define VER_NEED_CURRENT   1   /* current version */
806-#define VER_NEED_NUM       2   /* given version number */
807-
808-
809 /* auxiliary needed version information */
810 
811 struct Elf32_Vernaux {
812@@ -338,10 +173,6 @@
813    Elf32_Word  vna_next;       /* byte offset to next vernaux entry */
814 };
815 
816-/* values for vna_flags */
817-#define VER_FLG_WEAK   0x2     /* weak version identifier */
818-
819-
820 /*** inline functions ***/
821 
822 #ifdef __cplusplus
823Index: headers/private/system/elf_common.h
824===================================================================
825--- headers/private/system/elf_common.h (revision 0)
826+++ headers/private/system/elf_common.h (revision 0)
827@@ -0,0 +1,197 @@
828+/*
829+ * Copyright 2002-2010, Haiku Inc. All Rights Reserved.
830+ * Distributed under the terms of the MIT license.
831+ *
832+ * Copyright 2001, Travis Geiselbrecht. All rights reserved.
833+ * Distributed under the terms of the NewOS License.
834+ */
835+#ifndef _ELF_COMMON_H
836+#define _ELF_COMMON_H
837+
838+#define EI_NIDENT  16
839+#define ELF_MAGIC  "\x7f""ELF"
840+
841+// e_ident[] indices
842+#define EI_MAG0        0
843+#define EI_MAG1        1
844+#define EI_MAG2        2
845+#define EI_MAG3        3
846+#define EI_CLASS   4
847+#define EI_DATA        5
848+#define EI_VERSION 6
849+#define EI_OSABI   7
850+#define EI_ABIVERSION  8
851+#define EI_PAD     9
852+
853+// architecture class (EI_CLASS)
854+#define ELFCLASS32 1
855+#define ELFCLASS64 2
856+// endian (EI_DATA)
857+#define ELFDATA2LSB    1   /* little endian */
858+#define ELFDATA2MSB    2   /* big endian */
859+
860+
861+// special section indices
862+#define SHN_LORESERVE      0xff00
863+#define SHN_HIRESERVE      0xffff
864+
865+#define SHN_UNDEF      0
866+#define SHN_LOPROC     0xff00
867+#define SHN_HIPROC     0xff1f
868+#define SHN_LODS       0xff20
869+#define SHN_HIOS       0xff3f
870+#define SHN_ABS            0xfff1
871+#define SHN_COMMON     0xfff2
872+
873+// section header type
874+#define SHT_NULL       0
875+#define SHT_PROGBITS       1
876+#define SHT_SYMTAB     2
877+#define SHT_STRTAB     3
878+#define SHT_RELA       4
879+#define SHT_HASH       5
880+#define SHT_DYNAMIC        6
881+#define SHT_NOTE       7
882+#define SHT_NOBITS     8
883+#define SHT_REL            9
884+#define SHT_SHLIB      10
885+#define SHT_DYNSYM     11
886+
887+#define SHT_GNU_verdef 0x6ffffffd    /* version definition section */
888+#define SHT_GNU_verneed    0x6ffffffe    /* version needs section */
889+#define SHT_GNU_versym 0x6fffffff    /* version symbol table */
890+
891+#define SHT_LODS       0x60000000
892+#define SHT_HIOS       0x6fffffff
893+#define SHT_LOPROC     0x70000000
894+#define SHT_HIPROC     0x7fffffff
895+#define SHT_LOUSER     0x80000000
896+#define SHT_HIUSER     0xffffffff
897+
898+// section header flags
899+#define SHF_WRITE      1
900+#define SHF_ALLOC      2
901+#define SHF_EXECINSTR      4
902+
903+#define SHF_MASKOS 0x0f000000
904+#define SHF_MASKPROC   0xf0000000
905+
906+// program header segment types
907+#define PT_NULL        0
908+#define PT_LOAD        1
909+#define PT_DYNAMIC 2
910+#define PT_INTERP  3
911+#define PT_NOTE        4
912+#define PT_SHLIB   5
913+#define PT_PHDR        6
914+#define PT_STACK   0x6474e551
915+
916+#define PT_LOOS        0x60000000
917+#define PT_HIOS        0x6fffffff
918+#define PT_LOPROC  0x70000000
919+#define PT_HIPROC  0x7fffffff
920+
921+// program header segment flags
922+#define PF_EXECUTE 0x1
923+#define PF_WRITE   0x2
924+#define PF_READ        0x4
925+#define PF_PROTECTION_MASK (PF_EXECUTE | PF_WRITE | PF_READ)
926+
927+#define PF_MASKOS  0x00ff0000
928+#define PF_MASKPROC    0xff000000
929+
930+#define STT_NOTYPE 0
931+#define STT_OBJECT 1
932+#define STT_FUNC   2
933+#define STT_SECTION    3
934+#define STT_FILE   4
935+#define STT_LOOS   10
936+#define STT_HIOS   12
937+#define STT_LOPROC 13
938+#define STT_HIPROC 15
939+
940+#define STB_LOCAL  0
941+#define STB_GLOBAL 1
942+#define STB_WEAK   2
943+#define STB_LOOS   10
944+#define STB_HIOS   11
945+#define STB_LOPROC 13
946+#define STB_HIPROC 15
947+
948+#define STN_UNDEF  0
949+
950+#define DT_NULL        0
951+#define DT_NEEDED  1
952+#define DT_PLTRELSZ    2
953+#define DT_PLTGOT  3
954+#define DT_HASH        4
955+#define DT_STRTAB  5
956+#define DT_SYMTAB  6
957+#define DT_RELA        7
958+#define DT_RELASZ  8
959+#define DT_RELAENT 9
960+#define DT_STRSZ   10
961+#define DT_SYMENT  11
962+#define DT_INIT        12
963+#define DT_FINI        13
964+#define DT_SONAME  14
965+#define DT_RPATH   15
966+#define DT_SYMBOLIC    16
967+#define DT_REL     17
968+#define DT_RELSZ   18
969+#define DT_RELENT  19
970+#define DT_PLTREL  20
971+#define DT_DEBUG   21
972+#define DT_TEXTREL 22
973+#define DT_JMPREL  23
974+#define DT_BIND_NOW    24
975+#define DT_INIT_ARRAY  25
976+#define DT_FINI_ARRAY  26
977+#define DT_INIT_ARRAYSZ    27
978+#define DT_FINI_ARRAYSZ    28
979+
980+
981+#define DT_VERSYM       0x6ffffff0 /* symbol version table */
982+#define DT_VERDEF      0x6ffffffc  /* version definition table */
983+#define DT_VERDEFNUM   0x6ffffffd  /* number of version definitions */
984+#define DT_VERNEED     0x6ffffffe  /* table with needed versions */
985+#define DT_VERNEEDNUM  0x6fffffff  /* number of needed versions */
986+
987+#define DT_LOPROC      0x70000000
988+#define DT_HIPROC      0x7fffffff
989+
990+
991+/* values for vd_version (version revision) */
992+#define VER_DEF_NONE       0       /* no version */
993+#define VER_DEF_CURRENT        1       /* current version */
994+#define VER_DEF_NUM            2       /* given version number */
995+
996+/* values for vd_flags (version information flags) */
997+#define VER_FLG_BASE       0x1     /* version definition of file itself */
998+#define VER_FLG_WEAK       0x2     /* weak version identifier */
999+
1000+/* values for versym symbol index */
1001+#define VER_NDX_LOCAL      0       /* symbol is local */
1002+#define VER_NDX_GLOBAL     1       /* symbol is global/unversioned */
1003+#define VER_NDX_INITIAL        2       /* initial version -- that's the one given
1004+                                      to symbols when a library becomes
1005+                                      versioned; handled by the linker (and
1006+                                      runtime loader) similar to
1007+                                      VER_NDX_GLOBAL */
1008+#define VER_NDX_LORESERVE  0xff00  /* beginning of reserved entries */
1009+#define VER_NDX_ELIMINATE  0xff01  /* symbol is to be eliminated */
1010+
1011+#define VER_NDX_FLAG_HIDDEN    0x8000  /* flag: version is hidden */
1012+#define VER_NDX_MASK       0x7fff  /* mask to get the actual version index */
1013+#define VER_NDX(x)         ((x) & VER_NDX_MASK)
1014+
1015+/* values for vn_version (version revision) */
1016+#define VER_NEED_NONE      0   /* no version */
1017+#define VER_NEED_CURRENT   1   /* current version */
1018+#define VER_NEED_NUM       2   /* given version number */
1019+
1020+/* values for vna_flags */
1021+#define VER_FLG_WEAK   0x2     /* weak version identifier */
1022+
1023+
1024+#endif  /* _ELF_COMMON_H */
1025Index: headers/private/system/elf64.h
1026===================================================================
1027--- headers/private/system/elf64.h  (revision 0)
1028+++ headers/private/system/elf64.h  (revision 0)
1029@@ -0,0 +1,235 @@
1030+/*
1031+ * Copyright 2002-2010, Haiku Inc. All Rights Reserved.
1032+ * Distributed under the terms of the MIT license.
1033+ *
1034+ * Copyright 2001, Travis Geiselbrecht. All rights reserved.
1035+ * Distributed under the terms of the NewOS License.
1036+ */
1037+#ifndef _ELF64_H
1038+#define _ELF64_H
1039+
1040+#include <SupportDefs.h>
1041+#include <ByteOrder.h>
1042+
1043+#include <arch_elf.h>
1044+#include <elf_common.h>
1045+
1046+typedef uint64 Elf64_Addr;
1047+typedef uint16 Elf64_Half;
1048+typedef uint64 Elf64_Off;
1049+typedef int32 Elf64_Sword;
1050+typedef uint32 Elf64_Word;
1051+typedef int64 Elf64_Sxword;
1052+typedef uint64 Elf64_Xword;
1053+
1054+typedef Elf64_Half Elf64_Versym;
1055+
1056+/*** ELF header ***/
1057+
1058+struct Elf64_Ehdr {
1059+   uint8       e_ident[EI_NIDENT];
1060+   Elf64_Half  e_type;
1061+   Elf64_Half  e_machine;
1062+   Elf64_Word  e_version;
1063+   Elf64_Addr  e_entry;
1064+   Elf64_Off   e_phoff;
1065+   Elf64_Off   e_shoff;
1066+   Elf64_Word  e_flags;
1067+   Elf64_Half  e_ehsize;
1068+   Elf64_Half  e_phentsize;
1069+   Elf64_Half  e_phnum;
1070+   Elf64_Half  e_shentsize;
1071+   Elf64_Half  e_shnum;
1072+   Elf64_Half  e_shstrndx;
1073+
1074+#ifdef __cplusplus
1075+   bool IsHostEndian() const;
1076+#endif
1077+};
1078+
1079+/*** section header ***/
1080+
1081+struct Elf64_Shdr {
1082+   Elf64_Word  sh_name;
1083+   Elf64_Word  sh_type;
1084+   Elf64_Xword sh_flags;
1085+   Elf64_Addr  sh_addr;
1086+   Elf64_Off   sh_offset;
1087+   Elf64_Xword sh_size;
1088+   Elf64_Word  sh_link;
1089+   Elf64_Word  sh_info;
1090+   Elf64_Xword sh_addralign;
1091+   Elf64_Xword sh_entsize;
1092+};
1093+
1094+/*** program header ***/
1095+
1096+struct Elf64_Phdr {
1097+   Elf64_Word  p_type;
1098+   Elf64_Word  p_flags;
1099+   Elf64_Off   p_offset;   /* offset from the beginning of the file of the segment */
1100+   Elf64_Addr  p_vaddr;    /* virtual address for the segment in memory */
1101+   Elf64_Addr  p_paddr;
1102+   Elf64_Xword p_filesz;   /* the size of the segment in the file */
1103+   Elf64_Xword p_memsz;    /* the size of the segment in memory */
1104+   Elf64_Xword p_align;
1105+
1106+#ifdef __cplusplus
1107+   bool IsReadWrite() const;
1108+   bool IsExecutable() const;
1109+#endif
1110+};
1111+
1112+struct Elf64_Sym {
1113+   Elf64_Word  st_name;
1114+   uint8       st_info;
1115+   uint8       st_other;
1116+   Elf64_Half  st_shndx;
1117+   Elf64_Addr  st_value;
1118+   Elf64_Xword st_size;
1119+
1120+#ifdef __cplusplus
1121+   uint8 Bind() const;
1122+   uint8 Type() const;
1123+#endif
1124+};
1125+
1126+/* TODO: CHECK THESE DEFINES */
1127+#define ELF64_ST_BIND(i) ((i) >> 8)
1128+#define ELF64_ST_TYPE(i) ((i) & 0xffffffffL)
1129+#define ELF64_ST_INFO(b, t) (((b) << 8) + ((t) & 0xffffffffL))
1130+
1131+struct Elf64_Rel {
1132+   Elf64_Addr r_offset;
1133+   Elf64_Xword r_info;
1134+
1135+#ifdef __cplusplus
1136+   uint8 SymbolIndex() const;
1137+   uint8 Type() const;
1138+#endif
1139+};
1140+
1141+#ifdef __cplusplus
1142+struct Elf64_Rela : public Elf64_Rel {
1143+#else
1144+struct Elf64_Rela {
1145+   Elf64_Addr r_offset;
1146+   Elf64_Xword r_info;
1147+#endif
1148+   Elf64_Sxword r_addend;
1149+};
1150+
1151+#define ELF64_R_SYM(i) ((i) >> 32)
1152+#define ELF64_R_TYPE(i) ((i) & 0xffffffffL)
1153+#define ELF64_R_INFO(s,t) (((s) << 32) + ((t) & 0xffffffffL))
1154+
1155+struct Elf64_Dyn {
1156+   Elf64_Sxword d_tag;
1157+   union {
1158+       Elf64_Xword d_val;
1159+       Elf64_Addr d_ptr;
1160+   } d_un;
1161+};
1162+
1163+/* version definition section */
1164+/* TODO: ELF64 VERSION TABLES are guesses. Look up structure */
1165+struct Elf64_Verdef {
1166+   Elf64_Half  vd_version;     /* version revision */
1167+   Elf64_Half  vd_flags;       /* version information flags */
1168+   Elf64_Half  vd_ndx;         /* version index as specified in the
1169+                                  symbol version table */
1170+   Elf64_Half  vd_cnt;         /* number of associated verdaux entries */
1171+   Elf64_Word  vd_hash;        /* version name hash value */
1172+   Elf64_Xword vd_aux;         /* byte offset to verdaux array */
1173+   Elf64_Xword vd_next;        /* byte offset to next verdef entry */
1174+};
1175+
1176+/* auxiliary version information */
1177+
1178+struct Elf64_Verdaux {
1179+   Elf64_Word  vda_name;       /* string table offset to version or dependency
1180+                                  name */
1181+   Elf64_Xword vda_next;       /* byte offset to next verdaux entry */
1182+};
1183+
1184+/* version dependency section */
1185+
1186+struct Elf64_Verneed {
1187+   Elf64_Half  vn_version;     /* version of structure */
1188+   Elf64_Half  vn_cnt;         /* number of associated vernaux entries */
1189+   Elf64_Xword vn_file;        /* byte offset to file name for this
1190+                                  dependency */
1191+   Elf64_Xword vn_aux;         /* byte offset to vernaux array */
1192+   Elf64_Xword vn_next;        /* byte offset to next verneed entry */
1193+};
1194+
1195+/* auxiliary needed version information */
1196+
1197+struct Elf64_Vernaux {
1198+   Elf64_Word  vna_hash;       /* dependency name hash value */
1199+   Elf64_Half  vna_flags;      /* dependency specific information flags */
1200+   Elf64_Half  vna_other;      /* version index as specified in the symbol
1201+                                  version table */
1202+   Elf64_Xword vna_name;       /* string table offset to dependency name */
1203+   Elf64_Xword vna_next;       /* byte offset to next vernaux entry */
1204+};
1205+
1206+/*** inline functions ***/
1207+
1208+#ifdef __cplusplus
1209+
1210+inline bool
1211+Elf64_Ehdr::IsHostEndian() const
1212+{
1213+#if B_HOST_IS_LENDIAN
1214+   return e_ident[EI_DATA] == ELFDATA2LSB;
1215+#elif B_HOST_IS_BENDIAN
1216+   return e_ident[EI_DATA] == ELFDATA2MSB;
1217+#endif
1218+}
1219+
1220+
1221+inline bool
1222+Elf64_Phdr::IsReadWrite() const
1223+{
1224+   return !(~p_flags & (PF_READ | PF_WRITE));
1225+}
1226+
1227+
1228+inline bool
1229+Elf64_Phdr::IsExecutable() const
1230+{
1231+   return (p_flags & PF_PROTECTION_MASK) == (PF_READ | PF_EXECUTE);
1232+}
1233+
1234+
1235+inline uint8
1236+Elf64_Sym::Bind() const
1237+{
1238+   return ELF64_ST_BIND(st_info);
1239+}
1240+
1241+
1242+inline uint8
1243+Elf64_Sym::Type() const
1244+{
1245+   return ELF64_ST_TYPE(st_info);
1246+}
1247+
1248+
1249+inline uint8
1250+Elf64_Rel::SymbolIndex() const
1251+{
1252+   return ELF64_R_SYM(r_info);
1253+}
1254+
1255+
1256+inline uint8
1257+Elf64_Rel::Type() const
1258+{
1259+   return ELF64_R_TYPE(r_info);
1260+}
1261+
1262+#endif /* __cplusplus */
1263+
1264+#endif /* _ELF64_H_ */
1265Index: headers/private/system/arch/x86/arch_elf.h
1266===================================================================
1267--- headers/private/system/arch/x86/arch_elf.h  (revision 37496)
1268+++ headers/private/system/arch/x86/arch_elf.h  (working copy)
1269@@ -19,4 +19,22 @@
1270 #define R_386_GOTOFF   9   /* add GOT relative symbol address */
1271 #define R_386_GOTPC        10  /* add PC relative GOT table address */
1272 
1273+#define R_X86_64_NONE      0
1274+#define R_X86_64_64        1   /* add symbol value */
1275+#define R_X86_64_PC32      2   /* add PC relative symbol value */
1276+#define R_X86_64_GOT32     3   /* add PC relative GOT offset */
1277+#define R_X86_64_PLT32     4   /* add PC relative PLT offset */
1278+#define R_X86_64_COPY      5   /* copy data from shared object */
1279+#define R_X86_64_GLOB_DAT  6   /* set GOT entry to data address */
1280+#define R_X86_64_JMP_SLOT  7   /* set GOT entry to code address */
1281+#define R_X86_64_RELATIVE  8   /* add load address of shared object */
1282+#define R_X86_64_GOTOFF        9   /* add GOT relative symbol address */
1283+#define R_X86_64_32        10      /* Add 32 bit zero extended symbol value */
1284+#define R_X86_64_32S       11      /* Add 32 bit sign extended symbol value */
1285+#define R_X86_64_16        12      /* Add 16 bit zero extended symbol value */
1286+#define R_X86_64_PC16      13      /* Add 16 bit signed extended pc relative symbol value */
1287+#define R_X86_64_8     14      /* Add 8 bit zero extended symbol value */
1288+#define R_X86_64_PC8       15      /* Add 8 bit signed extended pc relative symbol value */
1289+
1290+
1291 #endif /* _KERNEL_ARCH_x86_ELF_H */
1292Index: headers/private/kernel/boot/addr_range.h
1293===================================================================
1294--- headers/private/kernel/boot/addr_range.h    (revision 37496)
1295+++ headers/private/kernel/boot/addr_range.h    (working copy)
1296@@ -6,22 +6,21 @@
1297 #ifndef KERNEL_BOOT_ADDR_RANGE_H
1298 #define KERNEL_BOOT_ADDR_RANGE_H
1299 
1300-
1301 #include <SupportDefs.h>
1302 
1303+#include <util/FixedWidthPointer.h>
1304 
1305 typedef struct addr_range {
1306-   addr_t start;
1307-   size_t size;
1308+   FixedWidthPointer<addr_t> start;
1309+   size_t  size;
1310 } addr_range;
1311 
1312 
1313 typedef struct phys_addr_range {
1314-   phys_addr_t start;
1315+   FixedWidthPointer<phys_addr_t> start;
1316    phys_size_t size;
1317 } phys_addr_range;
1318 
1319-
1320 #ifdef __cplusplus
1321 extern "C" {
1322 #endif
1323Index: headers/private/kernel/elf_priv.h
1324===================================================================
1325--- headers/private/kernel/elf_priv.h   (revision 37496)
1326+++ headers/private/kernel/elf_priv.h   (working copy)
1327@@ -10,6 +10,7 @@
1328 
1329 
1330 #include <elf32.h>
1331+#include <elf64.h>
1332 #include <image.h>
1333 
1334 
1335@@ -67,6 +68,7 @@
1336 #define STRING(image, offset) ((char *)(&(image)->strtab[(offset)]))
1337 #define SYMNAME(image, sym) STRING(image, (sym)->st_name)
1338 #define SYMBOL(image, num) ((struct Elf32_Sym *)&(image)->syms[num])
1339+#define SYMBOL64(image, num) ((struct Elf64_Sym *)&(image)->syms[num])
1340 #define HASHTABSIZE(image) ((image)->symhash[0])
1341 #define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2])
1342 #define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
1343Index: headers/private/kernel/util/FixedWidthPointer.h
1344===================================================================
1345--- headers/private/kernel/util/FixedWidthPointer.h (revision 0)
1346+++ headers/private/kernel/util/FixedWidthPointer.h (revision 0)
1347@@ -0,0 +1,56 @@
1348+/*
1349+ * Distributed under the terms of the MIT License.
1350+ */
1351+#ifndef KERNEL_UTIL_FIXED_WIDTH_POINTER_H
1352+#define KERNEL_UTIL_FIXED_WIDTH_POINTER_H
1353+
1354+#include <SupportDefs.h>
1355+
1356+#ifdef __cplusplus
1357+template<typename Type>
1358+class FixedWidthPointer {
1359+public:
1360+        operator Type() const
1361+        {
1362+                return (Type)(addr_t)fValue;
1363+        }
1364+        operator void*() const
1365+        {
1366+                return (void*)fValue;
1367+        }
1368+        Type* operator*() const
1369+        {
1370+                return *(Type)*this;
1371+        }
1372+        Type operator->() const
1373+        {
1374+                return *this;
1375+        }
1376+        FixedWidthPointer<Type> operator=(Type pointer)
1377+        {
1378+                fValue = (addr_t)pointer;
1379+                return *this;
1380+        }
1381+        FixedWidthPointer<Type> operator+=(Type pointer)
1382+        {
1383+                fValue = fValue + (addr_t)pointer;
1384+                return *this;
1385+        }
1386+        bool operator==(const Type pointer) const
1387+        {
1388+                return fValue == (addr_t)pointer;
1389+        }
1390+        bool operator>=(const Type pointer) const
1391+        {
1392+                return fValue >= (addr_t)pointer;
1393+        }
1394+        bool operator<(const Type pointer) const
1395+        {
1396+                return fValue < (addr_t)pointer;
1397+        }
1398+private:
1399+        uint64  fValue;
1400+};
1401+#endif
1402+
1403+#endif // _KERNEL_UTIL_FIXED_WIDTH_POINTER_H