Author Topic: Dev request? NASM, OMF & Borland linker  (Read 4758 times)

Offline AAG

  • New Member
  • Posts: 1
Dev request? NASM, OMF & Borland linker
« on: August 25, 2010, 01:34:57 PM »
Hi

To cut a long story short, is there a way for nasm to export the public functions in the OMF format, in the same way as the free borland c++ 5.5 command line tools?

Using Agnoer Fog's "Object file converter" (objconv http://www.agner.org/optimize/) I've dissassembles a simple C file contain 2 functions, applied the suggested "borland fixups" and compiled with nasm -fobj.

The code I'm compiling is :-

Code: [Select]
; Disassembly of file: .\bc\bcc.obj
; Fri Aug 20 22:42:17 2010
; Mode: 32 bits
; Syntax: YASM/NASM
; Instruction set: 80386


global _A
global _B

DGROUP  GROUP _DATA, _BSS


SECTION _TEXT   align=4 execute use32                         ; section number 1, code

_A:     ; Function begin
        push    ebp                                     ; 0000 _ 55
        mov     ebp, esp                                ; 0001 _ 8B. EC
        pop     ebp                                     ; 0003 _ 5D
        ret                                             ; 0004 _ C3
; _A End of function

_B:     ; Function begin
        push    ebp                                     ; 0005 _ 55
        mov     ebp, esp                                ; 0006 _ 8B. EC
        pop     ebp                                     ; 0008 _ 5D
        ret                                             ; 0009 _ C3
; _B End of function


(NB The only fixup I haven't applied is that each function needs to be its own section - but please see below)

Running objconv -ds lists the following for a native borland object file :-

Public names:
  _A, Segment _TEXT, Group none, Offset 0x0, Type 0

Public names:
  _B, Segment _TEXT, Group none, Offset 0x5, Type 0


Running the same for the NASM object file gives :-

Public names:
  _A, Segment _TEXT, Group none, Offset 0x0, Type 0
  _B, Segment _TEXT, Group none, Offset 0x5, Type 0


The delphi linker (and I presume borland c linker) only appears to be able to "see" the 1st public name for a given section. Hence the reason for borland nasm tutorials saying you have to delcare each pubic function  in its own section.

I had an email back from Agner Fog which said :-

"The file produced by bcc has separate sections of the _text segment, i.e.
start text
define A
end text
start text
define B
end text

I don't know if NASM can do this? MASM has an end segment directive, but NASM doesn't. "


Is there any way of being able to create the OMF as per borland c++ at with NASM at the moment? If not, would it be possible for submit a change request(?) to have some sort of extension added to the omf on the global instruction, eg global _A:borland ????


Thanks

Andy

PS: I have a large NASM file which declares around 15 public functions which works if I go for nasm -fwin32 and then use objconv on it. It would be great if NASM could produce OMF as the borland c++ 5.5 to save having to declare a load of separate sections with jumps OR change the code to insert the new code sctions + then fix the other calls to use the updated section.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2380
  • Country: us
Re: Dev request? NASM, OMF & Borland linker
« Reply #1 on: August 26, 2010, 11:39:03 PM »
If assembling to "-f win32" and "objconv -fomf" works for ya, that's what I would do, at least for now.

There's a "feature request tracker" at SourceForge:

http://sourceforge.net/tracker/?group_id=6208&atid=356208

I would not guarantee that it'll get you any satisfaction - there are a lot of open requests.

I've heard of this problem with Delphi, and the "put everything in its own segment" solution. It "sounds like a Borland problem, to me!" :)

Perhaps some macros could be written to "put everything in its own segment" automatically - ugly, and probably not much help with existing code...

Maybe someone can look at what "objconv" does to make it work, and "fix" Nasm to make Delphi happy... but I wouldn't hold my breath, Andy. Wish I could give you a more optimistic answer.

Best,
Frank


Offline cm

  • Jr. Member
  • *
  • Posts: 65
Re: Dev request? NASM, OMF & Borland linker
« Reply #2 on: August 31, 2010, 03:02:54 PM »
Quote from: Frank
Perhaps some macros could be written to "put everything in its own segment" automatically - ugly, and probably not much help with existing code...

It's not much help at all, because you would have to name every segment different - which means that every segment would really have to be a different segment. Otherwise, NASM automatically coalesces all the labels exported from one segment in the output file.

Quote from: Frank
Maybe someone can look at what "objconv" does to make it work, and "fix" Nasm to make Delphi happy...

Quote from: Agner Fog
The file produced by bcc has separate sections of the _text segment, i.e.
start text
define A
end text
start text
define B
end text

I don't know if NASM can do this? MASM has an end segment directive, but NASM doesn't.

The solution is to output "global _A:borland" (or whatever syntax you implement) in its own "segment record" of the output file (i.e. .obj), but with the same segment name. NASM currently can't be used to do that. You would have to look into outobj.c for that, around line 2086 (where the comment says "Write the PUBDEF records").
C. Masloch

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2380
  • Country: us
Re: Dev request? NASM, OMF & Borland linker
« Reply #3 on: September 04, 2010, 07:22:19 PM »
Sorry for the delayed reply. Told ya not to hold your breath! :)

