Korona wrote:
If you want the segments to start on different pages, it's enough to ensure that the vaddrs are at least 0x1000 apart (e.g., by doing . += 0x1000 in the linker script). This should be enough to properly map the segments at runtime and it's preferable to manual padding.
Can you clarify how this works? I've tried adding ". += 0x1000" in a few places and it doesn't appear to do anything (some results as before). Also adding 0x1000 to the vaddr doesn't appear to be what i need, I want the vaddr to be aligned to the next page boundary, not moved 0x1000 bytes ahead. Seems to me that the issue is that gcc will link program headers on page boundaries by default and clang doesn't.
Ultimately I want to be different program headers to be aligned to pages so that i can map them with different memory protections. I also need to be able to map the VDSO page(s) in user space: this also needs to be page-aligned and padded to not leak kernel data/code into user space.
Code:
SECTIONS
{
. = 0xFFFFFFFF80000000;
.text ALIGN(4K) :
{
*(.text*)
} :phdr_text
. += 0x1000;
.rodata ALIGN(4K) :
{
*(.rodata*)
} :phdr_rodata
. += 0x1000;
.data ALIGN(4K) :
{
*(.data*)
} :phdr_data
The following seems to almost work:
Code:
SECTIONS
{
. = 0xFFFFFFFF80000000;
.text ALIGN(4K) :
{
*(.text*)
} :phdr_text
.rodata ALIGN(4K) :
{
. = (. & ~0xFFF) + 0x1000;
*(.rodata*)
} :phdr_rodata
.data ALIGN(4K) :
{
. = (. & ~0xFFF) + 0x1000;
*(.data*)
} :phdr_data
Code:
08:11:36-kzinti@droneship:~/dev/rainbow-os-2/build (master)$ readelf -l kernel/src/kernel
Elf file type is EXEC (Executable file)
Entry point 0xffffffff80000000
There are 3 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000001000 0xffffffff80000000 0xffffffff80000000
0x000000000000000e 0x000000000000000e R E 0x1000
LOAD 0x0000000000002000 0xffffffff80001000 0xffffffff80001000
0x000000000000107c 0x000000000000107c R 0x1000
LOAD 0x0000000000004000 0xffffffff80003000 0xffffffff80003000
0x00000000000010e0 0x00000000000010e0 RW 0x1000
Section to Segment mapping:
Segment Sections...
00 .text
01 .rodata .interp .note.gnu.build-id .dynsym .dynstr .gnu.hash
02 .data .dynamic