avr-objdump and jump tables

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi folks,

I spent (far, far too much) time trying to isolate what I reluctantly suspected was a bug in avr-objdump or avr-gcc. The reluctance was warranted, because of course I was wrong.

I noticed there were extra RJMP instructions appended to the end of the interrupt vector table when looking at the output of avr-objdump -S. The extra RJMP instructions appeared in groups of at least 8, and appeared to point to random parts of the main code.

I whittled my 3800 line program down to 33 lines of code that reproduced the problem. Along the way I had thought to myself "Jump tables? Nah...!".

Turns out they are. The test code:

#include 
#define ONE_MORE
int main(void) {
  uint8_t mode;
  switch (mode) {
    case 0:
      TCNT0 = 0;
      break;
    case 1:
      TCNT0 = 0;
      break;
    case 2:
      TCNT0 = 0;
      break;
    case 3:
      TCNT0 = 0;
      break;
    case 4:
      TCNT0 = 0;
      break;
    case 5:
      TCNT0 = 0;
      break;
    case 6:       //  EDIT: OP was lacking this case, so
      TCNT0 = 0;  //  attempts by others to reproduce the
      break;      //  results below failed.  Apologies.
#ifdef ONE_MORE
    case 7:
      TCNT0 = 0;
      break;
#endif
  }
}

On an ATtiny85, compiling with #define ONE_MORE selects a switch statement with 8 cases, and generates a jump table:

00000000 <__vectors>:
   0:	16 c0       	rjmp	.+44     	; 0x2e <__ctors_end>
   2:	1d c0       	rjmp	.+58     	; 0x3e <__bad_interrupt>
   4:	1c c0       	rjmp	.+56     	; 0x3e <__bad_interrupt>
   6:	1b c0       	rjmp	.+54     	; 0x3e <__bad_interrupt>
   8:	1a c0       	rjmp	.+52     	; 0x3e <__bad_interrupt>
   a:	19 c0       	rjmp	.+50     	; 0x3e <__bad_interrupt>
   c:	18 c0       	rjmp	.+48     	; 0x3e <__bad_interrupt>
   e:	17 c0       	rjmp	.+46     	; 0x3e <__bad_interrupt>
  10:	16 c0       	rjmp	.+44     	; 0x3e <__bad_interrupt>
  12:	15 c0       	rjmp	.+42     	; 0x3e <__bad_interrupt>
  14:	14 c0       	rjmp	.+40     	; 0x3e <__bad_interrupt>
  16:	13 c0       	rjmp	.+38     	; 0x3e <__bad_interrupt>
  18:	12 c0       	rjmp	.+36     	; 0x3e <__bad_interrupt>
  1a:	11 c0       	rjmp	.+34     	; 0x3e <__bad_interrupt>
  1c:	10 c0       	rjmp	.+32     	; 0x3e <__bad_interrupt>
  1e:	18 c0       	rjmp	.+48     	; 0x50 
  20:	18 c0       	rjmp	.+48     	; 0x52 
  22:	18 c0       	rjmp	.+48     	; 0x54 
  24:	18 c0       	rjmp	.+48     	; 0x56 
  26:	18 c0       	rjmp	.+48     	; 0x58 
  28:	18 c0       	rjmp	.+48     	; 0x5a 
  2a:	10 c0       	rjmp	.+32     	; 0x4c 
  2c:	10 c0       	rjmp	.+32     	; 0x4e 

0000002e <__ctors_end>:
  2e:	11 24       	eor	r1, r1
  30:	1f be       	out	0x3f, r1	; 63
  32:	cf e5       	ldi	r28, 0x5F	; 95
  34:	d2 e0       	ldi	r29, 0x02	; 2
  36:	de bf       	out	0x3e, r29	; 62
  38:	cd bf       	out	0x3d, r28	; 61
  3a:	02 d0       	rcall	.+4      	; 0x40 
