flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > LINUX Support

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



Joined: 06 Oct 2005
Posts: 132
Hayden
feature request for linux *.so format... If any other users feel strongly for this please post commant here.

_________________
New User.. Hayden McKay.
Post 01 Jul 2007, 17:52
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
search forum for "shared object"
Post 01 Jul 2007, 18:01
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Yes, I would like them supported natively instead of using a linker. I'll continue working on that today and I hope to provide such feature soon (it will not be native though, but, only official fasm release will suffice).
Post 01 Jul 2007, 18:56
View user's profile Send private message Reply with quote
Hayden



Joined: 06 Oct 2005
Posts: 132
Hayden
thanks loco

_________________
New User.. Hayden McKay.
Post 02 Jul 2007, 07:44
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Hayden, almost a month now... I'm very sorry but I have to pass a math exam and since I suck very much on it I was studying all the long days along with other university stuff and a program that I must finish once for all.

If you (or anyone else) are interested I can share the unfinished sources. However, I'm not very sure if I'll continue the macrosed approach because after looking at fasm source I realized that perhaps it is not so hard to implement natively as I thought.

This is more or less how I imagined the case of producing an executable that imports libc
Code:
; fasm demonstration of writing ELF executable with macro formatter extentions

format ELF executable
entry start
needed 'libc.so'
abi linux ; Will support all the defined in constants.inc and it will be possible to supply a number as well


extrn printf
extrn getpid
extrn exit

segment loadable readable executable

start:
  call    [_getpid]

  ccall   [_printf], msg, eax

  call    exit ; Yes, relative relocation

msg db "Current process ID is %d.", $A, 0

  subsegment interpreter readable
    db '/lib/ld-linux.so.2'
  end subsegment

segment loadable readable writable

  subsegment dynamic readable writable
  end subsegment

  _printf dd printf
  _getpid dd getpid


end format ; Native implementation will not have this    


For the shared libraries the format would be "format elf shared".

[edit]Well, since I'm not uploading here I think I don't disturb anybody by posting a link to the sources Razz http://ellocodelassembler.googlepages.com/elf.zip [/edit]
Post 02 Aug 2007, 00:40
View user's profile Send private message Reply with quote
Hayden



Joined: 06 Oct 2005
Posts: 132
Hayden
Ah yes... it's been awhile for me too.
thankyou for effort loco.

_________________
New User.. Hayden McKay.
Post 08 Aug 2007, 16:17
View user's profile Send private message Reply with quote
nocona



Joined: 04 Aug 2007
Posts: 35
nocona
Please try the attached patch for 1.67.22. What I'm trying to achieve in this modifications is to extend the "segment" directive so we can do like the following :

Code:
segment <type> <flags> [align <const-expr>]
    


where <type> is one of interp, dynamic, load, ...etc (i try include gnustack here); <flags> is the same as original segment directive (readable, writeable, executable) and <const-expr> is a constant expression, power of 2 specifying the alignment of the segment. When <type> is a "load" segment, all segments defined "above" it will be included inside this "load" segment. So if we want a segment other than "load" segment to be loaded in memory, we just defined them followed by a load segment. Here's an example code that can be compiled :

Code:
format elf64 executable
entry main

segment interp readable align 1
db "/lib64/ld-linux-x86-64.so.2", 0

segment dynamic readable writeable align 8
dq 1, _strtab_.libc         ;DT_NEEDED
dq 5, _strtab_                    ;DT_STRTAB
dq 6, _symtab_                    ;DT_SYMTAB
dq 10, _strtab_.SIZE              ;DT_STRSZ
dq 11, 24                  ;DT_SYMENT
dq 7, _rela_                      ;DT_RELA
dq 8, _rela_.SIZE           ;DT_RELASZ
dq 9, 24                  ;DT_RELAENT
dq 0, 0                          ;terminator

_printf_ dq ?

_rela_:
.printf:
 dq _printf_
 dq 1 shl 32 + 1;6
   dq 0
.SIZE=$-_rela_

_symtab_:
.null=($-_symtab_)/24
        rb 24
.printf=($-_symtab_)/24
    dd _strtab_.printf
  db 1 shl 4 + 2          ;STT_FUNCTION
       db 0                    ;other (visibility = default)
       dw 0                    ;shndx
      dq 0, 0                 ;value, size
.SIZE=$-_symtab_

_strtab_:
.null=$-_strtab_
   db 0
.libc=$-_strtab_
    db "libc.so.6", 0
.printf=$-_strtab_
   db "printf", 0
.SIZE=$-_strtab_


segment load readable writeable

