flat assembler
Message board for the users of flat assembler.

flat assembler > Unix > Mach-O objects made with fasmg

Author
Thread Post new topic Reply to topic
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7310
Location: Kraków, Poland
After I got the Mach-O executables more or less working the next step is to extend the macros so that they can build linkable objects as well.

I have prepared the macros to create symbol tables and relocations - you may notice that they are a relatively simple addition on top of the basic layers I created earlier for the executable output. I managed to assemble and then successfully link (with LD) the following 32-bit example consisting of two objects:
Code:
include '80386.inc'
use32

MachO.Settings.FileType equ MH_OBJECT
include 'macho.inc'

public start
extrn writemsg

SYS_exit = 1

section '__TEXT''__text'

  start

        mov     esi,msg
        call    writemsg

        push    1
        mov     eax,SYS_exit
        sub     esp,4
        int     0x80

section '__TEXT''__cstring'

  msg db "Relocated and ready!",0xA,0    
Code:
include '80386.inc'
use32

MachO.Settings.FileType equ MH_OBJECT
include 'macho.inc'

public writemsg

SYS_write = 4

section '__TEXT''__text'

  writemsg
        mov     edi,esi
        mov     ecx,-1
        xor     al,al
        repne   scasb
        neg     ecx
        sub     ecx,2
        push    ecx
        push    esi
        push    1
        mov     eax,SYS_write
        sub     esp,4
        int     0x80
        add     esp,4*4
        ret    


Note that when Mach-O is used as an object, all sections should reside in a single unnamed segment, but each section in addition to its own name needs to specify the name of a segment it is intended for. Thus the unusual syntax in the above samples.

PS. I have not created any 64-bit objects yet. There are going to be some differences in relocations and perhaps some other things to adjust to make them work.


Description: Mach-O formatting macros with example objects
Download
Filename: machO.zip
Filesize: 9.1 KB
Downloaded: 253 Time(s)

Post 27 Aug 2017, 22:11
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7310
Location: Kraków, Poland
With a small tweak in the relocation generating macro I was able to get 64-bit objects to work, too. The sources are like:
Code:
include 'x64.inc'
use64

MachO.Settings.FileType equ MH_OBJECT
MachO.Settings.ProcessorType equ CPU_TYPE_X86_64
MachO.Settings.ProcessorSubtype equ CPU_SUBTYPE_X86_64_ALL
include 'macho.inc'

section '__TEXT''__text'

public start
extrn writemsg
extrn exit

start
        lea     rsi,msg
        call    writemsg
        call    exit

section '__DATA''__data'

        msg db 'Relocated and ready!',0Ah,0    
Code:
include 'x64.inc'
use64

MachO.Settings.FileType equ MH_OBJECT
MachO.Settings.ProcessorType equ CPU_TYPE_X86_64
MachO.Settings.ProcessorSubtype equ CPU_SUBTYPE_X86_64_ALL
include 'macho.inc'

section '__TEXT''__text'

public writemsg
public exit

        SYSCALL_CLASS_UNIX = 2
        SYSCALL_CLASS_SHIFT = 24
        define SYSCALL_CONSTRUCT_UNIX SYSCALL_CLASS_UNIX shl SYSCALL_CLASS_SHIFT +

        SYS_exit = 1
        SYS_write = 4

writemsg
        mov     rdi,rsi
        or      rcx,-1
        xor     al,al
        repne   scasb
        neg     rcx
        sub     rcx,2
        mov     rdx,rcx
        mov     rdi,1
        mov     rax,SYSCALL_CONSTRUCT_UNIXSYS_write
        syscall
        retn

exit
        mov     rdi,rax
        mov     rax,SYSCALL_CONSTRUCT_UNIXSYS_exit
        syscall    
