[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug binutils/30719] New: Relocation offset of IMAGE_REL_AMD64_ADDR32NB
From: |
mateusz.karcz at interia dot eu |
Subject: |
[Bug binutils/30719] New: Relocation offset of IMAGE_REL_AMD64_ADDR32NB discarded when linking into elf64-x86-64 |
Date: |
Fri, 04 Aug 2023 11:48:43 +0000 |
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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Bug binutils/30719] New: Relocation offset of IMAGE_REL_AMD64_ADDR32NB discarded when linking into elf64-x86-64,
mateusz.karcz at interia dot eu <=