segment load executable
main :
        ;int3   
    mov     rsi, rsp
    xor     eax, eax
    mov     edi, msg
    call    [_printf_]
  mov     eax, 34;60
  syscall

msg db "Current Stack Pointer = %p.", 10, 0

segment gnustack align 0 ;mark stack as no-execute
    


NOTE :: Currently i only patch elf64 part (so cannot do "format elf" with new segment syntax yet.. this is just for experiment.. until I know the meanings of all variables used in fasm core. END NOTE

Obviously there will be errors in this patch. i'm not an expert in elf and fasm internal. Some known errors are I cannot compile code like
Code:
        mov rax, [fs:0]
    

without patching expressi.inc file.. the error "value out of range" seems to relate with org_origin variable.. which I'm not sure what it is for (segment start virtual address?).


Description: extended-segment-directive-for-fasm-1.67.22-patch
Download
Filename: fasm-elf64-segment-patch.diff.tar.gz
Filesize: 2.52 KB
Downloaded: 167 Time(s)

Post 25 Aug 2007, 03:56
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Can't try now. However I see a problem, how do you define a segment that overlaps with another?

For example, how a dynamic segment can be contained in a loadable segment? I introduced the "subsegment" directive to allow this, do you do the same by other means?

I'll see if I can continue with the development of this soon (I'm targetting ELF32 though).

PS: Possibly I'll change dynamic segment definition to force explicit definition of dynamic elements instead of letting fasm to add them automatically. This way is possible to violate ELF specification but well, some OSes don't care about trivial aspects.

PS2: Of course I have almost NOTHING implemented in fasm source, I have only the posted macroses and some minor modifications to TABLES.INC Embarassed
Post 25 Aug 2007, 04:30
View user's profile Send private message Reply with quote
nocona



Joined: 04 Aug 2007
Posts: 35
nocona
Quote:

For example, how a dynamic segment can be contained in a loadable segment? I introduced the "subsegment" directive to allow this, do you do the same by other means?


I repeat.. When <type> is a "load" segment, all segments defined "above" it will be included inside this "load" segment. So if we want a segment other than "load" segment to be loaded in memory, we just defined them followed by a load segment..
Post 25 Aug 2007, 04:36
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Ahp, sorry then Razz
Post 25 Aug 2007, 11:47
View user's profile Send private message Reply with quote
nocona



Joined: 04 Aug 2007
Posts: 35
nocona
(Just forget the segment extension posted by me above..)

The idea cames from mr Loco. The subsegment directive allows you to define segment type other than loadable segment that is automatically created with "segment" directive. The main reason to do this so that we can use facilities of dynamic linking usually provided by glibc in Linux environment, or other environment.
This directive cannot be used before any segment directive because the idea is to embed a segment inside a loadable segment (but this may change in the future since fasm allows data/code before any segment directive, it automatically creates one). The syntax is

Code:
subsegment <type> [<flag>*]
      <data>
end subsegment
    


where

Code:
<type> ::= interp | dynamic | note | tls | gnustack
<flag> ::= segment flags allowed in "segment" directive
<data> ::= our data definition
    


interp - define null terminated C string path of dynamic linker - may be different in different environment, in my system it is /lib64/ld-linux-x86-64.so.2 for 64-bit app and /lib32/ld-linux.so.2 for 32-bit app.

dynamic - define data structure needed by interpreter.

tls - static tls information.

gnustack - mark stack as (non)executable. absence of executable bit in segment flags mark it as non-executable.

note that if no <data> is specified at all, which means file-size and mem-size are 0, then the offset and virt-addr fields are also set to 0.

known bugs - segment directive inside subsegment block cause fasm to segfault.

The full code is attached, the Linux binary and 2 very simple examples are in the Linux subdir. 32/64 elf support. Please try and comments.. thank you.


Description:
Download
Filename: fasm-1.67-22-subsegment-extension.tar.gz
Filesize: 177.98 KB
Downloaded: 170 Time(s)

Post 31 Aug 2007, 03:19
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
I've tried making a FASMW with your sources and I can't trigger the error you said. I'll look at your modifications to see if I can figure out what could be the problem (which seems to go unnoticed at times).

BTW, which is your reference? I was using this one but it doesn't mention tls and gnustack segment types so it seems to be a little bit outdated Sad
Post 31 Aug 2007, 16:11
View user's profile Send private message Reply with quote
nocona



Joined: 04 Aug 2007
Posts: 35
nocona
forgot to tell that the segfault occured in my linux system. i never tested this in other environment so not sure whether they trgger the same errors.

