Operating System - OpenVMS
1828667 Members
1638 Online
109984 Solutions
New Discussion

Global Section Problem of IA64

 
SOLVED
Go to solution
Kai.Zou
Advisor

Global Section Problem of IA64

Hi, newbie here.
I had met a problem when porting a system from Alpha to IA64.
When creating Global Section, the space is over, then cleared the other variable's memory space.
In the old alpha system, the link map files showed that, the global section space is very large then the real size. But in the IA64, the link map files shows the global section space the only little greater than the real size.
For more information pls refer to attched file.

My question is:
1. Why this happened?
2. What caused this? The compile or link option? Or some System settings, such page size etc.
3. What should I do to deal with it?
TIA
Best reguards
20 REPLIES 20
Joseph Huber_1
Honored Contributor

Re: Global Section Problem of IA64

Well I don't have IA64 available to prove.
Obviously the psect defined by
plgrp_table[PL_GRP_MAX];
is of different size. How is it declared ? which compiler options used (default integer or float size ?).

What I can see is: on alpha the length of the psect is not a multiple of the page-size: so either there was a hidden error already in the program when creating/mapping the psect to a global section, and this error now becomes effective overmapping something else.

The rules for global section mappings:
begin must be on a page boundary
length must be a multiple of the pagesize
(i.e. the last address must be at a page boundary).
if as in Your case on alpha the psect is not an integral multiple of the page size, then how precisely do You pass the parameters (start-address,end-address,size) to the map global section call ?
http://www.mpp.mpg.de/~huber
Joseph Huber_1
Honored Contributor

Re: Global Section Problem of IA64

And what do You really mean ?
>> global section space is very large then the real size.<<

The linker map knows nothing about a global section, it only has psects. It is your program code mapping the psect to the global section.
In the alpha case you either mapped only a part of the psect or more than the psect, i.e. some of the address-space following the array.
Maybe if You can show us the code, it becomes obvious what goes wrong.
http://www.mpp.mpg.de/~huber
Hein van den Heuvel
Honored Contributor

Re: Global Section Problem of IA64

Welcome Kai.

You need to show more of the program.
What is that type defined as?
Wat value is PL_GRP_MAX?
Is it the same on both systems?

If I create a silly C program, and compile with HP C V7.3-018 on IA64, V8.3, and link with Linker T02-28, then my MAP files shows something rather different from what you show:

PLGRP_TABLE 00010000 00019C3F 00009C40 ( 40000.)
PAGE 16 OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD

So there is more in play.


You talk about "creating Global Section"
May we assume this is dynamic, with a $CRMPSC call or other member of that family?

What is the input address range provided?
What is the mapped range returned?

Sound like the program wants to pre-define a 'zone' for an array and then with a slide of hand (crmpsc) make that array not point to the original memory range, but look a a pre-created global memory section.

Why not define the array as a pointer, never allocate space in the program, map the section and more the RETADRR to the pointer?

Cheers,
Hein.
Hein van den Heuvel
Honored Contributor

Re: Global Section Problem of IA64

Joseph wrote:

"Well I don't have IA64 available to prove."