Right, CM, that's where we'd fix it, I guess. Maybe nearer the "pub crawl :)" label, actually... Perhaps just moving that final "obj_emit(orp);" up into the "for" loop would do it(?).

But maybe outobj.c needs a lot more than that! I observe that if I assemble to "-f win32" and convert to OMF with "objconv", I get a completely different set of record types than if I assemble with "-f obj". There's an "omfdump.c" in the "misc/" directory of the nasm source (thanks to whoever put that there!). It shows that where Agner uses "PUBDEF32", "-f obj" uses "PUBDEF16"(!!!). Seems to work - except for Borland's tools - but it really doesn't look "right" to me.

Let's drag it out in the middle of the floor and let the cat sniff it. Here's my test file:

Code: [Select]
section _TEXT align=4 execute use32

global foo

foo:
ret

global bar

bar:
ret

global baz

baz:
ret

Here's what "omfdump" makes of "-f obj"...

Code: [Select]
80 THEADR       11 bytes, checksum DB (valid)
  0000: 09 62 74 65 73 74 2e 61-73 6d                    :  .btest.asm
88 COMENT       30 bytes, checksum 88 (valid)
  [NP=0 NL=0 UD=00] 00 Translator
  0002: 1a 54 68 65 20 4e 65 74-77 69 64 65 20 41 73 73  :  .The Netwide a**
  0012: 65 6d 62 6c 65 72 20 32-2e 30 39                 :  embler 2.09
96 LNAMES        8 bytes, checksum B9 (valid)
  0000: 00 05 5f 54 45 58 54                             :  .._TEXT
98 SEGDEF16      7 bytes, checksum B1 (valid)
  0000: a9 03 00 02 01 01                                :  ......
90 PUBDEF16     24 bytes, checksum 95 (valid)
  0000: 00 01 03 66 6f 6f 00 00-00 03 62 61 72 01 00 00  :  ...foo....bar...
  0010: 03 62 61 7a 02 00 00                             :  .baz...
88 COMENT        4 bytes, checksum 91 (valid)
  [NP=0 NL=1 UD=00] A2 Link pass separator
  0002: 01                                               :  .
a0 LEDATA16      7 bytes, checksum 0F (valid)
  0000: 01 00 00 c3 c3 c3                                :  ......
8b MODEND32      2 bytes, checksum 73 (valid)
  0000: 00                                               :  .

And here's what it thinks of "-f obj" followed by "objconv -fomf"...

Code: [Select]
80 THEADR       12 bytes, checksum AC (valid)
  0000: 0a 62 74 65 73 74 33 2e-6f 62 6a                 :  .btest3.obj
96 LNAMES       32 bytes, checksum C2 (valid)
  0000: 04 46 4c 41 54 04 43 4f-44 45 04 44 41 54 41 03  :  .FLAT.CODE.DATA.
  0010: 42 53 53 05 43 4f 4e 53-54 05 5f 54 45 58 54     :  BSS.CONST._TEXT
99 SEGDEF32      9 bytes, checksum AA (valid)
  0000: a9 03 00 00 00 06 02 00-                         :  ........
9a GRPDEF        2 bytes, checksum 63 (valid)
  0000: 01                                               :  .
91 PUBDEF32     12 bytes, checksum 1A (valid)
  0000: 01 01 03 66 6f 6f 00 00-00 00 00                 :  ...foo.....
91 PUBDEF32     12 bytes, checksum 28 (valid)
  0000: 01 01 03 62 61 72 01 00-00 00 00                 :  ...bar.....
91 PUBDEF32     12 bytes, checksum 1F (valid)
  0000: 01 01 03 62 61 7a 02 00-00 00 00                 :  ...baz.....
a1 LEDATA32      9 bytes, checksum 0C (valid)
  0000: 01 00 00 00 00 c3 c3 c3-                         :  ........
8a MODEND16      2 bytes, checksum 74 (valid)
  0000: 00                                               :  .

Note that Nasm uses MODEND32 while objconv uses MODEND16. I almost think Nasm has it right in that case... I dunno. I guess either works?

Another "symptom"... I took an old "hello world MessageBox" executable (assembled with "-f obj" and linked with... probably Alink(?)... I think it used to work...) and ran "objconv -fnasm" on it. It sees my code section as "no execute" and emits DBs instead of disassembling it. Could be a glitch in objconv, but I think it a lot more likely that it's a sign that outobj.c needs a serious re-write!

I'm not able to test any such proposed rewrite. (that's a lie - I'm not "willing"... I could run MS's stuff if I wanted to...) So unless someone is seriously interested in digging into this... Don't hold your breath...

Best,
Frank