Wrong ELF Class - requires consistent compiler flags

Rod Evans — Wednesday April 26, 2006

Surfing with the Linker-Aliens

Every now and then, someone encounters the following error.

  % cc -G -o foo.so foo.o -lbar
  ld: fatal: file foo.o: wrong ELF class: ELFCLASS64
  ld: fatal: File processing errors. No output written to foo

Or perhaps the similar error.

  % cc -G -xarch=amd64 -o foo.so foo.o -lbar
  ld: fatal: file foo.o: wrong ELF class: ELFCLASS32
  ld: fatal: File processing errors. No output written to foo

This issue stems from the compiler flags that have been used to compile the relocatable object foo.o, and the compiler flags that are finally used to invoke the link-edit of this object.

The man page for ld(1) hints at the issue.

  No command-line option is required to distinguish 32-bit
  objects or 64-bit objects. The link-editor uses the ELF
  class of the first relocatable object file that is found on
  the command line, to govern the mode in which to operate.

When the compiler drivers are used to generate an executable or shared object, the driver typically supplies a couple of their own files to the link-edit. One or more of these additional files will be read by the link-editor before the file foo.o. Expanding the compiler processing might reveal:

  % cc -# -G -o foo.so foo.o
  ...
  ld crti.o values-xa.o -o foo.so -G foo.o ... crtn.o

Here, the first input file read by the link-editor is crti.o (this is typically a full path to a compiler specific subdirectory). Expanding a 64-bit link-edit request might reveal:

  % cc -# -xarch=64 -G -o foo.so foo.o
  ...
  ld amd64/crti.o amd64/values-xa.o -o foo.so -G foo.o ... amd64/crtn.o

Armed with this information it should be easy to see how the ELFCLASS error messages can be produced. If for example, you wish to create a 64-bit shared object from one or more relocatable objects, you might first create the 64-bit relocatable object like:

  % cc -c -xarch=amd64 foo.c
  % file foo.o
  foo.o:       ELF 64-bit LSB relocatable AMD64 Version 1

But, if you fail to inform the compiler driver that this object should be linked into a 64-bit object, you'll produce the ELFCLASS64 error message. The first file read by the link-editor will be the 32-bit version of crti.o. This puts ld() into 32-bit mode, and hence when foo.o is read it will be rejected as being incompatible with the mode of the link-edit requested.

Similarly, a 32-bit relocatable object:

  % cc -c foo.c

that is handed to a 64-bit link-edit will produce the ELFCLASS32 error message.

Make sure that the architecture flag used to build a relocatable object is also passed to the compiler driver phase of linking the relocatable object into a final executable or shared object.

Surfing with the Linker-Aliens

Published Elsewhere

https://blogs.sun.com/rie/entry/wrong_elf_class_requires_consistent/
https://blogs.oracle.com/rie/entry/wrong_elf_class_requires_consistent/
https://blogs.oracle.com/rie/wrong-elf-class-requires-consistent-compiler-flags/

Surfing with the Linker-Aliens

[21] C++ symbol visibility issues
Blog Index (rie)
[23] Changing Paths with crle