ELF questions

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
moonlightcheese
Posts: 17
Joined: Tue Jan 20, 2009 7:03 pm

Re: ELF questions

Post by moonlightcheese »

berkus wrote:Why not parse all ELF file headers, there are some fields that pretty much can tell you if this is a real ELF file, what format it is in and if it actually contains information you're looking for. If it's not too big you can attach it here so that we can have a look instead.
i've posted both files (.gba rom and .elf binary) in a zip archive
Attachments
pong.zip
(7.06 KiB) Downloaded 108 times
xlq
Member
Member
Posts: 36
Joined: Mon Dec 11, 2006 7:51 am

Re: ELF questions

Post by xlq »

I remember doing GBA development with devkitarm. If I remember correctly. one usually links everything into an ELF file, and then converts it to a flat binary using objcopy.
Marionette the flexible kernel
moonlightcheese
Posts: 17
Joined: Tue Jan 20, 2009 7:03 pm

Re: ELF questions

Post by moonlightcheese »

ok i've gone a bit further with this after putting it off for a while. i'm able to read the elf file and get the information from the elf header and program headers. here's the info given by reading the file information:

elf header:

Code: Select all

e_type: 2
e_machine: 40
e_version: 1
e_entry: 0x02000000
e_phoff: 52
e_shoff: 102832
e_flags: 67108866
e_ehsize: 52
e_phentsize: 32
e_phnum: 3
e_shentsize: 40
e_shnum: 25
e_shstrndx: 22
phdr1:

Code: Select all

p_type: 1
p_vaddr: 0x02000000
p_paddr: 0x02000000
p_filesz: 40820
p_memsz: 40820
p_flags: 7
p_align: 32768
phdr2:

Code: Select all

p_type: 1
p_vaddr: 0x03000424  //exactly 1060 bytes, size of phdr3 (memsz)
p_paddr: 0x02009F74  //exactly 40820 bytes, size of phdr1
p_filesz: 4
p_memsz: 4
p_flags: 6
p_align: 32768
phdr3:

Code: Select all

p_type: 1
p_vaddr: 0x03000000
p_paddr: 0x03000000
p_filesz: 0
p_memsz: 1060
p_flags: 6
p_align: 32768
so what i'd like to do next is get the program running. i'm not worried about switching back to the caller, just in switching context. i'll need to use physical addressing as i'm not actually building an OS from this yet, just trying to get binaries loaded and running.

first, given the above program header information, do i really need to move the data into the above locations in physical memory? it doesn't seem like it should really matter where in memory the program sits so long as the interrupt send program execution to the place in memory where the beginning of the program exists, no? if it is actually necessary to move things into the physical addresses listed by the p_paddr member of the program headers, could someone explain why this is necessary?

second, if it is necessary to place the program in a specific place in memory, i'll need to ensure that those addresses aren't in use. so since i'll be loading up about 40KB of space (39KB in EWRAM and 1KB in IWRAM on the GBA), i'll need to ensure that the code i'm executing exists somewhere outside this boundary. since really the only code i need to be careful with on placement is the memcpy that places the code in it's appropriate location, how can i use C syntax to block the memcpys together and place them in a particular location in memory, at say, 0x02020000, so it isn't affected by the memcpy copying over the running code?
JohnnyTheDon
Member
Member
Posts: 524
Joined: Sun Nov 09, 2008 2:55 am
Location: Pennsylvania, USA

Re: ELF questions

Post by JohnnyTheDon »

Unless the code is position independent, you need to run it at the location specified in p_vaddr.
moonlightcheese
Posts: 17
Joined: Tue Jan 20, 2009 7:03 pm

Re: ELF questions

Post by moonlightcheese »

JohnnyTheDon wrote:Unless the code is position independent, you need to run it at the location specified in p_vaddr.
but doesn't that assume that you're using virtual addressing? as i said, this isn't for an OS, but just to load the file and run it. and how can i tell if the code is "position independent" or not? there is an objdump in one of the above posts; can you tell from that?