3c: 0f c0 rjmp .+30 ; 0x5c <_exit> 0000003e <__bad_interrupt>: 3e: e0 cf rjmp .-64 ; 0x0 <__vectors> 00000040
: 40: e0 e0 ldi r30, 0x00 ; 0 42: f0 e0 ldi r31, 0x00 ; 0 44: e1 5f subi r30, 0xF1 ; 241 46: ff 4f sbci r31, 0xFF ; 255 48: 12 be out 0x32, r1 ; 50 4a: 09 94 ijmp 4c: 08 95 ret 4e: 08 95 ret 50: 08 95 ret 52: 08 95 ret 54: 08 95 ret 56: 08 95 ret 58: 08 95 ret 5a: 08 95 ret 0000005c <_exit>: 5c: f8 94 cli 0000005e <__stop_program>: 5e: ff cf rjmp .-2 ; 0x5e <__stop_program>

Less than 7 cases, no jump table.

Interestingly, the threshold seems to be different when compiling for the ATmega328P. Instead of prefering jump tables at 8 cases, the threshold is 17 cases. Additionally, these jump tables are easier to spot:

00000000 <__vectors>:
   0:	0c 94 45 00 	jmp	0x8a	; 0x8a <__ctors_end>
   4:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
   8:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
   c:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  10:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  14:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  18:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  1c:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  20:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  24:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  28:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  2c:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  30:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  34:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  38:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  3c:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  40:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  44:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  48:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  4c:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  50:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  54:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  58:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  5c:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  60:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  64:	0c 94 4f 00 	jmp	0x9e	; 0x9e <__bad_interrupt>
  68:	5a 00       	.word	0x005a	; ????
  6a:	5b 00       	.word	0x005b	; ????
  6c:	5c 00       	.word	0x005c	; ????
  6e:	5d 00       	.word	0x005d	; ????
  70:	5e 00       	.word	0x005e	; ????
  72:	5f 00       	.word	0x005f	; ????
  74:	60 00       	.word	0x0060	; ????
  76:	61 00       	.word	0x0061	; ????
  78:	62 00       	.word	0x0062	; ????
  7a:	63 00       	.word	0x0063	; ????
  7c:	64 00       	.word	0x0064	; ????
  7e:	65 00       	.word	0x0065	; ????
  80:	66 00       	.word	0x0066	; ????
  82:	67 00       	.word	0x0067	; ????
  84:	68 00       	.word	0x0068	; ????
  86:	58 00       	.word	0x0058	; ????
  88:	59 00       	.word	0x0059	; ????

0000008a <__ctors_end>:
  8a:	11 24       	eor	r1, r1
  8c:	1f be       	out	0x3f, r1	; 63
  8e:	cf ef       	ldi	r28, 0xFF	; 255
  90:	d8 e0       	ldi	r29, 0x08	; 8
  92:	de bf       	out	0x3e, r29	; 62
  94:	cd bf       	out	0x3d, r28	; 61
  96:	0e 94 51 00 	call	0xa2	; 0xa2 
9a: 0c 94 6f 00 jmp 0xde ; 0xde <_exit> 0000009e <__bad_interrupt>: 9e: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> 000000a2
: a2: e0 e0 ldi r30, 0x00 ; 0 a4: f0 e0 ldi r31, 0x00 ; 0 a6: ec 5c subi r30, 0xCC ; 204 a8: ff 4f sbci r31, 0xFF ; 255 aa: 16 bc out 0x26, r1 ; 38 ac: 0c 94 69 00 jmp 0xd2 ; 0xd2 <__tablejump2__> b0: 08 95 ret b2: 08 95 ret b4: 08 95 ret b6: 08 95 ret b8: 08 95 ret ba: 08 95 ret bc: 08 95 ret be: 08 95 ret c0: 08 95 ret c2: 08 95 ret c4: 08 95 ret c6: 08 95 ret c8: 08 95 ret ca: 08 95 ret cc: 08 95 ret ce: 08 95 ret d0: 08 95 ret 000000d2 <__tablejump2__>: d2: ee 0f add r30, r30 d4: ff 1f adc r31, r31 000000d6 <__tablejump__>: d6: 05 90 lpm r0, Z+ d8: f4 91 lpm r31, Z da: e0 2d mov r30, r0 dc: 09 94 ijmp 000000de <_exit>: de: f8 94 cli 000000e0 <__stop_program>: e0: ff cf rjmp .-2 ; 0xe0 <__stop_program>

