Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!usc!sdsu!ucsd!ucsdhub!hp-sdd!hplabs!hp-ses!hpcuhb!hpcllla!hpclisp!hpclkwp!karl From: karl@hpclkwp.HP.COM (Karl Pettis) Newsgroups: comp.sys.hp Subject: Re: Array indexing problem (bug?) Message-ID: <1340093@hpclkwp.HP.COM> Date: 22 Dec 89 17:40:04 GMT References: Organization: Hewlett-Packard Calif. Language Lab Lines: 60 > The common thing among the usages that failed was that they all used > LDBX where the base register contained a value outside the allowable range, > even though the effective (or final) address was OK. Thus, it seems as if > the segmentation fault is based on the base register contents rather than > the effective address. BINGO! Yes, the segmentation fault IS based on the base register, not the final effective address. Your analysis is correct. When using short (32-bit) addressing, the top two bits of the base register select which space will be used. While the effective address is being computed, the hardware is simultaneously retrieving the space register value. The final address is the concatenation of the space register value and the 32-bit effective address. If the effective address has a different top two bits, the space register selected won't match the desired one and you will get a segmentation fault. > Does this behavior seem bogus to anyone except me? At first glance, it does. But if the hardware has to wait until the effective address computation completes before starting the space register selection, it will introduce a sequential dependency for something that is done in parallel now. By the way, this HAS been brought up before. The biggest problem is for Fortran and Pascal where the default is non-zero based arrays. One would like to use the index directly after pre-computing a "base" address that points to the "zero-th" element. As you have discovered, this doesn't work. For ANSI C, the behavior of your program is undefined. The ANSI spec is very clear that intermediate results of pointer arithmetic must remain within the bounds of an array (or at most pointing just past the last element) in order for the computation to be defined. This, of course, is little comfort for people who have code which breaks. But it is a justification for the compilers to not generate the extra instruction for every array index that it would take to guarantee that the space register is selected based on the effective address. > Is there any way to fix this problem without modifying the source code > of each and every application that does this sort of thing? > Stephan Schell schell@llandru.ucdavis.edu I feel your long range goal should be to root out such code. But in the meantime, the work-around I suggest is that you declare an initialized dummy array at the start of your data area, $PRIVATE$. You can do this using the assembler, or with a C routine. The relocatable with this array declaration should appear first in your link command (after the crt0 file). The size of the dummy array is however big it must be to ensure that your intermediate pointer calculations do not change the uppermost two bits of the address. You can verify that the dummy array is at the beginning of the data area by using nm on your executable file. - Karl Pettis Telnet 447-5754 California Language Laboratory Hewlett-Packard Cupertino, CA