flat assembler
Message board for the users of flat assembler.

Index > Unix > Building fasm-1.67.23 under FreeBSD 6.2

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
xanatose



Joined: 09 Jan 2004
Posts: 57
xanatose 10 Nov 2007, 01:55
This is In case someone else got a Segmentation Fault error using the ports system of FreeBSD,

Under FreeBSD the file /usr/include/stdio.h defines

stdout as __stoutp
stderr as __stderrp

And not 1 and 2, thus giving an access violation (Segmentation Fault) error when trying to use 1 for stdout and 2 for stderr. Both __stdoutp and __stderrp are declared as extern FILE *;

The solution, for FreeBSD 6.2 port at least, is to add
Code:
extrn __stdoutp
extrn __stderrp
    

to fasm/source/libc/system.inc

Changing
Code:
mov      [con_handle],1
    

to
Code:
push dword [__stdoutp]
pop [con_handle]
    

in fasm/source/libc/fasm.asm

And changing:
Code:
mov   [con_handle],2
    

To
Code:
push dword [__stderrp]
pop [con_handle]
    

In fasm/source/libc/system.inc

Im not sure on other FreeBSD as the 6.2 is the only one I got, if it applies to other FreeBSD I hope the port changes.

I included the patch to the libc sources to work on freebsd,

You can use patch -n to patch the original sources in the fasm/source/libc directory.

[bold]Update[/bold]
Removed the exe and the object. Changed the diff, because I skiped one mov [con_handle], 2 on system.inc (sorry for that).


Description: Updated diff file
Download
Filename: fasm.diff.tar.gz
Filesize: 283 Bytes
Downloaded: 1138 Time(s)



Last edited by xanatose on 11 Nov 2007, 00:37; edited 1 time in total
Post 10 Nov 2007, 01:55
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 10 Nov 2007, 10:41
Do you have any idea how to fix it in universal way for all the Unix systems? Perhaps there are some standard libc symbols or functions for this?
Post 10 Nov 2007, 10:41
View user's profile Send private message Visit poster's website Reply with quote
mike.dld



Joined: 03 Oct 2003
Posts: 235
Location: Belarus, Minsk
mike.dld 10 Nov 2007, 12:31
Yeah, someone already noticed the problem on our KolibriOS board (link to post), but that was on Motorola's "Chameleon" Linux. So the better solution would be to at least write:
Code:
extrn stdout
...
        pushd   [stdout]
        popd    [con_handle]    

And the same for stderr.
Post 10 Nov 2007, 12:31
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 10 Nov 2007, 13:20
I did this fix, please try the updated package.
Post 10 Nov 2007, 13:20
View user's profile Send private message Visit poster's website Reply with quote
xanatose



Joined: 09 Jan 2004
Posts: 57
xanatose 11 Nov 2007, 00:49
Under FreeBSD stdin, stdout and stderr are macros. Thus cannot be access directly from assembly.
Code:
#define stdin __stdinp
#define stdout __stdoutp
#define stderr __stderrp
    


Thus
Code:
pushd [stdout]
pushd [con_handle]
    

Will not link.

Maybe by using the environment variable OSTYPE (Which is FreeBSD, under FreeBSD), one can do a conditional compile.

BTW: Eliminated the exe and object, since no one downloaded it.
Forgot one mov [con_handle], 2 on the system.inc patch. Thus the assembler runned fine if no error was found, but crashed on error. That is corrected on the new patch.
Sorry for that
Post 11 Nov 2007, 00:49
View user's profile Send private message Reply with quote
xanatose



Joined: 09 Jan 2004
Posts: 57
xanatose 11 Nov 2007, 01:59
Tried with OSTYPE=FreeBSD

On fasm.asm, add
Code:
STDOUT equ 1
STDERR equ 2

match FreeBSD, %OSTYPE% {
  extrn __stderrp
     extrn __stdoutp
     STDOUT equ dword [__stdoutp]
        STDERR equ dword [__stderrp]
}
    


Before the main function. That is because system.inc is included after the mov [con_hande],1 on fasm.asm. If the compilation is not on FreeBSD then you will get the default 1 for STDOUT, 2 for STDERR, also you can add matches for other OSes and define their respective values for stdout and stderr.

and change the
Code:
mov     [con_handle],1
    


With
Code:
push STDOUT
pop [con_handle]
    


On system.inc

chage every
Code:
mov [con_handle], 2
    


with
Code:
push STDERR
pop [con_handle]
    


