Recent

Author Topic: [SOLVED] Linker issue  (Read 4929 times)

MathMan

  • Full Member
  • ***
  • Posts: 166
[SOLVED] Linker issue
« on: August 01, 2014, 11:24:55 pm »
Hi,

Environment: Lazarus 1.2.4 / FPC 2.6.4 / Win 7 64bit / Intel Core i5 430M @2.27 GHz

What do I have to do to convince the compiler to use 64 bit relocation for the inline assembler? Background is as follows.

I do keep some statistics counter in the general VAR definition

Code: [Select]
unit Main;
...

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus;

type
  ...

var
  LongCalc: TLongCalc;

  Add_LLEU_Counter: QWORD;    // Counter for calls to add low level
  Add_LLEU_TotalTime: QWORD;  // Total time spend (in CPU clocks)
  Add_LLEU_LastTime: QWORD;   // Time spend (in CPU clocks) on last call
  Add_LLEU_MinTime: QWORD;    // Lowest time spend on all calls

When I access these from within the inline assembler like

Code: [Select]
function Add_LLEU   // Add Low Level Even Unsigned
(
  Op1: pLimb;  // first summand
  Op2: pLimb;  // second summand
  Res: pLimb;  // resulting sum
  Size: QWORD   // number of limb to work
):QWORD;        // Carry

begin

  {$IFNDEF ASM_VERSION} // Use Pascal only if assembly version is not avail

  {$ifdef KEEP_STATS}   // Inline statistics to be used

  asm
    rdtsc;              // Read time-stamp-counter from core
    shl     RDX, 32;    // Convert to 64 bit
    or      RAX, RDX;
    mov     qword ptr [Add_LLEU_LastTime], RAX; // Initialize this
    inc     qword ptr [Add_LLEU_Counter]        // One more activation counted
  end ['RAX', 'RDX'];

  {$endif}

I do get the linker warning on 32bit absolute relocation used

Code: [Select]
LongCalculator.lpr(20,1) Warning: Object file "main.o" contains 32-bit absolute relocation to symbol ".bss.n_u_main_add_lleu_counter".

This means that I can only reliably run the code in the lower 4GByte of a virtual address range. As long as I keep the debugger info included Windows will start the program as required - but as soon as I remove debug info the program gets executed above that space and consequently stops with a SIGSEGV.

Any ideas what I can do about this? I read what I could find in the documentation but couldn't find something usefull.  Maybe there is doc available somewhere and I just haven't found it yet - linking me to where I should read on would then be highly appreciated.

Regards,
Jens

[02.08.2014] Edit: typos, rephrasing
« Last Edit: August 03, 2014, 01:08:27 pm by MathMan »

MathMan

  • Full Member
  • ***
  • Posts: 166
Re: Linker issue
« Reply #1 on: August 03, 2014, 01:07:21 pm »
Hi all again,

For all of you who'd like to see the solution (mainly my own stupidity) here's what happened and how I resolved it.

Hi,

Environment: Lazarus 1.2.4 / FPC 2.6.4 / Win 7 64bit / Intel Core i5 430M @2.27 GHz

What do I have to do to convince the compiler to use 64 bit relocation for the inline assembler? Background is as follows.

...

Starting again with assembly language after >20 years revealed a lot of lost knowledge :-)

I completely forgot that the instruction set of x86 isn't very orthogonal so I initially tried to use combinations of instructions & addressing modes which simply aren't available. The inline assembler converted them to what is available (unfortunately a lot of things are ambiguous in assembly too) so it was finally the linker hinting me to what went wrong.

I started out with

Code: [Select]
    rdtsc;              // Read time-stamp-counter from core
    shl     RDX, 32;    // Convert to 64 bit
    or      RAX, RDX;
    mov     qword ptr [SHR_LL_LastTime], RAX; // Initialize this
    inc     qword ptr [SHR_LL_Counter]        // One more activation counted

    ...

    rdtsc;              // Read time-stamp-counter from core
    shl     RDX, 32;    // Convert to 64 bit
    or      RAX, RDX;
    sub     RAX, qword ptr [SHR_LL_LastTime];   // Now RAX is the delta

    mov     qword ptr [SHR_LL_LastTime], RAX;   // Set last usage time
    add     qword ptr [SHR_LL_TotalTime], RAX;  // Add to total time spend
    cmp     RAX, qword ptr [SHR_LL_MinTime];    // Do we have a new low?
    cmovnc  RAX, qword ptr [SHR_LL_MinTime];    // No => keep old
    mov     qword ptr [SHR_LL_MinTime], RAX;    // Set accordingly

What I forgot was that the addressing mode "offset64" (going to a full 64 bit address specified as an immediate value in the code) is - with respect to the above - only available for "mov" in connection with register RAX. After some fiddling I found the following replacement

