Variable comment

Hi,

I have such a template for content of the ELF interpreter information.

local int64 pos;
local int64 end;
if( GetSelSize() > 0 ) {
    pos = GetSelStart();
    end = pos + GetSelSize();  
} else {
    pos = GetCursorPos();
    end = FileSize();    
}
  
FSeek(pos);
local uint64 type;

while (!FEof() && FTell() < end) {
    type = ReadUInt64();
    FSkip(8);
    
    switch (type) {
        case 0: uint64 AT_NULL; break;
        case 1: uint64 AT_IGNORE; break;
        case 2: uint64 AT_EXECFD; break;
        case 3: uint64 AT_PHDR; break;
        case 4: uint64 AT_PHENT; break;
        case 5: uint64 AT_PHNUM; break;
        case 6: uint64 AT_PAGESZ; break;
        case 7: uint64 AT_BASE; break;
        case 8: uint64 AT_FLAGS; break;
        case 9: uint64 AT_ENTRY; break;
        case 10: uint64 AT_NOTELF; break;
        case 11: uint64 AT_UID; break;
        case 12: uint64 AT_EUID; break;
        case 13: uint64 AT_GID; break;
        case 14: uint64 AT_EGID; break;
        case 15: uint64 AT_CLKTCK; break;
        case 16: uint64 AT_PLATFORM; break;
        case 17: uint64 AT_HWCAP; break;
        case 18: uint64 AT_FPUCW; break;
        case 19: uint64 AT_DCACHEBSIZE; break;
        case 20: uint64 AT_ICACHEBSIZE; break;
        case 21: uint64 AT_UCACHEBSIZE; break;
        case 22: uint64 AT_IGNOREPPC; break;
        case 23: uint64 AT_SECURE; break;
        case 24: uint64 AT_BASE_PLATFORM; break;
        case 25: uint64 AT_RANDOM; break;
        case 26: uint64 AT_HWCAP2; break;
        case 31: uint64 AT_EXECFN; break;
        case 32: uint64 AT_ASYSINFO; break;
        case 33: uint64 AT_SYSINFO_EHDR; break;
        case 34: uint64 AT_L1I_CACHESHAPE; break;
        case 35: uint64 AT_L1D_CACHESHAPE; break;
        case 36: uint64 AT_L2_CACHESHAPE; break;
        case 37: uint64 AT_L3_CACHESHAPE; break;
        case 40: uint64 AT_L1I_CACHESIZE; break;
        case 41: uint64 AT_L1I_CACHEGEOMETRY; break;
        case 42: uint64 AT_L1D_CACHESIZE; break;
        case 43: uint64 AT_L1D_CACHEGEOMETRY; break;
        case 44: uint64 AT_L2_CACHESIZE; break;
        case 45: uint64 AT_L2_CACHEGEOMETRY; break;
        case 46: uint64 AT_L3_CACHESIZE; break;
        case 47: uint64 AT_L3_CACHEGEOMETRY; break;
        default:uint64 UNKNOWN<comment=ReadUInt64(FTell()-8)>; break;
    }
}

First, instead of declaring multiple variables, I wanted to use something like this in the loop:

while(!FEof()) {
    uint64 value<name=get_name>;
}

string get_name(uint64 unused) {...}

but then all the names were the same. Hence the current solution.
In contrast, in the current solution I encountered a similar problem. When I encounter an unknown value, I would like to print its numeric value in the comment. Unfortunately, with each run of the loop, the comment value changes and it is a common value for all UNKNOWN. How can I solve this?

Thank you

Hello mmo

You should be able to use the get_name function but you have to test the value like this:

while(!FEof()) {
    uint64 value<name=get_name>;
}

string get_name(uint64 val) 
{
    switch( val ) {
        case 0 : return "AT_NULL";
        case 1 : return "AT_IGNORE";
        //...
        default : return "value";
    }
}

If you want to add a comment for unknown values you would have to write a separate comment function too. Cheers!

Graeme Sweet
SweetScape Software

I have a file in format:

uint64 name;
uint64 value;

When I try template:

while (!FEof()) {
    FSkip(8);
    uint64 value<name=get_name, comment=get_pos>;
}

string get_pos(uint64 val) {
    string s;
    SPrintf(s, "%d", FTell());
    return s;
}

string get_name(uint64 val) {
    switch (FTell()-8) {
    case 0: return "AT_NULL"; break;
        case 1:  return "AT_IGNORE"; break;
        case 2:  return "AT_EXECFD"; break;
        case 3:  return "AT_PHDR"; break;
        case 4:  return "AT_PHENT"; break;
        ...
   }
}

as a result all the names are the same, and comments too

it looks like the function used in name (get_name()) is called N times when the result is displayed, so the FTell()-8 is the same for all variables (which is clearly visible in the comment column).

I expected a different behavior, that function calls would be made when the variabe is created, and so I could determine the name/comment based on the position in the file.
At the moment, basing the file position in attribute functions such as name or comment can lead to unexpected results, as in my case.

The name and comment functions are actually run after the template has finished execution. They are only called when data needs to be displayed in the Template Results panel, so that we don’t have to cache potentially millions of strings. If you really want to have the name function return different values depending upon the position of each variable in the file you can use the ‘startof’ operator like this:

string get_name(uint64 &val) 
{
    switch( startof(val) ) {
    ...

Note that ‘&’ before val is required when using startof. Cheers!

Graeme Sweet
SweetScape Software

Thank you,

It is not the most convenient, but it works :slight_smile: