mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:32:46 +00:00 
			
		
		
		
	LibELF: Fix loading libs with a .text segment that's not page-aligned
It's perfectly acceptable for the segment's vaddr to not be page aligned as long as the segment itself is page-aligned. We'll just map a few more bytes at the start of the segment that will be unused by the library. We didn't notice this problem because because GCC either always uses 0 for the .text segment's vaddr or at least aligns the vaddr to the page size. LibELF would also fail to load really small libraries (i.e. smaller than 4096 bytes).
This commit is contained in:
		
							parent
							
								
									4591c00328
								
							
						
					
					
						commit
						13a14b3112
					
				
					 1 changed files with 5 additions and 7 deletions
				
			
		|  | @ -319,20 +319,18 @@ void DynamicLoader::load_program_headers() | |||
|     } | ||||
| 
 | ||||
|     for (auto& text_region : text_regions) { | ||||
|         FlatPtr ph_text_desired_base = text_region.desired_load_address().get(); | ||||
|         FlatPtr ph_text_base = text_region.desired_load_address().page_base().get(); | ||||
|         FlatPtr ph_text_end = ph_text_base + round_up_to_power_of_two(text_region.size_in_memory() + (size_t)(text_region.desired_load_address().as_ptr() - ph_text_base), PAGE_SIZE); | ||||
| 
 | ||||
|         auto* text_segment_address = (u8*)reservation + ph_text_base - ph_load_base; | ||||
|         size_t text_segment_size = ph_text_end - ph_text_base; | ||||
| 
 | ||||
|         // Now we can map the text segment at the reserved address.
 | ||||
|         auto* text_segment_begin = (u8*)mmap_with_name( | ||||
|             text_segment_address, | ||||
|             text_segment_size, | ||||
|             (u8*)reservation + ph_text_base - ph_load_base, | ||||
|             ph_text_desired_base - ph_text_base + text_region.size_in_image(), | ||||
|             PROT_READ, | ||||
|             MAP_FILE | MAP_SHARED | MAP_FIXED, | ||||
|             m_image_fd, | ||||
|             text_region.offset(), | ||||
|             VirtualAddress { text_region.offset() }.page_base().get(), | ||||
|             String::formatted("{}: .text", m_filename).characters()); | ||||
| 
 | ||||
|         if (text_segment_begin == MAP_FAILED) { | ||||
|  | @ -340,7 +338,7 @@ void DynamicLoader::load_program_headers() | |||
|             VERIFY_NOT_REACHED(); | ||||
|         } | ||||
| 
 | ||||
|         m_text_segments.append({ VirtualAddress { (FlatPtr)text_segment_begin }, text_segment_size }); | ||||
|         m_text_segments.append({ VirtualAddress { (FlatPtr)text_segment_begin }, ph_text_end - ph_text_base }); | ||||
|     } | ||||
| 
 | ||||
|     VERIFY(requested_load_address == nullptr || requested_load_address == reservation); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gunnar Beutner
						Gunnar Beutner