Bug 28334 - cannot handle offset into register
Summary: cannot handle offset into register
Status: REOPENED
Alias: None
Product: systemtap
Classification: Unclassified
Component: translator (show other bugs)
Version: unspecified
: P2 critical
Target Milestone: ---
Assignee: Unassigned
URL:
Keywords:
Depends on:
Blocks: 29037
  Show dependency treegraph
 
Reported: 2021-09-13 10:20 UTC by kora
Modified: 2022-07-01 17:44 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2022-05-19 00:00:00
Project(s) to access:
ssh public key:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description kora 2021-09-13 10:20:01 UTC
Hi team

I had a function trace demo with Struct parameter and Struct return, but got the "cannot handle offset into register" error.

my environments:
  os: Ubuntu 16.04 LTS
  gcc 8.3
  systemtap 4.5
  elfutils 0.185


# func.h
struct DataPackage {
    int len;
    float width;
    // float width2; // uncomment this line will work :)
    double angle;
};

struct DataPackage func_complex_v2(struct DataPackage input_data, int page);

# func.c

struct DataPackage func_complex_v2(struct DataPackage input_data, int page) {
    struct DataPackage d;
    d.len = 19;
    d.width = 115.33;
    d.angle = 6.66;

    return d;
}

# main.c
int main(int argc, char const *argv[])
{

    struct DataPackage d;
    d.len = 997;
    d.width = 10;
    d.angle = 0.777;

    struct DataPackage r =func_complex_v2(d, 789);

    return 0;
}

# cc_stap_test_complex.stp
probe process("/home/xyz/vs_workspace/CacheLab/build/test").function("func_complex_v2").return {
    printf("func_complex_v2 return: %s\n", fp_to_string($return->width, 6))
}


Here is the console output:

Debug translate_offsetsemantic error: cannot handle offset into register: identifier '$return' at 
/home/xyz/cc_stap_test_complex.stp:73:57
        source:     printf("func_complex_v2 return: %s\n", fp_to_string($return->width, 6))
                                                                        ^

semantic error: unresolved type : identifier '$return' at :73:57
        source:     printf("func_complex_v2 return: %s\n", fp_to_string($return->width, 6))


Any advice is appreciate, thanks!
Comment 1 Stan Cox 2022-05-19 20:25:37 UTC
This is due to the x8664 abi which specifies how structures are passed.  The structure in the example is returned by value, which will return the struct members in successive registers as specified by the x8664 abi.  In this particular case members are packed into a single register and systemtap is thus not able to pry it apart.  Thus the error "cannot handle offset into register"

The abi says:
 The classification of aggregate (structures and arrays) and union types works
as follows:
1. If the size of an object is larger than four eightbytes, or it contains unaligned
fields, it has class MEMORY

So if the example is changed to be double width; double angle; then the abi threshold is hit, the struct is passed by reference and systemtap can then access individual members.
Comment 2 Frank Ch. Eigler 2022-05-19 20:31:33 UTC
>  In this particular case members are packed into a single register and systemtap is thus not able to pry it apart.  Thus the error "cannot handle offset into register"

Why can systemtap not handle this though?  I believe the code knows about larger values being split across memory words or registers.
Comment 3 Stan Cox 2022-05-19 20:50:45 UTC
It is hitting this case:
dwflpp::translate_base_ref

    case loc_register:
      if (loc->offset != 0)
        throw SEMANTIC_ERROR (_("cannot handle offset into register"), ctx.e->tok);
      // The existing program is the value.
      break;
Comment 4 William Cohen 2022-07-01 17:44:44 UTC
Been working on PR29037. For bitfields there is some logic that handles to extract the bitfield of interest.  It doesn't look like there is similar code to extract other members of a struct:

https://sourceware.org/git/?p=systemtap.git;a=blob;f=dwflpp.cxx;h=ae06933df865fe1c6070327e72d103a14b0039d0;hb=refs/heads/master#l4000