This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: R_X86_64_COPY bug
- From: Fredrick Prashanth John Berchmans <fredrickprashanth at gmail dot com>
- To: gcc-help at gcc dot gnu dot org
- Cc: Suresh Siddha <sbsiddha at gmail dot com>, binutils at sourceware dot org, hjl dot tools at gmail dot com, nasuku at yahoo dot com, Alexander Ivchenko <aivchenk at gmail dot com>
- Date: Sat, 6 Apr 2013 18:48:53 -0700
- Subject: Re: R_X86_64_COPY bug
- References: <CACwgvgW5SNsXL2vND_qhgqO7RRsHwKyk+N-q5sTakeC9vwV0BA at mail dot gmail dot com> <20130406071305 dot GD3208 at bubble dot grove dot modra dot org> <CALmL7E92MjbsXbou8T3w895G9ahtd1tvC2JwREwV9EzT4Px20Q at mail dot gmail dot com> <CACysShj5aH4pWZHjxj74-B7z8a8d_NTKUyEcN8DFJXxaCa5=6g at mail dot gmail dot com> <CACwgvgXgjfwK9+HNRwyJMO-uJWM+WU9idj5gdBxJWr538rQRWQ at mail dot gmail dot com>
Restating the problem and adding GCC developers.
A struct with zero length array is defined in a shared library as a global data.
A binary links with this shared library and accesses the struct.
Because of copy relocation semantics, the binary linking with that
library sees(correctly) only the portion of the struct without the
zero length array.
We understand that it is due to the wrong or apparent size calculation
of the struct by GCC and using copy relocation semantics to resolve this
shared symbol is causing this problem.
Is there any way to disable copy relocation of a data (especially
structs with zero length array)
defined in a shared libary that gets used by a binary by linking with it?
We have tried -Wl,-z,norelocs. It causes the binary to segfault.
Or, is there any way for GCC to calculate the correct size of a struct with
zero length array which has been defined as global data.
We saw this bug also on ARM with R_ARM_COPY.
-Fredrick
The following program demonstrates the phenomenon.
test_misc.h:
#ifndef __TEST_MISC_H__
#define __TEST_MISC_H__
struct test_array {
int array_len;
int array[];
};
void print_array(struct test_array *);
#endif
test_lib.c:
#include "test_misc.h"
#include <stdio.h>
struct test_array test_dynamic = {
6,
{1, 2, 3, 4, 5, 6},
};
void
print_array(struct test_array *a) {
int i;
for (i = 0; i<a->array_len; i++) {
printf("%d\n", a->array[i]);
}
}
test_misc.c:
#include "test_misc.h"
extern struct test_array test_dynamic;
int
main() {
print_array(&test_dynamic);
return 0;
}
Makefile:
all: test_misc.bin
test_misc.bin: test_misc.o libtest.so
cc test_misc.o libtest.so -o test_misc.bin
libtest.so: test_lib.o
cc -shared -Wl,-soname,libtest.so -o libtest.so test_lib.o
test_lib.o: test_lib.c
cc -fPIC -o test_lib.o -c test_lib.c
.PHONY: clean
clean:
rm -rf test_misc.bin
rm -rf libtest.so
rm -rf *.o
$ LD_LIBRARY_PATH=. ./test_misc.bin
0
0
0
0
0
0
On Sat, Apr 6, 2013 at 11:34 AM, Fredrick Prashanth John Berchmans
<fredrickprashanth@gmail.com> wrote:
> On Sat, Apr 6, 2013 at 1:49 AM, Alexander Ivchenko <aivchenk@gmail.com> wrote:
>> Have you tried '-z nocopyrelocs' option for linker which tries to
>> avoid COPY relocations?
>
> nocopyreloc gives segfault :(
>
> ./test_misc.bin: Symbol `test_dynamic' causes overflow in R_X86_64_32 relocation
> Segmentation fault (core dumped)
>
> -Fredrick
>
> And also, as far as I understand, you can make
>> your binary 'pie'
>>
>> 2013/4/6 Suresh Siddha <sbsiddha@gmail.com>:
>>> On Sat, Apr 6, 2013 at 12:13 AM, Alan Modra <amodra@gmail.com> wrote:
>>>> On Fri, Apr 05, 2013 at 09:29:09PM -0700, Fredrick Prashanth John Berchmans wrote:
>>>>> Dear binutils developers,
>>>>>
>>>>> We are seeing a issue with copy relocation semantics in ld.
>>>>>
>>>>> A struct with zero length array is defined in a shared library.
>>>>> Because of copy relocation semantics, any binary linking with that
>>>>> library sees those elements as zero initialized.
>>>>>
>>>>> We saw this bug also on ARM with R_ARM_COPY.
>>>>
>>>> This is not a bug in gas or ld. gcc is sizing the struct incorrectly.
>>>>
>>>> .globl test_dynamic
>>>> .data
>>>> .align 4
>>>> .type test_dynamic, @object
>>>> .size test_dynamic, 4 # <===========
>>>> test_dynamic:
>>>> .long 6
>>>> .long 1
>>>> .long 2
>>>> .long 3
>>>> .long 4
>>>> .long 5
>>>> .long 6
>>>
>>> Thanks for the quick response. Is there any way we can avoid copy
>>> relocations for these problematic types? We tried even giving the
>>> attribute of protected visibility. And it doesn't seem to help.
>>>
>>> -Suresh Siddha