Linux Shared Library

  • Hi,

    I have nasm code successfully compiles to a win32 DLL. Now, I habe to provide this code on a Linux Shared Library (they call it a .so file) to be accessed by a tomcat application server (32 bit). OK, I have no glue about Linux. From the nasm manual I learnt about sections (instead of segments) and nasm -elf produces a .o object file (would be enough for me, also) but it did not run on the Linux server - link problems. Perhaps, it has to do with this suff arround GOT - but is completey unclear to me. All nasm examples generate .out executables, doesn't help me.

    Unfortunately, I've no Linux available to test some stuff by myself.

    If it's not big thing it would be great if somebody could post a code example i.e. a function "giveback" taking an Int32 argument and giving it back again like
    _StdCall Int32 giveback(Int32 number)
    This entry point giveback should be exposed by the resulting .o object file and the nasm.exe and alink.exe command line commands to generate this .o from the .asm would be helpful, also.
    (please, no gcc usage, I don't have any Linux tool available on my win32 computer, I can use nasm.exe and alink.exe, only)

    Many thanks for help,

    • Frank Kotler
      Frank Kotler

      Nasm.exe will produce ELF linkable object files, regardless of what OS it's running on. Alink.exe, however, has *no* idea how to make a shared object out of it. You're SOL on that score. Fergeddiit!

      It "should" be possible to compile ld to run under Windows as a "cross linker". Good luck, even if you use gcc... "should" be possible even with whatever non-gcc compiler you're using... says right in the glossy brochure that C is portable, right?

      I sympathize with your position. *I* can't (won't, I should say) test anything on Windows. However, as it happens, I've got more versions of ld than you can shake a stick at. I've seen an example of a "simple" shared library. I seem to recall that the command line to ld involves "--shared". We've gotta move our gem to some directory mentioned in /etc/ldconf and then do ldconfig to "activate" it.

      However, there's more to it than that. Unless I'm mistaken, the difference between a PE and a .dll is that the latter has a relocation section. An .so, AFAIK, does not have a relocation section and must be position independent code. "GOT" and friends are supposed to assist in this... I'm afraid I don't "get" how to use 'em...

      If you had a friend who was running Linux, say fbkotler at or at you might be able to get him to run your code past ld and report back what the error message was, at least...

      (incidentally, "segment" and "section" are exact aliases to Nasm. There are differences - *big* differences - between Windows and Linux, but this ain't one of 'em)


      P.S. You can use a "live CD" to test stuff under Linux, without having to "install" it...

      • Hi Frank,

        Thanks for your fast response - made me sure that the problem is not our .o from nasm. You are right, I can generate an ELF linkable object. When I compile i.e. this example code

                    bits  32                            ;32bit code
        global      rtnSeven
                    section .data
                    section .text
        %define     pObj        ebp+12                  ;jobject = UInt32
        %define     pEnv        ebp+8                   ;JNIEnv  = UInt32
                    push  ebp
                    mov   ebp,  esp
                    mov   eax,  dword 7                 ;Return 7
                    mov   esp,  ebp
                    pop   ebp
        .rtn        ret   4*2

        with the -felf32 option. I then have a .o we can use on the Linux server to link a .so library using ld!
        (the two extra arguments JNIEnv and jobject are necessary for the Java JNI interface - forget about it, here)

        OK, but tomcat could not link our .so ...
        Reason for that, we found out now: the Linux name of the library *must* start with the prefix 'lib'!
        LOL - omitting the .so extension is ok is some way, but having to name as ...
        I will remember that next time a Linux guy blame me that Microsoft identifies files by their extensions ;-)

        But, seriously, when I take a look into the .o generated by nasm with the editor, I see some "strange" things:

        1. The .o contains *all* labels used in the .asm file, in the above example two labels:
        regardless of the global instruction stating that only rtnSeven should be exposed! Every label is exposed! This makes no sense, isn't it?

        2. When I define variables (labels) in the .data section, same with those labels: *all* present in the .o!

        3. The .o contains *all* equ definitions from the file, even regardless whether they are used or not in the code. This means, when I have an include file with some definitions like
        NULL  equ 0x00000000
        TRUE  equ 0x00000001
        FALSE equ 0x00000000
        then the .o file exposes i.e. a 'label' named NULL or at least the .o file cares a parameter name NULL. But shouldn't NULL be replaced with 0x0000000 by the preprocessor and so will never occur in a library? At least nasm behaves like that when generating .obj files for PE!
        Because I have a lot of such equates they blow up the resulting .o especially those of them never used in the code!
        Can that behavior be correct?

        00006d0: 6d00 5452 5545 0046 414c 5345 004e 554c  m.TRUE.FALSE.NUL <-- equ used in code
        00006e0: 4c00 444c 4c5f 5052 4f43 4553 535f 4445  L.DLL_PROCESS_DE
        00006f0: 5441 4348 0044 4c4c 5f50 524f 4345 5353  TACH.DLL_PROCESS <-- equ never used in code
        0000700: 5f41 5454 4143 4800 444c 4c5f 5448 5245  _ATTACH.DLL_THRE
        0000710: 4144 5f41 5454 4143 4800 444c 4c5f 5448  AD_ATTACH.DLL_TH
        0000720: 5245 4144 5f44 4554 4143 4800 7056 6572  READ_DETACH.pVer <-- .data section labels
        0000730: 7369 6f6e 0075 4b65 7956 616c 7565 0064  sion.uKeyValue.d
        0000740: 4375 746f 6666 5800 6443 7574 6f66 6659  CutoffX.dCutoffY

        I use "The Netwide Assembler 0.99.05"

        Would be great you could help to make my (now working) .o libs more perfect.


    • Hi, me again!

      no response so far? Hmmm... ok, did I miss a simple "-s strip option" or something like that to eliminate all these useless equates and labels from the elf .o lib? Or is it an (un)known problem with the nasm.exe -felf32 ?

      I feel not good with all my local label names in my .o lib ... Nobody an idea how to make the "global/extern" mechanism working correctly - just like in nasm.exe -fobj?


      • Hi Martin,

        AFAIK, Nasm follows the ELF specification. You can use the "-s" switch - to ld, not Nasm - to remove unneeded cruft - or "strip -R.comment myfile" works good... but that's *after* Nasm has done its work.

        AFAIK, "global" and "extern" *do* work as intended. ELF is different from OMF. That isn't really a "problem"...

        You can look at the Manual, "ELF extensions to the 'global' directive", for "hidden", but I don't think it'll do what you want. I'm afraid the only way to eliminate the useless symbols is to eliminate the useless symbols...


        • Hi Frank,

          thanks, that's the way it works:
          nasm -felf32
          followed by
          strip -x

          Only global declared symbols remain in the .o
          That's what I wanted to have!

          Great, thanks,

    • ilikenasm

      Hi Frank,

      I put  Martin's program into demolib.asm, and compiled it with:
      nasm -f elf32 demolib.o demolib.asm

      Then wrote a program demo.asm to call rtnSeven:

      GLOBAL _start
      EXTERN rtnSeven
        call rtnSeven

      nasm -f elf32 -demo.o demo.asm

      link them:
      ld -s -o aout demo.o demolib.o

      ran it:

      got error:
      Segmentation fault (core dumped)

      I'm using ubuntu 7, nasm 2.05.01, why this error occured? are there any examples show how to create a linux shared library and call its function in other asm module?

      Many Thanks,

    • Frank Kotler
      Frank Kotler

      "_start" doesn't get called. (apparently just jumped to) The first thing on the stack will be the command line parameter count. So "ret" is going to try to execute code at... probably 1, unless you gave it parameters. Segfault!

      After the "call rtnSeven", the "result" (7, we hope) should be in eax. We probably want it in ebx for an "error code" to return to the system...

      mov ebx, eax
      mov eax, 1 ; __NR_exit
      int 80h

      ... now you should be able to see the result by "echo $?"

      There's a shared lib example, "libsimple", from "seadhurt"(?) in the "files" section of the !Yahoo! linux-nasm-users group. Here, I'll "liberate" it for us:

      This is quite a simple example, as the name indicates, but it'll give us something to start with.

      I've lost track of it, but I had another example from Robin Miyagi (from Here it is! "pic-asm". My recollection was that I never got this to work without segfaulting, but... it works now! (???) Same place:



    • Frank Kotler
      Frank Kotler

      Whups! Typo in that second URL...


    • ilikenasm

      Hi Frank,

      Thanks very much!

      Best Regards,

    • >
      I'd really appreciate if you made it for ELF64 as well. I've been trying to make my code work in Ubuntu 8.10 x64 for several days now ;(

      • Frank Kotler
        Frank Kotler

        I'll begin the port immediately upon receipt of the 64-bit machine you send me. :)

        Seriously, I'm glad you reminded me... That's Robin Miyagi's code, not mine. What I've got for a makefile - possibly modified from Robin's original - doesn't actually link as a shared library - links (via gcc) directly with However, I did get it to work by linking with ld -o test test.o -I/lib/ -ltextio -L/usr/local/lib (I *think* that's what I did) I'm going to have to look into it more...

        But 64-bit code is a whole different ballgame! I have *no* idea how you'd do a shared library. What have you tried?


    • > I'd really appreciate if you made it for ELF64 as well...

      Here's the simple code of my test library:

      BITS 64

      SECTION .text

      ALIGN 16

      const_shift: dd  1, 2, 3, 4

      global transform_em64



      ; int __cdecl transform_em64(unsigned int * buf)



      ALIGN 16


          movdqu      xmm0,   [rcx]

          paddd       xmm0,   [rel const_shift]

          movdqu      [rcx],  xmm0


      This works for Win64 (nasm 2.05, VS2005 SP1) but for Linux64 (nasm 2.03.01, gcc 4.3.2) I get all sorts of errors: "panic: intra-segment OUT_REL4ADR", floating point exception (when tried to use GOT code from nasm manual), etc.
      Please suggest correct code.
      Thanks a lot

      • Frank Kotler
        Frank Kotler

        Okay... I'm reading messages "out-of-order"... or perhaps my brain is out-of-order...

        Nasm 2.03.01 does complain about this code. The latest snapshot - 20090105 from - seems to like it okay. I'm not able to try linking/running it, but it assembles without error...

        See if that helps...


        • Yeah, 2.06rc2 works nicely (with rdi instead of rcx, that was Win64 code). Thanks a lot