Re: GOT error in gas

2007-02-19 Thread Mikulas Patocka

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

2007-02-16 Thread Mikulas Patocka

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

2007-02-16 Thread Nick Clifton

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

2007-02-15 Thread Nick Clifton

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

2007-02-12 Thread Mikulas Patocka

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

2007-02-12 Thread Andreas Schwab
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

2007-02-12 Thread Mikulas Patocka

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