flat assembler
Message board for the users of flat assembler.

flat assembler > High Level Languages > Rules for linking Fasm to g++ on AMD64

Author
Thread Post new topic Reply to topic
fpga



Joined: 22 Sep 2009
Posts: 36
Here's a Fasm program I know works.
Can someone please explain by example what you must do to link this to a g++ program on an AMD64 box so that you can call this "print string" routine from g++.

Any help would be very much appreciated.

Code:
format  ELF executable
entry   start

        SYSCALL_EXIT    equ 1     ; syscall to function exit
        SYSCALL_WRITE   equ 4     ; syscall to function write
        STDOUT          equ 1     ; file descriptor of standard output
        ESC             equ 0x1b  ; escape character

start
; first clear the screen
        mov     eax, SYSCALL_WRITE
        mov     ebx, STDOUT
        mov     ecx, clear_screen
        mov     edx, clear_screen_size
        int     0x80
; move cursor to x25, y12
        mov     eax, SYSCALL_WRITE
        mov     ebx, STDOUT
        mov     ecx, move_cursor
        mov     edx, move_cursor_size
        int     0x80
; write the message
        mov     eax, SYSCALL_WRITE
        mov     ebx, STDOUT
        mov     ecx, message
        mov     edx, message_size
        int     0x80
; exit from the program
        mov     eax, SYSCALL_EXIT
        xor     ebx, ebx
        int     0x80

clear_screen db ESC, "2J"
clear_screen_size = $ - clear_screen
move_cursor  db ESC, "12;25H"
move_cursor_size = $ - move_cursor
message      db ESC, "31m", ESC, "5m", ESC, "4m" ; red, blink on, underline on
              db "Programming linux is easy", 0xa
              db ESC, "25m", ESC, "24m" ; blink off, underline off
message_size = $ - message
    
Post 22 Sep 2009, 18:28
View user's profile Send private message Reply with quote
fpga



Joined: 22 Sep 2009
Posts: 36
The asm file containing the function to be called
i.e. print_str_2.fasm
Code:
format ELF64 ;executable             ;change
;format ELF executable

;entry   start 

        SYSCALL_EXIT    equ 1     
        SYSCALL_WRITE   equ 4     
        STDOUT          equ 1     
        ESC             equ 0x1b  

;start

_print_str                             ;change
; first clear the screen
        mov     eax, SYSCALL_WRITE
        mov     ebx, STDOUT
        mov     ecx, clear_screen
        mov     edx, clear_screen_size
        int     0x80
; move cursor to x25, y12
        mov     eax, SYSCALL_WRITE
        mov     ebx, STDOUT
        mov     ecx, move_cursor
        mov     edx, move_cursor_size
        int     0x80
; write the message
        mov     eax, SYSCALL_WRITE
        mov     ebx, STDOUT
        mov     ecx, message
        mov     edx, message_size
        int     0x80
; exit from the program
        mov     eax, SYSCALL_EXIT
        xor     ebx, ebx
        int     0x80
ret                                    ;change ie added

clear_screen db ESC, "2J"
clear_screen_size = $ - clear_screen
move_cursor  db ESC, "12;25H"
move_cursor_size = $ - move_cursor
message      db ESC, "31m", ESC, "5m", ESC, "4m" ; red, blink on, underline on
              db "Programming linux is easy", 0xa
              db ESC, "25m", ESC, "24m" ; blink off, underline off
message_size = $ - message

    

The c++ file that calls the asm function
i.e. call_asm.cpp
Code:
#include "iostream"
using namespace std;

extern "C" void print_str;

int main
   cout << "hi" << endl;
   print_str;
   return 0;

    


my compiling shell script
Code:
#!/bin/sh
./fasm print_str_2.fasm print_str_2.o
g++ -c call_asm.cpp
g++ -o blob call_asm.o print_str_2.o
./blob
rm blob
    