Another idea could be to instead of using OSTYPE as the environment variable use another one that is not defined. And define it before assemble time. That way you could get object for different OSes by changing the match value.
Post 11 Nov 2007, 01:59
View user's profile Send private message Reply with quote
Chewy509



Joined: 19 Jun 2003
Posts: 297
Location: Bris-vegas, Australia
Chewy509 11 Nov 2007, 23:19
xanatose wrote:
Under FreeBSD stdin, stdout and stderr are macros. Thus cannot be access directly from assembly.
Code:
#define stdin __stdinp
#define stdout __stdoutp
#define stderr __stderrp
    


Same as Sun Solaris, eg
Code:
#define stdin &__iob[0];
#define stdout &__iob[1];
#define stderr &__iob[2];
    

See the "Sun Solaris" thread for further info...

PS. http://board.flatassembler.net/topic.php?t=7759
Post 11 Nov 2007, 23:19
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 11 Nov 2007, 23:29
Could be somewhat more reliable to use /dev/stdin, /dev/stdout and /dev/stderr or those are not standard enough or does not behaves in the same way?
Post 11 Nov 2007, 23:29
View user's profile Send private message Reply with quote
Chewy509



Joined: 19 Jun 2003
Posts: 297
Location: Bris-vegas, Australia
Chewy509 11 Nov 2007, 23:31
xanatose wrote:

Another idea could be to instead of using OSTYPE as the environment variable use another one that is not defined. And define it before assemble time. That way you could get object for different OSes by changing the match value.

What about using the output of 'uname', and use a script to build fasm? Alternatively create a Makefile with appropriate targets?

PS. I'm having the exact same problem with my projects, and have looked at the autoconf system which is overkill (too many people said don't bother for asm applications)... I ended just using a Makefile with the appropriate targets for each OS, eg:

Code:
make Linux    ;; Build for Linux
gmake FreeBSD ;; Build for FreeBSD
gmake Solaris ;; Build for Solaris
make glibc    ;; Build for other OS that is using gcc/glibc    
Post 11 Nov 2007, 23:31
View user's profile Send private message Visit poster's website Reply with quote
Chewy509



Joined: 19 Jun 2003
Posts: 297
Location: Bris-vegas, Australia
Chewy509 12 Nov 2007, 03:28
LocoDelAssembly wrote:
Could be somewhat more reliable to use /dev/stdin, /dev/stdout and /dev/stderr or those are not standard enough or does not behaves in the same way?

Should be do'able, however not all *nix have them and may required symlinks to be in place before they'll work... And having a symlink in place may have some unusual side-effects.

eg On Solaris, '/dev/stdin' is a symlink to '/dev/fd/0'.
Post 12 Nov 2007, 03:28
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 12 Nov 2007, 04:30
Quote:
eg On Solaris, '/dev/stdin' is a symlink to '/dev/fd/0'.


I was expecting that such device files were not present at most, but those symlinked to something else certainly discourages the idea very much then...

After re-reading your link about Solaris I see that without modifications in the sources you got it run. So, why it worked when pointers to _iob's are needed actually? CC does some magic to correct this? Why FreeBSD can't take advantage of the same benefits?

