lkml.org 
[lkml]   [2020]   [Sep]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC PATCH v2 2/2] objtool: fix x86 orc generation on big endian cross compiles
    Correct objtool orc generation endianness problems to enable fully
    functional x86 cross compiles on big endian hardware.

    Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
    ---
    arch/x86/include/asm/orc_types.h | 24 ++++++++++++++++++++++++
    tools/arch/x86/include/asm/orc_types.h | 24 ++++++++++++++++++++++++
    tools/objtool/orc_dump.c | 4 ++--
    tools/objtool/orc_gen.c | 2 ++
    4 files changed, 52 insertions(+), 2 deletions(-)

    diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h
    index fdbffec4cfde..c72bee8e6ec0 100644
    --- a/arch/x86/include/asm/orc_types.h
    +++ b/arch/x86/include/asm/orc_types.h
    @@ -40,6 +40,13 @@
    #define ORC_REG_MAX 15

    #ifndef __ASSEMBLY__
    +#ifdef __KERNEL__
    +#include <linux/swab.h>
    +#include <asm/byteorder.h>
    +#else
    +#include <endian.h>
    +#endif
    +
    /*
    * This struct is more or less a vastly simplified version of the DWARF Call
    * Frame Information standard. It contains only the necessary parts of DWARF
    @@ -48,6 +55,9 @@
    * the stack for a given code address. Each instance of the struct corresponds
    * to one or more code locations.
    */
    +
    +#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
    +
    struct orc_entry {
    s16 sp_offset;
    s16 bp_offset;
    @@ -57,6 +67,20 @@ struct orc_entry {
    unsigned end:1;
    } __packed;

    +#else
    +
    +struct orc_entry {
    + s16 sp_offset;
    + s16 bp_offset;
    + unsigned bp_reg:4;
    + unsigned sp_reg:4;
    + unsigned unused:5;
    + unsigned end:1;
    + unsigned type:2;
    +} __packed;
    +
    +#endif
    +
    #endif /* __ASSEMBLY__ */

    #endif /* _ORC_TYPES_H */
    diff --git a/tools/arch/x86/include/asm/orc_types.h b/tools/arch/x86/include/asm/orc_types.h
    index fdbffec4cfde..c72bee8e6ec0 100644
    --- a/tools/arch/x86/include/asm/orc_types.h
    +++ b/tools/arch/x86/include/asm/orc_types.h
    @@ -40,6 +40,13 @@
    #define ORC_REG_MAX 15

    #ifndef __ASSEMBLY__
    +#ifdef __KERNEL__
    +#include <linux/swab.h>
    +#include <asm/byteorder.h>
    +#else
    +#include <endian.h>
    +#endif
    +
    /*
    * This struct is more or less a vastly simplified version of the DWARF Call
    * Frame Information standard. It contains only the necessary parts of DWARF
    @@ -48,6 +55,9 @@
    * the stack for a given code address. Each instance of the struct corresponds
    * to one or more code locations.
    */
    +
    +#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
    +
    struct orc_entry {
    s16 sp_offset;
    s16 bp_offset;
    @@ -57,6 +67,20 @@ struct orc_entry {
    unsigned end:1;
    } __packed;

    +#else
    +
    +struct orc_entry {
    + s16 sp_offset;
    + s16 bp_offset;
    + unsigned bp_reg:4;
    + unsigned sp_reg:4;
    + unsigned unused:5;
    + unsigned end:1;
    + unsigned type:2;
    +} __packed;
    +
    +#endif
    +
    #endif /* __ASSEMBLY__ */

    #endif /* _ORC_TYPES_H */
    diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c
    index 5e6a95368d35..19fa6f65040e 100644
    --- a/tools/objtool/orc_dump.c
    +++ b/tools/objtool/orc_dump.c
    @@ -197,11 +197,11 @@ int orc_dump(const char *_objname)

    printf(" sp:");

    - print_reg(orc[i].sp_reg, orc[i].sp_offset);
    + print_reg(orc[i].sp_reg, (s16)le16toh(orc[i].sp_offset));

    printf(" bp:");

    - print_reg(orc[i].bp_reg, orc[i].bp_offset);
    + print_reg(orc[i].bp_reg, (s16)le16toh(orc[i].bp_offset));

    printf(" type:%s end:%d\n",
    orc_type_name(orc[i].type), orc[i].end);
    diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
    index 235663b96adc..ab9cff93fabd 100644
    --- a/tools/objtool/orc_gen.c
    +++ b/tools/objtool/orc_gen.c
    @@ -96,6 +96,8 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
    /* populate ORC data */
    orc = (struct orc_entry *)u_sec->data->d_buf + idx;
    memcpy(orc, o, sizeof(*orc));
    + orc->sp_offset = htole16(orc->sp_offset);
    + orc->bp_offset = htole16(orc->bp_offset);

    /* populate reloc for ip */
    reloc = malloc(sizeof(*reloc));
    --
    ⣿⣿⣿⣿⢋⡀⣀⠹⣿⣿⣿⣿
    ⣿⣿⣿⣿⠠⣶⡦⠀⣿⣿⣿⣿
    ⣿⣿⣿⠏⣴⣮⣴⣧⠈⢿⣿⣿
    ⣿⣿⡏⢰⣿⠖⣠⣿⡆⠈⣿⣿
    ⣿⢛⣵⣄⠙⣶⣶⡟⣅⣠⠹⣿
    ⣿⣜⣛⠻⢎⣉⣉⣀⠿⣫⣵⣿
    \
     
     \ /
      Last update: 2020-09-30 14:25    [W:2.941 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site