Source for __libc_init_array and other mystery code showing up in my disassembly

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a very simple Atmel Studio 7 project for the SAM L21, and the disassembly shows some machine code generated after the end of my vector table, but before my reset handler or main().

 

I've tracked it down to these lines in my .ld file:

 

    KEEP (*(.init_array))

    ....

    KEEP (*(.fini_array))

 

If I remove both of the lines, the mystery machine code disappears.  Leaving either one in results in the exact same amount of mystery code.  A full disassembly listing is below, with the start of that code in question marked at 0xB4.

 

I've been doing some reading, and I suspect the space is being used by the libc library.  I've read __libc_init_array() looks for a list of function pointers to invoke to handle data initialization.  I don't have any variables or arrays defined in my own code, so it must be coming from libc or the SAM headers (I'm not using START or ASF).  Unfortunately I can't "Goto Implementation" for __libc_init_array (I guess it's in a precompiled .a file that ships with GCC?), and I haven't managed to locate any constructor(###) attributes in any of the header files or other dependencies for which I have source code.

 

I'm not super thrilled about compiled machine code ending up in my binary for which I can't view the source.  (How am I supposed to verify the code is legit, unlikely to contain exploits, etc?).

 

I tried adding the -nostartfiles switch but it didn't do anything.  Any suggestions on where I can get the original source code responsible for that machine code, and how I can integrate it into my project in place of the obfuscated pieces?

 

I'd be open to leaving it out altogether and handling my own variable and array initializations, but I don't want to inadvertantly break something else in a library.

 

Thanks!

 

