diff options
-rw-r--r-- | docs/exec-formats-and-tools.md | 121 |
1 files changed, 112 insertions, 9 deletions
diff --git a/docs/exec-formats-and-tools.md b/docs/exec-formats-and-tools.md index 3d9e7e8..85367c5 100644 --- a/docs/exec-formats-and-tools.md +++ b/docs/exec-formats-and-tools.md @@ -109,7 +109,6 @@ Table (GOT) and global data pointers values from known offset and 't9' register value. The startup code which conforms these requirements to call 'main()' function looks like this: - ``` /* file crt0local.S - replacement of C library complete startup machinery */ .globl main @@ -151,7 +150,6 @@ pseudo-instruction '.cpload' by sequence adding offset into global data area from actual instruction address and stores result in the 'gp' - ``` 00400500 <__start>: 400500: 04110001 bal 400508 <next> @@ -176,13 +174,12 @@ address and stores result in the 'gp' 40053c: 00000000 nop ``` -It can be seen that assembler not only expands '.cpload' +It can be seen that assembler does not only expand '.cpload' but even marks 'jalr t9' instruction as a target for link time optimization. Because 'main' function is near (offset less than 128 kB) to the startup code, the 'jal' instruction is replaced by 'bal main' during linking phase. - Then simple main function which outputs string to the serial port provided by QtMisp emulator can be implemented as: @@ -226,22 +223,39 @@ int main(void) Compilation: - ``` mips-linux-gnu-gcc -ggdb -fno-lto -c crt0local.S -o crt0local.o mips-linux-gnu-gcc -ggdb -O3 -fno-lto -c serial-port-test.c -o serial-port-test.o mips-linux-gnu-gcc -ggdb -nostartfiles -static -fno-lto crt0local.o serial-port-test.o -o serial-port-test ``` -The simulator implements 'rdhwr $rd, userlocal' instrcution -and allows code compiled agains musl C library to start as well. +Simulator Compatability with Musl libc +-------------------------------------- + +The 'mips-linux-gnu' toolchain can be alternativelly used with [musl libc](http://www.musl-libc.org/). +The library can be built for the MIPS target by command +``` +../musl/configure CC=mips-linux-gnu-gcc LD=mips-linux-gnu-ld --target=mips-linux-gnu \ + --prefix=/opt/musl/mips-linux-gnu --enable-debug --enable-optimize +``` +User projects can be compiled and linked against 'musl libc' by specifying +'-specs' option during C compiler invocation. ``` mips-linux-gnu-gcc -ggdb -O1 -march=mips2 -static -specs=/opt/musl/mips-linux-gnu/lib/musl-gcc.specs -c program.c -o program.o -mips-linux-gnu-gcc -ggdb -march=mips2 -static -specs=/opt/musl/mips-linux-gnu/lib/musl-gcc.specs programo -o program +mips-linux-gnu-gcc -ggdb -march=mips2 -static -specs=/opt/musl/mips-linux-gnu/lib/musl-gcc.specs program.o -o program ``` -The C library startup code which support both PIC/PIE and non-PIC environment +The simulator implements 'rdhwr $rd, userlocal' instruction +and allows code compiled agains [musl C library](http://www.musl-libc.org/). +to start with libc provided 'crt0.o'. But there are multiple syscalls +in the startup code which cause stop of continuous run mode and require +to press run button again. + +It is better to use simple C library startup code replacement. +It is enough to run 'printf()', 'sprintf()' and 'sscanf()' +functions without complete C library initialization. +Next variant supports both PIC/PIE and non-PIC environment. ``` /* minimal replacement of crt0.o which is else provided by C library */ @@ -284,3 +298,92 @@ loop: break .end _start ``` +Using of Make Utility with QtSim +-------------------------------------- + +The invocation of the compiler and 'gcc' in the role of the linker can be automated. +The 'make' utility is the standard solution. Next 'Makefile' provides a template +for automation of these tasks + +``` +ARCH=mips-elf +#ARCH=mips-linux-gnu + +SOURCES = crt0local.S qtmips_binrep.c +TARGET_EXE = qtmips_binrep + +CC=$(ARCH)-gcc +CXX=$(ARCH)-g++ +AS=$(ARCH)-as +LD=$(ARCH)-ld +OBJCOPY=$(ARCH)-objcopy + +#ARCHFLAGS += -march=mips3 +ARCHFLAGS += -fno-lto +#ARCHFLAGS += -mno-shared + +CFLAGS += -ggdb -O3 -Wall +CXXFLAGS+= -ggdb -O3 -Wall +AFLAGS += -ggdb +LDFLAGS += -ggdb +LDFLAGS += -nostartfiles +LDFLAGS += -static +#LDFLAGS += -specs=/opt/musl/mips-linux-gnu/lib/musl-gcc.specs + +CFLAGS += $(ARCHFLAGS) +CXXFLAGS+= $(ARCHFLAGS) +AFLAGS += $(ARCHFLAGS) +LDFLAGS += $(ARCHFLAGS) + +OBJECTS += $(filter %.o,$(SOURCES:%.S=%.o)) +OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o)) +OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o)) + +all : default + +.PHONY : default clean dep all + +%.o:%.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $@ + +%.o:%.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + +%.o:%.cpp + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< + +%.s:%.c + $(CC) $(CFLAGS) $(CPPFLAGS) -S $< -o $@ + +default : $(TARGET_EXE) + +$(TARGET_EXE) : $(OBJECTS) + $(CC) $(LDFLAGS) $^ -o $@ + +dep: depend + +depend: $(SOURCES) $(glob *.h) + echo '# autogenerated dependencies' > depend +ifneq ($(filter %.S,$(SOURCES)),) + $(CC) -D__ASSEMBLY__ $(AFLAGS) -w -E -M $(filter %.S,$(SOURCES)) \ + >> depend +endif +ifneq ($(filter %.c,$(SOURCES)),) + $(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \ + >> depend +endif +ifneq ($(filter %.cpp,$(SOURCES)),) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \ + >> depend +endif + +clean: + rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) depend + +#mips-elf-objdump --source -M no-aliases,reg-names=numeric qtmips_binrep + +-include depend +``` + +The example provides defines which allow select compiler to be used ('mips-elf' +or 'mips-linux-gnu') and enable build agains musl libc. |