and the error message that I get
Code:
flat assembler  version 1.68  16384 kilobytes memory
2 passes, 669 bytes.
call_asm.o In function `main'
call_asm.cpp.text+0x73 undefined reference to `print_str'
collect2 ld returned 1 exit status
run.sh 7 ./blob not found
rm cannot remove `blob' No such file or directory
    
Post 23 Sep 2009, 11:42
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16702
Location: In your JS exploiting you and your system
What is g++?
Post 23 Sep 2009, 12:24
View user's profile Send private message Visit poster's website Reply with quote
fpga



Joined: 22 Sep 2009
Posts: 36
It's gcc's c++ compiler
Post 23 Sep 2009, 12:51
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16702
Location: In your JS exploiting you and your system
I would expect you need to export the function names. Maybe ...
Code:
public _print_str as '_print_str@0'    
Post 23 Sep 2009, 12:56
View user's profile Send private message Visit poster's website Reply with quote
fpga



Joined: 22 Sep 2009
Posts: 36
revolution
Thanks for trying.
I put it as line 2 in print_str_2.fasm and got the same error.
Post 23 Sep 2009, 13:07
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16702
Location: In your JS exploiting you and your system
It is probably something to do with name mangling in g++. How does g++ mangle the function names? You need to match the C name mangling in the public directive.
Post 23 Sep 2009, 13:09
View user's profile Send private message Visit poster's website Reply with quote
MazeGen



Joined: 06 Oct 2003
Posts: 953
Location: Czechoslovakia
Compile the call_asm.cpp file and look into the object file what external symbol GCC expects.
Post 23 Sep 2009, 14:47
View user's profile Send private message Visit poster's website Reply with quote
fpga



Joined: 22 Sep 2009
Posts: 36
Sorry to lose the continuity. I had to pop out for a while.

Your comment on mangling seems correct.
Before I went I tried it with gcc and got
Code:
flat assembler  version 1.68  16384 kilobytes memory
2 passes, 706 bytes.
call_asm.c2 error expected identifier or ‘’ before string constant
call_asm.o In function `main'
call_asm.c.text+0x14 undefined reference to `print_str'
collect2 ld returned 1 exit status
    


Here's what I did...

Code:
#include <stdio.h>
extern "C" void print_str;
int main void
  printf "Hello, world!\n";
  print_str;
  return 0;

    


Code:
format ELF64 ;executable             ;change

public _print_str as '_print_str@0'

;format ELF executable

;entry   start 

        SYSCALL_EXIT    equ 1     
        SYSCALL_WRITE   equ 4     
        STDOUT          equ 1     
        ESC             equ 0x1b  

;start

_print_str                             ;change
; first clear the screen
        mov     eax, SYSCALL_WRITE
        mov     ebx, STDOUT
        mov     ecx, clear_screen
        mov     edx, clear_screen_size
        int     0x80
; move cursor to x25, y12
        mov     eax, SYSCALL_WRITE
        mov     ebx, STDOUT
        mov     ecx, move_cursor
        mov     edx, move_cursor_size
        int     0x80
; write the message
        mov     eax, SYSCALL_WRITE
        mov     ebx, STDOUT
        mov     ecx, message
        mov     edx, message_size
        int     0x80
; exit from the program
        mov     eax, SYSCALL_EXIT
        xor     ebx, ebx
        int     0x80
ret                                    ;change ie added




clear_screen db ESC, "2J"
clear_screen_size = $ - clear_screen
move_cursor  db ESC, "12;25H"
move_cursor_size = $ - move_cursor
message      db ESC, "31m", ESC, "5m", ESC, "4m" ; red, blink on, underline on
              db "Programming linux is easy", 0xa
              db ESC, "25m", ESC, "24m" ; blink off, underline off
message_size = $ - message


    


Code:
#!/bin/sh
./fasm print_str_2.fasm print_str_2.o
gcc -c call_asm.c
gcc -o blob call_asm.o print_str_2.o
./blob
rm blob
# Exit with successful status
exit 0
    
Post 23 Sep 2009, 14:54
View user's profile Send private message Reply with quote
fpga



Joined: 22 Sep 2009
Posts: 36
objdump -Dslx call_asm.o gives me the following.
I can see print_str in two places but am not sure what else this is telling me about the problem

Code:
call_asm.o     file format elf64-x86-64
call_asm.o
architecture i386x86-64, flags 0x00000011
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000

Sections
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         0000001f  0000000000000000  0000000000000000  00000040  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000000  0000000000000000  0000000000000000  00000060  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  00000060  2**2
                  ALLOC
  3 .rodata       0000000e  0000000000000000  0000000000000000  00000060  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .eh_frame     00000038  0000000000000000  0000000000000000  00000070  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
  5 .comment      00000024  0000000000000000  0000000000000000  000000a8  2**0
                  CONTENTS, READONLY
  6 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000cc  2**0
                  CONTENTS, READONLY
SYMBOL TABLE
0000000000000000 l    df *ABS*       0000000000000000 call_asm.c
0000000000000000 l    d  .text   0000000000000000 .text
0000000000000000 l    d  .data        0000000000000000 .data
0000000000000000 l    d  .bss 0000000000000000 .bss
0000000000000000 l    d  .rodata       0000000000000000 .rodata
0000000000000000 l    d  .eh_frame  0000000000000000 .eh_frame
0000000000000000 l    d  .note.GNU-stack  0000000000000000 .note.GNU-stack
0000000000000000 l    d  .comment   0000000000000000 .comment
0000000000000000 g     F .text     000000000000001f main
0000000000000000         *UND* 0000000000000000 puts
0000000000000000         *UND* 0000000000000000 print_str     <== here


Contents of section .text
 0000 554889e5 bf000000 00e80000 0000b800  UH..............
 0010 000000e8 00000000 b8000000 00c9c3    ............... 
Contents of section .rodata
 0000 48656c6c 6f2c2077 6f726c64 2100      Hello, world!.  
Contents of section .eh_frame
 0000 14000000 00000000 017a5200 01781001  .........zR..x..
 0010 030c0708 90010000 1c000000 1c000000  ................
 0020 00000000 1f000000 00410e10 8602430d  .........A....C.
 0030 06000000 00000000                    ........        
Contents of section .comment
 0000 00474343 3a202855 62756e74 7520342e  .GCC Ubuntu 4.
 0010 332e332d 35756275 6e747534 2920342e  3.3-5ubuntu4 4.
 0020 332e3300                             3.3.            

Disassembly of section .text

0000000000000000 <main>
main
   0    55                      push   %rbp
   1        48 89 e5                mov    %rsp,%rbp
   4   bf 00 00 00 00          mov    $0x0,%edi
                    5 R_X86_64_32      .rodata
   9    e8 00 00 00 00          callq  e <main+0xe>
                   a R_X86_64_PC32    puts-0x4
   e   b8 00 00 00 00          mov    $0x0,%eax
  13   e8 00 00 00 00          callq  18 <main+0x18>
                 14 R_X86_64_PC32   print_str-0x4     <=========here
  18        b8 00 00 00 00          mov    $0x0,%eax
  1d   c9                      leaveq 
  1e    c3                      retq   

Disassembly of section .rodata

0000000000000000 <.rodata>
   0    48                      rex.W
   1      65                      gs
   2 6c                      insb   %dx,%es%rdi
   3        6c                      insb   %dx,%es%rdi
   4        6f                      outsl  %ds%rsi,%dx
   5        2c 20                   sub    $0x20,%al
   7   77 6f                   ja     78 <main+0x78>
   9        72 6c                   jb     77 <main+0x77>
   b        64 21 00                and    %eax,%fs%rax

Disassembly of section .eh_frame

0000000000000000 <.eh_frame>
   0     14 00                   adc    $0x0,%al
   2    00 00                   add    %al,%rax
   4  00 00                   add    %al,%rax
   6  00 00                   add    %al,%rax
   8  01 7a 52                add    %edi,0x52%rdx
   b     00 01                   add    %al,%rcx
   d  78 10                   js     1f <.eh_frame+0x1f>
   f   01 03                   add    %eax,%rbx
  11 0c 07                   or     $0x7,%al
  13    08 90 01 00 00 1c       or     %dl,0x1c000001%rax
  19        00 00                   add    %al,%rax
  1b  00 1c 00                add    %bl,%rax,%rax,1
  1e   00 00                   add    %al,%rax
  20  00 00                   add    %al,%rax
                   20 R_X86_64_32     .text
  22      00 00                   add    %al,%rax
  24  1f                      bad  
  25    00 00                   add    %al,%rax
  27  00 00                   add    %al,%rax
  29  41 0e                   rex.B bad  
  2b      10 86 02 43 0d 06       adc    %al,0x60d4302%rsi
  31 00 00                   add    %al,%rax
  33  00 00                   add    %al,%rax
  35  00 00                   add    %al,%rax
   ...

Disassembly of section .comment

0000000000000000 <.comment>
   0      00 47 43                add    %al,0x43%rdi
   3      43 3a 20                rex.XB cmp    %r8,%spl
   6   28 55 62                sub    %dl,0x62%rbp
   9      75 6e                   jne    79 <main+0x79>
   b        74 75                   je     82 <main+0x82>
   d        20 34 2e                and    %dh,%rsi,%rbp,1
  10   33 2e                   xor    %rsi,%ebp
  12 33 2d 35 75 62 75       xor    0x75627535%rip,%ebp        # 7562754d <main+0x7562754d>
  18     6e                      outsb  %ds%rsi,%dx
  19        74 75                   je     90 <main+0x90>
  1b        34 29                   xor    $0x29,%al
  1d   20 34 2e                and    %dh,%rsi,%rbp,1
  20   33 2e                   xor    %rsi,%ebp
  22 33 00                   xor    %rax,%eax
    
Post 23 Sep 2009, 15:18
View user's profile Send private message Reply with quote
fpga



Joined: 22 Sep 2009
Posts: 36
Here's the dump for print_str_2.o
Code:

print_str_2.o     file format elf64-x86-64
print_str_2.o
architecture i386x86-64, flags 0x00000011
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000

Sections
Idx Name          Size      VMA               LMA               File off  Algn
  0 .flat         00000089  0000000000000000  0000000000000000  00000040  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, CODE
SYMBOL TABLE
0000000000000000 l    d  .flat    0000000000000000 .flat
0000000000000000 g     F .flat        0000000000000000 _print_str@0


Contents of section .flat
 0000 b8040000 00bb0100 0000b94c 000000ba  ...........L....
 0010 04000000 cd80b804 000000bb 01000000  ................
 0020 b9500000 00ba0800 0000cd80 b8040000  .P..............
 0030 00bb0100 0000b958 000000ba 31000000  .......X....1...
 0040 cd80b801 00000031 dbcd80c3 1b5b324a  .......1.....2J
 0050 1b5b3132 3b323548 1b5b3331 6d1b5b35  .12;25H.31m.5
 0060 6d1b5b34 6d50726f 6772616d 6d696e67  m.4mProgramming
 0070 206c696e 75782069 73206561 73790a1b   linux is easy..
 0080 5b32356d 1b5b3234 6d                 25m.24m       

Disassembly of section .flat

0000000000000000 <_print_str@0>
_print_str@0
   0       b8 04 00 00 00          mov    $0x4,%eax
   5   bb 01 00 00 00          mov    $0x1,%ebx
   a   b9 4c 00 00 00          mov    $0x4c,%ecx
                   b R_X86_64_32S     .flat
   f      ba 04 00 00 00          mov    $0x4,%edx
  14   cd 80                   int    $0x80
  16       b8 04 00 00 00          mov    $0x4,%eax
  1b   bb 01 00 00 00          mov    $0x1,%ebx
  20   b9 50 00 00 00          mov    $0x50,%ecx
                   21 R_X86_64_32S    .flat
  25      ba 08 00 00 00          mov    $0x8,%edx
  2a   cd 80                   int    $0x80
  2c       b8 04 00 00 00          mov    $0x4,%eax
  31   bb 01 00 00 00          mov    $0x1,%ebx
  36   b9 58 00 00 00          mov    $0x58,%ecx
                   37 R_X86_64_32S    .flat
  3b      ba 31 00 00 00          mov    $0x31,%edx
  40  cd 80                   int    $0x80
  42       b8 01 00 00 00          mov    $0x1,%eax
  47   31 db                   xor    %ebx,%ebx
  49   cd 80                   int    $0x80
  4b       c3                      retq   
  4c    1b 5b 32                sbb    0x32%rbx,%ebx
  4f     4a 1b 5b 31             rex.WX sbb    0x31%rbx,%rbx
  53      32 3b                   xor    %rbx,%bh
  55  32 35 48 1b 5b 33       xor    0x335b1b48%rip,%dh        # 335b1ba3 <_print_str@0+0x335b1ba3>
  5b      31 6d 1b                xor    %ebp,0x1b%rbp
  5e     5b                      pop    %rbx
  5f        35 6d 1b 5b 34          xor    $0x345b1b6d,%eax
  64    6d                      insl   %dx,%es%rdi
  65        50                      push   %rax
  66        72 6f                   jb     d7 <_print_str@0+0xd7>
  68        67 72 61                addr32 jb cc <_print_str@0+0xcc>
  6b     6d                      insl   %dx,%es%rdi
  6c        6d                      insl   %dx,%es%rdi
  6d        69 6e 67 20 6c 69 6e    imul   $0x6e696c20,0x67%rsi,%ebp
  74 75 78                   jne    ee <_print_str@0+0xee>
  76        20 69 73                and    %ch,0x73%rcx
  79      20 65 61                and    %ah,0x61%rbp
  7c      73 79                   jae    f7 <_print_str@0+0xf7>
  7e        0a 1b                   or     %rbx,%bl
  80  5b                      pop    %rbx
  81        32 35 6d 1b 5b 32       xor    0x325b1b6d%rip,%dh        # 325b1bf4 <_print_str@0+0x325b1bf4>
  87      34 6d                   xor    $0x6d,%al


    
Post 23 Sep 2009, 15:22
View user's profile Send private message Reply with quote
MazeGen



Joined: 06 Oct 2003
Posts: 953
Location: Czechoslovakia
I'm Windows guy so can't try it, however, the puts function is declared as 'puts'. And it expects also 'print_str'. Doesn't this work?
Code:
public _print_str as 'print_str'    

If not, try to ask on a GCC forum how it handles external symbols.
Post 23 Sep 2009, 16:23
View user's profile Send private message Visit poster's website Reply with quote
fpga



Joined: 22 Sep 2009
Posts: 36
No problem. Thx for trying.
I've had a thread on codeguru's non-ms c++ forum since last night.
It's normally very good but on this one I've had 0 responses.

I think I read in the notes that public is for coff output and this is ELF64.
I'll give it a go though.

Despite looking last night and all of today I've failed to find a single working example of g++ calling Fasm. As both are very popular this seems quite strange and suggests that the two don't mix. My best bet therefore seems in-line GAS.

Shame cos I really like the idea of Fasm.
Post 23 Sep 2009, 16:53
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
fpga, from your latest fasm code I changed this:
Code:
public _print_str as 'print_str' ; Changed string    


Then, I proceeded this way:

Code:
loco@athlon64~/Desktop/linktest$ cat call_asm.cpp 

#include "iostream"
using namespace std;

extern "C" void print_str;

int main
   cout << "hi" << endl;
   print_str;
   return 0;

loco@athlon64~/Desktop/linktest$ fasm print_str.fasm 
flat assembler  version 1.69.03  16384 kilobytes memory
2 passes, 703 bytes.
loco@athlon64~/Desktop/linktest$ g++ -c call_asm.cpp 
loco@athlon64~/Desktop/linktest$ g++ -o blob call_asm.o print_str.o
loco@athlon64~/Desktop/linktest$ uname -a
Linux athlon64 2.6.28-15-generic #49-Ubuntu SMP Tue Aug 18 192534 UTC 2009 x86_64 GNU/Linux    


The results of executing it are attached. (The font changed to red when I executed the code, it was previously black)

[edit]Please not that "public print_str as 'print_str'" would also be valid but I haven't used it because that would required to change more lines (the line with "_print_str:" to "print_str:"). For linking what matters is the name in the quoted string. "public print_str" is equivalent to "public print_str as 'print_str'".


Description:
Filesize: 16.42 KB
Viewed: 10209 Time(s)

linktest.png


Post 23 Sep 2009, 18:33
View user's profile Send private message Reply with quote
fpga



Joined: 22 Sep 2009
Posts: 36
LocoDelAssembly
It took about a minute to get in-line GAS working in g++ and after my difficulty documented above I thought GAS was the way to go.
You've just changed that and I'm very pleased about that.
Thankyou very much for your time and trouble
and to MazeGen and revolution.
Post 23 Sep 2009, 19:06
View user's profile Send private message 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.