--- No source file -------------------------------------------------------------
00000000 70.24                 movs	r4, #112    ; initial stack pointer (0x20002470)
00000002 00.20                 movs	r0, #0
00000004 19.01                 lsls	r1, r3, #4  ; reset vector to Reset_Handler (0x118)
00000006 00.00                 movs	r0, r0
00000008 15.01                 lsls	r5, r2, #4  ; NMI vector to Dummy_Handler (0x0114)
0000000A 00.00                 movs	r0, r0
0000000C 15.01                 lsls	r5, r2, #4  ; HardFault vector to Dummy_Handler
0000000E 00.00                 movs	r0, r0
00000010 00.00                 movs	r0, r0      ; reserved
00000012 00.00                 movs	r0, r0
00000014 00.00                 movs	r0, r0      ; reserved
00000016 00.00                 movs	r0, r0
00000018 00.00                 movs	r0, r0      ; reserved
0000001A 00.00                 movs	r0, r0
0000001C 00.00                 movs	r0, r0      ; reserved
0000001E 00.00                 movs	r0, r0
00000020 00.00                 movs	r0, r0      ; reserved
00000022 00.00                 movs	r0, r0
00000024 00.00                 movs	r0, r0      ; reserved
00000026 00.00                 movs	r0, r0
00000028 00.00                 movs	r0, r0      ; reserved
0000002A 00.00                 movs	r0, r0
0000002C 15.01                 lsls	r5, r2, #4  ; SVCall vector to Dummy_Handler
0000002E 00.00                 movs	r0, r0
00000030 00.00                 movs	r0, r0      ; reserved
00000032 00.00                 movs	r0, r0
00000034 00.00                 movs	r0, r0      ; reserved
00000036 00.00                 movs	r0, r0
00000038 15.01                 lsls	r5, r2, #4  ; PendSV vector to Dummy_Handler
0000003A 00.00                 movs	r0, r0
0000003C 15.01                 lsls	r5, r2, #4  ; SysTick vector to Dummy_Handler
0000003E 00.00                 movs	r0, r0
00000040 15.01                 lsls	r5, r2, #4  ; SYSTEM (PM, MCLK, OSCCTRL, OSC32KCTRL,
00000042 00.00                 movs	r0, r0      ;         SUPC, PAC)
00000044 15.01                 lsls	r5, r2, #4  ; WDT
00000046 00.00                 movs	r0, r0
00000048 15.01                 lsls	r5, r2, #4  ; RTC
0000004A 00.00                 movs	r0, r0
0000004C 15.01                 lsls	r5, r2, #4  ; EIC
0000004E 00.00                 movs	r0, r0
00000050 15.01                 lsls	r5, r2, #4  ; NVMCTRL
00000052 00.00                 movs	r0, r0
00000054 15.01                 lsls	r5, r2, #4  ; DMAC
00000056 00.00                 movs	r0, r0
00000058 15.01                 lsls	r5, r2, #4  ; USB
0000005A 00.00                 movs	r0, r0
0000005C 15.01                 lsls	r5, r2, #4  ; EVSYS
0000005E 00.00                 movs	r0, r0
00000060 15.01                 lsls	r5, r2, #4  ; SERCOM0
00000062 00.00                 movs	r0, r0
00000064 15.01                 lsls	r5, r2, #4  ; SERCOM1
00000066 00.00                 movs	r0, r0
00000068 15.01                 lsls	r5, r2, #4  ; SERCOM2
0000006A 00.00                 movs	r0, r0
0000006C 15.01                 lsls	r5, r2, #4  ; SERCOM3
0000006E 00.00                 movs	r0, r0
00000070 15.01                 lsls	r5, r2, #4  ; SERCOM4
00000072 00.00                 movs	r0, r0
00000074 15.01                 lsls	r5, r2, #4  ; SERCOM5
00000076 00.00                 movs	r0, r0
00000078 15.01                 lsls	r5, r2, #4  ; TCC0
0000007A 00.00                 movs	r0, r0
0000007C 15.01                 lsls	r5, r2, #4  ; TCC1
0000007E 00.00                 movs	r0, r0
00000080 15.01                 lsls	r5, r2, #4  ; TCC2
00000082 00.00                 movs	r0, r0
00000084 15.01                 lsls	r5, r2, #4  ; TC0
00000086 00.00                 movs	r0, r0
00000088 15.01                 lsls	r5, r2, #4  ; TC1
0000008A 00.00                 movs	r0, r0
0000008C 15.01                 lsls	r5, r2, #4  ; TC2
0000008E 00.00                 movs	r0, r0
00000090 15.01                 lsls	r5, r2, #4  ; TC3
00000092 00.00                 movs	r0, r0
00000094 15.01                 lsls	r5, r2, #4  ; TC4
00000096 00.00                 movs	r0, r0
00000098 15.01                 lsls	r5, r2, #4  ; ADC
0000009A 00.00                 movs	r0, r0
0000009C 15.01                 lsls	r5, r2, #4  ; AC
0000009E 00.00                 movs	r0, r0
000000A0 15.01                 lsls	r5, r2, #4  ; DAC
000000A2 00.00                 movs	r0, r0
000000A4 15.01                 lsls	r5, r2, #4  ; PTC
000000A6 00.00                 movs	r0, r0
000000A8 15.01                 lsls	r5, r2, #4  ; AES
000000AA 00.00                 movs	r0, r0
000000AC 15.01                 lsls	r5, r2, #4  ; TRNG
000000AE 00.00                 movs	r0, r0
000000B0 00.00                 movs	r0, r0      ; reserved
000000B2 00.00                 movs	r0, r0
000000B4 10.b5                 push	{r4, lr}    ; START OF MYSTERY CODE
000000B6 06.4c                 ldr	r4, [pc, #24]
000000B8 23.78                 ldrb	r3, [r4]
000000BA 00.2b                 cmp	r3, #0
000000BC 07.d1                 bne	#14
000000BE 05.4b                 ldr	r3, [pc, #20]
000000C0 00.2b                 cmp	r3, #0
000000C2 02.d0                 beq	#4
000000C4 04.48                 ldr	r0, [pc, #16]
000000C6 00.e0                 b	#0
000000C8 00.bf                 nop
000000CA 01.23                 movs	r3, #1
000000CC 23.70                 strb	r3, [r4]
000000CE 10.bd                 pop	{r4, pc}
000000D0 2c.04                 lsls	r4, r5, #16
000000D2 00.20                 movs	r0, #0
000000D4 00.00                 movs	r0, r0
000000D6 00.00                 movs	r0, r0
000000D8 98.03                 lsls	r0, r3, #14
000000DA 00.00                 movs	r0, r0
000000DC 08.4b                 ldr	r3, [pc, #32]
000000DE 10.b5                 push	{r4, lr}
000000E0 00.2b                 cmp	r3, #0
000000E2 03.d0                 beq	#6
000000E4 07.49                 ldr	r1, [pc, #28]
000000E6 08.48                 ldr	r0, [pc, #32]
000000E8 00.e0                 b	#0
000000EA 00.bf                 nop
000000EC 07.48                 ldr	r0, [pc, #28]
000000EE 03.68                 ldr	r3, [r0]
000000F0 00.2b                 cmp	r3, #0
000000F2 00.d1                 bne	#0
000000F4 10.bd                 pop	{r4, pc}
000000F6 06.4b                 ldr	r3, [pc, #24]
000000F8 00.2b                 cmp	r3, #0
000000FA fb.d0                 beq	#-10
000000FC 98.47                 blx	r3
000000FE f9.e7                 b	#-14
00000100 00.00                 movs	r0, r0
00000102 00.00                 movs	r0, r0
00000104 30.04                 lsls	r0, r6, #16
00000106 00.20                 movs	r0, #0
00000108 98.03                 lsls	r0, r3, #14
0000010A 00.00                 movs	r0, r0
0000010C 98.03                 lsls	r0, r3, #14
0000010E 00.00                 movs	r0, r0
00000110 00.00                 movs	r0, r0
--- F:\Project\Code\Sam1\Debug/../Device_Startup/startup_saml21.c
00000112 00.00                 movs	r0, r0      ; END OF MYSTERY CODE 
{
00000114 fe.e7                 b	#-4         ; Dummy_Handler() - while(1)
--- No source file -------------------------------------------------------------
00000116 00.00                 movs	r0, r0      ; alignment padding?
--- F:\Project\Code\Sam1\Debug/../Device_Startup/startup_saml21.c
{
00000118 10.b5                 push	{r4, lr}    ; Reset_Handler()
        if (pSrc != pDest) {
0000011A 12.4a                 ldr	r2, [pc, #72]
0000011C 12.4b                 ldr	r3, [pc, #72]
0000011E 9a.42                 cmp	r2, r3
00000120 09.d0                 beq	#18
00000122 11.4b                 ldr	r3, [pc, #68]
--- F:\Project\Code\Sam1\Debug/../Device_Startup/startup_saml21.c
00000124 0f.4a                 ldr	r2, [pc, #60]
00000126 03.e0                 b	#6
                        *pDest++ = *pSrc++;
00000128 11.68                 ldr	r1, [r2]
0000012A 19.60                 str	r1, [r3]
0000012C 04.33                 adds	r3, #4
0000012E 04.32                 adds	r2, #4
                for (; pDest < &_erelocate;) {
00000130 0e.49                 ldr	r1, [pc, #56]
00000132 8b.42                 cmp	r3, r1
00000134 f8.d3                 blo	#-16
                        *pDest++ = *pSrc++;
00000136 0e.4b                 ldr	r3, [pc, #56]
00000138 02.e0                 b	#4
                *pDest++ = 0;
0000013A 00.22                 movs	r2, #0
0000013C 1a.60                 str	r2, [r3]
0000013E 04.33                 adds	r3, #4
        for (pDest = &_szero; pDest < &_ezero;) {
00000140 0c.4a                 ldr	r2, [pc, #48]
00000142 93.42                 cmp	r3, r2
00000144 f9.d3                 blo	#-14
        SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk);
00000146 0c.4a                 ldr	r2, [pc, #48]
00000148 ff.21                 movs	r1, #255
0000014A 0c.4b                 ldr	r3, [pc, #48]
0000014C 8b.43                 bics	r3, r1
0000014E 93.60                 str	r3, [r2, #8]
        NVMCTRL->CTRLB.bit.MANW = 1;
00000150 0b.4a                 ldr	r2, [pc, #44]
00000152 51.68                 ldr	r1, [r2, #4]
00000154 80.23                 movs	r3, #128
00000156 0b.43                 orrs	r3, r1
00000158 53.60                 str	r3, [r2, #4]
        __libc_init_array();
0000015A 0a.4b                 ldr	r3, [pc, #40]
0000015C 98.47                 blx	r3
        main();
0000015E 0a.4b                 ldr	r3, [pc, #40]
--- F:\Project\Code\Sam1\Debug/../Device_Startup/startup_saml21.c
00000160 98.47                 blx	r3
00000162 fe.e7                 b	#-4
00000164 98.03                 lsls	r0, r3, #14
00000166 00.00                 movs	r0, r0
00000168 00.00                 movs	r0, r0
0000016A 00.20                 movs	r0, #0
0000016C 2c.04                 lsls	r4, r5, #16
0000016E 00.20                 movs	r0, #0
00000170 2c.04                 lsls	r4, r5, #16
00000172 00.20                 movs	r0, #0
00000174 6c.04                 lsls	r4, r5, #17
00000176 00.20                 movs	r0, #0
00000178 00.ed                ??? 		Unknown instruction
0000017A 00.e0                 b	#0
0000017C 00.00                 movs	r0, r0
0000017E 00.00                 movs	r0, r0
00000180 00.40                 ands	r0, r0
00000182 00.41                 asrs	r0, r0
00000184 d1.01                 lsls	r1, r2, #7
00000186 00.00                 movs	r0, r0
00000188 8d.01                 lsls	r5, r1, #6
0000018A 00.00                 movs	r0, r0
--- F:\Project\Code\Sam1\Debug/.././main.c -----------------------
int main(void) {

    // Note: At reset, OSC16M is enabled and configured to 4MHz. GENCTRL0 register defaults to 0x106, which enables
    // Generic Clock Generator 0 and selects OSC16M as its source, feeding the main system clock GCLK_MAIN.
    // Before increasing OSC16M to 16MHz, we need to switch GCLK_MAIN to another source.
    // Temporarily use 32K ultra low power oscillator OSCULP32K as source for Generic Clock Generator 0.
    // At the same time, turn on bit 11 of GENCTRL0 to enable output to the clock's IO pin, GCLK_IO[0].
    //const uint32_t GENCTRL0_REG = GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K;
    GCLK->GENCTRL[0].reg = GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K;
0000018C 0a.4a                 ldr	r2, [pc, #40]
0000018E 0b.4b                 ldr	r3, [pc, #44]
00000190 1a.62                 str	r2, [r3, #32]
    REG_PORT_DIR1 |= PORT_PB10; // Set PB10 (LED) direction to OUT (for LED)
00000192 0b.4a                 ldr	r2, [pc, #44]
00000194 11.68                 ldr	r1, [r2]
00000196 80.23                 movs	r3, #128
00000198 db.00                 lsls	r3, r3, #3
0000019A 0b.43                 orrs	r3, r1
--- F:\Project\Code\Sam1\Debug/.././main.c -----------------------
0000019C 13.60                 str	r3, [r2]
    REG_PORT_DIR0 |= PORT_PA27; // set PA27 direction to OUT (for main clock output)
0000019E 09.4a                 ldr	r2, [pc, #36]
000001A0 11.68                 ldr	r1, [r2]
000001A2 80.23                 movs	r3, #128
000001A4 1b.05                 lsls	r3, r3, #20
000001A6 0b.43                 orrs	r3, r1
000001A8 13.60                 str	r3, [r2]
    REG_PORT_PMUX13 = 0b01110000; // select MUX function H for PA27 (other bits 0 per power-on default)
000001AA 70.22                 movs	r2, #112
000001AC 06.4b                 ldr	r3, [pc, #24]
000001AE 1a.70                 strb	r2, [r3]
    REG_PORT_PINCFG27 = 0b1; // enable MUX function for PA27 (other bits are 0 per power-on default)
000001B0 6f.3a                 subs	r2, #111
000001B2 06.4b                 ldr	r3, [pc, #24]
000001B4 1a.70                 strb	r2, [r3]
000001B6 fe.e7                 b	#-4
000001B8 03.09                 lsrs	r3, r0, #4
000001BA 00.00                 movs	r0, r0
000001BC 00.18                 adds	r0, r0, r0
000001BE 00.40                 ands	r0, r0
000001C0 80.28                 cmp	r0, #128
000001C2 00.40                 ands	r0, r0
000001C4 00.28                 cmp	r0, #0
000001C6 00.40                 ands	r0, r0
000001C8 3d.28                 cmp	r0, #61
000001CA 00.40                 ands	r0, r0
000001CC 5b.28                 cmp	r0, #91
000001CE 00.40                 ands	r0, r0
--- No source file -------------------------------------------------------------
000001D0 70.b5                 push	{r4, r5, r6, lr}
000001D2 0d.4e                 ldr	r6, [pc, #52]
000001D4 0d.4d                 ldr	r5, [pc, #52]
000001D6 00.24                 movs	r4, #0
--- No source file -------------------------------------------------------------
000001D8 ad.1b                 subs	r5, r5, r6
000001DA ad.10                 asrs	r5, r5, #2
000001DC 05.d0                 beq	#10
000001DE a3.00                 lsls	r3, r4, #2
000001E0 f3.58                 ldr	r3, [r6, r3]
000001E2 01.34                 adds	r4, #1
000001E4 98.47                 blx	r3
000001E6 a5.42                 cmp	r5, r4
000001E8 f9.d1                 bne	#-14
000001EA 00.f0.c3.f8           bl	#390
000001EE 08.4e                 ldr	r6, [pc, #32]
000001F0 08.4d                 ldr	r5, [pc, #32]
000001F2 00.24                 movs	r4, #0
000001F4 ad.1b                 subs	r5, r5, r6
000001F6 ad.10                 asrs	r5, r5, #2
000001F8 05.d0                 beq	#10
000001FA a3.00                 lsls	r3, r4, #2
000001FC f3.58                 ldr	r3, [r6, r3]
000001FE 01.34                 adds	r4, #1
00000200 98.47                 blx	r3
00000202 a5.42                 cmp	r5, r4
00000204 f9.d1                 bne	#-14
00000206 70.bd                 pop	{r4, r5, r6, pc}
00000208 80.03                 lsls	r0, r0, #14
0000020A 00.00                 movs	r0, r0
0000020C 80.03                 lsls	r0, r0, #14
0000020E 00.00                 movs	r0, r0
00000210 80.03                 lsls	r0, r0, #14
00000212 00.00                 movs	r0, r0
00000214 88.03                 lsls	r0, r1, #14
00000216 00.00                 movs	r0, r0
00000218 03.4b                 ldr	r3, [pc, #12]
0000021A 10.b5                 push	{r4, lr}
0000021C 00.2b                 cmp	r3, #0
0000021E 02.d0                 beq	#4
00000220 02.48                 ldr	r0, [pc, #8]
00000222 00.f0.05.f8           bl	#10
00000226 10.bd                 pop	{r4, pc}
00000228 00.00                 movs	r0, r0
0000022A 00.00                 movs	r0, r0
0000022C 41.02                 lsls	r1, r0, #9
0000022E 00.00                 movs	r0, r0
00000230 10.b5                 push	{r4, lr}
00000232 01.00                 movs	r1, r0
00000234 00.23                 movs	r3, #0
00000236 00.22                 movs	r2, #0
00000238 00.20                 movs	r0, #0
0000023A 00.f0.1f.f8           bl	#62
0000023E 10.bd                 pop	{r4, pc}
00000240 70.b5                 push	{r4, r5, r6, lr}
00000242 09.4b                 ldr	r3, [pc, #36]
00000244 09.4c                 ldr	r4, [pc, #36]
00000246 e4.1a                 subs	r4, r4, r3
00000248 a4.10                 asrs	r4, r4, #2
0000024A 09.d0                 beq	#18
0000024C 08.4a                 ldr	r2, [pc, #32]
0000024E a5.18                 adds	r5, r4, r2

 

Last Edited: Fri. Jan 31, 2020 - 04:05 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Everything (AFAIK) in the GCC stack is open source. I'm not sure if the link below is the source for your version of the tool chain or not.

 

https://github.com/eblot/newlib/...

 

Atmel provides a release notes file with every version of Atmel Studio, such as this one, which should help:

http://ww1.microchip.com/downloa...

Josh @ CIHOLAS Inc - We fill the gaps from chips to apps

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libc/misc/init.c;h=95f1a742292aa8c07042f1352d4ed878f61d1686;hb=HEAD

 

(that's the official newlib site, I think.)

 

I don't like using newlib for embedded ARMs; it's very "bloaty."  But Everyone Does It, you don't really notice till you start trying to use the tiny ARM chips (SAMx10, etc), so no one seems to have done the equivalent of avr-libc for ARMs. :-(

 

I think you'd want "-nostdlib" rather than "-nostartfiles" to get rid of it.  But you might not get very far without libc...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are there any good alternatives to newlib?  e.g. nanolib?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is "nanolib" the same as "newlib nano"?
It looks like the standard distributions include both newlib and newlib nano, and some common tools (arduino) use the nano version by default.

It looks like AS7 has a project tools/linker/general option for "size optimized library", but it doesn't seem to be the default.