gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Finding 8-bit writes in a elf (heh)

#154042 - simonjhall - Wed Apr 09, 2008 11:08 pm

I was gonna stick this in the RAM library thread, but it's pretty fat.
Here's my mini-howto to finding where 8-bit writes are in your elf. Requires awk and the ARM binutils. If you don't know what this means then this likely isn't a problem that affects you!

Ok, here's the cock-eyed solution I've used on the two games I've done now:

At your command line (I'm a big Cygwin fan btw) type,
Code:
arm-eabi-objdump -d my_friend_the.elf | grep strb | awk '{print "0x"$1}' > strbs.txt

This will make a file that contains a lot of lines like,
Quote:
...
0x2023de8:
0x2023dec:
0x2023e20:
0x2023e38:
0x2023e3c:
0x2023e64:
0x2023ec0:
0x2023ec4:
0x2023ec8:
0x2023ecc:
0x2023ed0:
0x20247fc:
...

Note the annoying colon. I now fire up this file in a text editor and do a find/replace all on ':' and just replace it with a space or some kind of whitespace. Save strbs.txt.
(I realise I could replace this step with a bit of fancy awk in the previous command, but I've forgotten 95% of the awk I did in uni...can anyone help me with this?)
My file now looks like
Quote:
...
0x2023dec
0x2023e20
0x2023e38
0x2023e3c
0x2023e64
0x2023ec0
0x2023ec4
0x2023ec8
0x2023ecc
0x2023ed0
0x20247fc
...

Ok, so this gives us a list of the addresses within the program that contain the strb instruction. Not really that useful... So we use an awesome tool named addr2line to sort this out.

At your command prompt, type:
Code:
awk '{system("arm-eabi-addr2line -e im_in_love_with_an.elf " $1)}' strbs.txt | sort > strbs2.txt
This may take some time - be patient. Once you're done, strbs2.txt may contain such jollies as:
Quote:
...
c:/devkitPro/dswifi/arm9/source/wifi_arm9.c:645
c:/devkitPro/dswifi/arm9/source/wifi_arm9.c:646
c:/devkitPro/dswifi/arm9/source/wifi_arm9.c:887
c:/devkitPro/dswifi/arm9/source/wifi_arm9.c:892
c:/devkitPro/dswifi/arm9/source/wifi_arm9.c:973
c:\Documents and Settings\Simon\workspace\debugger_remote/network_trans.c:135
c:\Documents and Settings\Simon\workspace\debugger_remote/network_trans.c:195
c:\devkitPro\libnds\include/nds/arm9/videoGL.h:1098
c:\devkitPro\libnds\include/nds/arm9/videoGL.h:1098
c:\devkitPro\libnds\include/nds/arm9/videoGL.h:1098
c:\devkitPro\libnds\include/nds/arm9/videoGL.h:1098
c:\devkitPro\libnds\include/nds/arm9/videoGL.h:1104
...
These are all the locations of the strb instruction within your elf. Go to these locations within your code and assess if it's going to be a problem, and if it is replace it with either a 16-bit read-modify-write or change your data types to be 16-bit or bigger.

As this isn't the only offending instruction, repeat for instructions such as strbeq and strbgt (or whatever the objdump syntax is) etc etc. You'll also find that gcc will often insert calls to memcpy and memset (it's in the gcc spec - I'll find a link at some point) so make sure you grep for these calls too.

Going through the list by hand and fixing the code is the best thing I can then think of doing. I'm sure a more automated solution would be better.

Hope this helps someone.
_________________
Big thanks to everyone who donated for Quake2

#154043 - Dwedit - Wed Apr 09, 2008 11:26 pm

What about the DS Linux C compiler which changes strb into swpb?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#154046 - silent_code - Wed Apr 09, 2008 11:47 pm

nice post, thanks a lot!

#154047 - nanou - Thu Apr 10, 2008 12:00 am

simonjhall wrote:
Note the annoying colon.


| sed s/://

s/note/excise/ ;)

Now you can construct it as a single line if you're sufficiently crazy.
_________________
- nanou

#154052 - TypeError - Thu Apr 10, 2008 2:26 am

Dwedit wrote:
What about the DS Linux C compiler which changes strb into swpb?


That would be ideal, but somebody needs to port the GCC patches to the devkitPro compiler. (I'm assuming binaries created by the dslinux compiler can't be run as bare nds files, right?) It shouldn't be too hard for somebody who knows what they're doing. (read: not me)

The patches are here:
http://dslinux.gits.kiev.ua/trunk/toolchain/8bit/

I wonder if .o files from the dslinux compiler could be linked using the DKP linker to give us strb-free .nds files...

Thanks for sharing your procedure Simon!

#154053 - Lazy1 - Thu Apr 10, 2008 2:33 am

I remember asking Wintermute about that a while ago and if I remember correctly it would require quite a few changes to libnds which is why it would never be included with devkitARM.
Besides, it's better this way since it would require those wanting to use the external ram to be more cautious and not use it as an excuse not to optimize their memory usage.

That ram is very slow and should not be treated as a fast(lol) ticket to porting large applications.
If you need the extra ram that bad then you'd be willing to do the method posted in this very thread :D

Thanks for the guide, it will certainly come in handy.

#154054 - TypeError - Thu Apr 10, 2008 2:54 am

Lazy1 wrote:
I remember asking Wintermute about that a while ago and if I remember correctly it would require quite a few changes to libnds which is why it would never be included with devkitARM.


I'm with you so far. If the devs say it'll cause too much pain you've gotta respect that, but...

Quote:

Besides, it's better this way since it would require those wanting to use the external ram to be more cautious and not use it as an excuse not to optimize their memory usage.

That ram is very slow and should not be treated as a fast(lol) ticket to porting large applications.
If you need the extra ram that bad then you'd be willing to do the method posted in this very thread :D


Oh man, I can't say I agree here. If you need the ram you need the ram. If there's a tool that can give you the ram, it's fair game. If there's a tool that can get you running slowly in 20MB and let you whittle your resources down to 4MB from a position of comfort instead of a position of frustration then it's unequivocally a good thing. If the memory is "too slow" then the performance problems will be motivation enough for you to not use it unless you absolutely need it.

#154055 - Lazy1 - Thu Apr 10, 2008 4:30 am

You may have a point there, but what is stopping people from building libnds on the dslinux toolchain?

#154056 - TypeError - Thu Apr 10, 2008 4:43 am

I don't know. Is it possible? I'm assuming the linker will work differently since there's destined to be an OS involved. It's worth a shot though.

I'm actually trying to build dkp r21 with the dslinux patch right now. I think I've almost got it but I'm not quite done yet.

#154062 - simonjhall - Thu Apr 10, 2008 9:30 am

nanou wrote:
simonjhall wrote:
Note the annoying colon.


| sed s/://

s/note/excise/ ;)

