Operating System - OpenVMS
1753813 Members
7949 Online
108805 Solutions
New Discussion юеВ

Re: ANALYZE/IMAGE callable interface?

 
SOLVED
Go to solution
Hein van den Heuvel
Honored Contributor

Re: ANALYZE/IMAGE callable interface?


Thank you John & Hartmut!

I created a (cute? clever? reckless?) variant on the code posted exploiting the "image file descriptor" which the image activator provides as 4th argument for a main image.

It contains the CHANNEL which the image activator has set set up for the main image, and the full file spec, over and beyond the image name.

Using this, one does NOT have to open the image file again. You can just CRMPSC the whole image. This variant needs to be called pretty much right upon image activation (unless you save argument 4). Consequently I don't think you need to bother with trying to map just the header of the image, as the code will only touch the header parts, and it does a DELTVA after usage to clean up the expreg VA.

My test below uses a COBOL MAIN.

How the get the real image activator argument 4 for a C program, and not the LIB$INITIAL facilitated ARGV vector is left as an excercise for the reader (It's Miller time here!).

Enjoy?

Hein van den Heuvel
HvdH Performance Consulting

$ create ELF_IMGINFO_CRMPSC.C
// File: elf_imginfo_crmpsc.c
// Author: Hein van den Heuvel vandenheuvel@gmail.com
// Creation Date: 05-Mar-2007
// Adapted from elf_imginfo.c by Hartmut Becker 24-Sep-2004
//
// Follow the Elf structure and print some VMS image note entries.
//
// Usage : stat = format_note_section ( image_file_descriptor_address )
// image_file_descriptor_address = argument 4 from main image activation.
// Output : printf to STDOUT. To be adapted to target wished.
//
// Compile with : +sys$library:sys$lib_c.tlb/lib to get ifddef.h !
//

#include
#include
#include

#include
#include
#include

#include

extern sys$asctim(), sys$crmpsc(), sys$deltva() ;

int format_note_section (IFD *ifd) ;

static void decode_note_entries (char *section, int size) ;

static const char magic_plus[] = {
EHDR$K_ELFMAG0, EHDR$K_ELFMAG1, EHDR$K_ELFMAG2, EHDR$K_ELFMAG3,
EHDR$K_ELFCLASS64, EHDR$K_ELFDATA2LSB } ;

int format_note_section (IFD *ifd) {
ELF64_EHDR *ehdr ;
ELF64_SHDR *sh = NULL ;
char *section = NULL ;
char *name ;
int i, stat, return_stat, inadr[2] ;

name = (char *) ifd + ifd->ifd$w_filnamoff ;
i = *name++; // grab length and bump pointer
printf ("File Spec: %*s\n", i, name);

inadr[0] = 0 ;
stat = sys$crmpsc ( inadr, inadr, 0, SEC$M_EXPREG, 0, 0, 0,
ifd->ifd$w_chan, 0, 0, 0, 0);
if (!(stat & 1)) {
printf ("-e-crmpsc, could not map image header\n") ;
return 0;
}

ehdr = (void *) inadr[0] ;

if (0!=strncmp((char*) &ehdr->ehdr$t_e_ident, magic_plus, sizeof magic_plus-1)) {
printf ("-e-dunno, don't understand this file format\n") ;
return 0 ;
}

sh = (ELF64_SHDR*) ((char *) ehdr + ehdr->ehdr$q_e_shoff) ;

for (i=1; i < ehdr->ehdr$w_e_shnum; i++)
if (sh[i].shdr$l_sh_type==SHDR$K_SHT_NOTE) {
section = (char *) ((char *) ehdr + sh[i].shdr$q_sh_offset) ;
decode_note_entries (section, sh[i].shdr$q_sh_size) ;
break ;
}

return_stat = iehdr$w_e_shnum ;
stat = sys$deltva (inadr, 0, 0) ;
if (!(stat & 1)) {
printf ("-e-deltva, could not UNmap image header\n") ;
return 0;
}


return return_stat ;
}

static void decode_note_entries (char *section, int size) {
ELF64_NHDR *nh ;
char *owner;
char *entry;
for (nh = (ELF64_NHDR*)section ; (char*)nh-section nh= (ELF64_NHDR*)((char*)nh+sizeof(ELF64_NHDR)+((nh->nhdr$q_nh_namesz+7)&~7)+((nh->nhdr$q_nh_descsz+7)&~7))) {
if (nh->nhdr$q_nh_namesz>0)
owner = (char*)nh+sizeof(ELF64_NHDR) ;
else owner = "" ;
if (nh->nhdr$q_nh_descsz>0) {
if (nh->nhdr$q_nh_type == NHDR$K_NT_VMS_LINKTIME) {
char timbuf[32] ;
$DESCRIPTOR (timbuf_d, timbuf) ;
short int timlen ;
sys$asctim (&timlen,&timbuf_d,(char*)nh+sizeof(ELF64_NHDR)+((nh->nhdr$q_nh_namesz+7)&~7) ,0) ;
printf ("owner: '%s', linktime: %.*s\n",owner, timlen, timbuf) ;
}
else {
switch (nh->nhdr$q_nh_type) {
case NHDR$K_NT_VMS_IMGNAM:
entry = "imgnam" ;
break ;
case NHDR$K_NT_VMS_IMGID:
entry = "imgid" ;
break ;
case NHDR$K_NT_VMS_GSTNAM:
entry = "gstnam" ;
break ;
case NHDR$K_NT_VMS_IMGBID:
entry = "imgbid" ;
break ;
case NHDR$K_NT_VMS_LINKID:
entry = "linkid" ;
break ;
default:
entry = NULL ;
break ;
}
if (entry)
printf ("owner: '%s', %s: '%s'\n", owner, entry,
(char*)nh+sizeof(ELF64_NHDR) +((nh->nhdr$q_nh_namesz+7)&~7) ) ;
}
}
}
}
$
$
$ create test.cob
IDENTIFICATION DIVISION.
PROGRAM-ID. prn-test IDENT "test:1234".
DATA DIVISION.
WORKING-STORAGE SECTION.
01 link-time-text pic x(24) value spaces.
01 image_file_descriptor_address POINTER.
LINKAGE SECTION.
01 a1 pic s9(11)v9(7) comp.
01 a2 pic s9(11)v9(7) comp.
01 a3 pic s9(11)v9(7) comp.
01 a4 pic s9(11)v9(7) comp.
01 a5 pic s9(11)v9(7) comp.
01 a6 pic s9(11)v9(7) comp.


PROCEDURE DIVISION USING a1,a2,a3,a4,a5,a6.
MY_MAIN SECTION.
MAIN.
SET image_file_descriptor_address TO REFERENCE OF a4.

call "format_note_section" using by value image_file_descriptor_address.
STOP RUN.
$
$ cc ELF_IMGINFO_CRMPSC.C+sys$library:sys$lib_c.tlb/lib
$ link TEST,ELF_IMGINFO_CRMPSC
$ rename TEST.EXE TMP
$ run TMP
$ run TMP/nodeb
File Spec: $9$DKB200:[HEIN]TMP.EXE;1
owner: 'IPF/VMS', imgnam: 'TEST'
owner: 'IPF/VMS', gstnam: 'TEST'
owner: 'IPF/VMS', imgid: 'test:1234'
owner: 'IPF/VMS', linktime: 5-MAR-2007 22:42:05.55
owner: 'IPF/VMS', linkid: 'Linker I02-31'


Kay Dolle
Advisor

Re: ANALYZE/IMAGE callable interface?

Thank you all for help!
@Hein:
My c-compiler (Compaq C V6.5-001 on OpenVMS Alpha V7.3-2) has some problems with that code:
<<
$ cc ELF_IMGINFO_CRMPSC.C +sys$library:sys$lib_c.tlb/lib

sh = (ELF64_SHDR*) ((char *) ehdr + ehdr->ehdr$q_e_shoff) ;
.....................^
%CC-E-BADEXPR, Invalid expression.
at line number 61 in file DISK$SDE:[SRC]ELF_IMGINFO_CRMPSC.C;1

for (nh = (ELF64_NHDR*)section ; (char*)nh-section..........................^
%CC-E-BADEXPR, Invalid expression.
at line number 85 in file DISK$SDE:[SRC]ELF_IMGINFO_CRMPSC.C;1

nh= (ELF64_NHDR*)((char*)nh+sizeof(ELF64_NHDR)+((nh->nhdr$q_nh_
namesz+7)&~7)+((nh->nhdr$q_nh_descsz+7)&~7))) {
.................................^
%CC-E-BADEXPR, Invalid expression.
at line number 86 in file DISK$SDE:[SRC]ELF_IMGINFO_CRMPSC.C;1

ELF64_EHDR *ehdr ;
....^
%CC-E-UNDECLARED, In this statement, "ELF64_EHDR" is not declared.
at line number 36 in file DISK$SDE:[SRC]ELF_IMGINFO_CRMPSC.C;1

ELF64_EHDR *ehdr ;
................^
%CC-E-UNDECLARED, In this statement, "ehdr" is not declared.
at line number 36 in file DISK$SDE:[SRC]ELF_IMGINFO_CRMPSC.C;1

ELF64_SHDR *sh = NULL ;
....^
%CC-E-UNDECLARED, In this statement, "ELF64_SHDR" is not declared.
at line number 37 in file DISK$SDE:[SRC]ELF_IMGINFO_CRMPSC.C;1
...
>>
I'm not experienced enough in C, to solve that problem.

Thanks,
Kay
Kay Dolle
Advisor

Re: ANALYZE/IMAGE callable interface?

ok!
It seems to be a Compiler-version-problem. On I64 (Compiler: HP C V7.2-001 on OpenVMS IA64 V8.3) it works!
So we have to look for an Update for our Alpha...

Thanks, Kay
Hein van den Heuvel
Honored Contributor

Re: ANALYZE/IMAGE callable interface?


Kay,

This is one area where you will NOT get comparable code between the two unless, as others indicated before, you rely on your own external defintions to test / report on.

The Alpha vs I64 images are much too different and there is no VMS common routine to get you this info.

So no reason to update the compiler. John's and my recent code will only work on I64, my earlier post only on Alpha (and probably on VAX when using IHD defs vs EIHD and such.

Hein.
Hein van den Heuvel
Honored Contributor

Re: ANALYZE/IMAGE callable interface?

some more Free advice, worth every penny...
:-)

>>> Background: we are porting from ALPHA to I64

Just like you I want your port to have the best possible chances for success. I want OpenVMS on I64 to be a succesfull platform for you. To ensure that, your organization should seriously consider engaging with folks who can help you with that, perhaps under a support contract, or some contracting or consulting style setup.

While this whole porting thing typically is relatively straightforward, yhe questions you have raised suggest you are in it slightly over your head. No disrespect intended. We all have our areas of strength and new thing to learn. But first there was that question on the shareable library. And now the 'blaming' on the compiler for what is just a poor environment setup.

Clearly there is an include library missing. If that is not clear to the folks working this port, then they should not be doing that particular part of the work. Sorry to be so blunt about it.

I just verified, and Hartmut's example code works fine on a VMS V7.2-1 Alpha with a V6.2-003 C, or any random PC for that matter.

To make it work I did need to provide an 'elfdef.h' and 'elfdatyp.h' which you can snarf from a sys$library:SYS$STARLET_C.TLB on any 8.2 or better OpenVMS system.

Now the code I provided can only be run on I64 as I indicated before. This is because because, as per suggestion, it obtains the indent for the running image.

btw... I since learned that one pretty much needs to map the whole image, or map selectively, as those ident section live close to the end of file.

Kindest regards,

Hein van den Heuvel
HvdH Performance Consulting


Kay Dolle
Advisor

Re: ANALYZE/IMAGE callable interface?

Thanks Hein!
Now, we have to discuss in our team the possible soloutions while observing the facts:
- We need to run both architectures in a Cluster for sereral months
- We have to change roundabout 100 Programms. If we have to, with conditionalized code.

In my opinion a combination of your and Hartmut's examble could do the job, but we have to discuss that.

Best regards,
Kay Dolle
Hein van den Heuvel
Honored Contributor

Re: ANALYZE/IMAGE callable interface?

Right. But you also may want to set a big step back and try to remember WHY yo needed that ident. And how does it get there?
If it is a line in the .OPT file then that line could be changed to become an object module. Instead of priting/comparing strings in the code you could call a function in that ident object reporting its ident or comparing its hard-coded ident with lookup in an (indexed)file.

Regards,
Hein.

Kay Dolle
Advisor

Re: ANALYZE/IMAGE callable interface?

I'm not shure that i understand you right, but if you suggest, that the string with the ident could be a constant in the main program, then the effort in develloping in our SDE is the same as before.
One reason why we need the indent is to compare the Version of the running Program with the allowed Version, we would like the users have to use. In our EDP the users start a dialog-program in the morning and leave it, when going home. With that function we have the possibility to instal a new program-version an be shure the users use it when the program is in a defined state (that state, when the program can be terminated without data loss)

With the already existing function for the indexed-file-lookup (allowed Version) we should put that on the list with possible souloutions!

Thanks
Kay
Hoff
Honored Contributor

Re: ANALYZE/IMAGE callable interface?

Insert the declaration of an external variable or two directly into the options file, and reference it (them) in your code.

You could use KD_VERSION_MAJOR and KD_VERSION_MINOR, for instance.

No undocumented stuff.

No image file headers.

Fully portable.

Add the external references into the code where required, and you can access the constants from the LINKER options file directly.

You're done.

If you wanted to get a little fancier, a couple dozen lines of DCL can easily generate the options file contents on the fly, and can generate both the external symbols used by the program, and the image identification string. This would allow you to have a three line option file, with the two externals and the matching ident string.

Again, all fully documented, fully portable, platform-independent, and fully supported.

Kay Dolle
Advisor

Re: ANALYZE/IMAGE callable interface?

I found that syntax
SYMBOL=name,n
with n seems to be an integer!? All trys to place a string caused an %LINK-F-OPTSYNERR". I didn't find an example for that.
What is need to have access to that symbol in COBOL. How i understand the manual i should delare the variable with
external
The compiler like it, but at runtime the variable is hex(0).