I use http://www.sco.com/developers/gabi/ and the associated i386 and x86_64 elf abi asa reference.. and of course from the linux kernel source (binfmt_elf.c). The kernel only knows 3 types of segments - PT_INTERPRETER, PT_LOAD and PT_GNU_STACK. Looking at glibc sources there are some others, for example PT_TLS (or something like that) if it's compiled with tls support. i use gnustack to refer to PT_GNU_STACK, and tls to refer to PT_TLS.

not : just few days ago i reinstall my gentoo 2006.1 system that has glibc-2.4 and the example cause floating point exception when I run it. But this doesn't happen in glibc-2.5.
Post 02 Sep 2007, 05:52
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Incredible, I had the constants on my own macro package...
Code:
; Values for program header, p_type field.

PT_NULL             equ                 0 ; Program header table entry unused
PT_LOAD             equ                 1 ; Loadable program segment
PT_DYNAMIC          equ                 2 ; Dynamic linking information
PT_INTERP           equ                 3 ; Program interpreter
PT_NOTE             equ                 4 ; Auxiliary information
PT_SHLIB            equ                 5 ; Reserved, unspecified semantics
PT_PHDR             equ                 6 ; Entry for header table itself
PT_TLS              equ                 7 ; Thread local storage segment
PT_LOOS             equ         $60000000 ; OS-specific
PT_HIOS             equ         $6fffffff ; OS-specific
PT_LOPROC           equ         $70000000 ; Processor-specific
PT_HIPROC           equ         $7FFFFFFF ; Processor-specific

PT_GNU_EH_FRAME equ (PT_LOOS + 0x474e550) ; Frame unwind information
PT_SUNW_EH_FRAME    equ   PT_GNU_EH_FRAME ; Solaris uses the same value
PT_GNU_STACK        equ (PT_LOOS + 0x474e551) ; Stack flags
PT_GNU_RELRO        equ (PT_LOOS + 0x474e552) ; Read-only after relocation

; Program segment permissions, in program header p_flags field.

PF_X                equ         (1 shl 0) ; Segment is executable
PF_W                equ         (1 shl 1) ; Segment is writable
PF_R                equ         (1 shl 2) ; Segment is readable
PF_MASKOS           equ        0x0F000000 ; OS-specific reserved bits
PF_MASKOS           equ        0x0FF00000 ; New value, Oct 4, 1999 Draft
PF_MASKPROC         equ        0xF0000000 ; Processor-specific reserved bits    


So I think the definition should be this
Code:
<type> ::= interp | dynamic | note | tls | number
<flag> ::= readable | writable | executable | number 
<data> ::= our data definition 
    


Where "number" is a dword. I removed gnustack, the reason is because it is OS specific and we should try to focus in implementing an OS independent ELF formatter, not an ELF formatter with some favouritism to Linux. The idea of using a number is borrowed from the data directive of the PE formatter which allows to do things like "data 12".

Also, this time I see you removed the type definition for plain segment directive, I think it should be as featured as subsegment is (except for the "end segment" directive), for example I could be interested in having the interpreter segment out of the memory space (which if I remember right you can do that and your program will still work).

I'm in the process of a Gentoo installation (2007.0 though), I hope I can join to your development soon. I tested the program on Debian and I also got the floating point exception but I did not reported it because I though it was a bug in the example code Razz

I tried dissasembling the example with IDApro but it crashes so I think there is something wrong with the formatter and it is not generating a fully valid ELF (but Linux kernel does not complain about that). "readelf -a" worked however, so a carefull look at it perhaps gives some clues about what is wrong.
Post 02 Sep 2007, 18:42
View user's profile Send private message Reply with quote
nocona



Joined: 04 Aug 2007
Posts: 35
nocona
in the beginning i also want <type> to also accept number, but i think the parser wouldn't allow this (i tried this in my segment extension previously). e.g "subsegment 0x7474E550 executable" will cause error. But if we could do this it will be better..

the reason i include gnustack is just for completeness because there are not so may segment types and we could removed if you or me can make <type> as number if you think that's better.

I retained the syntax of "segment" so we can simply compile old codes and imo a segment should always means a loadable segment. maybe we can allow a subsegment directive before any segment directive that will make it not "embedded" inside any loadable segment..
Post 06 Sep 2007, 02:34
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Ah, I forgot to specify that loadable is default, so if a keyword related to segment permissions is found before type definition then loadable is assumed.

BTW, for 32-bit apps you better can use /lib/ld-linux.so.2 since in 64-bit systems it is a symbolic link to the correct interpreter
Code:
Athlon64 ~ # ls /lib/ld-linux.so.2 -l
lrwxrwxrwx 1 root root 22 Aug 31 20:12 /lib/ld-linux.so.2 -> ../lib32/ld-linux.so.2    


