DOORS 64 Bit Memory Hacks - DOORS 9.6.1.7 and upwards

Since DOORS 9.6.1.7 IBM (almost) "fixed" the integer handling inside the DOORS client to only handle 32 bit numbers. Therefore the memory tricks inside this post 

https://www.ibm.com/developerworks/community/forums/html/topic?id=c672482d-1470-4ed3-9f66-4160f0ed75e6&ps=25

do not work anymore. Fortunately for us, IBM introduced two new features to the DOORS client which will make life easier: 

  • 64 Bit literals (they actually exist in all 64 bit clients!) 
  • The new Addr64_ type 

Lets check it out: 

// get the dumpmemory function from the above mentioned post
int x = 0x01020304050607
print x "-->" dumpmemory(x, 8) // output: 67438087-->07060504 03020100

On a 32 bit system this obviously would not work, you would get something like:  2147483647-->ffffff7f 21436587 . The literal would have been converted to MAXINT (2147483647). 

Interestingly I found, that this is working on DOORS 9.6.0.0 64 bit too. So DOORS had 64 bit literals all along! Anyway. We want to solve four problems for all DOORS versions: 

  1.  testing for 64 bit mode
  2. creating a 64 bit integer
  3. converting a 64 bit literal to string (for passing into eval_ code) 
  4. converting a 64 bit literal string back to an integer

So here is my proposal for solving these problems (Tested on DOORS 9.5, 9.6.0.0 (64 bit), 9.6.1.7)

1. Testing for 64 bit mode

is easy. As we have 64 bit literals, we can simply check for clipping.  

bool is64Bit() {
   return 0x100000000 != 2147483647; 
}
print is64Bit() "\n"

2. Creating a 64 bit literal

You could think the second problem is solved, since you can embed 64 literals directly inside the code

int x = 0x01020304050607

BUT: 

again, like in 32 bit mode there is a Problem value -9223372036854775808 (0x8000000000000000, MAXINT + 1), which is a valid 64 Bit value, but DXL cannot parse the literal, since it will first parse the number part and then calculate a negation: 

int v = -9223372036854775808
print (v == -9223372036854775807) "\n"  // true? should be false ...

// You can generate that value only because they messed up with arithmetics on the increment decrement operators ...
int w = -9223372036854775807; 
w--; // they forgot to fix the decrement operator to 32 bit! sigh@IBM 
Addr64_ val = w; print val;  // prints -9223372036854775808

3. Making parsable string literals from integers 

DOORS 9.6.1.7 makes this very easy for us (we need to forget about the problem value in 2., this value cannot be generated as a single literal in DOORS anymore, lets just hope this number will never come up as a memory address): 

// NOTE: Only works for DOORS 9.6.1.7 upwards: 
int x = 0x01020304050607
string literal (int x) { Addr64_ ad = addr_ x; return "(" ad ")" }
print literal(x)

DOORS 64 < 9.6.1.7 makes this a little more hard, we need to get the literal by performing a calculation - otherwise we would have to calculate the hexadecimal, decimal, octal or binary represenation of the string, which in DXL would probably be slow: 

// NOTE: Does not work from DOORS 9.6.1.7 upwards, since 64 bit arithmetics have been disabled! 
// setup memory like this: 
// -- d1L -- -- d1H -- -- d2L -- -- d2H -- ...
//           -- d3L -- -- d3H --  ...
int d1 = 0, d2 = 0; int *d3; 
d3 = &d1; d3 += 4; 
string literal (int x) {
   d1 = 0; d2 = 0; *d3 = x;     
   string s = "(" (d2 & 0xFFFFFFFF) " * 0x100000000 + (" (*d3 & 0xFFFFFFFF) " & 0xFFFFFFFF))"
   return s; 
}

Note that this also works for the problem value MAXINT+1, since we use 32 Bit literals to calculate the 64 bit one. 

Finally for DOORS 32, we need a special variant of this function. Here we can handle the problem value again: 

string literal (int x) {
   int PV = 0x7FFFFFFF + 1; 
   if (x == PV) return "(0x7FFFFFFF + 1)" else return "(" x ")"; 
}

Using these 3 different functions allows us for all DOORS versions to get a literal value for an integer variable, which we can use to embed inside eval. 

4. Getting back the value from a parsable literal. 

Obviously if we want to make a literal that DOORS can parse, we would use eval_ .to get its value. With the above literal functions here we can simply embed the literals. 

// use applicable literal function from above 
int x = 0x01020304050607
eval_ " 
   int y = " (literal x) "
   int v = 0x01020304050607
   print (y == v) // prints true
"

So, now since we solved all the four problems for newer DOORS versions, we can finally handle our eval_ parameter passing again: 

Skip sk = addr_ 0x01020304050607 // assume our skip has a 64 bit memory address and we want to use in eval_ 
eval_ "
  Skip sk = addr_ " (literal addr_ sk) "
  // ... use the skip ... 
   // lets check if the skip got its original address   
  int x = 0x01020304050607 
  int y = addr_ sk
  print (x == y) 
"

Hope this makes it a bit easier for integrators to have their software compatible to all DOORS versions again. Please direct flames directly @ibm for not providing 64 bit calculations in DXL (like they should have!)

Regards, Mathias


Mathias Mamsch - Fri Jan 27 09:35:04 EST 2017

Re: DOORS 64 Bit Memory Hacks - DOORS 9.6.1.7 and upwards
Mathias Mamsch - Fri Jan 27 09:57:14 EST 2017

by the way, since IBM forgot to fix another arithmetics operator it is currently indeed possible to represent the problem value MAXINT+1 as a literal: 

int x = ~0x7FFFFFFFFFFFFFFF
Addr64_ ad = x; 
print ad "\n"  // prints -9223372036854775808

So who believes IBM will not fix this in the future should extend the literal function for DOORS 9.6.1.7 bit like so: 

string literal (int x) { 
   if (x == ~0x7FFFFFFFFFFFFFFF) return "(~0x7FFFFFFFFFFFFFFF)"; 
   Addr64_ ad = addr_ x; return "(" ad ")" 
}

int MAXINT = 0x7FFFFFFFFFFFFFFF; 
print "MAXINT:" (literal MAXINT) "\n"

MAXINT++; 
print "MAXINT+1:" (literal MAXINT) "\n"

Regards, Mathias

Re: DOORS 64 Bit Memory Hacks - DOORS 9.6.1.7 and upwards
SebastienBoucard - Fri Feb 03 08:40:46 EST 2017

Thanks for this detailed information, Mathias.

On my end I was then able to adapt the code for our MDAccess for DOORS product, so it can now claim compatibility with DOORS 9.6.1.7. As in this context we do execute DXL code from Java, my trick was to once determine the version of the connected DOORS client and then to dispatch to the DXL code dedicated to the discovered version.

Sebastien