Silverfrost Forums

Welcome to our forums

slink64 archiving problem

20 Apr 2018 12:55 #21896

Hello,

while testing the new functionality of slink64 concerning static libraries I ran into a problem when making use of a subroutine defined in a library which calls a subroutine defined in the same library. The scenario consists of three fortran files, main.for, MYSUB_1.for and MYSUB_2.for and a batch file create_main.bat which creates object files, libraries and executables in diffent ways depending on the command line parameters.

Main.for:

      character*256 MYFILE,MYTEXT
      integer*2 I1,I2,NUM
#if 1
      write(*,*) 'main: MYSUB_1 started'
      CALL MYSUB_1('abcdefgh',8_2,I1,MYFILE,I2)
      write(*,*) 'main: MYSUB_1 finished'
#else
      write(*,*) 'main: MYSUB_2 started'
      call MYSUB_2(MYTEXT,NUM)
      write(*,*) 'main: MYSUB_2 finished'
#endif
      stop
      end

MYSUB_1.for:

      SUBROUTINE MYSUB_1 (MYFILE,i1,i2,MYPATH,i3)
      INTEGER*2 i1,i2,i3
      CHARACTER MYFILE*(*),MYPATH*(*),MYTEXT*(2048)
      write(*,*) 'MYSUB_1 started'
      CALL MYSUB_2(MYTEXT,i1)
      write(*,*) 'MYSUB_1 finished'
      RETURN
      END

MYSUB_2.for:

      SUBROUTINE MYSUB_2(MYTEXT,NUM)
      CHARACTER MYTEXT*(*)
      INTEGER*2 NUM
      write(*,*) 'MYSUB_2 started'
      NUM=32
      MYTEXT='xxxx'
      write(*,*) 'MYSUB_2 finished'
      END

The code is created by means of batch file create_main.bat:

@echo off

setlocal
if '%1' == '' (
  echo Usage: create_main [64 or 32] [/objs]
  echo Params: 64 - 64 bit build
  echo         32 - 32 bit build
  echo         /objs - link against objects as opposed to library   
  exit /B 1
)
set DO_LINK_FROM_OBJECTS=0
set CCOPTS=/debug /Cfpp
if '%1' == '64' (
  set CCOPTS=%CCOPTS% /64
  set MYTARGET=_64
  set MYSLINK=slink64
) else (
  if '%1' == '32' (
    set MYTARGET=_32
    set MYSLINK=slink
  ) else (
    echo Error: one of 32 or 64 needs to be specified
    exit /B 2
  )
)
if '%2' == '/objs' set DO_LINK_FROM_OBJECTS=1
set MYFILES=MYSUB_1,MYSUB_2

for %%f in (%MYFILES%) do (
  echo ftn95 %%f.for /FIxed_format %CCOPTS% /Binary %%f%MYTARGET%.obj
  ftn95 %%f.for /FIxed_format %CCOPTS% /Binary %%f%MYTARGET%.obj
)

echo ; > mylib%MYTARGET%.lnk
if '%1' == '64' (
  for %%f in (%MYFILES%) do (
    echo lo %%f%MYTARGET% >> mylib%MYTARGET%.lnk
  )
) else (
  echo ; > mylib%MYTARGET%.lnk
  echo archive >> mylib%MYTARGET%.lib >> mylib%MYTARGET%.lnk
  for %%f in (%MYFILES%) do (
    echo addobj %%f%MYTARGET% >> mylib%MYTARGET%.lnk
  )
)
echo file mylib%MYTARGET%.lib >> mylib%MYTARGET%.lnk
echo %MYSLINK% mylib%MYTARGET%.lnk
%MYSLINK% mylib%MYTARGET%.lnk

echo ftn95 main.for /FIxed_format %CCOPTS% /Binary main%MYTARGET%.obj
ftn95 main.for /FIxed_format %CCOPTS% /Binary main%MYTARGET%.obj