... due to helpful label names like <__tablejump__>, and the fact that the tables are collections of addresses instead of RJMP instructions. I understand the reasons for the differences.

[edit]

    I'd say the mechanism used here (jump to 'jump handler', address fetch, indirect jump) more closely resembles a trampoline, albeit not one used to cross 16-bit address boundaries.
[/edit]

I'm left with one question, though. Is there any way to get avr-objdump to recognise these jump tables for what they are, and label them as such, instead of blindly disassembling them? It seems to me it might involve sections.

Any thoughts?

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Fri. Aug 2, 2013 - 03:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That would probably be a feature request for the binutils team...

http://www.gnu.org/software/binutils/

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't know how objdump would know which ones are vectors and which ones are not. Even if it did have an -mmcu option (which it does not seem to), how would it know if someone used a part of the vector table for something else.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ezharkov wrote:
I don't know how objdump would know which ones are vectors and which ones are not. Even if it did have an -mmcu option (which it does not seem to), how would it know if someone used a part of the vector table for something else.
It doesn't know interrupt vectors. It simply disassembles the interrupt vectors as the JMP or RJMP instructions that they are.

What it does know is this:

00000000 <__vectors>: 

... and this:

 0:   16 c0          rjmp   .+44        ; 0x2e <__ctors_end> 

... and this:

0000002e <__ctors_end>: 

It knows these things because of symbols contained within the object file it is dumping. A simple symbol emitted by the compiler/assembler/linker, included in the object file, would be enough for objdump to show:

0000001e <__jump_table_000>: 
  1e:   18 c0          rjmp   .+48        ; 0x50 
  20:   18 c0          rjmp   .+48        ; 0x52 
  22:   18 c0          rjmp   .+48        ; 0x54 
  24:   18 c0          rjmp   .+48        ; 0x56 
  26:   18 c0          rjmp   .+48        ; 0x58 
  28:   18 c0          rjmp   .+48        ; 0x5a 
  2a:   10 c0          rjmp   .+32        ; 0x4c 
  2c:   10 c0          rjmp   .+32        ; 0x4e  

... which is why I think that:

Quote:
a feature request for the binutils team.
... isn't the right approach.

But then, I mis-spoke when I asked:

Quote:
Is there any way to get avr-objdump to recognise these jump tables
I should have asked if there was a way to get gcc/as/ld to emit jump table symbols when creating the object file, so that objdump could report them.

[edit]

    It also knows how to display non-instruction data like string literals:
    0000003e :
      3e:	41 55 54 48 4f 52 3a 20 20 20 20 4a 6f 65 79 20     AUTHOR:    Joey 
      4e:	4d 6f 72 69 6e 20 28 43 29 20 32 30 31 33 0a 00     Morin (C) 2013..

    ... certainly because the symbol embedded_build_strings is associated with string data within the object file, and objdump knows how to interpret it. I expect it already has some facility for correctly displaying other types of non-instruction data, like addresses. Damned if I know how, though ;)

[/edit]

Or am I missing something?

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can you tell me what build options you used in the first code? I simply cannot get it to build as you illustrate at any -O setting.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is actually a jumptables section - the default linker script has

    *(.jumptables) 
    *(.jumptables*)

inside the .text output section. Should be trivial to add a new symbol there. Something like

    ${CONSTRUCTING+ __jumptables_start = . ; } 
    *(.jumptables) 
    *(.jumptables*)

This should make avr-objdump show that symbol just before the start of jumptable code.

Regards

Senthil

 

blog | website

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The jumptables sections are currently unused. Jump tables are in .progmem.gcc_sw_table, aren't they?

