https://sourceware.org/bugzilla/show_bug.cgi?id=30719
Bug ID: 30719 Summary: Relocation offset of IMAGE_REL_AMD64_ADDR32NB discarded when linking into elf64-x86-64 Product: binutils Version: 2.38 Status: UNCONFIRMED Severity: normal Priority: P2 Component: binutils Assignee: unassigned at sourceware dot org Reporter: mateusz.karcz at interia dot eu Target Milestone: --- Created attachment 15038 --> https://sourceware.org/bugzilla/attachment.cgi?id=15038&action=edit Build script generating five variants of the executable Overview: While trying to embed Windows Resources inside Linux executable (I've been doing that with tkchia's IA-16 GCC before) I've noticed that when targetting x86-64, relocations within the .rsrc section are replaced with its base address instead of base+offset. I am trying to understand if it's a bug in binutils, or just it so happen that for i386 it works 'by accident' and my use scenario is invalid. Steps to Reproduce: 1) Prepare a simple RC file: ---------- resource.rc ---------- // entry 6/1/1031 STRINGTABLE LANGUAGE 1031, 1 { 0, "Hallo" } // entry 6/1/1033 STRINGTABLE LANGUAGE 1033, 1 { 0, "Hello" } ---------- 2) Call windres (both i686-w64-mingw32 and x86_64-w64-mingw32 will result in the same content of .rsrc section) with .obj (COFF) as output format. The .rsrc section will have the following layout: 0x00 IMAGE_RESOURCE_DIRECTORY for root 0x10 IMAGE_RESOURCE_DIRECTORY_ENTRY (id 6, off 0x18) 0x18 IMAGE_RESOURCE_DIRECTORY for 6 0x28 IMAGE_RESOURCE_DIRECTORY_ENTRY (id 1, off 0x30) 0x30 IMAGE_RESOURCE_DIRECTORY for 6/1 0x40 IMAGE_RESOURCE_DIRECTORY_ENTRY (id 1031, off 0x50) 0x48 IMAGE_RESOURCE_DIRECTORY_ENTRY (id 1033, off 0x60) 0x50 IMAGE_RESOURCE_DATA_ENTRY for 6/1/1031 (at .rsrc+0x70) 0x60 IMAGE_RESOURCE_DATA_ENTRY for 6/1/1033 (at .rsrc+0xA0) 0x70 "Hallo" 0xA0 "Hello" 3) Link it with code into a full executable, in one of two ways: a. Use COFF as direct input of the linker (needs .rsrc section attribute in C source, reflected by NOOBJCOPY macro definition in my example). b. Use objcopy to convert COFF into ELF, while renaming .rsrc to .rodata.rsrc and adding a new symbol at its start. In both cases, I'm using -no-pie switch. I've prepared a build script (ATTACHMENT) which generates executables in five following variants: 1) 32-bit .obj -> 32-bit .o -> 32-bit executable 2) 64-bit .obj -> 32-bit .o -> 32-bit executable 3) 64-bit .obj -> 64-bit .o -> 64-bit executable 4) 32-bit .obj -> 32-bit executable 5) 64-bit .obj -> 64-bit executable Actual Result: In all 32-bit variants (1, 3, and 4) IMAGE_RESOURCE_DATA_ENTRY .OffsetToData fields point to "Hallo" (.rsrc+0x70) and "Hello" (.rsrc+0xA0) when loaded to memory, eg.: rsrc: 0x804a040 6/1/1031 offset: 0x804a0b0 6/1/1033 offset: 0x804a0e0 In variant 3 all IMAGE_RESOURCE_DATA_ENTRY.OffsetToData fields point to the start of the .rsrc section (offset is discarded): rsrc: 0x40203c 6/1/1031 offset: 0x40203c 6/1/1033 offset: 0x40203c In variant 5 IMAGE_RESOURCE_DATA_ENTRY.OffsetToData fields seem to lack the image base address in memory (but offset is preserved): rsrc: 0x404030 6/1/1031 offset: 0x40a0 6/1/1033 offset: 0x40d0 For examples, I was using the following C program: ---------- main.c ---------- #include <stdint.h> #include <stdio.h> #ifndef NOOBJCOPY extern #endif char rsrc[] #ifdef NOOBJCOPY __attribute__((section(".rsrc"))) = {} #endif ; #pragma pack(push, 1) typedef struct { uint32_t OffsetToData; uint32_t DoNotCare[3]; } IMAGE_RESOURCE_DATA_ENTRY; #pragma pack(pop) int main(void) { printf("rsrc: %p\n", rsrc); IMAGE_RESOURCE_DATA_ENTRY *entries = (IMAGE_RESOURCE_DATA_ENTRY *)(rsrc + 0x50); printf("6/1/1031 offset: %#lx\n", (long)entries[0].OffsetToData); printf("6/1/1033 offset: %#lx\n", (long)entries[1].OffsetToData); return 0; } ---------- Expected Result: I would expect 64-bit variants to provide the same result as 32-bit ones, IMAGE_RESOURCE_DATA_ENTRY.OffsetToData fields pointing to .rsrc+0x70 and .rsrc+0xA0 when loaded to memory. Toolset Builds and Platforms: binutils 2.38-4ubuntu2.3 binutils-mingw-w64-i686 2.38-3ubuntu1+9build1 binutils-mingw-w64-x86-64 2.38-3ubuntu1+9build1 on x86_64 Ubuntu 22.04 LTS (Linux 5.15) -- You are receiving this mail because: You are on the CC list for the bug.