Now you can construct it as a single line if you're sufficiently crazy.
That's mega. I'll update this later to include this. I had forgotten about (or blanked out) sed!
_________________
Big thanks to everyone who donated for Quake2

#154064 - TypeError - Thu Apr 10, 2008 10:12 am

Bah, stupid newlib won't build with or without the patch. I've been trying on OS X but maybe I'll switch to my linux machine to see if it'll work there.

Ok, it's a known bug:
http://forums.devkitpro.org/viewtopic.php?f=15&t=44

Well if anybody wants to try my modified version of the dslinux patch it's here:
http://pastebin.org/28711

Apply it *after* buildscripts-20080308 patches gcc. Note that you have to build newlib with make 3.80, not 3.81. I don't know about the libnds problem people mention in the thread above, but this should be a good start.

Grr. Now it's failing to build g++, not that I care much. Well, that's it for now. Must. Sleep.

#154065 - simonjhall - Thu Apr 10, 2008 10:52 am

Sleep?! It's nearly 11am! Some of us were out of bed at 7am!
_________________
Big thanks to everyone who donated for Quake2

#154092 - TypeError - Thu Apr 10, 2008 11:13 pm

Well, so far so good. I managed to build a DKP version of gcc with the -mswp-byte-writes option and used it to compile libnds and libfat. I tried compiling a simple test program and here's what I see:

Code:

Normal compile:
[n8gray@golux]% arm-eabi-objdump -d arm9/printf.arm9.elf| grep strb | wc -l
     156
[n8gray@golux]% arm-eabi-objdump -d arm9/printf.arm9.elf| grep swpb | wc -l
      33

Compile with -mswp-byte-writes:
[n8gray@golux]% arm-eabi-objdump -d arm9/printf.arm9.elf| grep strb | wc -l
       2
[n8gray@golux]% arm-eabi-objdump -d arm9/printf.arm9.elf| grep swpb | wc -l
     170


The two remaining strb's are in crtstuff.c, part of gcc. I think they're related to initializers and finalizers, so I don't think they'll cause problems. The test program runs properly in DeSmuME, but it's *really* simple. I need to try it on something more complex.

One thing to mention: this option only works with arm code, not thumb code.

#154100 - tepples - Fri Apr 11, 2008 12:38 am

TypeError wrote:
If there's a tool that can get you running slowly in 20MB and let you whittle your resources down to 4MB from a position of comfort instead of a position of frustration then it's unequivocally a good thing.

There is such a tool, and it is called "porting to the PC".
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.