Another possible way could be distributing fasm as an object along with a C file that export some functions to the fasm object to get the desired file descriptors, no? This adds the extra requirement of having a C compiler on the system and the stdio headers, but that is typically satisfied and is better solution than re-assembling fasm since well, you can't re-assemble it if you don't have one fasm working already.Razz (I don't consider cross-compiling acceptable). Or, I missing something in all this?

PS: And perhaps instead of export functions to get the pointers could be enough to just export initialized variables, but has been a long time since I touched C, so I'm not sure if this is actually possible.
Post 12 Nov 2007, 04:30
View user's profile Send private message Reply with quote
Chewy509



Joined: 19 Jun 2003
Posts: 297
Location: Bris-vegas, Australia
Chewy509 12 Nov 2007, 05:48
LocoDelAssembly wrote:

After re-reading your link about Solaris I see that without modifications in the sources you got it run. So, why it worked when pointers to _iob's are needed actually? CC does some magic to correct this?

I have no idea, however 1.67.21 works fine on Solaris as is (and IIRC 1.67.21 worked fine on FreeBSD as is, when I was running FreeBSD), but something changed in 1.67.23 that made it stop working? (I get a segfault if I try 1.67.23 on Solaris).

I don't have a copy of 1.67.22 libc version to check out... So if someone has a copy of the 1.67.22 libc version, can they please attach it here, and I'll test it on Solaris.
Post 12 Nov 2007, 05:48
View user's profile Send private message Visit poster's website Reply with quote
xanatose



Joined: 09 Jan 2004
Posts: 57
xanatose 12 Nov 2007, 17:38
LocoDelAssembly wrote:

Another possible way could be distributing fasm as an object along with a C file that export some functions to the fasm object to get the desired file descriptors, no? This adds the extra requirement of having a C compiler on the system and the stdio headers, but that is typically satisfied and is better solution than re-assembling fasm since well, you can't re-assemble it if you don't have one fasm working already.Razz


Sounds like a good idea. Something like:

SetFasmStdFilePointers.c
Code:
#include <stdio.h>

void SetFasmStdFilePointers(FILE ** pStdio, FILE ** pStderr) {
  *pStdio = stdio;
  *pStderr = stderr;
}
    


Should be portable across OSes.
Post 12 Nov 2007, 17:38
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 14 Nov 2007, 18:47
Tomasz Grysztar wrote:
I did this fix, please try the updated package.


Quote:
flat assembler 1.67.23 for Unix/libc
size: 179 kilobytes
last update: 08 September 2007


Code:
loco@athlon64:~/Desktop/fasm-libc$ ls -l fasm.o
-rw-r--r-- 1 loco loco 93848 2007-09-08 20:40 fasm.o
loco@athlon64:~/Desktop/fasm-libc$ readelf -s fasm.o

Symbol table '.symtab' contains 17 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 SECTION LOCAL  DEFAULT    1 .text
     2: 00000000     0 SECTION LOCAL  DEFAULT    3 .bss
     3: 00000000     0 FUNC    GLOBAL DEFAULT    1 main
     4: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND gettimeofday
     5: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND malloc
     6: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND free
     7: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND getenv
     8: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND fopen
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND fclose
    10: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND fread
    11: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND fwrite
    12: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND fseek
    13: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND ftell
    14: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND fputc
    15: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND time
    16: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND exit    


The Linux package contains the updated sources for the libc port but well, it is the Linux package that doesn't comes with the fasm.o object file.

xanatose, since the libc package wasn't really updated I must ask: have you actually tested the suggested modification or you have assumed that it will not work? Perhaps, despite what stdio.h says, the libc object file publishes those symbols.
Post 14 Nov 2007, 18:47
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 15 Nov 2007, 03:03
xanatose, don't worry, I've just tried with a i386 FreeBSD and it did NOT work, segfault with the original code and undefined symbol when I try to link the version with stdout/stdin symbols.

I think I know why previous versions of fasm worked:
Quote:
version 1.67.23 (Sep 08, 2007)

[+] Added "static" keyword for the "public" directive in COFF format.

[-] Redirected error information into stderr.


Perhaps fasm was using puts or maybe putchar before that feature addition?

Well, if nothing better comes then the C source file is our option.
Post 15 Nov 2007, 03:03
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 17 Nov 2007, 23:49
Here a prototype libc package. Tested on Ubuntu 7.10 AMD64, FreeBSD 6.2 i386 and Debian Etch i386, all gracefully executed "make" command and no core dumps Very Happy

But, this is JUST a prototype, future releases must be made with autoconf/automake to make the package REALLY portable across all unices. Since I have no the time required to read all the necessary stuff to prepare the package as it should be I'm posting this so you can start testing.

[edit]I forgot to remove readme.txt, just ignore it an run "make" inside the directory[/edit]


Description:
Download
Filename: fasm.tar.gz
Filesize: 181.21 KB
Downloaded: 1127 Time(s)

Post 17 Nov 2007, 23:49
View user's profile Send private message Reply with quote
xanatose



Joined: 09 Jan 2004
Posts: 57
xanatose 20 Nov 2007, 03:32
Nicely done. This should make fasm portable across x86 unixes.
Post 20 Nov 2007, 03:32
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 01 Dec 2007, 15:15
Got better solution. Don't use functions that work with FILE structure (buffered file access), instead use functions that work with system handles directly. System handles 0, 1, and 2 should be quaranteed to be STDIN, STDOUT, STDERR on all Unixes:

Code:
write(1, "abcd", 4); //stdout
write(2, "abcd", 4); //stderr
    
Post 01 Dec 2007, 15:15
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 03 Dec 2007, 20:40
In version 1.67.24 i use 'write' function, like vid proposed. Please test it on various Unixes and let me know, how it behaves.
Post 03 Dec 2007, 20:40
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 03 Dec 2007, 21:12
Works OK in FreeBSD 6.2.
Post 03 Dec 2007, 21:12
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< 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.