Description of problem: when linking the linux kernel, ld produces a PT_LOAD segment, which according to the linker script should be 4 byte aligned, but the p_align value for the section is 0x1000 Version-Release number of selected component (if applicable): fedora kernel 2.6.18-1.2682.fc6kdump and later (possibly earlier versions as well) How reproducible: always Steps to Reproduce: 1.readelf -e /boot/vmlinux-2.6.18-1.2682.fc6kdump Actual results: Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0xc1000000 0x01000000 0x266820 0x266820 R E 0x1000 LOAD 0x267880 0xc1266880 0x01266880 0x162804 0x375638 RWE 0x1000 NOTE 0x000000 0x00000000 0x00000000 0x00000 0x00000 R 0x4 Note that the second LOAD segment shows and Alignment of 0x1000, but the VirtAddr and Offset values for the segment are not on 4096 byte boundaries Expected results: According the linker script for this kernel the Align value should be 0x4 Additional info:
That's just misunderstanding what p_align means. It doesn't mean that the segment has to start on an p_align aligned address, but that p_vaddr % p_align == p_paddr % p_align == p_offset % p_align. Look at any ELF shared library or binary, you'll see the same: E.g. on ppc64, /lib64/libc.so.6 has: LOAD 0x000000 0x00000080761b0000 0x00000080761b0000 0x17b99f 0x17b99f R E 0x10000 LOAD 0x17bda0 0x000000807633bda0 0x000000807633bda0 0x0127b0 0x016670 RW 0x10000 The 0x10000 alignment here just ensures that the library will be usable with any page size up to 64K, it is e.g. not possible to adjust it in a way where it couldn't be mmaped on 64K page kernel.
Here is what gABI 4.1, chapter 5 says on this: p_align As ``Program Loading'' describes in this chapter of the processor supplement, loadable process segments must have congruent values for p_vaddr and p_offset, modulo the page size. This member gives the value to which the segments are aligned in memory and in the file. Values 0 and 1 mean no alignment is required. Otherwise, p_align should be a positive, integral power of 2, and p_vaddr should equal p_offset, modulo p_align.