I see the jump tables with 4.8. It is generated by the compiler and is not a problem of binutils. You can influence jump tables generation by

    --param case-values-threshold=value
value defaults to 7.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Can you tell me what build options you used in the first code? I simply cannot get it to build as you illustrate at any -O setting.
Ah, crap. That's because I'm a jerk and I made a copy/paste error. There's a missing case in the code I posted. Specifically:
    case 6:
      TCNT0 = 0;
      break;

Sorry about that :oops: ... I was fiddling with the number of cases required to trigger the use of jump tables with different -mmcu... should have been more careful posting...

For the record, my build commands were simply:

avr-gcc -O3 -mmcu=attiny85 foo.c -o foo.c.elf

... and:

avr-gcc -O3 -mmcu=atmega328p foo.c -o foo.c.elf

Results were the same at -O3 and -Os.

SprinterSB wrote:
I see the jump tables with 4.8. It is generated by the compiler and is not a problem of binutils.
If by that you mean that if I compile with avr-gcc 4.8.0 that I should be able to see the jump tables identified by avr-objdump, perhaps I'm doing something wrong.

Mind you, I consider my install of 4.8.0 to be suspect. It seems to work fine, but I've never used it to generate code for real devices. I installed the toolchain from source, shortly after it was released, onto Ubuntu 10.04.4 LTS. Had quite a bit of trouble, and I'm not confident about using it. I keep it around for testing purposes when posting here :).

In any case, the version of avr-objdump that I installed from source was the same as it is in version 3.4.2 of Atmel's toolchain for Linux, version 2.23.1.

Quote:
You can influence jump tables generation by
    --param case-values-threshold=value
value defaults to 7.
Thanks for the tip!

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

There's a missing case in the code

Ah that fixed it. I just wanted to see the Asm passed from the compiler to binutils to see if there was anything there that could be used:

	.section	.text.startup.main,"ax",@progbits
.global	main
	.type	main, @function
main:
//==> int main(void) {
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
//==> 	switch (mode) {
	ldi r30,0
	ldi r31,0
	subi r30,lo8(-(gs(.L11)))
	sbci r31,hi8(-(gs(.L11)))
//==> 		TCNT0 = 0;
	out 0x32,__zero_reg__
//==> 	switch (mode) {
	ijmp

	.section	.progmem.gcc_sw_table.main,"ax",@progbits
	.p2align	1
.L11:
	rjmp .L2
	rjmp .L2
	rjmp .L2
	rjmp .L2
	rjmp .L2
	rjmp .L2
	rjmp .L2
	rjmp .L2

	.section	.text.startup.main
.L2:
//==> }
	ldi r24,0
	ldi r25,0
	ret
	.size	main, .-main

Sadly no. You learn that the table is in:

.progmem.gcc_sw_table.main,"ax",@progbits

but apart from the local .L11 label there's nothing to aid access to it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
I just wanted to see the Asm passed from the compiler to binutils to see if there was anything there that could be used
clawson wrote:
Sadly no. You learn that the table is in:
.progmem.gcc_sw_table.main,"ax",@progbits

but apart from the local .L11 label there's nothing to aid access to it.

I assume this could be amended in the upstream gcc?

What would be the correct approach? For each jump table, adding a .global label for that table? So:

   .section   .progmem.gcc_sw_table.main,"ax",@progbits
   .p2align   1
.L11: 

... could become:

   .section   .progmem.gcc_sw_table.main,"ax",@progbits
   .p2align   1
.global gcc_sw_table_main: 

It looks like the .section line has the correct information already, i.e. on devices with <= 8K of flash these tables are RJMP instructions and the .section descriptions have "ax", and on devices with > 8K of flash, the tables are simply addresses and the .section description have "a".

Would there be anything else needed to get avr-objdump to cough up a label for jump tables?

Where would be the appropriate place to make a feature request?

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Where would be the appropriate place to make a feature request?
You're wasting your time. If you want this do it yourself. There aren't enough contributors to do the important stuff let alone trivial fluff, a bug report will just get bounced.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

