Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Semihosting error - alignment issue
#1
I have found a problem with semihosting which seems to be caused by an odd byte aligned string in initialise_monitor_handles.

Board: STM32F407VG Discovery

I was having erratic results with semihosting - somtimes it worked, sometimes it didn't. I created a project using the wizard, enabled semihosting, no standard peripheral library. I managed to reduced the code to a minimum which illustrates the problem:

#include "stm32f4xx.h"
#include <stdio.h>
#include <errno.h>
int i=0, j=0 ,k;

int main(void)
{
    i = printf("\fBegin\n");
    j = errno;
    printf("Done12\n");
}

Nothing is output on the console. Interestingly the first printf() returns 7 which is correct but errno is 22 - EINVAL

Now change the last printf to "Done123\n" and it seems to work - ie. the output appears on the console, but now printf() returns -1 and errno is 0! "Done1234\n" also works as does "Done1234567\n" but "Done12345\n" doesn't.

Investigating further, the problem comes from the constant strings in the rodata part of main.o containing the path name passed to the SYS_OPEN() call via BKPT 0xAB at the start of initialise_monitor_handles() when populating the file descriptor tables. The path string is ":tt" which is used to get the file handles for stdin, stdout and stderr from the gdbserver. When semihosting fails, this string is located at an odd byte address and SYS_OPEN() returns -1 for the stdin FD handle. From the map file:

.rodata.str1.1
                0x200019bf        0x4 d:/development/tools/embitz/1.11/share/em_armgcc/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/lib/armv7e-m/fpu\librdimon_n.a(rdimon-syscalls.o)
 *fill*         0x200019c3        0x1 

(I am executing from RAM and relocating the vector table to 0x20000000)

Adding '3' to the last printf 16 bit word aligns the ":tt" string and the SYS_OPEN() call suceeds.

So it appears there are two errors - 1) the gdbserver can't handle the path string not being word aligned, and 2) the returns from printf() and errno are wrong. Interestingly when the file handle table is incorrectly setup due to the odd alignment of the path string, printf() eventually calls SYS_WRITEC() via BKPT 0xAB (ouptut a single character) but when semihosting appears to work SYS_WRITE0() is invoked to output the whole string.

Hope there is enough there to resolve the problem. I don't have source to rdimon or newlib so I diagosed the above by stepping through the assembler. I have attached the project.


Attached Files
.zip   Semihosting.zip (Size: 119.91 KB / Downloads: 34)
Reply
#2
FWIW the problem didn't occur in version 0.42 because the earlier GCC compiler/linker appears to have always 32bit aligned the const strings in .rodata.

I can't see any reason why strings shouldn't be byte aligned but there may be a compiler/linker op[tion to force 32bit alignment. The bug where printf returns the wrong value was the same in 0.42 - probably a newlib bug.

What surprises me is that no one seems to have come across semihosting not working in version 1.11 - is it that little used or have I done something wrong? Can anyone else confirm this problem?
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)