This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: ABI, I don't get it...
- From: "Maciej W. Rozycki" <macro at imgtec dot com>
- To: ANDY KENNEDY <ANDY dot KENNEDY at adtran dot com>
- Cc: "'binutils at sourceware dot org'" <binutils at sourceware dot org>
- Date: Mon, 15 Aug 2016 19:50:32 +0100
- Subject: Re: ABI, I don't get it...
- Authentication-results: sourceware.org; auth=none
- References: <F9C551623D2CBB4C9488801D14F864C6EE87E184@ex-mb1.corp.adtran.com>
On Fri, 12 Aug 2016, ANDY KENNEDY wrote:
> So, after working with the new toolchain for about a week, and
> attempting to port the changes (which, from the 2.24 release of binutils
> conflicts with the changes put in for the Octeon3), I gave up and
> reverted back to my 2.24 binutils. I then found a patch from Maciej to
> allow me to set the default ABI of the toolchain to 64, however, it
> didn't seem to work. Following the spirit of the patch, I made
> additional changes to Gcc, (all of the support packages for binutils),
> GDB, and eglibc. Nothing has seemed to work.
NB these days you can configure GCC with the default ABI of your choice,
by using the `--with-abi=' option, e.g.:
$ /path/to/configure --target=mips64-linux-gnu --with-abi=64 ...
and the resulting compiler will then default to the n64 ABI. The same ABI
names are supported as with the `-mabi=' compiler option. See the GCC
manual and the GCC installation manual for further details.
Therefore as long as you always use the GCC driver to run individual
programs from within the toolchain, including GAS and LD (which is
recommended), you don't need to modify the configuration of other pieces.
The build process of GLIBC (which is preferred to EGLIBC these days, long
unmaintained) will handle such a configuration normally, although the
FHS-defined library paths will be used for your libraries, so e.g. 64-bit
libraries will land in /lib64, etc. That hopefully shouldn't be a
problem. If it is, then you'll have to look yourself into the guts of
configury.
> Next, I focused in on my build system (which is a highly modified
> version of an old BuildRoot -- everything stripped out of it an only our
> proprietary stuff being built by a heavy modification of it -- really,
> the only thing we kept was the configuration. Having said that, there
> were adaptations of the toolchain settings that we kept from BR.
> Adjusting these values (selecting the ABI for the platform, soft/hard
> float etc) has led me into a situation in which I get the following
> error routinely:
>
> ABI is incompatible with that of the selected emulation
This means that the linker emulation chosen with LD invocation cannot
handle the input files presented. With the MIPS ABIs the linker emulation
selected with the `-m' option has to match the ABI of the input files.
The usual selections for the Linux targets are: `elf32btsmip',
`elf32btsmipn32' and `elf64btsmip' for the big-endian o32, n32 and n64
ABIs respectively. Substitute `lt' for `bt' for the little endianness.
Run `ld --help' for the complete list of emulations configured. The GCC
driver is supposed to select the correct emulation on linker invocation,
based on the ABI selection (so you need to use the same `-mabi=' driver
option with linker invocation as you used with source compilation).
> Another error, from a mixture that I cannot get to build correctly,
> gives me the following:
>
> /opt/toolchains/mips64-LinuxBSP-linux-gnu/mips64-LinuxBSP-linux-gnu/sysroot/usr/include/gnu/stubs.h:20:33: fatal error: gnu/stubs-n64_soft.h: No such file or directory
>
> with a toolchain that was supposedly 64-bit native, hard-float. Why
> the floating point selection is soft, I cannot say.
I can't help you with that offhand, you might want to seek a GLIBC
expert. Perhaps you have a soft-float multilib inadvertently included in
your configuration. Depending on the exact GCC target chosen a different
list of multilibs is configured which then affects the build process of
other components.
FYI, multilibs are library configuration variants covering different
endiannesses, ABIs, ISAs, floating-point and other architecture
peculiarities and the configured list for a given GCC binary can be listed
with `gcc -print-multi-lib'. Some may be incompatible with each other and
some hardware, while some may just provide different optimisations.
> Now, to be clear on what I'm asking in this e-mail:
>
> 1) Is there a way to determine the ABI calls being used in a particular
> object file?
You'll get basic ABI/ISA information with the usual *nix `file' command.
Experiment with `readelf' for further details, but beware that information
given will be dense and may require some expertise to interpret. The `-h'
and `-A' options will be particularly relevant here. You may ignore any
and all the GOT information listed with the latter option.
> One thing I see from objdump is ".mdebug.abi64", but I see this in all
> of the object files... which indicates to me that this is not a good
> predictor.
That itself actually indicates the n64 ABI, but you'll need to peek at
the objects with `readelf' for further information.
> --- my take on this is to build three int main () { return 0 ;} object
> files with -mabi={64,o32,n32} and then link EACH object file from our IP
> against each of these, to show which ones are being linked in with the
> wrong ABI.
A 64-bit Linux toolchain will normally support all the three ABIs, with
the default set according to `--with-abi=' as noted above. For the
remaining two you'll need to use `-mabi=' explicitly.
> 1.a) Does it matter (speaking of ABI) on the hard/soft float?
It does, as the calling convention is different and therefore you can't
link soft-float (`-msoft-float') objects and hard float (`-mhard-float')
objects together. Please note that there are further hard-float ABI
variations, however with the XLP processor the compiler defaults will
probably be right for you.
> 2) How can I determine whether an object file is built using hard-float
> ABI calls? I know that the XLP has a HW FPU.
The MIPS FPU is a part of the Linux user ABI, so you can always use hard
float in user programs as the kernel will emulate the FPU if missing in
hardware. Use `readelf -A' to determine the floating-point convention of
an ELF file; it will be printed at the top, e.g.:
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float (32-bit CPU, Any FPU)
Old versions of `readelf' won't print this information.
HTH,
Maciej