Other PIE, ASLR, and Linux

Hi there,
Years ago, I wrote this assembly language program that plays Beethoven's "Ode to Joy" in beeps. (Apologies if I've posted it before - I lose track of what I've posted and where!)
Anyway it had bit-rotted a bit but I managed to get it running again on both Linux and FreeBSD. However, there is a problem. Since Linux introduced ASLR and PIEs by default, I get this warning (non-fatal) when linking:

/usr/bin/ld: beep.o: warning: relocation in read-only section `.text' /usr/bin/ld: warning: creating DT_TEXTREL in a PIE

I suspect that FreeBSD will soon follow Linux, as we already have ASLR, it's just not the default yet.
How to I get rid of these warnings on Linux and any warnings as a result of future changes to FreeBSD?
Here is the assembly source and instructions how to build it. You need first to install devel/sdl2 and lang/fasm.

Code:
format ELF64

public main

extrn 'SDL_Init' as SDL_Init:qword
extrn 'SDL_Quit' as SDL_Quit:qword
extrn 'SDL_OpenAudio' as SDL_OpenAudio:qword
extrn 'SDL_CloseAudio' as SDL_CloseAudio:qword
extrn 'SDL_PauseAudio' as SDL_PauseAudio:qword
extrn 'SDL_Delay' as SDL_Delay:qword

extrn 'exit' as exit:qword

AUDIOS16LSB equ 0x8010

SDL_INIT_AUDIO equ 0x00000010

struc SDL_AudioSpec
{
        .freq dd ?
        .format dw ?
        .channels db ?
        .silence db ?
        .samples dw ?
        dw ?
        .size dd ?
        .callback dq ?
        .userdata dq ?
}

SAMPLE_RATE equ 44100 ; samples per second
TEMPO equ 160 ; beats per minute
CROTCHETS_PER_SECOND equ (4 * (TEMPO / 60)) ; quarter beats per second
CROTCHET_DURATION equ (1000 / CROTCHETS_PER_SECOND) ; length of a quarter beat in ms
SAMPLES_PER_CROTCHET equ (SAMPLE_RATE / CROTCHETS_PER_SECOND) ; samples per quarter beat

; macro for declaration of note data
macro NOTE f,d
{
        local .frequency, .duration
        .frequency dq f ; floating point frequency in Hz
        .duration dq d ; duration in quarter notes
}

section '.data' writable

audio_desired SDL_AudioSpec

NEGATIVE_ONE dq -1.0
MAX_SIGNED_SHORT dq 32767.0 ; max signed value that can be stored in a 2 byte integer
TWO_TIMES_PI dq 6.2831
ANGLE dq 0.0 ; current input to sine function
STEP_SIZE dq 0.0 ; rate at which to step through sine function
AMPLITUDE dq 1.0 ; current volume
SAMPLES_THIS_NOTE dq 0 ; samples REMAINING for the current note
CROTCHETS_THIS_NOTE dq 0 ; current note length in quarter beats
TEMP dq 0
SAMPLE dw 0 ; storage for integer audio sample
align 8
MUSIC_PLAYING dq 1 ; controls when the program ends
MUSIC_REST dq 0 ; is the current note a rest?

NOTE_POINTER dq MUSIC ; pointer to current note

; frequencies for the notes

G2 equ 195.998
C3 equ 261.626
D3 equ 293.664
E3 equ 329.628
F3 equ 349.228
G3 equ 391.996

; music melody

MUSIC:

NOTE E3,2
NOTE 0,2
NOTE E3,2
NOTE 0,2
NOTE F3,2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE F3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE E3, 4
NOTE 0,2
NOTE D3, 2
NOTE D3, 6
NOTE 0, 2

NOTE E3,2
NOTE 0,2
NOTE E3,2
NOTE 0,2
NOTE F3,2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE F3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 4
NOTE 0,2
NOTE C3, 2
NOTE C3, 6
NOTE 0, 2

NOTE D3, 6
NOTE 0, 2
NOTE E3, 2
NOTE 0, 2
NOTE C3, 2
NOTE 0, 2
NOTE D3, 4
NOTE E3, 2
NOTE F3, 2
NOTE E3, 2
NOTE 0, 2
NOTE C3, 2
NOTE 0, 2
NOTE D3, 4
NOTE E3, 2
NOTE F3, 2
NOTE E3, 2
NOTE 0, 2
NOTE D3, 2
NOTE 0, 2
NOTE C3, 2
NOTE 0, 2
NOTE D3, 2
NOTE 0, 2
NOTE G2, 6
NOTE 0, 2

NOTE E3,2
NOTE 0,2
NOTE E3,2
NOTE 0,2
NOTE F3,2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE F3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 4
NOTE 0,2
NOTE C3, 2
NOTE C3, 6
NOTE 0, 2

dq -1.0 ; note data ends

section '.text' executable

main:

push rbp
mov rbp, rsp

mov rax, 0
mov rdi, SDL_INIT_AUDIO
mov r10, SDL_Init
call r10

mov [audio_desired.freq], SAMPLE_RATE
mov [audio_desired.format], AUDIOS16LSB
mov [audio_desired.channels], 1
mov [audio_desired.silence], 0
mov [audio_desired.samples], 4096
mov [audio_desired.size], 8192
mov rax, audio_callback
mov [audio_desired.callback], rax
mov [audio_desired.userdata], 0

mov rax, 0
mov rdi, audio_desired
mov rsi, 0
mov r10, SDL_OpenAudio
call r10

; unpause audio
mov rax, 0
mov rdi, 0
mov r10, SDL_PauseAudio
call r10

call next_note

; loop till we hit the last note
.main_loop:

; small delay to avoid maxing out CPU
mov rax, 0
mov rdi, CROTCHET_DURATION
mov r10, SDL_Delay
call r10

mov rax, [MUSIC_PLAYING]
cmp rax, 0
jz .exit_main_loop

jmp .main_loop
.exit_main_loop:

mov rax, 0
mov r10, SDL_CloseAudio
call r10

mov rax, 0
mov r10, SDL_Quit
call r10

mov rax, 0
mov rdi, 0
mov r10, exit
call r10

; SDL calls this function when it requires audio data

audio_callback:

push rbx rbp r12 r13 r14 r15
sub rsp, 8

; get the number of bytes of audio samples
; divide by two because each sample comprises 2 bytes
; store in rbx

mov rax, rdx
mov rbx, 2
mov rdx, 0
idiv rbx
mov rbx, rax

mov rdi, rsi ; put audio buffer pointer in rdi

; loop to fill the buffer with zeroes

mov rcx, 0 ; initialise counter

.zero_init_loop:

cmp rcx, rbx ; exit the loop if we've reached the end of the audio buffer
jge .exit_zero_init_loop

mov si, 0
mov word [rdi + rcx * 2], si

inc rcx
jmp .zero_init_loop
.exit_zero_init_loop:

; loop to write the audio samples into the buffer

mov rcx, 0 ; initialise counter

.loop:

; if there are no samples remaining to be written for the current note, progress to the next note
cmp [SAMPLES_THIS_NOTE], 0
jnz .skip_next_note

push rdi rcx
call next_note
pop rcx rdi

.skip_next_note:

cmp rcx, rbx ; exit the loop if we've reached the end of the audio buffer
jge .exit_loop

cmp [MUSIC_REST], 1 ; if the current note is a rest, skip writing the samples
je .rest

; calculate amplitude (volume)
; amplitude = samples_still_unwritten / (crotchets_this_note * samples_per_crotchet)
mov rax, [CROTCHETS_THIS_NOTE]
imul rax, SAMPLES_PER_CROTCHET
mov [TEMP], rax
fild [TEMP]
mov rsi, [SAMPLES_THIS_NOTE]
mov [TEMP], rsi
fild [TEMP]
fdivrp st1, st
fstp qword [AMPLITUDE]
fwait

; obtain our sine value and store it in memory as a 2 byte word
; sample = sin(angle) * amplitude * max_signed_short
fld qword [AMPLITUDE]
fld qword [MAX_SIGNED_SHORT]
fld qword [ANGLE]
fsin
fmulp st1, st
fmulp st1, st
fistp word [SAMPLE]

; transfer the sample into the audio buffer

mov si, [SAMPLE]
mov word [rdi + rcx * 2], si

; increase angle by step size

fld qword [STEP_SIZE]
fld qword [ANGLE]
faddp st1, st

; compare the angle to (2.0 * Pi)

fcom qword [TWO_TIMES_PI]
fstsw ax
fwait
sahf
jb .skip ; if the angle is less than (2.0 * Pi), skip the next instruction

fsub qword [TWO_TIMES_PI] ; reduce the angle by (2.0 * Pi) to bring it back within the range 0.0 to 2.0 * Pi

.skip:
fstp qword [ANGLE] ; write the new angle

.rest:

dec [SAMPLES_THIS_NOTE] ; decrease sample counter

inc rcx ; increase offset into audio buffer

jmp .loop
.exit_loop:

add rsp, 8
pop r15 r14 r13 r12 rbp rbx
ret

next_note:

push rbx

; restore amplitude (volume) to 1.0

fld1
fstp qword [AMPLITUDE]

; load the new note's frequency (measured in Hz) and duration (measured in quarter-notes)
; also store the length of the note in quarter-notes, and the length of the note in samples

mov rsi, [NOTE_POINTER]
mov rsi, [rsi + 8]
mov [CROTCHETS_THIS_NOTE], rsi
imul rsi, SAMPLES_PER_CROTCHET
mov [SAMPLES_THIS_NOTE], rsi
mov rbx, [NOTE_POINTER]
mov rbx, [rbx]

cmp rbx, [NEGATIVE_ONE]; negative one marks the end of the music
jne .skip

mov [MUSIC_PLAYING], 0 ; tell the main thread the program has finished

pop rbx
ret

.skip:

cmp rbx, 0.0 ; if frequency is 0.0, the note is a rest so next few calculations are not needed
jz .rest

mov [MUSIC_REST], 0 ; not a rest

; calculate the rate at which we need to step through the sine function's domain
; step_size = (2.0 * Pi) / (sample_rate / frequency)
mov [TEMP], rbx
fld [TEMP]
mov [TEMP], SAMPLE_RATE
fild [TEMP]
fdivrp st1, st
fld [TWO_TIMES_PI]
fdivrp st1, st
fstp [STEP_SIZE]
fwait

jmp .skip_rest
.rest:
mov [MUSIC_REST], 1 ; note is a rest
.skip_rest:

; progress to the next note

mov rbx, [NOTE_POINTER]
add rbx, 16
mov [NOTE_POINTER], rbx

mov [ANGLE], 0.0 ; reset angle for new frequency

pop rbx
ret

Build, run:

fasm beep.asm cc beep.o `sdl2-config --libs` -lc ./a.out
 
On x86_64 you can use rip relative addressing. As an example:
Code:
.section .data
        retcode: .quad 0x42

.section .text
        .globl _start

_start:
main:
        ;;; movq (retcode), %rdi   <-- absolute address "retcode" is used here
        movq retcode(%rip), %rdi    ; relative addressing to rip
        movl $1, %eax
        pushq %rax
        syscall
You can compile this code as PIE. The commented line would not work in PIE due to absolute address being used.

I oversimplified ; but if you google ELF/relocations/PIE you get plenty of articles with nice examples.
 
Thanks _martin
I managed to get it working on both OS.
In the end I created a writable section called '.stubs' to "trick" the linker into thinking it was dealing with RIP-relative stuff only in the text section.
Basically changing code like:

mov r10, SDL_OpenAudio

to

Code:
lea r10, [SDL_OpenAudio@stub]
mov r10, [r10]

And the stubs look like:

Code:
section '.stubs' writable

SDL_OpenAudio@stub dq SDL_OpenAudio
...

Now it links on both OS without warnings. And it's ready for when FreeBSD makes ASLR the default.
It's probably a slight security risk to have writable function pointers, but then, just switching a computer on is a slight security risk, so I'm not going to worry about that...

Here's the fixed code in case anyone's interested:

Code:
format ELF64

public main

extrn 'SDL_Init' as SDL_Init:qword
extrn 'SDL_Quit' as SDL_Quit:qword
extrn 'SDL_OpenAudio' as SDL_OpenAudio:qword
extrn 'SDL_CloseAudio' as SDL_CloseAudio:qword
extrn 'SDL_PauseAudio' as SDL_PauseAudio:qword
extrn 'SDL_Delay' as SDL_Delay:qword

extrn 'exit' as exit:qword

AUDIOS16LSB equ 0x8010
SDL_INIT_AUDIO equ 0x00000010

struc SDL_AudioSpec
{
        .freq dd ?
        .format dw ?
        .channels db ?
        .silence db ?
        .samples dw ?
        dw ?
        .size dd ?
        .callback dq ?
        .userdata dq ?
}

SAMPLE_RATE equ 44100 ; samples per second
TEMPO equ 160 ; beats per minute
CROTCHETS_PER_SECOND equ (4 * (TEMPO / 60)) ; quarter beats per second
CROTCHET_DURATION equ (1000 / CROTCHETS_PER_SECOND) ; length of a quarter beat in ms
SAMPLES_PER_CROTCHET equ (SAMPLE_RATE / CROTCHETS_PER_SECOND) ; samples per quarter beat

; macro for declaration of note data
macro NOTE f,d
{
        local .frequency, .duration
        .frequency dq f ; floating point frequency in Hz
        .duration dq d ; duration in quarter notes
}

section '.stubs' writable
SDL_OpenAudio@stub dq SDL_OpenAudio
SDL_Init@stub dq SDL_Init
SDL_Quit@stub dq SDL_Quit
SDL_CloseAudio@stub dq SDL_CloseAudio
SDL_PauseAudio@stub dq SDL_PauseAudio
SDL_Delay@stub dq SDL_Delay
exit@stub dq exit

section '.data' writable

audio_desired SDL_AudioSpec

NEGATIVE_ONE dq -1.0
MAX_SIGNED_SHORT dq 32767.0 ; max signed value that can be stored in a 2 byte integer
TWO_TIMES_PI dq 6.2831
ANGLE dq 0.0 ; current input to sine function
STEP_SIZE dq 0.0 ; rate at which to step through sine function
AMPLITUDE dq 1.0 ; current volume
SAMPLES_THIS_NOTE dq 0 ; samples REMAINING for the current note
CROTCHETS_THIS_NOTE dq 0 ; current note length in quarter beats
TEMP dq 0
SAMPLE dw 0 ; storage for integer audio sample
align 8
MUSIC_PLAYING dq 1 ; controls when the program ends
MUSIC_REST dq 0 ; is the current note a rest?

NOTE_POINTER dq MUSIC ; pointer to current note

; frequencies for the notes

G2 equ 195.998
C3 equ 261.626
D3 equ 293.664
E3 equ 329.628
F3 equ 349.228
G3 equ 391.996

; music melody

MUSIC:

NOTE E3,2
NOTE 0,2
NOTE E3,2
NOTE 0,2
NOTE F3,2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE F3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE E3, 4
NOTE 0,2
NOTE D3, 2
NOTE D3, 6
NOTE 0, 2

NOTE E3,2
NOTE 0,2
NOTE E3,2
NOTE 0,2
NOTE F3,2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE F3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 4
NOTE 0,2
NOTE C3, 2
NOTE C3, 6
NOTE 0, 2

NOTE D3, 6
NOTE 0, 2
NOTE E3, 2
NOTE 0, 2
NOTE C3, 2
NOTE 0, 2
NOTE D3, 4
NOTE E3, 2
NOTE F3, 2
NOTE E3, 2
NOTE 0, 2
NOTE C3, 2
NOTE 0, 2
NOTE D3, 4
NOTE E3, 2
NOTE F3, 2
NOTE E3, 2
NOTE 0, 2
NOTE D3, 2
NOTE 0, 2
NOTE C3, 2
NOTE 0, 2
NOTE D3, 2
NOTE 0, 2
NOTE G2, 6
NOTE 0, 2

NOTE E3,2
NOTE 0,2
NOTE E3,2
NOTE 0,2
NOTE F3,2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE F3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 4
NOTE 0,2
NOTE C3, 2
NOTE C3, 6
NOTE 0, 2

dq -1.0 ; note data ends

section '.text' executable

main:

push rbp
mov rbp, rsp

mov rax, 0
mov rdi, SDL_INIT_AUDIO
lea r10, [SDL_Init@stub]
mov r10, [r10]
call r10

mov [audio_desired.freq], SAMPLE_RATE
mov [audio_desired.format], AUDIOS16LSB
mov [audio_desired.channels], 1
mov [audio_desired.silence], 0
mov [audio_desired.samples], 4096
mov [audio_desired.size], 8192
lea rax, [audio_callback]
mov [audio_desired.callback], rax
mov [audio_desired.userdata], 0

mov rax, 0
lea rdi, [audio_desired]

mov rsi, 0
lea r10, [SDL_OpenAudio@stub]
mov r10, [r10]
call r10

; unpause audio
mov rax, 0
mov rdi, 0
lea r10, [SDL_PauseAudio@stub]
mov r10, [r10]
call r10

call next_note

; loop till we hit the last note
.main_loop:

; small delay to avoid maxing out CPU
mov rax, 0
mov rdi, CROTCHET_DURATION
lea r10, [SDL_Delay@stub]
mov r10, [r10]
call r10

lea rax, [MUSIC_PLAYING]
mov rax, [rax]
cmp rax, 0
jz .exit_main_loop

jmp .main_loop
.exit_main_loop:

mov rax, 0
lea r10, [SDL_CloseAudio@stub]
mov r10, [r10]
call r10

mov rax, 0
lea r10, [SDL_Quit@stub]
mov r10, [r10]
call r10

mov rax, 0
mov rdi, 0
lea r10, [exit@stub]
mov r10, [r10]
call r10

; SDL calls this function when it requires audio data

audio_callback:

push rbx rbp r12 r13 r14 r15
sub rsp, 8

; get the number of bytes of audio samples
; divide by two because each sample comprises 2 bytes
; store in rbx

mov rax, rdx
mov rbx, 2
mov rdx, 0
idiv rbx
mov rbx, rax

mov rdi, rsi ; put audio buffer pointer in rdi

; loop to fill the buffer with zeroes

mov rcx, 0 ; initialise counter

.zero_init_loop:

cmp rcx, rbx ; exit the loop if we've reached the end of the audio buffer
jge .exit_zero_init_loop

mov si, 0
mov word [rdi + rcx * 2], si

inc rcx
jmp .zero_init_loop
.exit_zero_init_loop:

; loop to write the audio samples into the buffer

mov rcx, 0 ; initialise counter

.loop:

; if there are no samples remaining to be written for the current note, progress to the next note
cmp [SAMPLES_THIS_NOTE], 0
jnz .skip_next_note

push rdi rcx
call next_note
pop rcx rdi

.skip_next_note:

cmp rcx, rbx ; exit the loop if we've reached the end of the audio buffer
jge .exit_loop

cmp [MUSIC_REST], 1 ; if the current note is a rest, skip writing the samples
je .rest

; calculate amplitude (volume)
; amplitude = samples_still_unwritten / (crotchets_this_note * samples_per_crotchet)
mov rax, [CROTCHETS_THIS_NOTE]
imul rax, SAMPLES_PER_CROTCHET
mov [TEMP], rax
fild [TEMP]
mov rsi, [SAMPLES_THIS_NOTE]
mov [TEMP], rsi
fild [TEMP]
fdivrp st1, st
fstp qword [AMPLITUDE]
fwait

; obtain our sine value and store it in memory as a 2 byte word
; sample = sin(angle) * amplitude * max_signed_short
fld qword [AMPLITUDE]
fld qword [MAX_SIGNED_SHORT]
fld qword [ANGLE]
fsin
fmulp st1, st
fmulp st1, st
fistp word [SAMPLE]

; transfer the sample into the audio buffer
mov si, [SAMPLE]
mov word [rdi + rcx * 2], si

; increase angle by step size

fld qword [STEP_SIZE]
fld qword [ANGLE]
faddp st1, st

; compare the angle to (2.0 * Pi)

fcom qword [TWO_TIMES_PI] 
fstsw ax
fwait
sahf
jb .skip ; if the angle is less than (2.0 * Pi), skip the next instruction

fsub qword [TWO_TIMES_PI] ; reduce the angle by (2.0 * Pi) to bring it back within the range 0.0 to 2.0 * Pi

.skip:
fstp qword [ANGLE] ; write the new angle

.rest:

dec [SAMPLES_THIS_NOTE] ; decrease sample counter

inc rcx ; increase offset into audio buffer

jmp .loop
.exit_loop:

add rsp, 8
pop r15 r14 r13 r12 rbp rbx
ret

next_note:

push rbx

; restore amplitude (volume) to 1.0

fld1
fstp qword [AMPLITUDE]

; load the new note's frequency (measured in Hz) and duration (measured in quarter-notes)
; also store the length of the note in quarter-notes, and the length of the note in samples

mov rsi, [NOTE_POINTER]
mov rsi, [rsi + 8]
mov [CROTCHETS_THIS_NOTE], rsi
imul rsi, SAMPLES_PER_CROTCHET
mov [SAMPLES_THIS_NOTE], rsi
mov rbx, [NOTE_POINTER]
mov rbx, [rbx]

cmp rbx, [NEGATIVE_ONE]; negative one marks the end of the music
jne .skip

mov [MUSIC_PLAYING], 0 ; tell the main thread the program has finished

pop rbx
ret

.skip:

cmp rbx, 0.0 ; if frequency is 0.0, the note is a rest so next few calculations are not needed
jz .rest

mov [MUSIC_REST], 0 ; not a rest

; calculate the rate at which we need to step through the sine function's domain
; step_size = (2.0 * Pi) / (sample_rate / frequency)
mov [TEMP], rbx
fld [TEMP]
mov [TEMP], SAMPLE_RATE
fild [TEMP]
fdivrp st1, st
fld [TWO_TIMES_PI]
fdivrp st1, st
fstp [STEP_SIZE]
fwait

jmp .skip_rest
.rest:
mov [MUSIC_REST], 1 ; note is a rest
.skip_rest:

; progress to the next note

mov rbx, [NOTE_POINTER]
add rbx, 16
mov [NOTE_POINTER], rbx

mov [ANGLE], 0.0 ; reset angle for new frequency

pop rbx
ret
 
The advantage of rip related addressing is that it doesn't matter where in memory you are loaded offset from rip will be always the same (position /in memory/ independent).

The warning you see is ld - it detects that the code you have can't be PIE. It puts a trick of its hand and deals with it with extra ELF section. Your workaround is the same in the principle.
But as you have 64b code it would be worth remaking with rip-related addressing.
This is a small program. But imagine having big program with lots of relocations. Load of such program would delay significantly.

Yes, having RELRO is a security feature. It's not a "fix for all" but not having it could simplify attack or widen attack vector (depending on a bug in code).
 
Yet again, I should have read the f***ing manual.
Flat assembler provides a "plt" operator for just this situation. So you don't need any of my clumsy hacks.
You just put, for example:
Code:
call plt malloc
Tbh I'm just relieved there's a solution as my code really sucked.
 
Back
Top