Unsigned Address conversion

Over my head again.  How do I convert a signed 32-bit precision integer back to an unsigned one, in string form?

I'm getting the "addr_" of a "ModName_" variable to pass to an "eval_" code.  I notice that when the address is larger than 2147483647 then the integer conversion makes it a negative number; and re-converting that number generates an error:

  • Skip pf_ModProps_GetAllValues(ModName_ in_mn)
    { Buffer bufCode = create() // DXL Code sent to the "eval_" command

     bufCode += "ModName_  mn = addr_ "
     bufCode += (int (addr_ in_mn)) ""
     bufCode += etc

Often the bufCode contains this nice string, which works:

  • ModName_  mn = addr_ 205123454

But for large addresses, looks like this, which generates an interpret error:

  • ModName_  mn = addr_ -2005178864

So I need a mechanism for converting this for very high addresses.  My thoughts are; when I detect a negative number then..

  • Get the Remainder when I divide by 10 and then divide by 10; convert it back to a positive number, then rebuild the string using the positive number concatenated with the Remainder digit (or perhaps 10-Remainder..). 
  • Capture the "addr_ mn" in something other than an "int" variable, but that doesn't seem productive. 
  • Perhaps I can convert the (signed) integer into it's 32 specific bits, then convert that to a string using it as a binary constant.

-Louie

 


llandale - Tue Jun 03 14:37:29 EDT 2014

Re: Unsigned Address conversion
Mathias Mamsch - Wed Jun 04 12:05:22 EDT 2014

Hmm interesting .. I know I made this mistake also a lot of times, but never thought about a problem with large adresses. However I would have thought that a simple pair of parenthesis should do the trick ...

int large = 0x7FFFFFFF
int tolarge = large + 10

print "Large: " large "\n"
print "ToLarge: " tolarge "\n"

eval_ "int x = addr_ " (large) "; print \"EVAL Large: \" x \"\\n\""

// this fails:
// eval_ "int x = addr_ " (tolarge) "; print \"EVAL Tolarge: \" x \"\\n\""

// but this works:
eval_ "int x = addr_ (" (tolarge) "); print \"EVAL Tolarge: \" x \"\\n\""


Output:
Large: 2147483647
ToLarge: -2147483639
EVAL Large: 2147483647
EVAL Tolarge: -2147483639


There is only one special case and the problem here is, that the DXL interpreter seems to have an error with interpreting integer literals:

The smallest integer possible in DOORS is 0x8000000 which is: -2147483648

The DXL Parser however will clip this literal (and all smaller numbers) to a minimum of: -2147483647 ... I never noticed that problem and I think it should not have practical relevance, however you need to be aware that for this number the addr_ statement will be 'off-by-one' ... If you want to be sure, you need to do something like this to trick the DXL parser:

string int2dxl_literal(int x) {
   if (x - 1 == 0x7FFFFFFF) return "(0x7FFFFFFF+1)"
   return x ""
}

int tolarge = 0x7FFFFFFF + 1

eval_ "int x = addr_ (" (int2dxl_literal tolarge) "); print \"EVAL Tolarge: \" x \"\\n\""



Good find! Regards, Mathias

Re: Unsigned Address conversion
Wolfgang Uhr - Fri Jun 06 04:50:35 EDT 2014

Mathias Mamsch - Wed Jun 04 12:05:22 EDT 2014

Hmm interesting .. I know I made this mistake also a lot of times, but never thought about a problem with large adresses. However I would have thought that a simple pair of parenthesis should do the trick ...

int large = 0x7FFFFFFF
int tolarge = large + 10

print "Large: " large "\n"
print "ToLarge: " tolarge "\n"

eval_ "int x = addr_ " (large) "; print \"EVAL Large: \" x \"\\n\""

// this fails:
// eval_ "int x = addr_ " (tolarge) "; print \"EVAL Tolarge: \" x \"\\n\""

// but this works:
eval_ "int x = addr_ (" (tolarge) "); print \"EVAL Tolarge: \" x \"\\n\""


Output:
Large: 2147483647
ToLarge: -2147483639
EVAL Large: 2147483647
EVAL Tolarge: -2147483639


There is only one special case and the problem here is, that the DXL interpreter seems to have an error with interpreting integer literals:

The smallest integer possible in DOORS is 0x8000000 which is: -2147483648

The DXL Parser however will clip this literal (and all smaller numbers) to a minimum of: -2147483647 ... I never noticed that problem and I think it should not have practical relevance, however you need to be aware that for this number the addr_ statement will be 'off-by-one' ... If you want to be sure, you need to do something like this to trick the DXL parser:

string int2dxl_literal(int x) {
   if (x - 1 == 0x7FFFFFFF) return "(0x7FFFFFFF+1)"
   return x ""
}

int tolarge = 0x7FFFFFFF + 1

eval_ "int x = addr_ (" (int2dxl_literal tolarge) "); print \"EVAL Tolarge: \" x \"\\n\""



Good find! Regards, Mathias

Hello Mathias

I think that the Problem is something larger than this. The following code

int i80000000 = 0x80000000;
int i80000001 = 0x80000001;
int i80000002 = 0x80000002;
int i80000003 = 0x80000003;

int iFFFFFFFF = 0xFFFFFFFF;

int i7FFFFFF0 = 0x7FFFFFF0;
int i7FFFFFFF = 0x7FFFFFFF;


print "i80000000: " i80000000 "\tEigentlich: -2147483648 (smallest Int)\n";
print "i80000001: " i80000001 "\tEigentlich: -2147483647\n";
print "i80000002: " i80000002 "\tEigentlich: -2147483646\n";
print "i80000003: " i80000003 "\tEigentlich: -2147483645\n";

print "iFFFFFFFF: " i80000003 "\tEigentlich: -1\n";

print "i7FFFFFF0: " i7FFFFFF0 "\tEigentlich: 2147483632\n";
print "i7FFFFFFF: " i7FFFFFFF "\tEigentlich: 2147483647 (largest Int)\n";

bool bCompare = i80000000 == i80000003

print bCompare;

delivers the following result.

i80000000: 2147483647      Eigentlich: -2147483648 (smallest Int)
i80000001: 2147483647      Eigentlich: -2147483647
i80000002: 2147483647      Eigentlich: -2147483646
i80000003: 2147483647      Eigentlich: -2147483645
iFFFFFFFF: 2147483647      Eigentlich: -1
i7FFFFFF0: 2147483632      Eigentlich: 2147483632
i7FFFFFFF: 2147483647      Eigentlich: 2147483647 (largest Int)
true

Best regards

Wolfgang

Re: Unsigned Address conversion
Mathias Mamsch - Fri Jun 06 18:33:08 EDT 2014

Wolfgang Uhr - Fri Jun 06 04:50:35 EDT 2014

Hello Mathias

I think that the Problem is something larger than this. The following code

int i80000000 = 0x80000000;
int i80000001 = 0x80000001;
int i80000002 = 0x80000002;
int i80000003 = 0x80000003;

int iFFFFFFFF = 0xFFFFFFFF;

int i7FFFFFF0 = 0x7FFFFFF0;
int i7FFFFFFF = 0x7FFFFFFF;


print "i80000000: " i80000000 "\tEigentlich: -2147483648 (smallest Int)\n";
print "i80000001: " i80000001 "\tEigentlich: -2147483647\n";
print "i80000002: " i80000002 "\tEigentlich: -2147483646\n";
print "i80000003: " i80000003 "\tEigentlich: -2147483645\n";

print "iFFFFFFFF: " i80000003 "\tEigentlich: -1\n";

print "i7FFFFFF0: " i7FFFFFF0 "\tEigentlich: 2147483632\n";
print "i7FFFFFFF: " i7FFFFFFF "\tEigentlich: 2147483647 (largest Int)\n";

bool bCompare = i80000000 == i80000003

print bCompare;

delivers the following result.

i80000000: 2147483647      Eigentlich: -2147483648 (smallest Int)
i80000001: 2147483647      Eigentlich: -2147483647
i80000002: 2147483647      Eigentlich: -2147483646
i80000003: 2147483647      Eigentlich: -2147483645
iFFFFFFFF: 2147483647      Eigentlich: -1
i7FFFFFF0: 2147483632      Eigentlich: 2147483632
i7FFFFFFF: 2147483647      Eigentlich: 2147483647 (largest Int)
true

Best regards

Wolfgang

Hi Wolfgang,

I dont think the problem is really larger... You just need to know one fact. The DXL parser will "clip" literals that are outside of the range

-2147483647 <= x <= +2147483647

You can write in DXL:

int x = 12423423423467238423468

However the DXL Parser will make that:

int x = 2147483647

The same is true for negative numbers:

int x = - 21342374823942384

will be interpreted as

int x = - 2147483647

And that is not really surprising, because "-" is a unary operator in DXL, meaning -123 is not treated as one literal by the DXL interpreter. Instead it is treated as - (+123), meaning the unary operator "-" applied to to the positive literal. And since the highest positive literal is 2147483647 (0x7FFFFFFF) you cannot put any integer literal in DXL code that is larger. So to write -1 in HEX you need to use a signed notation:

- 0x00000001

instead of 0xFFFFFFFF because DXL uses signed integers.

So the only number you cannot express in DXL as one literal at all is -2147483648. All other numbers can be expressed in signed notation. And for that one specific number you can simply use the addition with overflow: (2147483647+1) , which should be -2147483648.

Hope that clears matters up. Regards, Mathias

Re: Unsigned Address conversion
Mike.Scharnow - Tue Sep 02 18:08:27 EDT 2014

Hi Louie and all,

did you develop a solution for your problem that works? Just putting () around the negative int value does not work for me.

I can run Mathias' example (the negative number is printed), but when I try to access the value behind the addr_, I get an "invalid access" fault.

This issue is difficult to test, as it is not very often that big (thus: negative) values of addr_ are given.

I only encountered this behavior with doors 9.6 64-bit. Louie, In what environment did you get this behavior?

 

Is it correct thinking that with the introduction of a bigger address space, DXL would need a new datatype (dword or the like?)

thanks & Regards,
Mike

Re: Unsigned Address conversion
llandale - Wed Sep 03 14:12:38 EDT 2014

Mike.Scharnow - Tue Sep 02 18:08:27 EDT 2014

Hi Louie and all,

did you develop a solution for your problem that works? Just putting () around the negative int value does not work for me.

I can run Mathias' example (the negative number is printed), but when I try to access the value behind the addr_, I get an "invalid access" fault.

This issue is difficult to test, as it is not very often that big (thus: negative) values of addr_ are given.

I only encountered this behavior with doors 9.6 64-bit. Louie, In what environment did you get this behavior?

 

Is it correct thinking that with the introduction of a bigger address space, DXL would need a new datatype (dword or the like?)

thanks & Regards,
Mike

I got this:

string int2dxl_literal(int x) {
   if (x - 1 == 0x7FFFFFFF) return "(0x7FFFFFFF+1)"
   return x ""
}
In the function:

bufCode += "ModName_  mn = addr_ ("
bufCode += int2dxl_literal(int (addr_ in_mn))    ")"

Seems to be working.

-Louie

Re: Unsigned Address conversion
Mike.Scharnow - Thu Sep 04 07:09:13 EDT 2014

llandale - Wed Sep 03 14:12:38 EDT 2014

I got this:

string int2dxl_literal(int x) {
   if (x - 1 == 0x7FFFFFFF) return "(0x7FFFFFFF+1)"
   return x ""
}
In the function:

bufCode += "ModName_  mn = addr_ ("
bufCode += int2dxl_literal(int (addr_ in_mn))    ")"

Seems to be working.

-Louie

Strange. I always get exceptions. See the following example where I get the same value for the addr_ of two strings which have a different content.
I omitted the check for 0x800000, as the addr_ value is quite constant in every run and not near this specific value.

a) calling function

