Home Explore Blog CI



man-pages

42th chunk of `ld.man`
80dcf9978b9be728602023cdc302372473c886b406e114730000000100000fe1
 ’auto-import’ extension will cause the text section of the image file to be made writable. This does not conform to the PE‐COFF format specification published by Microsoft.

           Note - use of the ’auto-import’ extension will also cause read only data which would normally be placed into the .rdata section to be placed into the .data section instead.  This is  in  order  to  work  around  a
           problem with consts that is described here: http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html

           Using ’auto-import’ generally will ’just work’ ‐‐ but sometimes you may see this message:

           "variable ’<var>’ can’t be auto‐imported. Please read the documentation for ld’s "--enable-auto-import" for details."

           This  message  occurs  when  some  (sub)expression  accesses an address ultimately given by the sum of two constants (Win32 import tables only allow one).  Instances where this may occur include accesses to member
           fields of struct variables imported from a DLL, as well as using a constant index into an array variable imported from a DLL.  Any multiword variable (arrays, structs,  long  long,  etc)  may  trigger  this  error
           condition.  However, regardless of the exact data type of the offending exported variable, ld will always detect it, issue the warning, and exit.

           There are several ways to address this difficulty, regardless of the data type of the exported variable:

           One  way  is  to use --enable-runtime-pseudo-reloc switch. This leaves the task of adjusting references in your client code for runtime environment, so this method works only when runtime environment supports this
           feature.

           A second solution is to force one of the ’constants’ to be a variable ‐‐ that is, unknown and un‐optimizable at compile time.  For arrays, there are two possibilities: a) make the indexee (the array’s  address)  a
           variable, or b) make the ’constant’ index a variable.  Thus:

                   extern type extern_array[];
                   extern_array[1] -->
                      { volatile type *t=extern_array; t[1] }

           or

                   extern type extern_array[];
                   extern_array[1] -->
                      { volatile int t=1; extern_array[t] }

           For structs (and most other multiword data types) the only option is to make the struct itself (or the long long, or the ...) variable:

                   extern struct s extern_struct;
                   extern_struct.field -->
                      { volatile struct s *t=&extern_struct; t->field }

           or

                   extern long long extern_ll;
                   extern_ll -->
                     { volatile long long * local_ll=&extern_ll; *local_ll }

           A  third  method  of  dealing  with this difficulty is to abandon ’auto-import’ for the offending symbol and mark it with "__declspec(dllimport)".  However, in practice that requires using compile‐time #defines to
           indicate whether you are building a DLL, building client code that will link to the DLL, or merely building/linking to a static library.   In making the choice between the various methods of resolving the  ’direct
           address with constant offset’ problem, you should consider typical real‐world usage:

           Original:

                   --foo.h
                   extern int arr[];
                   --foo.c
                   #include "foo.h"
                   void main(int argc, char **argv){
                     printf("%d\n",arr[1]);
                   }

           Solution 1:

                   --foo.h
                   extern int arr[];
                   --foo.c
                   #include "foo.h"
                   void main(int argc, char **argv){
                     /* This workaround is for win32 and cygwin; do not "optimize" */
                     volatile int *parr = arr;
                     printf("%d\n",parr[1]);

Title: LD (GNU Linker) Auto-Import Caveats and Solutions
Summary
This section details potential issues with the auto-import feature of the LD linker, specifically regarding writable text sections, the movement of read-only data, and errors that arise when accessing DLL-imported variables with constant offsets. It presents several solutions, including using the `--enable-runtime-pseudo-reloc` switch, forcing constants to be variables using volatile pointers, and abandoning auto-import for specific symbols by using `__declspec(dllimport)`. Example code illustrates how to apply these solutions in practice.