title: linking error when using sprintf()
body: <p>on my cortex-m3, i am trying to output a float variable to my UART port.. so i need to convert the <code>float DATA</code> into a <code>char outputstr[]</code>.</p>
  
  <p>For this purpose, i used sprintf from the libc.a</p>
  
  <ol>
  <li>if i comment out the sprintf(), i can compile and link.</li>
  <li>if i use <code>sprintf(outputstr, "t")</code>, i can compile and link.</li>
  <li>if i use <code>sprintf(outputstr, "The value is %f", DATA)</code>, i will get linking errors like: no memory region specified for loadable section `.rodata', '.bss', '.text', '.data'</li>
  </ol>
  
  <p>But i had already added *(.rodata), *(.bss) etc... in my linker script as below:</p>
  
  <pre><code>...
  OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
  OUTPUT_ARCH(arm)
  ENTRY(reset_handler)
  
  MEMORY {
     ROM : ORIGIN = 0x08000000, LENGTH = 128K
     RAM : ORIGIN = 0x20000000, LENGTH = 16K
  }
  
  SECTIONS {
  
      .ROMdata 0x8000000: AT(0x8000000){
      startup.o(.romvect)
      . = ALIGN(0x4);
      system_stm32l1xx.o(.rodata*)
      *(.rodata*)
      _ROMdataend_ = ALIGN(0x4);
      }
  
      .ROMstartup (_ROMdataend_): AT(_ROMdataend_){
      startup.o(.startup)
      lowlevelinit.o(.lowlevelinit .tempexchandler)
      system_stm32l1xx.o(.text*)
      . = ALIGN(0x4);
      }
  
      .RAMbss 0x20000000 (NOLOAD):{
  
      lowlevelinit.o(.ramvectortable)
      . = ALIGN(0x4);
      _RAMbssstart_ = .;
      startup.o(.stack .heap)
      . = ALIGN(0x4);
      sensor_MTH01.o(.bss*)
      . = ALIGN(0x4);
      comm_BT-HC-05.o(.bss)
      tim6.o(.bss)
      main.o(.bss)
      system_stm32l1xx.o(.bss*)
      *(.bss*)
      _RAMbssend_ = ALIGN(0x4);
      }
  
      .RAMcode (_RAMbssend_): AT(LOADADDR(.ROMstartup)+SIZEOF(.ROMstartup)){
      _RAMcodeVMAstart_ = .;
      _RAMcodeLMAstart_ = LOADADDR(.RAMcode);
      main.o(.ramcode .text)
      tim6.o(.tim6isr)
      tim6.o(.text)
      sensor_MTH01.o(.text)
      comm_BT-HC-05.o(.text)
      exti0_isr.o(.exti0isr)
      *(.text*)
      KEEP (*(.eh_*))
      _RAMcodeVMAend_ = ALIGN(0x4);
      }
  
      .RAMdata (_RAMcodeVMAend_): AT(LOADADDR(.RAMcode)+SIZEOF(.RAMcode)){
      _RAMcodeLMAend_ = (LOADADDR(.RAMcode)+SIZEOF(.RAMcode));
      _RAMdataVMAstart_ = .;
      _RAMdataLMAstart_ = LOADADDR(.RAMdata);
      sensor_MTH01.o(.data)
      system_stm32l1xx.o(.data*)
      *(.data*)
      _RAMdataVMAend_ = ALIGN(0x4);
      _RAMdataLMAend_ = LOADADDR(.RAMdata) + SIZEOF(.RAMdata);
      }
  
  
  }
  ...
  </code></pre>
  
  <p>Also, i did include the lib paths and include paths in my makefile as below:</p>
  
  <p>On a side note, i am also using <code>strlen()</code> and <code>other float division operations</code> from the libc.a and libgcc.a and these functions complile, link and work ok.</p>
  
  <pre><code>    ...
      CC = arm-none-eabi-gcc
      AS = arm-none-eabi-as
      LD = arm-none-eabi-ld
      OBJCPY = arm-none-eabi-objcopy
  
      CCFLAGS = -c -mcpu=cortex-m3 -mthumb -O0 -g -Wall
      ASMFLAGS = -mcpu=cortex-m3 -mthumb --gdwarf-2
      LDFLAGS = -T CortexM3.ld -M=memmap.map
      OBJCPYFLAGS = -O ihex
      FLOATFLAGS = -mfloat-abi=soft -mfpu=vfp
      LIBDIR = -L C:\\yagarto-20121222\\lib\\gcc\\arm-none-eabi\\4.7.2\\thumb\\v7m -L C:\\yagarto-20121222\\arm-none-eabi\\lib\\thumb\\v7m
      INCDIR = -I C:\\yagarto-20121222\\lib\\gcc\\arm-none-eabi\\4.7.2\\include -I C:\\yagarto-20121222\\arm-none-eabi\\include
  
      all: m3.elf
      m3.elf: startup.o lowlevelinit.o system_stm32l1xx.o main.o tim6.o exti0_isr.o sensor_MTH01.o comm_BT-HC-05.o
          $(LD) $(LDFLAGS) $(LIBDIR) $^ -lc -lgcc -o $@
          $(OBJCPY) $(OBJCPYFLAGS) m3.elf m3.hex
      startup.o: startup.s
      lowlevelinit.o: lowlevelinit.c system_stm32l1xx.h stm32l1xx.h core_cm3.h
      system_stm32l1xx.o: system_stm32l1xx.c stm32l1xx.h core_cm3.h system_stm32l1xx.h
      main.o: main.c stm32l1xx.h
      tim6.o: tim6.c
      exti0_isr.o: exti0_isr.c
      sensor_MTH01.o: sensor_MTH01.c
      comm_BT-HC-05.o: comm_BT-HC-05.c
  
      clean:
          -rm -f startup.o lowlevelinit.o system_stm32l1xx.o main.o tim6.o tim6_isr.o exti0_isr.o sensor_MTH01.o comm_BT-HC-05.o memmap.map m3.elf m3.hex
  
      %.o: %.s
          $(AS) $(ASMFLAGS) $&lt; -o $@
      %.o: %.c
          $(CC) $(CCFLAGS) $(INCDIR) $(FLOATFLAGS) $&lt; -o $@
  
  
      .PHONY: all clean 
      ...
  </code></pre>
  
  <ol>
  <li><p>can anyone advise?</p></li>
  <li><p>also, if i come across linking error message like: no memory region specified for loadable section `.rodata'... how can i know which object's (.o) .rodata section is being left out of my linker script?</p></li>
  </ol>
  
  <hr>
  
  <p>update:
  i realized that if the sprintf() function is called in main(), the program can compile and link successfully.. but if i call the sprintf() function in other functions, i will get above linking errors (no memory region specified for loadable section .bss), even if i used *(.bss) as the input sections for my output sections.</p>