bug-mes
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-mes] "Architectural"_displacement confusion


From: Danny Milosavljevic
Subject: [bug-mes] "Architectural"_displacement confusion
Date: Wed, 13 Feb 2019 15:46:42 +0100

Hi Jeremiah,
Hi Jan,

currently, mescc-tools uses "Architectural"_displacement for all of the 
following prefixes:

  ! @ ~ %

and it uses an absolute target for all of the following prefixes:

  $ &

Furthermore, blood-elf emits debug information, containing

  %...>...

in order to determine sizes.

Wouldn't that cause debug metadata to be architecture-dependent? (right now in 
my local ARM branch I get a failure because the debug info is not word-aligned. 
 Well, it isn't.  I started aligning it and then I stopped myself, because what 
was I doing?  It makes no sense to do that!).

On RISC architectures, the Fetch stage fetching the instructions is (mostly) 
independent of any other stage.  This means that the Fetch stage happily 
marches on (increases program counter) no matter what you do, including 
branches (the program counter will eventually be updated for the branch, but 
only *eventually*).  Therefore, it would be natural for an 
"Architectural"_displacement to take this into account.  Also, on ARM the 
branch immediate is the number of INSTRUCTIONS, not the number of Bytes, to 
skip.

However, if the data structure size determination is done like blood-elf does 
it, and we took the above into account, then that would break the debug info 
size calculation.  Same for the ELF headers.

Maybe I misunderstood the purpose of Architectural_displacement, but as it is 
now, I don't see how it can specialize per architecture because if it was any 
different than (target - base) then it would break size determination by users.

As a better way, I would suggest to clearly separate which are 
architecture-dependent displacements (to be put into instructions) and which 
are architecture-independent "displacements" (sizes and absolute addresses, 
really) in the user interface.

I suggest to change storePointer to read:

void storePointer(char ch, FILE* source_file)
{
...
        displacement = Architectural_displacement(target, base);

        /* output calculated difference */
        if('!' == ch) outputPointer(displacement, 1); /* Deal with ! */
/*!!*/  else if('$' == ch) outputPointer(('>' == base_sep_p) ? target - base : 
target, 2); /* Deal with $ */
        else if('@' == ch) outputPointer(displacement, 2); /* Deal with @ */
        else if('~' == ch) outputPointer(displacement, 3); /* Deal with ~ */
        else if('&' == ch)
/*!!*/          outputPointer(('>' == base_sep_p) ? target - base : target, 4); 
/* Deal with & */
        else if('%' == ch) outputPointer(displacement, 4);  /* Deal with % */
        else
        {
                file_print("storePointer reached impossible case: ch=", stderr);
                fputc(ch, stderr);
                file_print("\n", stderr);
                exit(EXIT_FAILURE);
        }
}

And change size-determining users to do "&foo>bar" instead of "%foo>bar" if 
they mean size determination.

Then, Architectural_displacement can do:

int Architectural_displacement(int target, int base)
{
        if(0 == Architecture) return (target - base);
        else if(1 == Architecture) return (target - base);
        else if(2 == Architecture) return (target - base);
        else if(40 == Architecture)
        {
                /* Note: Branch displacements on ARM are in number of
                   instructions to skip, basically. */
                if (base & 3)
                {
                        file_print("Unaligned base, aborting\n", stderr);
                        exit(EXIT_FAILURE);
                }
                if (target & 3)
                {
                        file_print("Unaligned target, aborting\n", stderr);
                        exit(EXIT_FAILURE);
                }
                /* The "fetch" stage already moved forward by 8 from the
                   beginning of the instruction because it is already
                   prefetching the next instruction.
                   We already moved forward by 4 (see Update_Pointer).
                   Compensate for it by subtracting the space for
                   one instruction (not the branch instruction). */
                return ((target - base) >> 2) - 1;
        }

        file_print("Unknown Architecture, aborting before harm is done\n", 
stderr);
        exit(EXIT_FAILURE);
}

What do you think?

Attachment: pgparXXMdqoc4.pgp
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]