This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

m68k structure return register


Hello,
it appears that the way gdb expects code to
return structure values on m68k is not exactly
consistent with how gcc actually passes them.

Basically, for function returning structures,
caller should pass an address of memory where
structure should be returned, using either register a0,
or register a1. Which register is used for what target
is precisely where confusion lies.

In gcc/config/m68k there are three definitions:

m68k.h:#define M68K_STRUCT_VALUE_REGNUM A1_REG
m68kelf.h:#define M68K_STRUCT_VALUE_REGNUM A0_REG
netbsd-elf.h:#define M68K_STRUCT_VALUE_REGNUM A0_REG

This, together with config.gcc, gives me the following table
of what register is used for what target.

        1. m68k-*-aout*                                 a1
        2. m68k-*-coff*                                 a1
        3. m68k-*-elf*                                  a0
        4. m68k*-*-netbsdelf*                           a0
        5. m68k*-*-openbsd*                             a1
        6. m68k-*-uclinuxoldabi*                        a0
        7. m68k-*-uclinux*                              a1
        8. m68k-*-linux*                                a1
        9. m68k-*-rtems*                                a0

Here's a breakdown of how those targets map to gdb's .mt files in
config/m68k:

Group I -- monitor.mt -- just m68k-tdep.c

        1. m68k-*-aout*                                 a1
        2. m68k-*-coff*                                 a1
        3. m68k-*-elf*                                  a0
        6. m68k-*-uclinuxoldabi*                        a0
        7. m68k-*-uclinux*                              a1
        9. m68k-*-rtems*                                a0

In gdb, all target here use the register set in m68k_gdbarch_init -- 
currently A1, which register is wrong for half of targets. I'll get to this
group shortly.

Group II -- nbsd.mt/obsd.mt -- m68k-tdep.c + m68kbsd-tdep.c

        4. m68k*-*-netbsdelf*                           a0
        5. m68k*-*-openbsd*                             a1
        
In this group. netbsd has osabi sniffer that sets a0. openbsd
just gets whatever  m68k_gdbarch_init sets -- currently a1.

Group III -- linux.mt -- m68k-tdep.c + m68klinux-tdep.c

        8. m68k-*-linux*                                a1

Here, there's osabi sniffer that causes a1 to be used.

The problem is therefore, group I. Notably, for m68k-elf gcc uses
a0, whereas gdb assumes a1. And for m68k-elf, we cannot set
any osabi sniffer. I think that nowdays m68k-elf is probably the most
important target in that group.

I would suggest the following:

1. Change gdb's default to use a0 register, so that bare-metal works.
2. If possible, add osabi sniffers to uclinux, openbsdb and rtems, that
will cause gdb to use a1. 

Does this sound reasonable, and if so, anybody knows how I can
implement osabi sniffers listed in (2)? I've being told osabi sniffer for
uclinux might be impossible, and I don't know much about either openbsd
or rtems.

Thanks,
Volodya


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]