Add support for IMPORT_CONST in ILF (MSVC style) import libraries

Message ID 20250111190436.4012103-1-martin@martin.st
State New
Headers
Series Add support for IMPORT_CONST in ILF (MSVC style) import libraries |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Martin Storsjö Jan. 11, 2025, 7:04 p.m. UTC
  This is a very strange and obsolete kind of import type; it is
used for imported data just like IMPORT_DATA - but with an extra
odd caveat.

The behaviour is explained at [1]; generating such import libraries
with current MSVC tools produces "warning LNK4087: CONSTANT keyword is
obsolete; use DATA".

While obsolete, some import libraries within the Microsoft WDK (Windows
Driver Kit) do contain such symbols, which currently are ignored by
binutils and produce warnings about "file format not recognized".

For IMPORT_CONST for a DLL exported symbol "foo", we should provide
the import library symbols "__imp_foo" and "foo". For IMPORT_DATA, we
only provide "__imp_foo", and for IMPORT_CODE, "foo" points at a thunk.
The odd/surprising thing for IMPORT_CONST is that the "foo" symbol also
points at the same thing as "__imp_foo", i.e. directly at the IAT
entry.

[1] https://learn.microsoft.com/en-us/cpp/build/importing-using-def-files

Signed-off-by: Martin Storsjö <martin@martin.st>
---
 bfd/peicode.h | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)
  

Comments

Alan Modra Jan. 12, 2025, 10:06 a.m. UTC | #1
On Sat, Jan 11, 2025 at 09:04:24PM +0200, Martin Storsjö wrote:
> This is a very strange and obsolete kind of import type; it is
> used for imported data just like IMPORT_DATA - but with an extra
> odd caveat.
> 
> The behaviour is explained at [1]; generating such import libraries
> with current MSVC tools produces "warning LNK4087: CONSTANT keyword is
> obsolete; use DATA".
> 
> While obsolete, some import libraries within the Microsoft WDK (Windows
> Driver Kit) do contain such symbols, which currently are ignored by
> binutils and produce warnings about "file format not recognized".
> 
> For IMPORT_CONST for a DLL exported symbol "foo", we should provide
> the import library symbols "__imp_foo" and "foo". For IMPORT_DATA, we
> only provide "__imp_foo", and for IMPORT_CODE, "foo" points at a thunk.
> The odd/surprising thing for IMPORT_CONST is that the "foo" symbol also
> points at the same thing as "__imp_foo", i.e. directly at the IAT
> entry.
> 
> [1] https://learn.microsoft.com/en-us/cpp/build/importing-using-def-files
> 
> Signed-off-by: Martin Storsjö <martin@martin.st>
> ---
>  bfd/peicode.h | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/bfd/peicode.h b/bfd/peicode.h
> index c48953dfee6..ad4f1963b9c 100644
> --- a/bfd/peicode.h
> +++ b/bfd/peicode.h
> @@ -815,14 +815,8 @@ pe_ILF_build_a_bfd (bfd *	    abfd,
>      {
>      case IMPORT_CODE:
>      case IMPORT_DATA:
> -      break;
> -
>      case IMPORT_CONST:
> -      /* XXX code yet to be written.  */
> -      /* xgettext:c-format */
> -      _bfd_error_handler (_("%pB: unhandled import type; %x"),
> -			  abfd, import_type);
> -      return false;
> +      break;
>  
>      default:
>        /* xgettext:c-format */
> @@ -1082,6 +1076,7 @@ pe_ILF_build_a_bfd (bfd *	    abfd,
>        break;
>  
>      case IMPORT_DATA:
> +    case IMPORT_CONST:
>        break;
>  
>      default:
> @@ -1102,6 +1097,10 @@ pe_ILF_build_a_bfd (bfd *	    abfd,
>        /* Nothing to do here.  */
>        break;
>  
> +    case IMPORT_CONST:
> +      pe_ILF_make_a_symbol (&vars, "", symbol_name, id5, 0);
> +      break;
> +
>      default:
>        /* XXX code not yet written.  */
>        abort ();
> -- 
> 2.43.0

OK.
  
Martin Storsjö Jan. 15, 2025, 9:54 p.m. UTC | #2
On Sun, 12 Jan 2025, Alan Modra wrote:

> On Sat, Jan 11, 2025 at 09:04:24PM +0200, Martin Storsjö wrote:
>> This is a very strange and obsolete kind of import type; it is
>> used for imported data just like IMPORT_DATA - but with an extra
>> odd caveat.
>>
>> The behaviour is explained at [1]; generating such import libraries
>> with current MSVC tools produces "warning LNK4087: CONSTANT keyword is
>> obsolete; use DATA".
>>
>> While obsolete, some import libraries within the Microsoft WDK (Windows
>> Driver Kit) do contain such symbols, which currently are ignored by
>> binutils and produce warnings about "file format not recognized".
>>
>> For IMPORT_CONST for a DLL exported symbol "foo", we should provide
>> the import library symbols "__imp_foo" and "foo". For IMPORT_DATA, we
>> only provide "__imp_foo", and for IMPORT_CODE, "foo" points at a thunk.
>> The odd/surprising thing for IMPORT_CONST is that the "foo" symbol also
>> points at the same thing as "__imp_foo", i.e. directly at the IAT
>> entry.
>>
>> [1] https://learn.microsoft.com/en-us/cpp/build/importing-using-def-files
>>
>> Signed-off-by: Martin Storsjö <martin@martin.st>
>> ---
>>  bfd/peicode.h | 13 ++++++-------
>>  1 file changed, 6 insertions(+), 7 deletions(-)
>
> OK.

Thanks, pushed!

// Martin
  

Patch

diff --git a/bfd/peicode.h b/bfd/peicode.h
index c48953dfee6..ad4f1963b9c 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -815,14 +815,8 @@  pe_ILF_build_a_bfd (bfd *	    abfd,
     {
     case IMPORT_CODE:
     case IMPORT_DATA:
-      break;
-
     case IMPORT_CONST:
-      /* XXX code yet to be written.  */
-      /* xgettext:c-format */
-      _bfd_error_handler (_("%pB: unhandled import type; %x"),
-			  abfd, import_type);
-      return false;
+      break;
 
     default:
       /* xgettext:c-format */
@@ -1082,6 +1076,7 @@  pe_ILF_build_a_bfd (bfd *	    abfd,
       break;
 
     case IMPORT_DATA:
+    case IMPORT_CONST:
       break;
 
     default:
@@ -1102,6 +1097,10 @@  pe_ILF_build_a_bfd (bfd *	    abfd,
       /* Nothing to do here.  */
       break;
 
+    case IMPORT_CONST:
+      pe_ILF_make_a_symbol (&vars, "", symbol_name, id5, 0);
+      break;
+
     default:
       /* XXX code not yet written.  */
       abort ();