#184 ✓resolved
Peter Johnson

YASM-1.0 produces incorrect GOT offset in ELF output on Linux

Reported by Peter Johnson | June 25th, 2011 @ 07:51 PM

Originally posted on Trac by Derek Atkins derek@pgp.com
Original Trac Ticket

  Description

Using yasm 1.0.0.2319, building with: -f elf -Xgnu -rnasm -pnasm. I have code that reads (effectively):

extern _GLOBAL_OFFSET_TABLE_

section .text align=32
align 32
global fcn
 [ save registers ]
  call getgot
getgot:
  pop ebx
  add ebx, _GLOBAL_SYMBOL_TABLE_ + $$ - getgot wrt ..gotpc
...

When I use yasm 1.0.0.2319 and then disassemble the output file using objdump -d I see the following:

00000000 :
   [ save registers ]
    13:        e8 00 00 00 00         call  18 
    18:        5b                     pop   %ebx
    19:        81 c3 05 00 00 00      add   $0x5,%ebx
...

Unfortunately that %0x5 is incorrect! That should be $0X3, which is what version 0.7.2 produces. With this value of $0x5 the GOT computation is incorrect amd my program SEGVs. If I use 0.7.2 it works great, it outputs $0x3, and my program links and runs fine. I'll note that a C program compiled with -fPIC produces code that uses $0x3, so I'm fairly sure that $0x3 is the correct value to have here, not $0x5.

Trac Attachments

h3. Trac Comments
comment:1

              Changed 14 months ago by Derek Atkins


I just attached two files.  Both files are the "objdump -d" output from disassembling the elf32 compiled output from the same assembly source file using the same command arguments to yasm.  The only difference is the version of yasm used.  The 0.7.2 output works, the 1.0.0 output does not.  And you can see in the disassembly that the 0.7.2 shows the GLOBAL_OFFSET_TABLE whereas the 1.0.0 output does not.

Note that this is all on x86 32-bit.

comment:2

              Changed 14 months ago by hfinney@pgp.com


(I work with Derek, who reported the bug.)

Here is a way to demostrate the problem using the built-in tests:

cd modules/objfmts/elf/tests
yasm -f elf elfso.asm
gcc -shared -o libelf.so elfso.o
gcc -o elftest elftest.c libelf.so
./elftest

With yasm 0.8, this outputs:

Testing lrotate: should get 0x00400000, 0x00000001
lrotate(0x00040000, 4) = 0x00400000
lrotate(0x00040000, 14) = 0x00000001
This string should read `hello, world': `hello, world'
The integers here should be 1234, 1235 and 4321:
integer==1234, localint==1235, commvar=4321
These pointers should be equal: 0x804854c and 0x804854c
So should these: 0x8049a18 and 0x8049a18

With yasm 1.0, this outputs:

Testing lrotate: should get 0x00400000, 0x00000001
lrotate(0x00040000, 4) = 0x00400000
lrotate(0x00040000, 14) = 0x00000001
This string should read `hello, world': `hello, world'
The integers here should be 1234, 1235 and 4321:
Segmentation fault

comment:3

              Changed 14 months ago by peter@tortall.net


It was broken in [2206]; I'll look into the cause.

      comment:3

                  Changed 14 months ago by peter@tortall.net

      Owner
        set to peter@tortall.net
    
      Status
        changed from new to assigned

It was broken in [2206]; I'll look into the cause.

      Owner
        set to peter@tortall.net
    
      Status
        changed from new to assigned

comment:4

              Changed 14 months ago by peter


(In [2321]) Fix #202 .

Don't generate an additional offset for _GLOBAL_OFFSET_TABLE_ if a WRT was
specified (the NASM usage).  In GAS, _GLOBAL_OFFSET_TABLE_ doesn't have a WRT
but instead has special handling.

This isn't quite *exactly* the right fix; a better fix would be to recognize
the _GLOBAL_OFFSET_TABLE_ case in the GAS parser and adjust the value
appropriately there.  However, this fix seems to do the right thing in the
meantime for both GAS and NASM cases.

      comment:4

                  Changed 14 months ago by peter

      Status
        changed from assigned to closed
    
      Resolution
        set to fixed

(In [2321]) Fix #202 .

Don't generate an additional offset for _GLOBAL_OFFSET_TABLE_ if a WRT was
specified (the NASM usage).  In GAS, _GLOBAL_OFFSET_TABLE_ doesn't have a WRT
but instead has special handling.

This isn't quite *exactly* the right fix; a better fix would be to recognize
the _GLOBAL_OFFSET_TABLE_ case in the GAS parser and adjust the value
appropriately there.  However, this fix seems to do the right thing in the
meantime for both GAS and NASM cases.

      Status
        changed from assigned to closed
    
      Resolution
        set to fixed

Comments and changes to this ticket

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

The Yasm Modular Assembler Project

Shared Ticket Bins

People watching this ticket

Pages