flat assembler
Message board for the users of flat assembler.

Index > Linux > gotpc and shared libraries

Author
Thread Post new topic Reply to topic
part time student



Joined: 27 Feb 2023
Posts: 2
part time student 28 Feb 2023, 02:02
How do I use a value defined in a shared library that I don't control from a shared library written in FASM?

I'll illustrate my question with a snippet that uses fputs and stdout, defined in glibc, to print "test". This is how I'd do a standalone executable:

Code:
; fasm test.asm
; ld test.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc
; ./a.out

format ELF64
extrn fputs
extrn stdout

section '.text' writeable executable
public _start
_start:
    mov rdi, message
    mov rsi, qword [stdout]
    call fputs
    mov     rax, 60
    xor     rdi, rdi
    syscall

section '.data'
message db 'test', 10, 0
    


How can I do the same from a shared library with position-independent code? My approach would be:

Code:
; fasm test.asm && ld -shared test.o -o libtest.so

format ELF64
extrn fputs
extrn stdout

section '.text' writeable executable
public f
f:
    mov    rax, something something stdout, TODO
    lea    rdi, [message]
    mov    rsi, qword [rax]
    jmp    PLT fputs

section '.data'
message db "test", 10, 0
    


(the line with "something something" is the line where I'm stuck)

For reference, the following snippets work as intended in GAS and NASM:

NASM:

Code:
; nasm -felf64 name.asm && ld -shared name.o -o name.so

extern stdout, fputs

section .text
global f
f:
    mov    rax, qword [rel stdout wrt ..gotpc]
    lea    rdi, [rel message]
    mov    rsi, qword [rax]
    jmp    fputs wrt ..plt

section .data
message db "test", 10, 0
    


GAS:

Code:
# as name.s -o name.o && ld -shared name.o -o name.so

    .intel_syntax noprefix

    .section .text
    .global f
f:
    mov    rax, QWORD PTR stdout@GOTPCREL[rip]
    lea    rdi, message[rip]
    mov    rsi, QWORD PTR [rax]
    jmp    fputs@PLT

    .section .data
message:
    .string "test\n"
    .section .note.GNU-stack,"",@progbits
    


But they have special syntax just for that. I couldn't find anything similar for FASM. So I might have to do it manually. How do I do that?

_________________
a person that can shapeshift into a student on the night of a full moon
Post 28 Feb 2023, 02:02
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 28 Feb 2023, 12:45
The GOT-related relocation types were not implemented in fasm's ELF64 formatter.

It is easier to add them with fasmg, where the fasm-compatible formatter is just a set of headers.

Even though these macros were not written with ease of adding new relocation types in mind, it is still possible without modifying the base headers:
Code:
; Assemble with fasmg, with "format" and "cpu" headers sets either in the same directory or in the path provided by INCLUDE variable:
include 'format/format.inc'

format ELF64
extrn fputs
extrn stdout

; The "extrn" macro has defined symbols PLT.fputs and PLT.stdout,
; as variable terms with metadata of form PLT+index,
; where PLT is another special variable term and the constant terms is index into the symbol table.

; Let's define a similarly structured GOT.stdout:
element GOT
element GOT.stdout : 1 metadataof PLT.stdout - PLT + GOT ; replace PLT term with GOT in the metadata
; Of course we may also alter the "extrn" macro to always define such symbol

; Now override the "dword" instruction that is called by x86 encoders to generate displacement/immediate fields:
calminstruction dword? value
        check   1 elementof (1 metadataof (value + ELF.SECTION_BASE)) eq GOT
        jyes    r_gotpcrel
        ; If the argument does not contain our special symbol, just call the previous implementation of "dword":
        call    dword?, value
        exit
    r_gotpcrel:
        compute offset, $%
        emit    4
        check   $% > offset
        jno     done
        compute offset, offset - ELF.SECTION_OFFSET
        compute addend, value + ELF.SECTION_BASE + offset - 1 elementof value
        compute info, R_X86_64_GOTPCREL + (0 scaleof (1 metadataof value)) shl 32
    add_relocation:
        local   Rela
        compute Rela, ELF.RELOCATION_INDEX * sizeof Elf64_Rela
        asm     store offset at ELF.relocations : Rela + Elf64_Rela.r_offset
        asm     store addend at ELF.relocations : Rela + Elf64_Rela.r_addend
        asm     store info at ELF.relocations : Rela + Elf64_Rela.r_info
        compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1
    done:
end calminstruction

section '.text' writeable executable

public f
f:
    mov    rax, [GOT.stdout]
    lea    rdi, [message]
    mov    rsi, qword [rax]
    jmp    PLT.fputs

section '.data'
message db "test", 10, 0    
Note that PLT is implemented slightly differently in fasmg's version - I decided it didn't make much sense to make it an operator when it cannot be applied to any other values anyway. Although I should perhaps add some processing layer for legacy syntax, even this should suffice:
Code:
iterate instruction, call,jmp
        calminstruction instruction? operand*
                match =PLT? operand, operand
                jyes legacy_PLT
                call instruction, operand
                exit
            legacy_PLT:
                arrange operand, =instruction =PLT.operand
                assemble operand
        end calminstruction
end iterate    

I may add this kind of GOT relocations into fasmg's distributed headers - please let me know if that would work for you. I cannot promise the same for fasm 1.
Post 28 Feb 2023, 12:45
View user's profile Send private message Visit poster's website Reply with quote
part time student



Joined: 27 Feb 2023
Posts: 2
part time student 02 Mar 2023, 17:15
Thank you for your help. I've downloaded fasmg (the download page calls it "new" and I genuinely didn't realize it's almost 20 years since the initial release Smile ), exported the INCLUDE path and now everything assembles and runs correctly.

Quote:

I may add this kind of GOT relocations into fasmg's distributed headers - please let me know if that would work for you.


That would be very nice.
Post 02 Mar 2023, 17:15
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 02 Mar 2023, 18:51
part time student wrote:
the download page calls it "new" and I genuinely didn't realize it's almost 20 years since the initial release Smile
It was first released in early 2014, so it's "only" 10 years. Coincidentally, 2024 is going to be 25th anniversary for fasm 1.

part time student wrote:
Quote:
I may add this kind of GOT relocations into fasmg's distributed headers - please let me know if that would work for you.
That would be very nice.
I'm making a commit then. Please let me know if it works correctly.
Post 02 Mar 2023, 18:51
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.