Note that there are some explanatory texts on larger screens.

plurals
  1. POAIX loadquery() return value interpretation (was also SEGV in 64-bit mode)
    primarykey
    data
    text
    <p>I'm trying to compile Ruby 1.9.3-p125 on AIX 5.3 using xlc_r. I want to use the --enable-load-relative but that's dependent on the dladdr() function to get the pathname of the Ruby shared library and dladdr() isn't available on AIX. I found an implementation of dladdr() <a href="http://root.cern.ch/drupal/content/aix-and-dladdr" rel="nofollow">here on root.cern.ch</a> for AIX based on a call to loadquery(L_GETINFO).</p> <p>The loadquery(L_GETINFO) call gets a list of the binary files that make up a program. So to implement dladdr(), I'm doing a check to see if the address of the function passed to dladdr is between ldinfo_textorg and ldinfo_textorg+ldinfo_textsize. But the address of the function isn't within this address range for <em>any</em> of the structures returned. Maybe I'm not correctly interpreting the ld_info structure.</p> <p>I've attached the code I'm testing. Any help that can be rendered to these questions will be much appreciated.</p> <pre><code>#include &lt;sys/types.h&gt; #include &lt;sys/ldr.h&gt; #include &lt;stdlib.h&gt; #include &lt;stdio.h&gt; typedef struct { char* dli_fname; } Dl_info; int dladdr(void* s, Dl_info* i) { size_t bufSize = 40960; struct ld_info* ldi; void *buf; int r; printf("sym at %lu\n", (ulong)s); buf = (void *)malloc(bufSize); if (!buf) { i-&gt;dli_fname = 0; return 0; } r = loadquery((int)L_GETINFO, buf, (int)bufSize); if (r == -1) { i-&gt;dli_fname = 0; return 0; } do { ldi = (struct ld_info*)buf; printf("checking %s, text %lu - %lu\n", ldi-&gt;ldinfo_filename, (ulong)ldi-&gt;ldinfo_textorg, (ulong)(ldi-&gt;ldinfo_textorg + ldi-&gt;ldinfo_textsize)); if ((ldi-&gt;ldinfo_textorg &lt;= s) &amp;&amp; (s &lt; (ldi-&gt;ldinfo_textorg + ldi-&gt;ldinfo_textsize))) { i-&gt;dli_fname = ldi-&gt;ldinfo_filename; return 1; } buf += ldi-&gt;ldinfo_next; } while (ldi-&gt;ldinfo_next); i-&gt;dli_fname = 0; return 0; } int test_func() { 1; } int main() { Dl_info dli; int rc = dladdr((void *)test_func, &amp;dli); printf("rc = %d\n", rc); if (rc) { printf("dli.dli_fname = %s\n", dli.dli_fname); } } </code></pre> <p><strong>Update 30-Apr-2012:</strong> When I originally posted this question, I was also seeing loadquery(L_GETINFO) cause a segmentation violation when called from a 64-bit program. I can't live without 64-bit so this was a showstopper for me. This now looks like it's a problem with the installation of the compiler; other AIX machines can compile and run the code in 64-bit mode.</p> <p>The stack back-trace looked like this:</p> <pre><code>.() at 0xf458 usl_getinfo_user(??, ??, ??, ??) at 0x9fffffff00096b8 uloadquery(??, ??, ??, ??, ??, ??, ??) at 0x9fffffff0009b40 loadquery(0x200000002, 0x1000b3f0, 0xa0000000a000, 0x0, 0x0, 0x0, 0x0, 0x0) at 0x900000000043874 dladdr(s = 0x0000000110000900, i = 0x0ffffffffffffa00), line 18 in "dladdr.c" main(), line 11 in "test_dladdr.c" </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload