@@ -29,7 +29,7 @@ struct Loader<'a, M, F> {
29
29
30
30
struct Inner < ' a , M , F > {
31
31
kernel_offset : PhysAddr ,
32
- virtual_address_offset : u64 ,
32
+ virtual_address_offset : i128 ,
33
33
page_table : & ' a mut M ,
34
34
frame_allocator : & ' a mut F ,
35
35
}
@@ -65,18 +65,26 @@ where
65
65
let load_program_headers = elf_file
66
66
. program_iter ( )
67
67
. filter ( |h| matches ! ( h. get_type( ) , Ok ( Type :: Load ) ) ) ;
68
- let size = load_program_headers
68
+ let max_addr = load_program_headers
69
69
. clone ( )
70
70
. map ( |h| h. virtual_addr ( ) + h. mem_size ( ) )
71
71
. max ( )
72
72
. unwrap_or ( 0 ) ;
73
+ let min_addr = load_program_headers
74
+ . clone ( )
75
+ . map ( |h| h. virtual_addr ( ) )
76
+ . min ( )
77
+ . unwrap_or ( 0 ) ;
78
+ let size = max_addr - min_addr;
73
79
let align = load_program_headers. map ( |h| h. align ( ) ) . max ( ) . unwrap_or ( 1 ) ;
74
80
75
- used_entries. get_free_address ( size, align) . as_u64 ( )
81
+ let offset = used_entries. get_free_address ( size, align) . as_u64 ( ) ;
82
+ offset as i128 - min_addr as i128
76
83
}
77
84
header:: Type :: Core => unimplemented ! ( ) ,
78
85
header:: Type :: ProcessorSpecific ( _) => unimplemented ! ( ) ,
79
86
} ;
87
+ log:: info!( "virtual_address_offset: {virtual_address_offset:#x}" ) ;
80
88
81
89
used_entries. mark_segments ( elf_file. program_iter ( ) , virtual_address_offset) ;
82
90
@@ -141,7 +149,13 @@ where
141
149
}
142
150
143
151
fn entry_point ( & self ) -> VirtAddr {
144
- VirtAddr :: new ( self . elf_file . header . pt2 . entry_point ( ) + self . inner . virtual_address_offset )
152
+ VirtAddr :: new (
153
+ u64:: try_from (
154
+ i128:: from ( self . elf_file . header . pt2 . entry_point ( ) )
155
+ + self . inner . virtual_address_offset ,
156
+ )
157
+ . unwrap ( ) ,
158
+ )
145
159
}
146
160
}
147
161
@@ -158,7 +172,10 @@ where
158
172
let end_frame: PhysFrame =
159
173
PhysFrame :: containing_address ( phys_start_addr + segment. file_size ( ) - 1u64 ) ;
160
174
161
- let virt_start_addr = VirtAddr :: new ( segment. virtual_addr ( ) ) + self . virtual_address_offset ;
175
+ let virt_start_addr = VirtAddr :: new (
176
+ u64:: try_from ( i128:: from ( segment. virtual_addr ( ) ) + self . virtual_address_offset )
177
+ . unwrap ( ) ,
178
+ ) ;
162
179
let start_page: Page = Page :: containing_address ( virt_start_addr) ;
163
180
164
181
let mut segment_flags = Flags :: PRESENT ;
@@ -198,7 +215,10 @@ where
198
215
) -> Result < ( ) , & ' static str > {
199
216
log:: info!( "Mapping bss section" ) ;
200
217
201
- let virt_start_addr = VirtAddr :: new ( segment. virtual_addr ( ) ) + self . virtual_address_offset ;
218
+ let virt_start_addr = VirtAddr :: new (
219
+ u64:: try_from ( i128:: from ( segment. virtual_addr ( ) ) + self . virtual_address_offset )
220
+ . unwrap ( ) ,
221
+ ) ;
202
222
let mem_size = segment. mem_size ( ) ;
203
223
let file_size = segment. file_size ( ) ;
204
224
@@ -343,7 +363,10 @@ where
343
363
fn remove_copied_flags ( & mut self , elf_file : & ElfFile ) -> Result < ( ) , & ' static str > {
344
364
for program_header in elf_file. program_iter ( ) {
345
365
if let Type :: Load = program_header. get_type ( ) ? {
346
- let start = self . virtual_address_offset + program_header. virtual_addr ( ) ;
366
+ let start = u64:: try_from (
367
+ self . virtual_address_offset + i128:: from ( program_header. virtual_addr ( ) ) ,
368
+ )
369
+ . unwrap ( ) ;
347
370
let end = start + program_header. mem_size ( ) ;
348
371
let start = VirtAddr :: new ( start) ;
349
372
let end = VirtAddr :: new ( end) ;
@@ -380,7 +403,10 @@ where
380
403
381
404
fn handle_tls_segment ( & mut self , segment : ProgramHeader ) -> Result < TlsTemplate , & ' static str > {
382
405
Ok ( TlsTemplate {
383
- start_addr : segment. virtual_addr ( ) + self . virtual_address_offset ,
406
+ start_addr : u64:: try_from (
407
+ i128:: from ( segment. virtual_addr ( ) ) + self . virtual_address_offset ,
408
+ )
409
+ . unwrap ( ) ,
384
410
mem_size : segment. mem_size ( ) ,
385
411
file_size : segment. file_size ( ) ,
386
412
} )
@@ -476,11 +502,15 @@ where
476
502
// R_AMD64_RELATIVE
477
503
8 => {
478
504
check_is_in_load ( elf_file, rela. get_offset ( ) ) ?;
479
- let addr = self . virtual_address_offset + rela. get_offset ( ) ;
480
- let value = self
481
- . virtual_address_offset
482
- . checked_add ( rela. get_addend ( ) )
483
- . unwrap ( ) ;
505
+ let addr =
506
+ u64:: try_from ( self . virtual_address_offset + i128:: from ( rela. get_offset ( ) ) )
507
+ . unwrap ( ) ;
508
+ let value = u64:: try_from (
509
+ self . virtual_address_offset
510
+ . checked_add ( i128:: from ( rela. get_addend ( ) ) )
511
+ . unwrap ( ) ,
512
+ )
513
+ . unwrap ( ) ;
484
514
485
515
let ptr = addr as * mut u64 ;
486
516
if ptr as usize % align_of :: < u64 > ( ) != 0 {
@@ -511,7 +541,9 @@ where
511
541
/// need to be writable while applying relocations, but should never be
512
542
/// written to after relocations have been applied.
513
543
fn handle_relro_segment ( & mut self , program_header : ProgramHeader ) {
514
- let start = self . virtual_address_offset + program_header. virtual_addr ( ) ;
544
+ let start =
545
+ u64:: try_from ( self . virtual_address_offset + i128:: from ( program_header. virtual_addr ( ) ) )
546
+ . unwrap ( ) ;
515
547
let end = start + program_header. mem_size ( ) ;
516
548
let start = VirtAddr :: new ( start) ;
517
549
let end = VirtAddr :: new ( end) ;
0 commit comments