That reminds me...
Almost a year ago I donated a well equipped RX2600 to OpenVMS-Rocks.com ( aka deathrow ).
It was supposed to become a cluster member, for all to use.
That still has not happened. :-(
I'll ask Da Beave to please please please just bring it online standalone with a clone of the SYSUAF ?!

Also, The old HP testdrive system were very nice to try little things like the above. In fact, that's what I used.

Joseph, send me an Email, and maybe I can find a host system for experiments if you are interested.

Cheers,
Hein van den Heuvel at gmail
Kai.Zou
Advisor

Re: Global Section Problem of IA64

Hi, everyone, thanks very much for your warm hearted help, and sorry for my less information.

It seemed that, the map result became different with the same compile & link optionis, the same source code on alpha and IA64.

I could not tell why it happened and how fix it. My goal is make the program run well on IA64.

For more detail information & explanation, please refer to the new attached file.

TIA
BR
Zou Kai
Hein van den Heuvel
Honored Contributor

Re: Global Section Problem of IA64

>> It seemed that, the map result became different with the same compile & link optionis, the same source code on alpha and IA64.

I doubt it is the same.
But you do NOT show us enough from the map to explain.
You need to show the the next few lines where the MODULE names are filled in, and where the contribution from each module it made clear.
And you need to show us what FOLLOWS the section in question.

>> I could not tell why it happened and how fix it. My goal is make the program run well on IA64.

I suspect that this is BROKEN code, which happens to work on Alpha.

_ALIGN only specifies the START address.
CRMPSC only maps entire pages.
So the program needs to make sure it is over allocated.
By hook or by crook.
(btw... you failed to answer whether, or how, that is used)

Good luck,
Hein
Hein van den Heuvel
Honored Contributor

Re: Global Section Problem of IA64

>> It seemed that, the map result became different with the same compile & link optionis, the same source code on alpha and IA64.

I doubt it is the same. Something probably changed. I would focus on why the Alpha appears to have overalloced.

You do NOT show us enough from the map to help explain.
You need to show the next few lines where the MODULE names are filled in, and where the contribution from each module it made clear.
And you need to show us what FOLLOWS the section in question.

>> I could not tell why it happened and how fix it. My goal is make the program run well on IA64.

I suspect that this is BROKEN code, which happens to work on Alpha.

_ALIGN only specifies the START address.
CRMPSC only maps entire pages.
So the program needs to make sure it is over allocated.
By hook or by crook.
(btw... you failed to answer whether, or how, that is used)

Good luck,
Hein
Kai.Zou
Advisor

Re: Global Section Problem of IA64

Hi. Hein

Sorry for unclear information.
I can send the entrie map file, or the allocation function source code to you.
That will show all about "how to be used"
May I send mail to you privately?

Sincerely
Zou Kai
Hein van den Heuvel
Honored Contributor

Re: Global Section Problem of IA64

Sure, send the Email.
But all we need is the output from:

$ SEARC/WIN=(0,9) xx.MAP PLGRP_TABLE

And the call to CRMPSC (if the is one), its parameters declarations, and immediate use lines.

Cheers,
Hein

Joseph Huber_1
Honored Contributor
Solution

Re: Global Section Problem of IA64

So the question is why the psect on alpha becomes 64KB: obviously it is not from the array declaration alone. As hein asked: in the environment map (use the search window) there must be one object module bringing in the psect with a bigger size, a module obviously not linked on IA64.

Now to the real problem in the way the global section is mapped:
I assume the section is mapped by a $CRMPSC or $MGBLSC call:
the psect on IA64 is less than 2 pages, but the global section is mapped to the next page boundary (16384 bytes), i.e. whatever is following in the programs address space after the PLGRP_TABLE array is also mapped to the global section and zeroed (SEC$M_DZRO is default if it is a page file section).

So to resolve the issue, make the length of the array an integral multiple of the page size (or put it into a structure which is padded to the page boundary by a dummy array),
and at best verify at runtime the actual page size is the same as the one assumed at compile time: then the program is save against future VMS and/or CPU developments.

Maybe it helps to read the comments in
http://www.mppmu.mpg.de/~huber/util/crmpsc.FOR

(although written in Fortran): it was working initially for vax, then adapted for Alpha, and is valid for IA64 as well.
http://www.mpp.mpg.de/~huber
Kai.Zou
Advisor

Re: Global Section Problem of IA64

Hi, Dear Joseph, you hit the target.
It is just like you described.
Now what I want to know is:
is it natrual or abnormal caused by some reason.
If it is natrual, maybe padding a 8192 space will be a easy & good idea to deal with it.
But if is is an issue should be fixed, then investigate the root reason will be necessary.

And altogether, thanks very much for your help.
Joseph Huber_1
Honored Contributor

Re: Global Section Problem of IA64

>>Is it natrual or abnormal caused by some reason.<<

natural what?
The psect length is not aligned to the (target-) systems page size by all compilers I use. Fortran e.g. has options to align natural, and then the length is padded to the next 16 (or is it 32 ?) byte boundary to produce the same psect size as an equivalent C program.
So psects destined to be mapped to global sections should be a multiple of the page size, using structure paddding or "guard pages" or whatever means to adjust the ending address mapped.


Your program had the problem from the beginning, it just was covered by the 64K size of the psect: where this 64K come from You have to find out yourself looking at the map or the program sources.
http://www.mpp.mpg.de/~huber
Hein van den Heuvel
Honored Contributor

Re: Global Section Problem of IA64

I received the full maps, but nothing stands out immediately, and I'm low on time today.

I do not at all like how this appears to work, but I guess 'it worked'.... sort of.

If this was my issue, and I needed to get go on this in a hurry, then I would GENERATE a dedicated C module with over allocated PSECTS for each of the PSECT which are supposed to me mapped.
I would use PERL or DCL on the Alpha MAP to generate just CHAR variables big enough to match each Alpha Psect.

That should allow you to move forward.
With that in place I'd want to understand what is really behind this.

You might also want to use the linker COLLECT option to collect PSECTs which are NOT re-mapped all together.

And most certainly I'd talk with development to step away froom allocating and re-mapping towards just CRMPSC and use the addresses as returned.

Cheers,
Hein
Kai.Zou
Advisor

Re: Global Section Problem of IA64

Hi, thanks everyone.

Since I do not have enough time to investigate it clearly, I decided to find a work around to deal with it.
And I tried yesterday, and it worked.
Here is the points:
1. Give a 8192(8k) dummy space after every GS variables declared by "_align(PAGE)".
2. The dummy space also should be declared as "_align(PAGE)".
3. The variable name of dummy date should be as alphebit order as the former GS varibale, so that it should be adjoined togeter when linking.
( A typedef struct method seemed to take no effects)

Although the work around seemed dirty, but it really worked.
Now thanks you everyone again for your help.
Thanks.
Hein van den Heuvel
Honored Contributor

Re: Global Section Problem of IA64



Looking as the MAP some more, I noticed you used an OLD C compiler and oldish linker.

Rule #1 in Alpha -> Itanium porting: Compile with the most recent Alpha compiler first, to clear out any latent problems!

Anyway I tried the workaround I hinted at.
It works fine, of course.

Consider this PERL (long) one-liner:

perl -ne "print qq(char _align(PAGE) ${1}[$2];\n) if /^(\S+)\s.*0000 \(\s+(\d+).. PAGE.*OVR/ && !$x{$1}++" alpha.map > helper.c

That looks for lines for the first time defining a PSECT which is 10000x aligned and overlayed. For those it prints a C line like:

helper.c

char _align(PAGE) PLAN_TABLE[23068672];
char _align(PAGE) PLGRP_TABLE[65536];
char _align(PAGE) SPAT_MNG_VAL_TABLE[131072];

Create test main like:

tmp.c

int _align(PAGE) plgrp_table[10000];
int _align(QUADWORD) pwash_que_bot;
main (){
}

Compile and link with map, and search the map.

$ CC TMP
$ CC HELPER
$ LINK/MAP TMP,HELPER
$ sea/win=(0,5) tmp.map PLGRP_TABLE
PLGRP_TABLE 0DE20000 0DE2FFFF 00010000 ( 65536.) PAGE 16
TMP 0DE20000 0DE29C3F 00009C40 ( 40000.) PAGE 16
HELPER 0DE20000 0DE2FFFF 00010000 ( 65536.) PAGE 16
PWASH_QUE_BOT 0DE30000 0DE30003 00000004 ( 4.) OCTA 4
TMP 0DE30000 0DE30003 00000004 ( 4.) OCTA 4
SPAT_MNG_VAL_TABLE 0DE40000 0DE5FFFF 00020000 ( 131072.) PAGE 16

So now the total Psect size is defined by the helper to match the size as found in the Alpha link map.


Btw.... C V7.1-015-48F8P did something funny:

PERICLE_EQP_TABLE 22 65536 page
PLAN_TABLE 23 23068672byte
PLGRP_TABLE 24 65536 page
SPAT_MNG_VAL_TABLE 25 131072 page

See that 'byte' in the middle? I did not ask for that!

Hein





Joseph Huber_1
Honored Contributor

Re: Global Section Problem of IA64

Kai,
why use this 'workaround', and not finally make the program correct by just changing the array length PL_GRP_MAX to a page-length multiple ?
Apparently You have access to the source to insert the 'dumy' space variables, so why not change the definition of PL_GRP_MAX ?
As Hein demonstrates, relying on the alphabetic order of global variables is very dangerous.

If changing PL_GRP_MAX is not possible , then a secure alternative is the CLUSTER option in LINK: make a cluster of the PLGRP_TABLE psect and some dummy psect with a name being later in alphabetic order. Other than the behaviour of different compilers, the linker guarantees the alphabetic order of psects in a cluster, and You don't have to touch the source, except adding a separate mudule defining the dummy psect.

http://www.mpp.mpg.de/~huber
Joseph Huber_1
Honored Contributor

Re: Global Section Problem of IA64

To demonstrate psect clustering:
Source of the dummy psect _dummy.c:

#include
//vms_pagesize contains the architecture-dependant pagesize like
// #define VMS_PAGESIZE 8192
unsigned char _DUMMY[VMS_PAGESIZE];

$ CC/EXTERN_MODEL=COMMON _dummy

Then link it:
$ LINK myobject,...,_dummy,sys$input/opt
COLLECT=mycluster,PRGRP_TABLE,_DUMMY

This way it is always guaranteed PRGRP_TABLE is followed by the dummy psect as a rear guard page.
Note the underscrore in the _DUMMY psect name, which forces it behind all others (although it may violate C purists name-space rules :-).


http://www.mpp.mpg.de/~huber
H.Becker
Honored Contributor

Re: Global Section Problem of IA64

Looking at Hein's example, the CC is actually a CC/EXTERN=COMMON, for both source modules. IF you use (the default) CC/EXTERN=RELAXED for HELPER you end up with a PLGRP_TABLE of 40000.

It is an error to mix extern models. The linker uses the OVR PSECT PLGRP_TABLE to define the relaxed refdef symbol PLGRP_TABLE.

A linker /MAP/FULL shows the contributors. In the relaxed refdef model you see only the as contributor for PLGRP_TABLE. And as far as I understand the thread, that's not what you want, here.
Hein van den Heuvel
Honored Contributor

Re: Global Section Problem of IA64

Joseph,

Well alphabetic is not a big big problem.
Just append a "$" to the name? and yes I also suggested the collect to get some control.

Hartmut,

I'm not sure I understand what you are trying to say, and I know one should not dismiss your remarks.
I believe to see the PLGRP_TABLE having contributions from both TMP and HELPER where helper is the bigger on and defines the final, rounded up, size.
Neither provide init value.

I had checked and tried various options working with the ever important Tables 4â 4:External Models and Definitions, and Table 4â 7: Combination Attributes in the C-USER GUIDE.

In the end I compiled and linked with no options which I beliewe gave me flavor (1) = #pragma extern_model common_block noshr.
I don't think that creates a mix, but please help me understand if it does. Is there a confusion between definer and referencers?

I did this on ALPHA first, where the linker nicely shows each contribution.

Based on you entry I also checked IA64, and sure enough is show NO module as contributor, only .

But the sizes were right (as desired) and it makes sense in so far as no single byte came from the modules themselves, it is just the linker doing smoke and mirrors.

So I think the program would work as expected, even though that expectation was crooked/ugly.

Here are the complete sections from the MAP file generated. I added in one more variable (top) to proof it would be tightly against the (bot) and not skip to the next 10000x boundary.

I'd still like to figure out how the original Alpha code ended up rounding up those _align(PAGE) entries.
Maybe is was specific to the compiler version used by Kai? ( Compaq C V6.4-008 ).
_all_ the modules had this, so it was not an explicit 'helper' as in my workaround.

Hein.

PLGRP_TABLE 0DE20000 0DE2FFFF 00010000 ( 65536.) PAGE 16 NOPIC,OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD
TMP 0DE20000 0DE29C3F 00009C40 ( 40000.) PAGE 16
HELPER 0DE20000 0DE2FFFF 00010000 ( 65536.) PAGE 16

PWASH_QUE_BOT 0DE30000 0DE30003 00000004 ( 4.) OCTA 4 NOPIC,OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD
TMP 0DE30000 0DE30003 00000004 ( 4.) OCTA 4

PWASH_QUE_TOP 0DE30010 0DE30013 00000004 ( 4.) OCTA 4 NOPIC,OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD
TMP 0DE30010 0DE30013 00000004 ( 4.) OCTA 4

SPAT_MNG_VAL_TABLE 0DE40000 0DE5FFFF 00020000 ( 131072.) PAGE 16 NOPIC,OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD
HELPER 0DE40000 0DE5FFFF 00020000 ( 131072.) PAGE 16


-- IA64 --

PLGRP_TABLE 0DE00000 0DE0FFFF 00010000 ( 65536.) PAGE 16 OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD
0DE00000 0DE0FFFF 00010000 ( 65536.) PAGE 16

PWASH_QUE_BOT 0DE10000 0DE10003 00000004 ( 4.) OCTA 4 OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD
0DE10000 0DE10003 00000004 ( 4.) OCTA 4

PWASH_QUE_TOP 0DE10010 0DE10013 00000004 ( 4.) OCTA 4 OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD
0DE10010 0DE10013 00000004 ( 4.) OCTA 4

SPAT_MNG_VAL_TABLE 0DE20000 0DE3FFFF 00020000 ( 131072.) PAGE 16 OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD
0DE20000 0DE3FFFF 00020000 ( 131072.) PAGE 16

H.Becker
Honored Contributor

Re: Global Section Problem of IA64

On both platforms, the default extern model is RELAXED_REFDEF

On Alpha the compiler creates storage for a releaxed refdef: an ovr psect. On I64 the compiler creates just a symbol.

On I64 the linker has to check if there is alrady storage for a releaxed refdef symbol. If there is one, the linker uses that storage. If there is none, the linker creates the storage.

On I64, if you mix the extern models, you can end up with a section from one module and a symbol from the other. In the case the section is smaller than the symbol you end up with only the storage from the section.

You can argue that the linker could do better here and a) give a warning or b) create a bigger section. On the other hand, one can argue that the extern model in the application is broken.

With the TMP/HELPER example:

$ cc tmp/extern=common
$ cc helper/extern=relaxed
$ link/map/full tmp,helper
$ search tmp.map "PLGRP_TABLE",GBL/match=and/wind=(0,3)
PLGRP_TABLE 01610000 01619C3F 00009C40 ( 40000.) PAGE 1
6 OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD
TMP 01610000 01619C3F 00009C40 ( 40000.) PAGE 1
6

PWASH_QUE_BOT 01619C40 01619C43 00000004 ( 4.) OCTA
4 OVR,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,NOMOD
$