Advise on long types in 64-bit binutils PE compiles.

Ian Lance Taylor iant@google.com
Thu Jun 19 16:20:00 GMT 2008


Jerker Bäck <jerker.back@telia.com> writes:

> This may seem like a trivial and off-topic question, but it puzzles me every
> time I try dive into binutils.
> How to treat the long type in binutils?
> The obvious answer is: A long type is a long type is a long type...
> But actually it's not that simple, at least not for me.

This is my opinion.

You may assume that long is at least 32 bits.  If you need to store a
target value which may be 64 bits, you must not use long; you should
use bfd_vma, bfd_signed_vma, symvalue, etc., and you should ensure
that target_size=64 appears in the entry for your target vector in
bfd/configure.in.

> Do binutils assume that a long type is capable of holding a pointer?

They shouldn't.  But I wouldn't be surprised if they do.  If you need
to treat a pointer as an integer for some reason, #include
"bfd_stdint.h" and use uintptr_t.

Note that of course you should never use a long to hold a target
address; for a target address you should always bfd_vma.

> When it comes to the PE header as described in the <ntimage.h> WDK header,
> the structures requires a 32bit long. Using the LP64 model here would never
> work as the structure sizes would be totally wrong. What about the
> corresponding structures in binutils? Do they also requires 32bit longs?
> I've tried to figure this out, but it's very difficult to tell as the
> structures may never be used as is.

BFD never uses host types such as long when describing the external
view of a structure in an object file.  It uses char arrays of the
proper size.  See include/coff/pe.h.  These values are then swapped in
and out of internal arrays.  The internal arrays may use host types
such as long; as mentioned above long may only be used if the value is
known to be 32 bits or less.

> Examples of binutils PE structures with wrong sizes if LP64 is used:
> internal_extra_pe_aouthdr, internal_filehdr

As noted by the name, those are internal structures.  They do not
reflect the layout of the structure in the file.  Those are expressed
by external_PEI_DOS_hdr and external_PEI_IMAGE_hdr.

> Examples of ambiguous use of longs in binutils:
>
> long bfd_get_mtime (bfd *abfd); returns a long converted time_t type.

This is a bug, it should be time_t.

> unsigned long bfd_calc_gnu_debuglink_crc32 (
>     unsigned long crc, const unsigned char *buf, bfd_size_type len);

This seems fine, since we can assume that long is 32 bits.  The code
looks correct to me even if long is a 64-bit type.

Ian



More information about the Binutils mailing list