echo lo main%MYTARGET% > main%MYTARGET%.lnk
if '%DO_LINK_FROM_OBJECTS%' == '1' (
  echo lo MYSUB_1%MYTARGET%.obj >> main%MYTARGET%.lnk
  echo lo MYSUB_2%MYTARGET%.obj >> main%MYTARGET%.lnk
) else (
  echo lo mylib%MYTARGET%.lib >> main%MYTARGET%.lnk
)
echo map main%MYTARGET%.map >> main%MYTARGET%.lnk
echo file >> main%MYTARGET%.lnk

echo %MYSLINK% main%MYTARGET%.lnk
%MYSLINK% main%MYTARGET%.lnk

endlocal

Now executing

create_main.bat 64

results in creating executable main_64.exe, however, symbol MYSUB_2 is marked as undefined and executing main_64.exe results in exception

Silverfrost 64-bit exception report on c:\ds\samples\salford_8.30\test_link\gplini\sample_2salford\main_64.EXE  Fri Apr 20 14:32:04 2018


Call to missing routine - MYSUB_2 at address 1c0086c0

Within file main_64.EXE
in MYSUB_1 in line 6, at address 8b
in MAIN@ in line 6, at address ac


RAX = 000000000000001d   RBX = 000000000240fda0   RCX = 00000000004019a3   RDX = 00000000004050c8
RBP = 000000001c000000   RSI = 00000000004051ef   RDI = 00000000004014f0   RSP = 000000000240f490
R8  = 00000000004019a3   R9  = 000000000240d940   R10 = 0000000000000000   R11 = 0000000000000246
R12 = 0000000000000000   R13 = 0000000000000000   R14 = 0000000000000008   R15 = 0000000000000100

1c0086c0) int       9

This seems strange to me for I think the symbol **has **been defined in library mylib_64.lib which executable main_64.exe is linked against.

Please find more information in the continuation of this post.

20 Apr 2018 1:31 #21897

slink64 archiving problem continuation

Now executing

create_main.bat 64

results in creating executable main_64.exe, however, symbol MYSUB_2 is marked as undefined and executing main_64.exe results in exception

Silverfrost 64-bit exception report on c:\ds\samples\salford_8.30\test_link\gplini\sample_2salford\main_64.EXE  Fri Apr 20 14:32:04 2018


Call to missing routine - MYSUB_2 at address 1c0086c0

Within file main_64.EXE
in MYSUB_1 in line 6, at address 8b
in MAIN@ in line 6, at address ac


RAX = 000000000000001d   RBX = 000000000240fda0   RCX = 00000000004019a3   RDX = 00000000004050c8
RBP = 000000001c000000   RSI = 00000000004051ef   RDI = 00000000004014f0   RSP = 000000000240f490
R8  = 00000000004019a3   R9  = 000000000240d940   R10 = 0000000000000000   R11 = 0000000000000246
R12 = 0000000000000000   R13 = 0000000000000000   R14 = 0000000000000008   R15 = 0000000000000100

1c0086c0) int       9

This seems to be strange to me for I think symbol MYSUB_2 **has **been defined in static library mylib_64.lib which main_64.EXE is linked against. To prove this, line

#if 1

of file main.for was substituted by line

#if 0

deactivating call MYSUB_1 and activating call MYSUB_2. Note that library mylib_64.lib remains unchanged. Calling command

create_main.bat 64

produces executable main_64.EXE without any unresolved and when executed, successfully calls subroutine MYSUB_2 of library mylib_64.lib.

Here are the files created by command 'create_main.bat 64':

MYSUB_1_64.obj
MYSUB_2_64.obj
mylib_64.lnk
mylib_64.lib
main_64.lnk
main_64.obj
main_64.EXE
main_64.map

Now we change back line '#if 0' to '#if 1' in main.for and link executable main_64.exe against object files

MYSUB_1_64.obj
MYSUB_2_64.obj

as opposed to library mylib_64.lib. This is done via call

create_main.bat 64 /objs

. Now executable main_64.EXE is created without any unresolved symbol and executes successfully.

