linux-assembly.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* writing a jump table
@ 2011-03-16  0:10 Nicolas Bock
  2011-03-16  0:25 ` Brian Raiter
  0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Bock @ 2011-03-16  0:10 UTC (permalink / raw)
  To: linux-assembly

[-- Attachment #1: Type: text/plain, Size: 1620 bytes --]

Hello list,

I am trying to write a jump table, but unfortunately with limited
success. When I compile the code and disassemble it, the offset of
"table" is 0, which I guess means that something didn't work out. Any
help would be gratefully appreciated.

The assembly code, jump_table.S:

  .text
  .global jump_table
  .type jump_table, @function

jump_table:
  push %rax

  mov $0x02, %rax # Move index into rax; 2 is supposed to end up at
label_02.
  jmp *table(, %rax, 4) # Jump into the table.

  .align 8
table:
  .long label_00
  .long label_01
  .long label_02

label_00:
  nop

label_01:
  nop

label_02:
  nop

done:
  pop %rax
  ret

  .size jump_table, .-jump_table


compiled with: gcc -c -g -o jump_table.o jump_table.S

disassembled code:

(gdb) disassemble jump_table
Dump of assembler code for function jump_table:
   0x0000000000000000 <+0>:     push   %rax
   0x0000000000000001 <+1>:     mov    $0x2,%rax
   0x0000000000000008 <+8>:     jmpq   *0x0(,%rax,4)
   0x000000000000000f <+15>:    nop
   0x0000000000000010 <+16>:    add    %al,(%rax)
   0x0000000000000012 <+18>:    add    %al,(%rax)
   0x0000000000000014 <+20>:    add    %al,(%rax)
   0x0000000000000016 <+22>:    add    %al,(%rax)
   0x0000000000000018 <+24>:    add    %al,(%rax)
   0x000000000000001a <+26>:    add    %al,(%rax)
   0x000000000000001c <+0>:     nop
   0x000000000000001d <+0>:     nop
   0x000000000000001e <+0>:     nop
   0x000000000000001f <+0>:     pop    %rax
   0x0000000000000020 <+1>:     retq
End of assembler dump.



Thanks already, nick


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: writing a jump table
  2011-03-16  0:10 writing a jump table Nicolas Bock
@ 2011-03-16  0:25 ` Brian Raiter
  2011-03-16 14:13   ` Nicolas Bock
                     ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Brian Raiter @ 2011-03-16  0:25 UTC (permalink / raw)
  To: linux-assembly

> I am trying to write a jump table, but unfortunately with limited
> success. When I compile the code and disassemble it, the offset of
> "table" is 0, which I guess means that something didn't work out.

Actually, table appears immediately following your indirect jump
instruction, so I would assume that the offset would be zero. Did you
actually try this code to verify that it doesn't do what you expect?

b

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: writing a jump table
  2011-03-16  0:25 ` Brian Raiter
@ 2011-03-16 14:13   ` Nicolas Bock
  2011-03-16 14:26     ` Frank Kotler
  2011-03-16 16:57   ` Nicolas Bock
  2011-03-17  2:12   ` Nicolas Bock
  2 siblings, 1 reply; 10+ messages in thread
From: Nicolas Bock @ 2011-03-16 14:13 UTC (permalink / raw)
  To: Brian Raiter; +Cc: linux-assembly