Post 28 Aug 2017, 17:07
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7310
Location: Kraków, Poland
As an additional test of the macros I have assembled the MacOS version of fasmg as a linkable object and it appears to be working correctly. In the current packaging "source/macos/fasmg.asm" assembles directly to executable, to get an object instead it needs to be replaced with the following:
Code:
match ,

        err ; fasm 1 assembly not supported

 match -,
else

        include 'selfhost.inc'

end match
_ equ 

format MachO
public main as '_main'

include '../version.inc'

extrn '_malloc' as libc.malloc
extrn '_realloc' as libc.realloc
extrn '_free' as libc.free
extrn '_fopen' as libc.fopen
extrn '_fclose' as libc.fclose
extrn '_fread' as libc.fread
extrn '_fwrite' as libc.fwrite
extrn '_fseek' as libc.fseek
extrn '_ftell' as libc.ftell
extrn '_time' as libc.time
extrn '_write' as libc.write

extrn '_getenv' as getenv
extrn '_gettimeofday' as gettimeofday
extrn '_exit' as exit

struct timeval
        time_t dd ?
        suseconds_t dd ?
ends

section '__TEXT''__text' align 16

  main
        mov     ecx,esp+4
        mov     argc,ecx
        mov     ebx,esp+8
        mov     argv,ebx

        call    system_init

        mov     esi,_logo
        xor     ecx,ecx
        call    display_string

        call    get_arguments
        jc      display_usage_information

        xor     al,al
        mov     ecx,verbosity_level
        jecxz   init
        or      al,TRACE_ERROR_STACK
        dec     ecx
        jz      init
        or      al,TRACE_DISPLAY
  init
        call    assembly_init

        ccall   gettimeofday,start_time,0

  assemble
        mov     esi,initial_commands
        mov     edx,source_path
        call    assembly_pass
        jc      assembly_done

        mov     eax,current_pass
        cmp     eax,maximum_number_of_passes
        jb      assemble

        call    show_display_data

        mov     ebx,_code_cannot_be_generated
        jmp     fatal_error

  assembly_done

        call    show_display_data

        cmp     first_error,0
        jne     assembly_failed

        mov     eax,current_pass
        mov     edi,string_buffer
        call    itoa
        call    display_string
        mov     esi,_passes
        cmp     current_pass,1
        jne     display_passes_suffix
        mov     esi,_pass
      display_passes_suffix
        xor     ecx,ecx
        call    display_string
        ccall   gettimeofday,end_time,0
        mov     eax,end_time.time_t
        sub     eax,start_time.time_t
        mov     ecx,1000000
        mul     ecx
        add     eax,end_time.suseconds_t
        adc     edx,0
        sub     eax,start_time.suseconds_t
        sbb     edx,0
        add     eax,50000
        mov     ecx,1000000
        div     ecx
        mov     ebx,eax
        mov     eax,edx
        xor     edx,edx
        mov     ecx,100000
        div     ecx
        mov     tenths_of_second,eax
        xchg    eax,ebx
        or      ebx,eax
        jz      display_output_length
        mov     edi,string_buffer
        call    itoa
        call    display_string
        mov     esi,_message_suffix
        mov     ecx,1
        call    display_string
        mov     eax,tenths_of_second
        mov     edi,string_buffer
        call    itoa
        call    display_string
        mov     esi,_seconds
        xor     ecx,ecx
        call    display_string
      display_output_length
        call    get_output_length
        push    eax
        mov     edi,string_buffer
        call    itoa
        call    display_string
        pop     eax
        mov     esi,_bytes
        cmp     eax,1
        jne     display_bytes_suffix
        mov     esi,_byte
      display_bytes_suffix
        xor     ecx,ecx
        call    display_string
        mov     esi,_new_line
        xor     ecx,ecx
        call    display_string

        mov     edi,output_path
        call    write_output_file
        jc      write_failed

        call    assembly_shutdown
        call    system_shutdown

        ccall   exit,0

  assembly_failed

        call    show_errors

        call    assembly_shutdown
        call    system_shutdown

        ccall   exit,2

  write_failed
        mov     ebx,_write_failed
        jmp     fatal_error

  out_of_memory
        mov     ebx,_out_of_memory
        jmp     fatal_error

  fatal_error

        mov     esi,_error_prefix
        xor     ecx,ecx
        call    display_error_string
        mov     esi,ebx
        xor     ecx,ecx
        call    display_error_string
        mov     esi,_message_suffix
        xor     ecx,ecx
        call    display_error_string

        call    assembly_shutdown
        call    system_shutdown

        ccall   exit,3

  display_usage_information

        mov     esi,_usage
        xor     ecx,ecx
        call    display_string

        call    system_shutdown

        ccall   exit,1

  get_arguments
        xor     eax,eax
        mov     initial_commands,eax
        mov     source_path,eax
        mov     output_path,eax
        mov     maximum_number_of_passes,100
        mov     maximum_number_of_errors,1
        mov     maximum_depth_of_stack,10000
        mov     ecx,argc
        mov     ebx,argv
        add     ebx,4
        dec     ecx
        jz      error_in_arguments
    get_argument
        mov     esi,ebx
        mov     al,esi
        cmp     al,'-'
        je      get_option
        cmp     source_path,0
        jne     get_output_file
        mov     source_path,esi
        jmp     next_argument
    get_output_file
        cmp     output_path,0
        jne     error_in_arguments
        mov     output_path,esi
        jmp     next_argument
    get_option
        inc     esi
        lodsb
        cmp     al,'e'
        je      set_errors_limit
        cmp     al,'E'
        je      set_errors_limit
        cmp     al,'i'
        je      insert_initial_command
        cmp     al,'I'
        je      insert_initial_command
        cmp     al,'p'
        je      set_passes_limit
        cmp     al,'P'
        je      set_passes_limit
        cmp     al,'r'
        je      set_recursion_limit
        cmp     al,'R'
        je      set_recursion_limit
        cmp     al,'v'
        je      set_verbose_mode
        cmp     al,'V'
        je      set_verbose_mode
    error_in_arguments
        stc
        ret
    set_verbose_mode
        cmp     byte esi,0
        jne     get_verbose_setting
        dec     ecx
        jz      error_in_arguments
        add     ebx,4
        mov     esi,ebx
      get_verbose_setting
        call    get_option_value
        cmp     edx,2
        ja      error_in_arguments
        mov     verbosity_level,edx
        jmp     next_argument
    set_errors_limit
        cmp     byte esi,0
        jne     get_errors_setting
        dec     ecx
        jz      error_in_arguments
        add     ebx,4
        mov     esi,ebx
      get_errors_setting
        call    get_option_value
        test    edx,edx
        jz      error_in_arguments
        mov     maximum_number_of_errors,edx
        jmp     next_argument
    set_recursion_limit
        cmp     byte esi,0
        jne     get_recursion_setting
        dec     ecx
        jz      error_in_arguments
        add     ebx,4
        mov     esi,ebx
      get_recursion_setting
        call    get_option_value
        test    edx,edx
        jz      error_in_arguments
        mov     maximum_depth_of_stack,edx
        jmp     next_argument
    set_passes_limit
        cmp     byte esi,0
        jne     get_passes_setting
        dec     ecx
        jz      error_in_arguments
        add     ebx,4
        mov     esi,ebx
      get_passes_setting
        call    get_option_value
        test    edx,edx
        jz      error_in_arguments
        mov     maximum_number_of_passes,edx
    next_argument
        add     ebx,4
        dec     ecx
        jnz     get_argument
        cmp     source_path,0
        je      error_in_arguments
        cmp     output_path,0
        je      error_in_arguments
        clc
        ret
    get_option_value
        xor     eax,eax
        mov     edx,eax
      find_option_value
        cmp     byte esi,20h
        jne     get_option_digit
        inc     esi
        jmp     find_option_value
      get_option_digit
        lodsb
        test    al,al
        jz      option_value_ok
        sub     al,30h
        jc      invalid_option_value
        cmp     al,9
        ja      invalid_option_value
        imul    edx,10
        jo      invalid_option_value
        add     edx,eax
        jc      invalid_option_value
        jmp     get_option_digit
      option_value_ok
        dec     esi
        clc
        ret
      invalid_option_value
        stc
        ret
    insert_initial_command
        cmp     byte esi,0
        jne     measure_initial_command
        dec     ecx
        jz      error_in_arguments
        add     ebx,4
        mov     esi,ebx
      measure_initial_command
        push    ebx ecx edi
        mov     edi,esi
        or      ecx,-1
        xor     al,al
        repne   scasb
        not     ecx
        dec     ecx
        mov     edi,initial_commands
        lea     eax,ecx+2
        test    edi,edi
        jz      allocate_initial_commands_buffer
        mov     edx,initial_commands_length
        add     edi,edx
        add     eax,edx
        cmp     eax,initial_commands_maximum_length
        ja      grow_initial_commands_buffer
      copy_initial_command
        rep     movsb
        mov     ax,0Ah
        stosw
        dec     edi
        sub     edi,initial_commands
        mov     initial_commands_length,edi
        pop     edi ecx ebx
        jmp     next_argument
      allocate_initial_commands_buffer
        push    ecx
        mov     ecx,eax
        call    malloc
        jc      out_of_memory
        mov     initial_commands,eax
        mov     initial_commands_maximum_length,ecx
        mov     edi,eax
        pop     ecx
        jmp     copy_initial_command
      grow_initial_commands_buffer
        push    ecx
        mov     ecx,eax
        mov     eax,initial_commands
        call    realloc
        jc      out_of_memory
        mov     initial_commands,eax
        mov     initial_commands_maximum_length,ecx
        mov     edi,eax
        add     edi,initial_commands_length
        pop     ecx
        jmp     copy_initial_command

  include 'system.inc'

  include '../assembler.inc'
  include '../symbols.inc'
  include '../expressions.inc'
  include '../conditions.inc'
  include '../directives.inc'
  include '../floats.inc'
  include '../errors.inc'
  include '../map.inc'
  include '../reader.inc'
  include '../output.inc'
  include '../console.inc'

