startrail wrote:
3. all `.data`, `.ctors`, and `.rodata` end up with the `RW` flags.
Well, duh. You are telling the linker to place .rodata after .data, and .ctors is not mentioned at all, meaning the linker just has to link it anywhere. My guess is you never thought about what sections needed to be writable. That would also explain the excessive 4k alignment all over the place.
For reference, here's my linker script again:
Code:
ENTRY(_kstart)
OUTPUT_FORMAT("elf64-x86-64")
PHDRS {
headers PT_PHDR PHDRS;
text PT_LOAD FILEHDR PHDRS;
data PT_LOAD;
}
SECTIONS {
. = 0xffffffff80000000 + SIZEOF_HEADERS;
.text : {
*(.text)
*(.text.*)
} :text
.rodata : {
*(.rodata)
*(.rodata.*)
}
.eh_frame_hdr : {
__eh_frame_hdr = .;
*(.eh_frame_hdr)
}
.eh_frame : {
*(.eh_frame)
*(.eh_frame.*)
}
/* Normally, the overlap between text and data section is handled by having
* two different pages for the last bits of text and the first bits of data.
* That way, if the last bits of text are overwritten, it won't affect the
* text that is actually used. Unfortunately, for the kernel this is not
* possible. The whole file is loaded into memory en bloc, so the same page
* would be mapped twice. Therefore, a write access to the writable page
* would end up being visible in the non-writable side of things. Therefore,
* we must actually page-align here.
*/
. = ALIGN(2M);
.data : {
*(.data)
*(.data.*)
} :data
.bss : {
*(.bss)
*(COMMON)
*(.bss.*)
}
}
Note that I don't have a lower half. I get the paging set up by the bootloader. Where the bootloader does not provide for that, I add a shim that does it for me. This allows me to completely uncouple the unpaged and paged code.
Alignment directives should never be necessary in the linker script because you already have section alignment in all the input sections. And even there, page alignment is rarely necessary. I only use one single alignment directive to cause a page break between the writable and non.writable sections. And I could normally do that well enough with just ". += 2M" were it not for the reasoning outlined in the linker script.