my understanding, from the ARM ELF reference, is that p_vaddr is used on most modern operating systems with virtual addressing
p_vaddr - this member gives the virtual address at which the first byte of the segment resides in memory.

p_paddr - on systems for which physical addressing is relevant, this member is reserved for the segment's physical address. this member requires operating system specific information.
i'm assuming that the operating system specific information has to do with simply how the OS would avoid issues with memory overwrite...

i think i'm correct in my assumptions, and since you say the code must be PIC and i don't know how to verify if it is or not (should i post the Makefile i'm using? it came with the gcc 4.3 ARM eabi and some gba libraries...) but i'm not sure how to write C syntax to place blocks of code at specific addresses. i thought about defining a pointer to a function at a specified address in a preprocessor directive, but this would just place the pointer in that address and not the actual code...

i realize a lot of you guys have written full blown operating systems where virtual addressing is relevant but this is merely a simple ELF loader that i'm writing for the GBA. basically, the flash cartridge will load a .gba rom that i'm building that will do the following:
  • load ELF from disk to main memory according to p_paddr(?) variable (using stdio)
  • send a hardware interrupt that will perform re-entrant capable interrupts (i already have the code for this and have gone through many guides for writing interrupt handlers for ARM)
  • switch execution to address of loaded ELF binary
i think i've got this right, but i'm, more or less, asking for the advice of people who have much more experience with this than myself... at this point i feel like i'm shooting in the dark and i don't know if i've given the correct information about what i'm trying to accomplish and how to get there...
User avatar
Firestryke31
Member
Member
Posts: 550
Joined: Sat Nov 29, 2008 1:07 pm
Location: Throw a dart at central Texas
Contact:

Re: ELF questions

Post by Firestryke31 »

Isn't the 'p_vaddr' field (for all intents and purposes) just the place the ELF expects to be loaded? There's a similar field in EXE that I just load my old OS's EXE to physically instead of dealing with virtual memory and all of that. It still works because the addresses that the program sees are all the same. "Virtual" address is just used because it's assumed that people are running on a multi-tasking OS (I think).
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
moonlightcheese
Posts: 17
Joined: Tue Jan 20, 2009 7:03 pm

Re: ELF questions

Post by moonlightcheese »

Firestryke31 wrote:Isn't the 'p_vaddr' field (for all intents and purposes) just the place the ELF expects to be loaded? There's a similar field in EXE that I just load my old OS's EXE to physically instead of dealing with virtual memory and all of that. It still works because the addresses that the program sees are all the same. "Virtual" address is just used because it's assumed that people are running on a multi-tasking OS (I think).
if that's the case then i'll just have to write two functions for building the process image; one that uses the p_paddr member and one that uses the p_vaddr member. but before i can do that, i still need to know how i can use C syntax to place the .gba rom code away from the addresses that will be used by the program being loaded.

so if i wanted to place code at 0x02020000 (EWRAM, well away from the addresses specified in the ELF binary), how can i do that? the gba will expect the first bit of code to be at 0x02000000 when the rom is first loaded but any code after that can be elsewhere.
User avatar
Firestryke31
Member
Member
Posts: 550
Joined: Sat Nov 29, 2008 1:07 pm
Location: Throw a dart at central Texas
Contact:

Re: ELF questions

Post by Firestryke31 »

moonlightcheese wrote: so if i wanted to place code at 0x02020000 (EWRAM, well away from the addresses specified in the ELF binary), how can i do that? the gba will expect the first bit of code to be at 0x02000000 when the rom is first loaded but any code after that can be elsewhere.
You could compile as if loaded to 0x02020000, but have the first thing you do be copy the code there, then jump (does the ARM have IP-relative jumps?). That's what my second stage does, since the copy loop can use a relative jump on the x86, and I'm sure something similar can be done on the ARM.
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Re: ELF questions

Post by frank »

If you are using GCC and LD you should look into using a linker script. With a linker script you can tell LD to make the code think that its running at any address you tell it to.
Post Reply