section '__TEXT''__cstring' align 4

  _logo db 'flat assembler  version g.',VERSION,10,0

  _usage db 'Usage fasmg source output',10
         db 'Optional settings',10
         db '    -p limit    Set the maximum allowed number of passes default 100',10
         db '    -e limit    Set the maximum number of displayed errors default 1',10
         db '    -r limit    Set the maximum depth of stack default 10000',10
         db '    -v flag     Enable or disable showing all lines from the stack default 0',10
         db '    -i command  Insert instruction at the beginning of source',13,10
         db 0

  _pass db ' pass, ',0
  _passes db ' passes, ',0
  _dot db '.'
  _seconds db ' seconds, ',0
  _byte db ' byte.',0
  _bytes db ' bytes.',0

  _write_failed db 'failed to write the output file',0
  _out_of_memory db 'not enough memory to complete the assembly',0
  _code_cannot_be_generated db 'could not generate code within the allowed number of passes',0

  _open_mode db 'r',0
  _create_mode db 'w',0

  include '../tables.inc'
  include '../messages.inc'

section '__DATA''__data' align 4

  include '../variables.inc'

  source_path dd ?
  output_path dd ?
  maximum_number_of_passes dd ?

  initial_commands dd ?
  initial_commands_length dd ?
  initial_commands_maximum_length dd ?

  argc dd ?
  argv dd ?
  timestamp dq ?

  start_time timeval
  end_time timeval
  tenths_of_second dd ?

  verbosity_level dd ?
  string_buffer rb 100h

  path_buffer rb 1000h    
Post 01 Sep 2017, 20:47
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-2019, Tomasz Grysztar.

Powered by rwasa.