During some troubleshooting over at VSI forum hb told me that running a shareable image will execute LIB$INITIALIZE functions.
During some troubleshooting over at VSI forum hb told me that
running a shareable image will execute LIB$INITIALIZE
functions.
That made me write this:
$ type lib.pas
[inherit('sys$library:pascal$lib_routines', 'sys$library:starlet')]
module lib(input, output);
[global]
procedure check;
var
imgnam : varying [1024] of char;
begin
lib$getjpi(item_code := jpi$_imagname, resultant_string :=
imgnam.body, resultant_length := imgnam.length);
if index(imgnam, ']libshr.EXE') > 0 then begin
writeln('This is a shareable image to link against not run');
$exit(ss$_normal);
end;
end;
[global]
procedure say;
begin
writeln('Hi');
end;
end.
$ type prg.pas
program prg(input,output);
[external]
procedure say; external;
begin
say;
end.
$ type trick.mar
.title trick
.extrn lib$initialize
.psect lib$initialize long,nopic,con,gbl,noshr,noexe,nowrt
.address check
.end
$ macro trick
$ pas lib
$ link/share=libshr lib + trick + sys$input/opt
SYMBOL_VECTOR=(say=PROCEDURE)
$
$ define/nolog libshr sys$disk:[]libshr
$ pas prg
$ link prg + sys$input/opt
libshr/share
$
$ run prg
Hi
$ run libshr
This is a shareable image to link against not run
:-)
Arne
On 1/7/2025 8:58 PM, Arne Vajhøj wrote:...
During some troubleshooting over at VSI forum hb told me that
running a shareable image will execute LIB$INITIALIZE
functions.
That made me write this:
Pascal has an [INITIALIZE] attribute that you can put on the PROCEDURE
CHECK and the compiler should do the contribution to the LIB$INITIALIZE PSECT.
And you should include LIB$INITIALIZE (the code module, not the data
PSECT) from STARLET when linking. The x86 linker will do that for you,
but the Alpha and Itanium linkers do not.
On 1/8/2025 12:37 PM, John Reagan wrote:
On 1/7/2025 8:58 PM, Arne Vajhøj wrote:...
During some troubleshooting over at VSI forum hb told me that
running a shareable image will execute LIB$INITIALIZE
functions.
That made me write this:
Pascal has an [INITIALIZE] attribute that you can put on the PROCEDURE
CHECK and the compiler should do the contribution to the
LIB$INITIALIZE PSECT.
And you should include LIB$INITIALIZE (the code module, not the data
PSECT) from STARLET when linking. The x86 linker will do that for
you, but the Alpha and Itanium linkers do not.
Zweite Sehr Verbesserte Ausgabe:
$ type lib.pas
[inherit('sys$library:pascal$lib_routines', 'sys$library:starlet')]
module lib(input, output);
[initialize]
procedure check;
var
imgnam : varying [1024] of char;
begin
lib$getjpi(item_code := jpi$_imagname, resultant_string :=
imgnam.body, resultant_length := imgnam.length);
if index(imgnam, ']libshr.EXE') > 0 then begin
writeln('This is a shareable image to link against not run');
$exit(ss$_normal);
end;
end;
[global]
procedure say;
begin
writeln('Hi');
end;
end.
$ type prg.pas
program prg(input,output);
[external]
procedure say; external;
begin
say;
end.
$ pas lib
$ link/share=libshr lib + sys$library:starlet/lib/incl=lib$initialize + sys$input/opt
SYMBOL_VECTOR=(say=PROCEDURE)
$
$ define/nolog libshr sys$disk:[]libshr
$ pas prg
$ link prg + sys$input/opt
libshr/share
$
$ run prg
Hi
$ run libshr
This is a shareable image to link against not run
Arne
On 1/8/2025 3:42 PM, John Reagan wrote:
And the compiler also supports the Extended Pascal TO BEGIN DO and TO
END DO statements. TO BEGIN DO is just the same as [INITIALIZE] but
allows any statement. TO END DO is an exit handler (registered with
an initialization routine).
$ type prg.pas
program prg(input,output);
[external]
procedure say; external;
begin
writeln('2');
say;
writeln('4');
end.
$ type lib.pas
module lib(input, output);
[global]
procedure say;
begin
writeln('3');
end;
to begin do writeln('1');
to end do writeln('5');
end.
$ pas lib
$ link/share=libshr lib + sys$library:starlet/lib/incl=lib$initialize + sys$input/opt
SYMBOL_VECTOR=(say=PROCEDURE)
$
$ define/nolog libshr sys$disk:[]libshr
$ pas prg
$ link prg + sys$input/opt
libshr/share
$
$ run prg
1
2
3
4
5
And the compiler also supports the Extended Pascal TO BEGIN DO and TO
END DO statements. TO BEGIN DO is just the same as [INITIALIZE] but
allows any statement. TO END DO is an exit handler (registered with an initialization routine).
During some troubleshooting over at VSI forum hb told me that
running a shareable image will execute LIB$INITIALIZE
functions.
That made me write this:
And the compiler also supports the Extended Pascal TO BEGIN DO and TO
END DO statements. TO BEGIN DO is just the same as [INITIALIZE] but
allows any statement. TO END DO is an exit handler (registered with an initialization routine).
On 1/8/2025 5:11 PM, hb0815 wrote:
On 1/8/25 02:58, Arne Vajhøj wrote:
During some troubleshooting over at VSI forum hb told me that
running a shareable image will execute LIB$INITIALIZE
functions.
That made me write this:
Yeah, but ... You do not need init code for this.
Oh.
Can one get a transfer address into a shareable image?
Arne
On 1/8/25 02:58, Arne Vajhøj wrote:
During some troubleshooting over at VSI forum hb told me that
running a shareable image will execute LIB$INITIALIZE
functions.
That made me write this:
Yeah, but ... You do not need init code for this.
On 1/8/25 23:20, Arne Vajhøj wrote:
On 1/8/2025 5:11 PM, hb0815 wrote:
On 1/8/25 02:58, Arne Vajhøj wrote:
During some troubleshooting over at VSI forum hb told me that
running a shareable image will execute LIB$INITIALIZE
functions.
That made me write this:
Yeah, but ... You do not need init code for this.
Oh.
Can one get a transfer address into a shareable image?
$ ty s.c
#include <stdio.h>
static int firstFunctionInThisModuleBecomesTheEntryPoint () {
printf ("It's the shareable, stupid!\n");
return 1;
}
int foo () {
printf ("This is %s\n", __func__);
return 1;
}
$ cc s/stand=rel
$ link/share s,tt:/opt ! symbol_v=(foo=proc)
symbol_v=(foo=proc)
Exit
$ r s
It's the shareable, stupid!
Hmmm.
It works in C, but it does not seem to work in
any other language (tested with Pascal and Fortran).
...
I assume the difference relates to user code main not being
the real program entry.
On 1/9/25 02:00, Arne Vajhøj wrote:
Hmmm.
It works in C, but it does not seem to work in
any other language (tested with Pascal and Fortran).
...
I assume the difference relates to user code main not being
the real program entry.
So, make it a main entry.
This is on Alpha. It should work on IA64 and x86. I don't have access to
any of the latter systems. If this does not work on these systems, I
know how to make it work, anyway.
$ gdiff -ub lib.pas-orig lib.pas
$ gdiff -ub lib.for-orig lib.for
On 1/9/25 02:00, Arne Vajhøj wrote:
Hmmm.
It works in C, but it does not seem to work in
any other language (tested with Pascal and Fortran).
...
I assume the difference relates to user code main not being
the real program entry.
So, make it a main entry.
This is on Alpha. It should work on IA64 and x86. I don't have access to
any of the latter systems. If this does not work on these systems, I
know how to make it work, anyway.
$ gdiff -ub lib.pas-orig lib.pas
$ gdiff -ub lib.for-orig lib.for
Also, I should have mentioned ... Your shareable with printing a message
from init code can not be used as a "normal" shareable image. The
message will always be printed. That's probably not what you want.
Init code of an image is always run. For a shareable image it is run at activation time, for a main image it is run at image startup time. For
some reasons I distinguish these two phases although others prefer to
say that "startup" is part of activation.
My shareable image only prints its message if a user (accidently) runs
it as main image.
All this works because VMS defines a weak transfer (or entry) address.
The C compiler in absence of a "main" assigns this weak transfer to the
first function seen in a source module. (I admit, I initially didn't
test this with other compilers; obviously FORTRAN and PASCAL do not
define this). The linker keeps track of the first weak transfer it
encounters and uses it as image transfer, if there is no "strong"
transfer, in C no "main". This makes the shareable image "runnable".
On Mon, 13 Jan 2025 13:45:50 -0500, Arne Vajhøj wrote:
There are probably a lot of shareable images written in C out there
where the developer has no idea that they are runnable or what code will
run.
If it has no main(), then nothing will run.
There are probably a lot of shareable images written in C out there
where the developer has no idea that they are runnable or what code will
run.
On 1/8/2025 3:42 PM, John Reagan wrote:
And the compiler also supports the Extended Pascal TO BEGIN DO and TO
END DO statements. TO BEGIN DO is just the same as [INITIALIZE] but
allows any statement. TO END DO is an exit handler (registered with
an initialization routine).
The compiler tell me that those two are only valid in modules
not in programs.
They are probably most useful for modules, but why not allow
them for programs?
Arne
On 1/13/2025 5:18 PM, Lawrence D'Oliveiro wrote:
On Mon, 13 Jan 2025 13:45:50 -0500, Arne Vajhøj wrote:
There are probably a lot of shareable images written in C out there
where the developer has no idea that they are runnable or what code will >>> run.
If it has no main(), then nothing will run.
That is what the developer thinks.
But it is not so.
$ type lawrence.c
#include <stdio.h>
int foobar()
{
printf("Hi Lawrence\n");
return 1;
}
$ cc lawrence
$ link/share lawrence
$ run lawrence
Hi Lawrence
No main() and it runs anyway.
Arne
Extended Pascal says only MODULEs so we just didn't
think about allowing them in PROGRAMs even though we allow [INITIALIZE].
On 1/13/2025 5:18 PM, Lawrence D'Oliveiro wrote:
If it has no main(), then nothing will run.
That is what the developer thinks.
But it is not so.
On 1/13/2025 5:55 PM, Arne Vajhøj wrote:
On 1/13/2025 5:18 PM, Lawrence D'Oliveiro wrote:COBOL paragraphs behave like C. First routine/PARAGRAPH gets a WEAK transfer address. Linker finds the first one.
On Mon, 13 Jan 2025 13:45:50 -0500, Arne Vajhøj wrote:
There are probably a lot of shareable images written in C out there
where the developer has no idea that they are runnable or what code
will
run.
If it has no main(), then nothing will run.
That is what the developer thinks.
But it is not so.
$ type lawrence.c
#include <stdio.h>
int foobar()
{
printf("Hi Lawrence\n");
return 1;
}
$ cc lawrence
$ link/share lawrence
$ run lawrence
Hi Lawrence
No main() and it runs anyway.
On Mon, 13 Jan 2025 21:08:11 -0500, John Reagan wrote:### They are probably most useful for modules, but why not allow
Extended Pascal says only MODULEs so we just didn't
think about allowing them in PROGRAMs even though we allow [INITIALIZE].
Not sure what the point would be in having them in PROGRAMs, anyway.
$get_entropy(ent, 8);
On 1/13/2025 11:38 PM, Lawrence D'Oliveiro wrote:
On Mon, 13 Jan 2025 21:08:11 -0500, John Reagan wrote:### They are probably most useful for modules, but why not allow
### them for programs?
Extended Pascal says only MODULEs so we just didn't
think about allowing them in PROGRAMs even though we allow [INITIALIZE].
Not sure what the point would be in having them in PROGRAMs, anyway.
Definitely most useful for modules. I was just wondering
why not allow it in programs as well.
It seems to have been explicit disallowed. The error message is:
%PASCAL-E-TOPROGRAM, TO BEGIN/END DO not allowed in PROGRAM
If one start to look for something useful then I would say that
TO BEGIN is just code after PROGRAM BEGIN, but TO END is more
than just code before PROGRAM END as it get triggered by other
program exits as well.
Demo:
$ type m.pas
module m(input,output);
to begin do writeln('m to begin');
to end do writeln('m to end');
end.
$ type p.pas
[inherit('m', 'sys$library:starlet')]
program p(input,output);
[initialize]
procedure init;
begin
writeln('init');
end;
procedure done;
begin
writeln('done');
end;
var
ent : integer64;
desblk : array [1..4] of integer;
cond : integer;
begin
writeln('begin');
desblk[1] := 0;
desblk[2] := iaddress(done);
desblk[3] := 0;
desblk[4] := iaddress(cond);
$dclexh(desblk);
$get_entropy(ent, 8);
if (ent mod 2) = 0 then $exit(SS$_NORMAL);
$canexh(desblk);
writeln('end');
end.
$ pas/env m
$ pas p
$ link p + m
$ run p
m to begin
init
begin
end
m to end
$ run p
m to begin
init
begin
done
m to end
$ run p
m to begin
init
begin
end
m to end
$ run p
m to begin
init
begin
done
m to end
Arne
On 1/14/2025 11:06 AM, Arne Vajhøj wrote:
On 1/13/2025 9:11 PM, John Reagan wrote:
COBOL paragraphs behave like C. First routine/PARAGRAPH gets a WEAK
transfer address. Linker finds the first one.
I have many prejudices about COBOL developers.
One of them is that they don't create shareable images.
:-)
But let us say that someone wanted to create a shareable
image in Cobol.
A typical Cobol program just have all the paragraphs that
get performed and they share state. Simple.
To make them entry points with arguments in a shareable image,
then I assume one need to make them programs with linkage section
and procedure division using.
Normal variables are just passed as arguments. Seems entirely
unproblematic to me.
But how does one share open files between modules?
Fortran and Basic numeric identifiers work across modules.
Pascal can share via inherit. C can use global variables
or just pass as argument.
But how does one do that in Cobol?
Can one mark an fd as global or can one pass a fd as argument?
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 432 |
Nodes: | 16 (2 / 14) |
Uptime: | 30:54:26 |
Calls: | 9,081 |
Calls today: | 4 |
Files: | 13,409 |
Messages: | 6,022,249 |