I have a small x86-64 assembly program which I compiled and linked in 2018. I am now trying to reproduce the build, but at the point of linking I get different results in the final binaries.
Both files were assembled and linked using the following command:
$ nasm -f elf64 prng.asm; ld -s -o prng prng.o
The original ELF that I created in 2018 is named prng. The version I created today is named prng2. I have verified that the intermediate object files prng.o are identical so I'm ruling out the source code or nasm as the cause of the differences I'm seeing. Below I've shown the output from objdump on each of the ELFs, old and new:
Original:
$ objdump -x prng
prng: file format elf64-x86-64
prng
architecture: i386:x86-64, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x00000000004000b0
Program Header:
LOAD off 0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**21
filesz 0x0000000000000150 memsz 0x0000000000000150 flags r-x
LOAD off 0x0000000000000150 vaddr 0x0000000000600150 paddr 0x0000000000600150 align 2**21
filesz 0x0000000000000008 memsz 0x0000000000000008 flags rw-
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000000a0 00000000004000b0 00000000004000b0 000000b0 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000008 0000000000600150 0000000000600150 00000150 2**2
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
no symbols
Latest:
$ objdump -x prng2
prng2: file format elf64-x86-64
prng2
architecture: i386:x86-64, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x0000000000401000
Program Header:
LOAD off 0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**12
filesz 0x00000000000000e8 memsz 0x00000000000000e8 flags r--
LOAD off 0x0000000000001000 vaddr 0x0000000000401000 paddr 0x0000000000401000 align 2**12
filesz 0x00000000000000a0 memsz 0x00000000000000a0 flags r-x
LOAD off 0x0000000000002000 vaddr 0x0000000000402000 paddr 0x0000000000402000 align 2**12
filesz 0x0000000000000008 memsz 0x0000000000000008 flags rw-
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000000a0 0000000000401000 0000000000401000 00001000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000008 0000000000402000 0000000000402000 00002000 2**2
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
no symbols
I can see that the difference seems to be down to the different alignments. However, I cannot determine what has caused different alignments to be used.
- I'm using Ubuntu 20.04.1 today, whereas in 2018 I was using Ubuntu 16.04.
- I'm using an AMD Ryzen 3700X CPU today, whereas in 2018 I was using an Intel Core i7-860.
I believe the version of ld will have changed between the two versions of Ubuntu. Is it likely that ld's behaviour on alignment changed during that time, e.g. with a different default linker script?
Or could the CPU be influencing choice of alignment values?
And why are there three sections of program header now, whereas there were only two before?