EmbeddedRelated.com
Forums

HELP: gcc + newlib +pic

Started by Jason Morgan July 29, 2009
Hi,

This does not happen very often, but I am completely stuck.

I have some code that is running in place as a callable application located in flash. The application is run from a bootloader.
I have the compiler flags -fpic and -msingle-pic-base. So when the application is called, r10 is set to point to the GOT.

This is where things start to go wrong.

The compiler does not produce any indirection through the GOT, it just adds r10 to ROM pointer retrival, I'm not sure this is correct but this is OK and works fine. I would expect to have to update the GOT with the location of the relocated .text and .data sections, how do I do this?

The real problem comes with newlib, when my applicaton calls newlib functions it hangs.

It appears that newlib expects a struct _reent table, pointed to by _global_impure_pointer to point to an entry _impure pointer. I suspect that this table is not initalised correctly. What do I do to it to to fit it up?

I've only got a couple more days to get this working!!
Thanks,
Jason.

An Engineer's Guide to the LPC2100 Series

--- In l..., "Jason Morgan" wrote:
>
> Hi,
>
> This does not happen very often, but I am completely stuck.
>
> I have some code that is running in place as a callable application located in flash. The application is run from a bootloader.
> I have the compiler flags -fpic and -msingle-pic-base. So when the application is called, r10 is set to point to the GOT.
>
> This is where things start to go wrong.
>
> The compiler does not produce any indirection through the GOT, it just adds r10 to ROM pointer retrival, I'm not sure this is correct but this is OK and works fine. I would expect to have to update the GOT with the location of the relocated .text and .data sections, how do I do this?

You need to use the information in the .rel.dyn section - google for uclinux bflt format.

>
> The real problem comes with newlib, when my applicaton calls newlib functions it hangs.
>
> It appears that newlib expects a struct _reent table, pointed to by _global_impure_pointer to point to an entry _impure pointer. I suspect that this table is not initalised correctly. What do I do to it to to fit it up?
>
> I've only got a couple more days to get this working!!

What happens then?

Regards
Michael

> Thanks,
> Jason.
>
> The compiler does not produce any indirection through the GOT, it just adds r10 to ROM pointer retrival, I'm not sure this is correct but this is OK and works fine.

GCC only builds PIC intended for use in Linux where the .text and .data/.bss sections are contiguous in a "virtual" address space. It sets R10 to the beginning of the virtual address space; then both .text and .data/.bss can be reference relative to the same base address.

In the embedded environment, however, the .text section usually resides in FLASH and .data/.bss resides in RAM and they are not contiguous. If you set R10 to the beginning of the .data/.bss section instead, then GCC generates code that works most of the time in embedded systems except for certain cases where it takes the address of a function and offsets it using R10. There are some workarounds for that case too and there are some patches available for most architectures that add a -membedded-pic (or -mno-got) option to GCC to make it work as expected.

> I would expect to have to update the GOT with the location of the relocated .text and .data sections, how do I do this?

I recently implemented supported for PIC execution in FLASH for ARMs, but it is only integrated under an OS that I wrote. There is documentation here that discusses some of the issues: http://nuttx.sourceforge.net/NuttXNxFlat.html . It is a based on the logic from http://xflat.sourceforge.net/ (unlike bFLT, NxFLT will work in embedded systems without Linux).

The way that is down is by writing some kind of dynamic loader that can read the binary format of the PIC program and can fix up the addresses at runtime.

> It appears that newlib expects a struct _reent table, pointed to by _global_impure_pointer to point to an entry _impure pointer. I suspect that this table is not initalised correctly. What do I do to it to to fit it up?

Are you linking newlib with your PIC program? Newlib is not compiled PIC is it? I'm not sure what happens when you try to execute non-PIC code as PIC, but I doubt that it is good. Most likely either newlib will have to be compiled PIC (bad) or you will have to dynamically link to non-PIC newlib code that is in you base FLASH image (better).

> I've only got a couple more days to get this working!!

That sounds like a serious challenge!

Greg