Where would be the appropriate place to make a feature request?
You're wasting your time. If you want this do it yourself. There aren't enough contributors to do the important stuff let alone trivial fluff, a bug report will just get bounced.
Fair enough.

I don't have a burning need. However, I suspect that this is actually something I might be able to contribute, and it seem innocuous enough that I imagine it would be hard to break anything by trying ;)

Can anyone suggest what source to check out, and where to do so?

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Can anyone suggest what source to check out, and where to do so?
If you want .LL1 replaced or accompanied by a global symbol that has to happen in the compiler so pull the source for GCC. Be warned that if this change may affect the global compiler and not just AVR it could be close to impossible to convince the maintainers it is justified. There is a gcc manual dedicated to the internals.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
If you want .LL1 replaced or accompanied by a global symbol that has to happen in the compiler so pull the source for GCC. Be warned that if this change may affect the global compiler and not just AVR it could be close to impossible to convince the maintainers it is justified. There is a gcc manual dedicated to the internals.
I've started looking at it. The list of projects for beginner GCC hackers is [ahem] long.

Much as I generally like to, I don't want to re-invent a wheel:

joeymorin wrote:
SprinterSB wrote:
I see the jump tables with 4.8. It is generated by the compiler and is not a problem of binutils.
If by that you mean that if I compile with avr-gcc 4.8.0 that I should be able to see the jump tables identified by avr-objdump, perhaps I'm doing something wrong.
As mentioned, I see objdump output doesn't look any different when dumping an .elf built with avr-gcc 4.8.0 and avr binutils 2.23.1, at least not on my machine.

Can @SprinterSB or anyone else confirm this?

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I still don't understand what you are trying to achieve and what the purpose of the change is. Understanding the code? Better dumps by tagging jump tables / offset tables by a global symbol?

To discuss changes in the tools, a far better place to discuss are the respective mailing lists. The forum here read by guys using the tools, I am not aware of any GCC or Binutils developer around here (expect, maybe, some Atmel stuff that work on their branch).

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SprinterSB wrote:
I still don't understand what you are trying to achieve and what the purpose of the change is. Understanding the code?
No, I get it.
Quote:
Better dumps by tagging jump tables / offset tables by a global symbol?
Precisely. Truth be told, I realise it's not that big a deal. As I mentioned:
joeymorin wrote:
I don't have a burning need. However, I suspect that this is actually something I might be able to contribute, and it seem innocuous enough that I imagine it would be hard to break anything by trying ;)

SprinterSB wrote:
To discuss changes in the tools, a far better place to discuss are the respective mailing lists. The forum here read by guys using the tools, I am not aware of any GCC or Binutils developer around here (expect, maybe, some Atmel stuff that work on their branch).
Agreed. However as I said in my last post I wanted to avoid re-inventing the wheel. You mentioned in a previous post that you:
Quote:
... see the jump tables with 4.8.
... but (as mentioned in my last post) I cannot reproduce this result, and wondered simply if you could clarify. Obviously if 4.8.0 already identifies jump tables with global labels which objdump spits out, I'll consider the matter closed. If not, I'll pursue this elsewhere.

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If I wanted to label jump tables, I think that I would use Python or something to analyze the .lss file.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
If I wanted to label jump tables, I think that I would use Python or something to analyze the .lss file.
I use "something" to analyze, well, the .elf file rather than .lss. One of the things that I do is locate the jump tables. I can say that this is not that simple (well, for me, anyway).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ezharkov wrote:
skeeve wrote:
If I wanted to label jump tables, I think that I would use Python or something to analyze the .lss file.
I use "something" to analyze, well, the .elf file rather than .lss. One of the things that I do is locate the jump tables. I can say that this is not that simple (well, for me, anyway).
Of course.
If they work well, use the tools one knows.
I know Python. I don't know .elf files.

Iluvatar is the better part of Valar.