20 Apr 2018 1:46 #21898

slink64 archiving problem continuation (ii)

To compare all this with the results in the 32 bit compile environment you may execute commands

create_main.bat 32
create_main.bat 32 /objs

. The first command creates files

MYSUB_1_32.obj
MYSUB_2_32.obj
mylib_32.lnk
mylib_32.lib
main_32.obj
main_32.lnk
main_32.exe
main_32.map

and symbol MYSUB_2 is **not **marked as **unresolved **by slink. Moreover the resulting executable main_32.exe is linked against mylib_32.lib and executes as expected.

I have no explanation for symbol MYSUB_2 being unreloved in the 64 bit case (where main_64.exe is linked against library mylib_64.lib).

Moreover, how would I check if a static library defines a symbol, e.g. MYSUB_2 without using the linker slink64 itself?

Thanks for any help. Regards, Dietmar

23 Apr 2018 12:09 #21927

A couple of comments on these posts:

  1. Dietmar, thank you very much for the .bat file example. It is very informative of doing things that I was not familiar with.

  2. Can we please stop using .lnk as a file extension for slink / slink64. I have instead used the command slink64 @main_64_lnk.txt. .lnk extensions are such a hassle !!

  3. I overcame the problem reported by double loading the .lib, with

    lo main_64
    lo mylib_64.lib
    lo mylib_64.lib
    map main_64.map
    file

This shows than 'lo xxx.lib' is not sufficient. We need a multi-pass load 'le xxx.lib' or 'le xxx.sl64'

24 Apr 2018 9:44 #21949

John,

thanks for your hint loading archive mylib_64.lib twice which worked for this sample. To my opinion slink64 would have to try resolving all symbols of library mylib_64.lib in library mylib_64.lib itself first, before creating an error (multipass load as you said).

Concerning the suffixes: I am not a friend of using link files in batch files, no matter how the suffixes are. In batch files I would prefer using command line options directly. However, if using slink64, I do not know the slink64 command line which would result in the same as the *.lnk file I used; I tried with options -archive and -file but both result in errors for slink64.

Please note the following: if using suffix 'txt' instead of 'lnk' when linking and using files

mylib_32.txt

; 
archive 
addobj MYSUB_1_32 
addobj MYSUB_2_32 
file mylib_32.lib 

and mylib_64.txt

; 
lo MYSUB_1_64 
lo MYSUB_2_64 
file mylib_64.lib

then

slink mylib_32.txt   works
slink @mylib_32.txt does not work
slink64 mylib_64.txt does not work
slink64 @mylib_64.txt works.

which to my opinion seems to be confusing, as well. I think the best would be to have analogous interfaces for utility slink64 and slink.

Regards, Dietmar

24 Apr 2018 2:12 #21952

This failure has now been fixed and a new version of SLINK64 is available for download here...

https://www.dropbox.com/s/f96fq82k9q4nqy6/Slink64.zip?dl=0

25 Apr 2018 7:43 #21963

Paul,

I note that LE is no longer documented for SLINK, although last time I used a library 'LE xxx.lib' did work. ( Has this always been the case and I have been copying old slink interactive mode command files from FTN77 ?)

Does this mean that 'LO xxx.lib' will now do a multi-pass load for both SLINK and SLINK64 ?

I had a look through the ftn95.chm, but did not see where reference to multi-pass loading of .lib files is performed.

regards,

John

25 Apr 2018 8:14 #21965

John

LE was new to me (or maybe I had just forgotten it). As you say it's not in the electronic documentation (it might be in the paper manual).

As a SLINK command It stands for 'load exhaustive'. It's quite possible that LO does this anyway and that as a result LE has become redundant.

The recent fix to SLINK64 should mean that LO is sufficient. LE is not implemented as a separate command in SLINK64.

25 Apr 2018 10:30 #21970

Hello,

with the latest version of slink64 I could link and execute the test example successfully.

Thanks, Dietmar

Please login to reply.