Selaa lähdekoodia

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).
Gunnar Beutner 4 vuotta sitten
vanhempi
commit
13a14b3112
1 muutettua tiedostoa jossa 5 lisäystä ja 7 poistoa
  1. 5 7
      Userland/Libraries/LibELF/DynamicLoader.cpp

+ 5 - 7
Userland/Libraries/LibELF/DynamicLoader.cpp

@@ -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);