I am defining a special section for some data that I want to show up at the beginning of my PIC32 binary image, as follows in the SECTIONS part of my elf32pic32mx.ld file:

  .headerdata ORIGIN(kseg0_program_mem)  :
  } >kseg0_program_mem

and then in my code, I am initializing a structure like so:

const MODULEINFO SER_05_ModuleInfo __attribute__((section (".headerdata"))) = 
    sizeof(MODULEINFO),         // UINT16 HeaderSize
    MODULE_TYPE,                // UNIT16 ModuleType
    // etc. etc.

When I compile and link the program, the structure shows up in the map file:

.headerdata     0x9d000000       0x48
 .headerdata    0x9d000000       0x48 DriverHeader.o
                0x9d000000                SER_05_ModuleInfo

but the actual data does not show up in the hex output file.

If I leave off the attribute ((section (".headerdata"))) in the structure, the structure shows up in the .rodata of the map file, and the data does show up in my hex output file.

When defining special sections, is there something else that needs to be done to actually get them to generate output besides the >kseg0_program_mem line?


Given the presented code, an object dump of the headers will show something similar to the following:

pic32-objdump -x main.o

9 .rodata       00000004  00000000  00000000  00000360  2**2
10 .headerdata   00000004  00000000  00000000  00000364  2**2

This shows that the section in which header data is placed does not have the READONLY and CODE attributes and this in turn causes the linker to operate differently on the data from that section. In my limited tests, it would seem that content in .headerdata is treated as other data, meaning that it is put into a special section named .dinit and loaded from flash to RAM on program startup. You mention that the data from the .headerdata section doesn't appear in your hex file - I suspect you'll find it in the .dinit section.

If you are trying to get functionality similar to .rodata but with your own section name, you will need to mark your .headerdata section with an additional r attribute like this:

static const MODULEINFO SER_05_ModuleInfo __attribute__((section (".headerdata,r"))) =

resulting in an object header dump as follows:

  9 .rodata       00000004  00000000  00000000  00000360  2**2
 10 .headerdata   00000004  00000000  00000000  00000364  2**2

This will then be treated similar to .rodata in the linker as long as you have added your special linker script snippet as listed.

I presume that you're trying to make your header the first set of data that is present in program space. Although the linker script additions you have listed would appear to work, I usually prefer to just add the additional sections in line with existing sections in the preferred order. Instead of a separate .headerdata ORIGIN(kseg0_program_mem) type section, you could edit the .text section to end up with something like this:

 .text :
   *(.stub .gnu.linkonce.t.*)
   KEEP (*(.text.*personality*))
 } >kseg0_program_mem

Using pic32-objdump -d main.elf will show a complete disassembly of the final binary in which you should now see your header data at the correct address.

You may want to check that placing your header at the start of program space does not upset operation of other parts of the system such as exception handling.

I found a copy of pic30.c gcc compiler code floating around on the web somewhere and the accepted section attribute flags appear to be:

b - BSS

x - Executable code

r - Read only data

d - Writeable data

| improve this answer | |
  • \$\begingroup\$ Thanks, I'll try this Monday morning when I get back to my on-site job where I am dealing with this problem. I was not aware of the attribute flags. I don't think they are documented in the PIC32 linker manual. \$\endgroup\$ – tcrosley Oct 30 '11 at 11:44
  • \$\begingroup\$ The section (".headerdata,r")) worked perfectly. Thank you very much. \$\endgroup\$ – tcrosley Oct 31 '11 at 18:41
  • \$\begingroup\$ Glad it worked. I'm surprised at the linker's behavior and would normally expect the linker scripts to handle the section allocation, and crt0.S type code to handle data loading, and not ignore your specified section. In addition, perhaps the compiler also needs to know the section type to allow it to choose the correct instructions for addressing. ie for program/data space accesses. \$\endgroup\$ – Austin Phillips Nov 1 '11 at 0:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.