[-- Attachment #1: Type: text/plain, Size: 772 bytes --]

Hi Brian,

yes, I compiled it and when I run the code it segfaults.

nick


On 03/15/11 18:25, Brian Raiter wrote:
>> I am trying to write a jump table, but unfortunately with limited
>> success. When I compile the code and disassemble it, the offset of
>> "table" is 0, which I guess means that something didn't work out.
> 
> Actually, table appears immediately following your indirect jump
> instruction, so I would assume that the offset would be zero. Did you
> actually try this code to verify that it doesn't do what you expect?
> 
> b
> --
> To unsubscribe from this list: send the line "unsubscribe linux-assembly" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: writing a jump table
  2011-03-16 14:13   ` Nicolas Bock
@ 2011-03-16 14:26     ` Frank Kotler
  2011-03-16 16:48       ` Nicolas Bock
  0 siblings, 1 reply; 10+ messages in thread
From: Frank Kotler @ 2011-03-16 14:26 UTC (permalink / raw)
  To: Nicolas Bock; +Cc: linux-assembly

Nicolas Bock wrote:
> Hi Brian,
> 
> yes, I compiled it and when I run the code it segfaults.

Don't you need 64-bit addresses in your jump-table for 64-bit code?

Best,
Frank



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: writing a jump table
  2011-03-16 14:26     ` Frank Kotler
@ 2011-03-16 16:48       ` Nicolas Bock
  0 siblings, 0 replies; 10+ messages in thread
From: Nicolas Bock @ 2011-03-16 16:48 UTC (permalink / raw)
  To: Frank Kotler; +Cc: linux-assembly

[-- Attachment #1: Type: text/plain, Size: 408 bytes --]

Hi frank

Honestly I don't know. I don't have a lot of assembly experience and
this is all pretty new to me.

nick


On Wednesday, March 16, 2011, Frank Kotler <fbkotler@zytor.com> wrote:
> Nicolas Bock wrote:
>
> Hi Brian,
>
> yes, I compiled it and when I run the code it segfaults.
>
>
> Don't you need 64-bit addresses in your jump-table for 64-bit code?
>
> Best,
> Frank
>
>
>


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: writing a jump table
  2011-03-16  0:25 ` Brian Raiter
  2011-03-16 14:13   ` Nicolas Bock
@ 2011-03-16 16:57   ` Nicolas Bock
  2011-03-17  2:12   ` Nicolas Bock
  2 siblings, 0 replies; 10+ messages in thread
From: Nicolas Bock @ 2011-03-16 16:57 UTC (permalink / raw)
  To: Brian Raiter; +Cc: linux-assembly

[-- Attachment #1: Type: text/plain, Size: 1954 bytes --]

Using a larger switch statement in C, I looked at the code that gcc
produces and changed a few things in my assembly function. It now looks
like below. This function works now, it actually jumps to label_02. When
I try to put that function into a project that uses libtool to build a
dynamic library however, I get the following linking error:

/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/../../../../x86_64-pc-linux-gnu/bin/ld:
./.libs/libspamm_kernel.a(jump_table.o): relocation R_X86_64_32S against
`.rodata' can not be used when making a shared object; recompile with -fPIC
./.libs/libspamm_kernel.a(jump_table.o): could not read symbols: Bad value

What does this error mean?

Thanks,

nick





jump_table.S:

  .text
  .global jump_table
  .type jump_table, @function

jump_table:
  # Push stack pointer so we can make room for local storage.
  push %rax

  mov $0x02, %rax # Move index into rax; 2 is supposed to end up at
label_02.
  jmp *table(, %rax, 8) # Jump into the table.

  .section .rodata
  .align 8
table:
  .quad label_00
  .quad label_01
  .quad label_02

  .text
label_00:
  jmp done

label_01:
  jmp done

label_02:
  jmp done

done:
  pop %rax
  ret

  .size jump_table, .-jump_table


On 03/15/11 18:25, Brian Raiter wrote:
>> I am trying to write a jump table, but unfortunately with limited
>> success. When I compile the code and disassemble it, the offset of
>> "table" is 0, which I guess means that something didn't work out.
> 
> Actually, table appears immediately following your indirect jump
> instruction, so I would assume that the offset would be zero. Did you
> actually try this code to verify that it doesn't do what you expect?
> 
> b
> --
> To unsubscribe from this list: send the line "unsubscribe linux-assembly" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: writing a jump table
  2011-03-16  0:25 ` Brian Raiter
  2011-03-16 14:13   ` Nicolas Bock
  2011-03-16 16:57   ` Nicolas Bock
@ 2011-03-17  2:12   ` Nicolas Bock
  2011-03-17  2:23     ` Brian Raiter
  2 siblings, 1 reply; 10+ messages in thread
From: Nicolas Bock @ 2011-03-17  2:12 UTC (permalink / raw)
  To: Brian Raiter; +Cc: linux-assembly

[-- Attachment #1: Type: text/plain, Size: 1642 bytes --]

I think I figured it out now. I used gcc to compile PIC for the C switch
statement and checked what it does. I don't fully understand it to be
honest, but it seems to do the job also for non PIC code. For posterity,
here is the code:

  .text
  .global jump_table
  .type jump_table, @function

jump_table:
  # Push stack pointer so we can make room for local storage.
  push %rax

  mov $0x02, %rax # Move index into rax; 2 is supposed to end up at
label_02.

  lea 0(,%rax, 4), %rdx
  lea table(%rip), %rax
  mov (%rdx, %rax), %edx
  movslq %edx, %rdx
  lea table(%rip), %rax
  lea (%rdx, %rax), %rax
  jmp *%rax

  .section .rodata
  .align 4
table:
  .long label_00-table
  .long label_01-table
  .long label_02-table
  .long label_03-table

  .text
label_00:
  jmp done

label_01:
  jmp done

label_02:
  jmp done

label_03:
  jmp done

done:
  pop %rax
  ret

  .size jump_table, .-jump_table


On 03/15/11 18:25, Brian Raiter wrote:
>> I am trying to write a jump table, but unfortunately with limited
>> success. When I compile the code and disassemble it, the offset of
>> "table" is 0, which I guess means that something didn't work out.
> 
> Actually, table appears immediately following your indirect jump
> instruction, so I would assume that the offset would be zero. Did you
> actually try this code to verify that it doesn't do what you expect?
> 
> b
> --
> To unsubscribe from this list: send the line "unsubscribe linux-assembly" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: writing a jump table
  2011-03-17  2:12   ` Nicolas Bock
@ 2011-03-17  2:23     ` Brian Raiter
  2011-03-17  2:26       ` Nicolas Bock
  0 siblings, 1 reply; 10+ messages in thread
From: Brian Raiter @ 2011-03-17  2:23 UTC (permalink / raw)
  To: Nicolas Bock; +Cc: linux-assembly

> I think I figured it out now. I used gcc to compile PIC for the C
> switch statement and checked what it does. I don't fully understand
> it to be honest, but it seems to do the job also for non PIC code.

Of course -- PIC code just means that the code doesn't assume it knows
where it's located in memory, which for a shared-object library is a
necessary thing. It does mean the code has to jump through a few more
hoops, which is why the compiler doesn't make it the default.

b

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: writing a jump table
  2011-03-17  2:23     ` Brian Raiter
@ 2011-03-17  2:26       ` Nicolas Bock
       [not found]         ` <AANLkTinzgyzwN3Zj7bmqw7tDF0QKDSJiJj7MQt7vFx-h@mail.gmail.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Bock @ 2011-03-17  2:26 UTC (permalink / raw)
  To: Brian Raiter; +Cc: linux-assembly

[-- Attachment #1: Type: text/plain, Size: 940 bytes --]

But how does non-PIC code where it is in memory? When I disassemble the
non-PIC version, the address space starts at 0 which must mean that the
linker relocates the code. Also, labels represent offsets if I
understand this correctly, which is also a relative address and not an
absolute. That's what I meant with that I don't fully understand why
these extra hoops are necessary.

On 03/16/11 20:23, Brian Raiter wrote:
>> I think I figured it out now. I used gcc to compile PIC for the C
>> switch statement and checked what it does. I don't fully understand
>> it to be honest, but it seems to do the job also for non PIC code.
> 
> Of course -- PIC code just means that the code doesn't assume it knows
> where it's located in memory, which for a shared-object library is a
> necessary thing. It does mean the code has to jump through a few more
> hoops, which is why the compiler doesn't make it the default.
> 
> b


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Fwd: writing a jump table
       [not found]         ` <AANLkTinzgyzwN3Zj7bmqw7tDF0QKDSJiJj7MQt7vFx-h@mail.gmail.com>
@ 2011-03-17 10:11           ` Hendrik Visage
  0 siblings, 0 replies; 10+ messages in thread
From: Hendrik Visage @ 2011-03-17 10:11 UTC (permalink / raw)
  To: linux assembly

---------- Forwarded message ----------
From: Hendrik Visage <hvjunk@gmail.com>
Date: Thu, Mar 17, 2011 at 9:49 AM
Subject: Re: writing a jump table
To: Nicolas Bock <nicolasbock@gmail.com>
Cc: Brian Raiter <breadbox@muppetlabs.com>, linux-assembly@vger.kernel.org




On Thu, Mar 17, 2011 at 4:26 AM, Nicolas Bock <nicolasbock@gmail.com> wrote:
>
> But how does non-PIC code where it is in memory? When I disassemble the
> non-PIC version, the address space starts at 0 which must mean that the
> linker relocates the code.

non-PIC code would typically start at the start of the address space
for that platform.

>
> Also, labels represent offsets if I
> understand this correctly, which is also a relative address and not an
> absolute. That's what I meant with that I don't fully understand why
> these extra hoops are necessary.

PIC code can be put anywhere in address space. So let's assume a few things:

START_ADDR: The starting point of the platform's address space for
code/data/etc.

LABEL_OFFSET: The offset for that LABEL inside the code/data relative
from 0 for the code/data when just normally assembled.

Now in the non-PIC case, it is "easy" to find the actual place in
address space: START_ADDR + LABEL_OFFSET, and this could be hard coded
during the static linking phase.

But in the PIC case, we also have:

PIC_OFFSET_CODE_SEG_A: The offset from START_ADDR where the RUNTIME
linker put the code for CODE_SEG_A. This is unknown till the code
actually gets executed. Okay, in *nost* cases you would find it is the
same place everytime, for a given piece of compiled code, but never
bargain on that, especially when you have hardened kernels that would
randomly assign address space offsets to frustrate crackers.

Now instead of a fixed calculated START_ADDR+PIC_OFFSET_CODE_SEG_A +
LABEL_OFFSET or compile/link time, we now have to calculate that value
at RUNTIME, as PIC_OFFSET_CODE_SEG_A could be different for each
execution.

That is a layman's description as I understand it, and I definitely
miss some other implementation details, but that is the gist of why
you need those extra hoops for PIC code.



>
> On 03/16/11 20:23, Brian Raiter wrote:
> >> I think I figured it out now. I used gcc to compile PIC for the C
> >> switch statement and checked what it does. I don't fully understand
> >> it to be honest, but it seems to do the job also for non PIC code.
> >
> > Of course -- PIC code just means that the code doesn't assume it knows
> > where it's located in memory, which for a shared-object library is a
> > necessary thing. It does mean the code has to jump through a few more
> > hoops, which is why the compiler doesn't make it the default.
> >
> > b
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-03-17 10:11 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-16  0:10 writing a jump table Nicolas Bock
2011-03-16  0:25 ` Brian Raiter
2011-03-16 14:13   ` Nicolas Bock
2011-03-16 14:26     ` Frank Kotler
2011-03-16 16:48       ` Nicolas Bock
2011-03-16 16:57   ` Nicolas Bock
2011-03-17  2:12   ` Nicolas Bock
2011-03-17  2:23     ` Brian Raiter
2011-03-17  2:26       ` Nicolas Bock
     [not found]         ` <AANLkTinzgyzwN3Zj7bmqw7tDF0QKDSJiJj7MQt7vFx-h@mail.gmail.com>
2011-03-17 10:11           ` Fwd: " Hendrik Visage

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).