bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/30359] Create Resource-Only DLL


From: pali at kernel dot org
Subject: [Bug ld/30359] Create Resource-Only DLL
Date: Tue, 25 Apr 2023 19:13:13 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=30359

--- Comment #6 from Pali Rohár <pali at kernel dot org> ---
(In reply to Nick Clifton from comment #5)
> (In reply to Pali Rohár from comment #4)
>  
> > > These markers are used by the execution startup code to help find the two
> > > tables.
> > 
> > I see... But in this case there is nothing in .text section, just those
> > markers. Does not linker script language support conditions to put markers
> > only when at least one of those input sections is non-empty?
> 
> Sadly, no.

I was thinking that it could be possible to define some linker variables before
and after those symbols to the current position and then do difference between
values of these variables. For example:

_BEGIN_OF_DATA_ = .
KEEP(...)
KEEP(...)
_END_OF_DATA_ = .
_LENGTH_OF_DATA_ = _END_OF_DATA_ - _BEGIN_OF_DATA_

And then somehow put 

LONG (-1); LONG (-1);

only if _LENGTH_OF_DATA_ is non-zero.

This is also not possible by linker script language? Because it looks like very
common thing...

> But of course it is possible to create a copy of the linker script that does
> not contain these directives and then use that when creating the dll.  I
> think that this could also solve the other problem...
> 
> > But still this --only-section does not remove .idata completelly. There is
> > still reference to (now removed) import table and objdump prints warning
> > about it. Visible also in readpe.
> 
> Except - when I tried to create a simple test to verify this I ran into a
> problem.  The dll linked OK with my test linker script:
> 
>   $ i686-w64-mingw32-ld -dll --subsystem windows -e 0 -s test-rsrc.o -o
> test-rsrc.dll -T test-rsrc.ld
> 
> and it only has the .rsrc section:
> 
>   $ i686-w64-mingw32-objdump -h test-rsrc.2.dll
> 
>   test-rsrc.dll:     file format pei-i386
> 
>   Sections:
>   Idx Name          Size      VMA       LMA       File off  Algn
>     0 .rsrc         000000b8  00000000  00000000  00000200  2**2
> 
> but, when I checked it with objdump, it complains about the .rsrc section
> being corrupt:
> 
>   $ i686-w64-mingw32-objdump -p test-rsrc.2.dll
> 
>   test-rsrc.2.dll:     file format pei-i386
>   [...]
>   The .rsrc Resource Directory section:
>   000  Type Table: Char: 0, Time: 00000000, Ver: 0/0, Num Names: 0, IDs: 1
>   010   Entry: ID: 0x000010, Value: 0x80000018
>   018    Name Table: Char: 0, Time: 00000000, Ver: 0/0, Num Names: 0, IDs: 1
>   028     Entry: ID: 0x000001, Value: 0x80000030
>   030      Language Table: Char: 0, Time: 00000000, Ver: 0/0, Num Names: 0,
> IDs: 1
>   040       Entry: ID: 0x000409, Value: 0x000048
>   048        Leaf: Addr: 0x000058, Size: 0x00005c, Codepage: 0
>   Corrupt .rsrc section detected!

That is really strange.

> I think that this might be due to missing padding at the end of the section,
> but I am not sure.  Given that you are a windows expert, perhaps you can
> find out more ?

I have looked at the output and file seems to be correct. It does not missing
any padding. I have replaced simple resource file by one with large icons and I
still can see this error in objdump. I have tried to use this icon-only-dll on
Windows and it loaded icons from this file without any issue.

So I have feeling that generated DLL file is valid and this is bug in the
binutils PE parser.

What is interesting on this DLL file is that it has .rsrc section located to
VMA address 0x0:

Entry 2 00000000 000000b8 Resource Directory [.rsrc]

I'm not sure if it is fully OK but if Windows do not see any problem with it
then it is acceptable.

And resource entry points to VMA address 0x000058 which is in the range
0x0-0xb8 of .rsrc:

048        Leaf: Addr: 0x000058, Size: 0x00005c, Codepage: 0

So this is also correctly generated.

I played a bit with binutils code and found out that zero VMA in peicode.h is
handled specially - as ignored. I'm feeling that this rather should have been
check if directory entry is available/valid. So should not it rather check
non-zero size?

I have done simple change

--- peicode.h   2023-04-25 21:01:05.005927648 +0200
+++ peicode.h   2023-04-25 21:01:30.558118254 +0200
@@ -223,15 +223,15 @@ coff_swap_scnhdr_in (bfd * abfd, void *
                         + (H_GET_16 (abfd, scnhdr_ext->s_nreloc) << 16));
   scnhdr_int->s_nreloc = 0;
 #else
   scnhdr_int->s_nreloc = H_GET_16 (abfd, scnhdr_ext->s_nreloc);
   scnhdr_int->s_nlnno = H_GET_16 (abfd, scnhdr_ext->s_nlnno);
 #endif

-  if (scnhdr_int->s_vaddr != 0)
+  if (scnhdr_int->s_size != 0)
     {
       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
       /* Do not cut upper 32-bits for 64-bit vma.  */
 #ifndef COFF_WITH_pex64
       scnhdr_int->s_vaddr &= 0xffffffff;
 #endif
     }

And with it, objdump that generated DLL accepted.

But I really do not know if the issue is that LD put .rsrc to VMA address 0x0
or that OBJDUMP does not correctly re-calculate address of sections with VMA
0x0.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]