Re: GOT error in gas
Hi Mikulas, I see but gas should at least write error and not generate incorrect code. In which case please could you create a bugzilla entry for this so that we can track this problem properly. I did. Mikulas Cheers Nick ___ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils
Re: GOT error in gas
Hi Hi Mikulas, __asm__ (".global number; number = 0x12345678"); extern void number; These two declarations are not compatible. The latter declares number as a data symbol, but the former defines it is an absolute symbol. I thought that .types do not care for linking, Andreas is not talking about .types. He is talking about the sections to which the symbol belongs. Writing "extern void number" declares "number" as a symbol that will live in the .data section(1). The address of "number" is not known until the linker has performed a final link (for static code) or the loader has initialised the executable (for PIC code). Writing "__asm__(".global number; number=0x12345678")" however declares "number" as a symbol with an absolute *address*. The symbol does not have a value, or rather its value is whatever happens to be in the memory location 0x12345678. This symbol does not live in a section, and its address does not change during linking or loading. I know --- but in the example I posted I am just taking its address (which should be 0x12345678), I am not taking value of that variable (that should segfault on access to 0x12345678). But taking address shouldn't segfault. I looked at gas code --- fixing it to stop evaluating constant symbols for @GOT expressions seems to be hard or impossible because expression evaluation function doesn't know that there is "@GOT" following. --- but there is another issue --- @GOT is completely ignored if expression is constant. Note that movl [EMAIL PROTECTED], %eax shouldn't put 123 to eax but an offset in GOT where 123 is stored. Gas should either write error or make symbol with absolute value 123 and output relocation against it. movl [EMAIL PROTECTED], %eax will correctly output internal symbol name ("L0\001") as relocation, so movl [EMAIL PROTECTED], %eax could do just the same trick, setting "L0\001" to absolute value --- static or dynamic linker will handle it correctly. Hence the two declarations are inconsistent and you get undefined behaviour. How otherwise should external C variables be placed at absolute locations? You could adapt the mechanism that you already have. You say that everything works if the __asm__ statement is in a separate compilation unit, so just split out all of your absolute C variables into one (or more) separate files and have a header file containing "extern void..." declarations for them. I see but gas should at least write error and not generate incorrect code. Mikulas Alternatively you could provide the addresses for these symbols via a linker script, rather than trying to define them in C. For example: % cat addr.t number = ABSOLUTE (0x12345678); % cat test.c #include extern void number; int main (void) { return printf ("%p\n", & number); } % gcc test.c -Wl,addr.t -fPIC % ./a.out 0x12345678 Cheers Nick (1) Or some similar section such as .common or .sdata. ___ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils
Re: GOT error in gas
Hi Mikulas, I see but gas should at least write error and not generate incorrect code. In which case please could you create a bugzilla entry for this so that we can track this problem properly. Cheers Nick ___ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils
Re: GOT error in gas
Hi Mikulas, __asm__ (".global number; number = 0x12345678"); extern void number; These two declarations are not compatible. The latter declares number as a data symbol, but the former defines it is an absolute symbol. I thought that .types do not care for linking, Andreas is not talking about .types. He is talking about the sections to which the symbol belongs. Writing "extern void number" declares "number" as a symbol that will live in the .data section(1). The address of "number" is not known until the linker has performed a final link (for static code) or the loader has initialised the executable (for PIC code). Writing "__asm__(".global number; number=0x12345678")" however declares "number" as a symbol with an absolute *address*. The symbol does not have a value, or rather its value is whatever happens to be in the memory location 0x12345678. This symbol does not live in a section, and its address does not change during linking or loading. Hence the two declarations are inconsistent and you get undefined behaviour. How otherwise should external C variables be placed at absolute locations? You could adapt the mechanism that you already have. You say that everything works if the __asm__ statement is in a separate compilation unit, so just split out all of your absolute C variables into one (or more) separate files and have a header file containing "extern void..." declarations for them. Alternatively you could provide the addresses for these symbols via a linker script, rather than trying to define them in C. For example: % cat addr.t number = ABSOLUTE (0x12345678); % cat test.c #include extern void number; int main (void) { return printf ("%p\n", & number); } % gcc test.c -Wl,addr.t -fPIC % ./a.out 0x12345678 Cheers Nick (1) Or some similar section such as .common or .sdata. ___ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils
Re: GOT error in gas
On Mon, 12 Feb 2007, Andreas Schwab wrote: Mikulas Patocka <[EMAIL PROTECTED]> writes: __asm__ (".global number; number = 0x12345678"); extern void number; These two declarations are not compatible. The latter declares number as a data symbol, but the former defines it is an absolute symbol. Thus what you get is undefined behaviour. Andreas. Hi I thought that .types do not care for linking, I never ran into problem with different .types on symbols. BTW. if you look at assembler, there are no .type directives regarding "number" at all. How otherwise should external C variables be placed at absolute locations? (I need variables and function on absolute locations quite often and I always used this method) Mikulas ___ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils
Re: GOT error in gas
Mikulas Patocka <[EMAIL PROTECTED]> writes: > __asm__ (".global number; number = 0x12345678"); > extern void number; These two declarations are not compatible. The latter declares number as a data symbol, but the former defines it is an absolute symbol. Thus what you get is undefined behaviour. Andreas. -- Andreas Schwab, SuSE Labs, [EMAIL PROTECTED] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ___ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils
GOT error in gas
Hi I found the following issue. This program: #include __asm__ (".global number; number = 0x12345678"); extern void number; int main() { printf("%p\n", &number); return 0; } works when compiled without -fPIC and segfaults when compiled with -fPIC. When the program is broken to two files (one file containing __asm__ line and the second file containing main), it works fine even with -fPIC --- even if I break it into two files and link them dynamically with each other, it works and prints correct number --- it just doesn't work when all program is contained in one file. It seems like an error in gas --- gas replaced [EMAIL PROTECTED] with constant 0x12345678 when number was constant --- it probably errorneously thought that [EMAIL PROTECTED] is equivalent to number for costant numbers. (tested on i386) Mikulas Output of gcc: .file "got.c" #APP .global number; number = 0x12345678 #NO_APP .section.rodata.str1.1,"aMS",@progbits,1 .LC0: .string "%p\n" .text .p2align 4,,15 .globl main .type main, @function main: pushl %ebp movl%esp, %ebp pushl %ebx subl$20, %esp andl$-16, %esp call__i686.get_pc_thunk.bx addl$_GLOBAL_OFFSET_TABLE_, %ebx movl[EMAIL PROTECTED](%ebx), %eax subl$16, %esp movl%eax, 4(%esp) leal[EMAIL PROTECTED](%ebx), %eax movl%eax, (%esp) call[EMAIL PROTECTED] movl-4(%ebp), %ebx xorl%eax, %eax leave ret .size main, .-main .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits .globl __i686.get_pc_thunk.bx .hidden __i686.get_pc_thunk.bx .type __i686.get_pc_thunk.bx, @function __i686.get_pc_thunk.bx: movl(%esp), %ebx ret .section.note.GNU-stack,"",@progbits .ident "GCC: (GNU) 3.4.6" objdump -d: : 0: 55 push %ebp 1: 89 e5 mov%esp,%ebp 3: 53 push %ebx 4: 83 ec 14sub$0x14,%esp 7: 83 e4 f0and$0xfff0,%esp a: e8 fc ff ff ff call b f: 81 c3 02 00 00 00 add$0x2,%ebx 15: 8b 83 78 56 34 12 mov0x12345678(%ebx),%eax !! This causes crash!!! 1b: 83 ec 10sub$0x10,%esp 1e: 89 44 24 04 mov%eax,0x4(%esp) 22: 8d 83 00 00 00 00 lea0x0(%ebx),%eax 28: 89 04 24mov%eax,(%esp) 2b: e8 fc ff ff ff call 2c 30: 8b 5d fcmov0xfffc(%ebp),%ebx 33: 31 c0 xor%eax,%eax 35: c9 leave 36: c3 ret Disassembly of section .gnu.linkonce.t.__i686.get_pc_thunk.bx: <__i686.get_pc_thunk.bx>: 0: 8b 1c 24mov(%esp),%ebx 3: c3 ret objdump -r: got.o: file format elf32-i386 RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 000b R_386_PC32__i686.get_pc_thunk.bx 0011 R_386_GOTPC _GLOBAL_OFFSET_TABLE_ 0024 R_386_GOTOFF .LC0 002c R_386_PLT32 printf ^ note that there is no R_386_GOT32 relocation for offset 0017, although there should be. ___ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils