Ticket #6307: haiku_loader.elf64support.txt

File haiku_loader.elf64support.txt, 35.8 KB (added by nmentley, 14 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