Code: [Select]
    rdtsc;              // Read time-stamp-counter from core
    shl     RDX, 32;    // Convert to 64 bit
    or      RAX, RDX;
    mov     SHR_LL_LastTime, RAX; // Initialize this
    mov     RAX, SHR_LL_Counter;  // One more activation counted
    inc     RAX
    mov     SHR_LL_Counter, RAX;

    ...

    rdtsc;              // Read time-stamp-counter from core
    shl     RDX, 32;    // Convert to 64 bit in RDX
    or      RDX, RAX;
    mov     RAX, SHR_LL_LastTime;
    sub     RDX, RAX;   // Now RDX is the delta

    mov     RAX, RDX;               // Set last usage time
    mov     SHR_LL_LastTime, RAX;
    mov     RAX, SHR_LL_TotalTime;  // Add to total time spend
    add     RAX, RDX;
    mov     SHR_LL_TotalTime, RAX;
    mov     RAX, SHR_LL_MinTime;    // Do we have a new low?
    cmp     RDX, RAX;
    cmovc   RAX, RDX;               // Yes => use it
    mov     SHR_LL_MinTime, RAX;    // Set accordingly

This one now eliminates the linker warnings and the produces code looks as intended.

I think I have to re-read the Intel reference guide carefully :-)

Regards,
Jens

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7644
Re: [SOLVED] Linker issue
« Reply #2 on: August 03, 2014, 01:46:53 pm »
I assume that can be considered an assembler reader bug, so I reported it: http://bugs.freepascal.org/view.php?id=26555

MathMan

  • Full Member
  • ***
  • Posts: 166
Re: [SOLVED] Linker issue
« Reply #3 on: August 03, 2014, 02:16:37 pm »
I assume that can be considered an assembler reader bug, so I reported it: http://bugs.freepascal.org/view.php?id=26555

I don't think so. From assembler sources one can usually infer verry little because it could always be the case that the author intentionally did something in a special way. In my bogus code above all resulting addressing modes were completely legal - so the assembler had to make do with what is available (in this case use 32bit offset variants of certain menmonics). That this can lead to catastrophy when linked & executed in a pure 64bit environment is beyond recognition of the assembler.

What the assembler could do IMO is throw a warning that the used addressing mode does not correspond to the intended environment. But even this I would only do in a very verbose setting. When using assembler the hard work of knowing what you're doing resides with the author.

That's my view on the issue - even if I have spend two days tracking this down.
« Last Edit: August 03, 2014, 02:18:11 pm by MathMan »

MathMan

  • Full Member
  • ***
  • Posts: 166
Re: [SOLVED] Linker issue
« Reply #4 on: August 03, 2014, 03:05:05 pm »
I assume that can be considered an assembler reader bug, so I reported it: http://bugs.freepascal.org/view.php?id=26555

I just followed your link and read the comments from Jonas - makes perfect sense. I'll rewrite so that I only do the access to the processor time stamp counter in assembler.

BTW: Bugtracker - I wanted to raise a bug myself for missing mnemonics (ADCX, ADOX). Now I have two questions regarding this

1 - I can't seem to login. Neither under my existing account nor can I register a new one. Is there something special required - e.g. allowing Cookies?
2 - Is there a documentation on the usage of bugtracker avail? Before I register a new bug I'd like to search existing ones so that I do not duplicate and the search functionality looks pretty arcane to me.

Regards,
Jens

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: [SOLVED] Linker issue
« Reply #5 on: August 03, 2014, 03:51:48 pm »
1/ Have you received the confirmation email after you've signed up for a new account  in the BugTracker? And of course, did you supply a valid email address for it ?

I can't remember the exact process, but AFAIR it's working OK; and I can't neither remember if I've allowed cookies or not (but I'm not sure they are necessary).

2/ You can use the search option, even without being logged (see capture).
-select 'View Issues' first if necessary, to get the corresponding entries (i.e. like the capture),
-select your targeted project (FPC for instance in your case),
-enter the requested keywords. Don't be too restrictive; you may have to try several times to find what you search,
-optionally, you can restrict any available options (all the options in blue: Reporter, Monitored By,  Assigned To ... Match Type). I'm not sure but I think that they are not all usable.

PS. If you've signed up but not received the confirmation email and/or not used it for your confirmation, it's indicated that your account will be purged after 7 days (that's why you can signed up again with the same account currently, I guess).
« Last Edit: August 03, 2014, 04:02:17 pm by ChrisF »

MathMan

  • Full Member
  • ***
  • Posts: 166
Re: [SOLVED] Linker issue
« Reply #6 on: August 03, 2014, 04:18:45 pm »
...

I can't remember the exact process, but AFAIR it's working OK; and I can't neither remember if I've allowed cookies or not (but I'm not sure they are necessary).

All seems to rely on cookies - now that I have them enabled for the Bugtracker I can register and search.