string hook_beforeCreateBaseline(Module mTgt, int iBaselineVersion, string sSuffix, string sDescr, string errMsg)
{
    sDescr = "test entry for sDescr"
    string hookCode = "#include <src/hooks/userBranchHooks.dxl>
 Module mTgt = (addr_ (" ((addr_ mTgt) int) ")) Module
 int iBaselineVersion = (addr_ (" ((addr_ iBaselineVersion) int) ")) int
 string sSuffix = (addr_ (" ((addr_ sSuffix) int) ")) string
 string sDescr = (addr_ (" ((addr_ sDescr) int) ")) string
 string errMsg = (addr_ (" ((addr_ errMsg) int) ")) string
 return_ userHook_beforeCreateBaseline(mTgt, iBaselineVersion, sSuffix, sDescr, errMsg)"
print "In calling procedure: sSuffix: " sSuffix ", "
print "sDescr: " sDescr ", "
print "errMsg: " errMsg "\n"
print hookCode "\n" // xxx 
 noError()
 string strEval = eval_(hookCode)
 string strErr = lastError()
    return(combineReturnedStrings(strEval, strErr))
}

b) called function

string userHook_beforeCreateBaseline(Module mTgt, int iBaselineVersion, string sSuffix, string sDescr, string errMsg)
{
    if(gb_USERHOOK_PRINT)
 {
  print "In called Procedure\t\tuserHook_beforeCreateBaseline:\n"
  print ((null mTgt) ? "null Module" : (fullName mTgt)) "\n" 
  print ((null sSuffix) ? "no Suffix" : (sSuffix)) "\n"
  print ((null sDescr) ? "no Description" : (sDescr)) "\n"
  print ((null errMsg) ? "no error Message" : (errMsg)) "\n"
  print "\n"
 }
 return("userHook_beforeCreateBaseline")
}

 

c) output

In calling procedure: sSuffix: , sDescr: test entry for sDescr, errMsg:
#include <src/hooks/userBranchHooks.dxl>
        Module mTgt = (addr_ (193688784)) Module
        int iBaselineVersion = (addr_ (0)) int
        string sSuffix = (addr_ (-2147301144)) string
        string sDescr = (addr_ (98916240)) string
        string errMsg = (addr_ (-2147301144)) string
        return_ userHook_beforeCreateBaseline(mTgt, iBaselineVersion, sSuffix, s
Descr, errMsg)


In called Procedure             userHook_beforeCreateBaseline:
/<project/<dir>/<dir>/<modulename>
DOORS: **** Translating a structured exception ****
DOORS: Version 9.6.0.0, build number 96085, built on May  8 2014 23:02:05.
DOORS: Microsoft Windows 7 Professional Service Pack 1 (build 7601), 64-bit
[…]
DOORS: doors.exe caused an EXCEPTION_ACCESS_VIOLATION in module doors.exe at 000
00000407E489E

 

Anyone any idea??

Thanks & Best regards
Mike