About the parser I think it should be no problem since data directive already supports both, a keyword or a number. Actually the parser will correctly interpret it, but the assembler needs some modifications to accept the parsed number.

I'm almost done with the Gentoo installation and actually I have a good enough environment now (I have Wine working and FASMW works just great so far), but I'm needing to pass some exams... Anyway, I think this Sunday I'll have some time to work with this, I hope!

Cheers

PS: And for 64-bit interpreter again you can use /lib/ld-linux-x86-64.so.2 since it is a symlink to the correct interpreter located at /lib64
Post 06 Sep 2007, 03:24
View user's profile Send private message Reply with quote
nocona



Joined: 04 Aug 2007
Posts: 35
nocona
Quote:

About the parser I think it should be no problem since data directive already supports both, a keyword or a number. Actually the parser will correctly interpret it, but the assembler needs some modifications to accept the parsed number.

as i mentioned before, i did this in "segment" directive modification above and it just doesn't work. Maybe Tomasz can provide us with some info about this.


Quote:

I'm almost done with the Gentoo installation and actually I have a good enough environment now (I have Wine working and FASMW works just great so far), but I'm needing to pass some exams... Anyway, I think this Sunday I'll have some time to work with this, I hope!

Great. and good luck for your exam.
Post 06 Sep 2007, 04:06
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
nocona, I worked on it today. IT IS the parser the problem Sad

The parser has this
Code:
        cmp     bx,segment_directive-assembler
        je      parse_label_directive
    
and hence, it needs segment's first argument to be an identifier (even though the elf formatter will interpret it as a permission flag). There is no problem however if you do things like "segment executable 5+4 3 or 9 readable" because "executable" is playing the label roll here and later the elf formatter will use it as executable permission flag (instead of label like the MZ formatter does).

To allow the example sentence I did the following modification to Tomasz's sources

FORMATS.INC
Code:
      elf_segment_flags:
        cmp     byte [esi],19h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; CHANGED
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        je      elf_segment_named_flag

        cmp     byte [esi],'('
        jne     elf_segment_flags_ok
        lodsb
        call    get_dword_value
        or      [ebx+18h], eax

        jmp     elf_segment_flags

      elf_segment_named_flag:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;    


Well, a workaround to avoid changing the parser could be using "type" keyword to specify that number or named type follows (though it would be optional to use the keyword for named types), and the keyword flags to specify that a number or named permission follows (optional when using named permission or when a type was specified). Ugly workaround but should work and it is backwards compatible to original sintax at the same time.

Now, I must continue with my universitary stuff...

Cheers

PS: BTW, actually there is a problem when you use expression other than just simple numbers. Seems that calling get_dword_value corrupts elf data in some way. At least IDApro complains when I use things like "1+2" or "1 or 2" but it is just fine when I use just "3". Perhaps your seg fault problems are related to this side effect too?
Post 08 Sep 2007, 19:47
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Changing the calling code of get_dword_value with this extremist register protection code fixes the segment origin corruption
Code:
        push    eax ebx ecx edx edi ebp
        call    get_dword_value
        pop     ebp edi edx ecx ebx eax
    


Obviously I'm saving more registers than needed but the point here is that there is no misterious memory boundaries problems fortunatelly.

Well, apart that I SHOULD dedicate my time to my universitary stuff the syntax must be carefully planned before continuing the implementation. (I'm not stopping you from keep developing it since it is your code after all Razz)

Tomasz, any suggestion?Very Happy Anyone else?
Post 09 Sep 2007, 03:18
View user's profile Send private message Reply with quote
Raedwulf



Joined: 13 Jul 2005
Posts: 375
Location: United Kingdom
Raedwulf
I've updated the code to 1.67-23.... but i've not tested it at all... except that it compiles Smile.
LocoDelAssembly: your extremist register protection code... doesn't get_dword_value return with a value in eax? If so.... you're 'protecting' that too?

Cheers.

nocona: where are you from? I know you're from Southeast asia because I can speak Malay as well Smile "mula" was a dead giveaway in the examples lol. I was like... huh!!?? Very Happy. I used to live in Brunei Razz and did my primary/secondary-schooling up to O-levels there.


Description: FASM 1.67-23 subsegment extension.
Download
Filename: fasm-1.67-23-subsegment-extension.tgz
Filesize: 136.67 KB
Downloaded: 155 Time(s)


_________________
Raedwulf
Post 06 Nov 2007, 06:47
View user's profile Send private message MSN Messenger 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-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.