Linking nominally incompatible object files
Nick Clifton
nickc@redhat.com
Thu May 6 13:32:00 GMT 2004
Hi Bernd,
>>Reloc 2 is for a function call.
>>
>>
>
>It is for v850 indeed. Which is why I'm surprised that the linker
>claims it's *not* supported.
>
>
Agreed - it is quite strange.
>I notice now that in my "new" file bfd/elf32-v800.c (*derived* from, not
>replacing elf32-v850.c!) the token "R_V850_22_PCREL" appears only in the
>macro call to HOWTO - IOW it is otherwise unhandled.
>
This is probably not quite true. If the "special_function" field is set
to "bfd_elf_generic_reloc" then the generic reloc handling code in
bfd/elf.c will handle the processing of the reloc.
>>Neither and both. It is supposed to interpret them based on the target
>>architecture that it was built to support. When it is built to support
>>more than one architecture then it is supposed to select the relocs that
>>is supports based upon the input file that it is processing.
>>
>>
>
>So if I configured my binutils with --enable-targets=all, the linker
>*should* interpret the relocs based on the input file in which they
>appear?
>
Yes - but only if it can tell the difference between the input file
types. In particular if both the GNU toolchain and the Green Hills
toolchain are using the same machine number in the ELF header's
e_machine field then the linker will not be able to distinguish them.
(See elf_object_p() in bfd/elfcode.h). Also note that for a lot of
targets with related variants (eg ARM, MIPS etc) a supplementary
mechanism is used to distinguish between variants. This can be flags in
the e_flags of the header or a special section in the object file
containing information about how the file was compiled. The v850 port
uses the flags method. (See bfd/elf32-v850.c:v850_elf_object_p()). If
this function is unable to distinguish between Green Hills object files
and GNU object files then it will be unable to set the correct (internal
BFD) machine number and then the linker will not be able to determine
which kind of relocs it should be processing.
>Seriously, what sort of circumstances could cause ld to bail like this?
>I would have thought that relocs always operate on bits in the same
>object file as where the relocs are. Isn't that the whole point of BFD,
>to abstract object files as just BFDs which can then be linked together
>in an architecture-independent way?
>
>
Yes - but the *meaning* of a reloc is not encoded within the reloc
structure stored in the object file. All the linker has to go on is a
reloc number. (Plus the knowledge of the target architecture of the
object file). If the linker encounters a reloc number that it has not
been programmed to handle (for a given architecture) then all it can do
it complain. It has no way to derive the semantics of the reloc.
>So, because my new linker is configured to produce v800 *output*, all
>*input* object files have their relocs interpreted as v800 relocs as
>well! Now, what do I do about it? Hah! I do this:
>
>- --- binutils/bfd/elflink.h.borig Wed Jan 14 23:07:43 2004
>+++ binutils/bfd/elflink.h Wed May 5 19:39:49 2004
>@@ -4678,7 +4678,7 @@
> struct elf_link_hash_entry **sym_hashes;
>
> output_bfd = finfo->output_bfd;
>- - bed = get_elf_backend_data (output_bfd);
>+ bed = get_elf_backend_data (input_bfd);
> relocate_section = bed->elf_backend_relocate_section;
>
> /* If this is a dynamic object, we don't want to do anything here:
>
>And now the only "not SUPPORTED" relocs are the v800 ones for which I
>haven't yet added support. What did I break?
>
>
In theory, only the assumption that input_architecture ==
output_architecture. Well actually a lot more than that. For example
the decision about whether relocs should be copied into the output file
is specific to the output file architecture
(bed->elf_backend_emit_relocs). Or the routine to be used to emit the
relocated section (bed->elf_backend_write_section). It looks like
elf_link_input_bfd() needs some tidying up to remove assumptions about
input and output architectures.
Cheers
Nick
More information about the Binutils
mailing list