Parse Error in Diab compiler - c

i'm trying to run LZMA (C version) (7-zip.org/sdk.html) on an MPC5748G from NXP, by compiling a simple code to encode/decode a stream , but i get some errors ...
However the files are compiled successfully on my laptop and i was able to run the LZMA application
Here is the errors that DCC displays:
scons: done reading SConscript files.
scons: Building targets ...
..\tools\wr\mpc5748_wr594\diab\5.9.4.2\WIN32\bin\dcc.exe -c -Xenum-is-best -Xrtti-off -Xexceptions-off -Xforce-declarations -ee1481 -tPPCVLEES:simple -Xsection-split -g3 -XO -Xsize-opt -DTGT_MPC5748_WR594 -DC_DERIVATIVE_MPC5748G -DFREESCALE_OS -DAUTOSAR_OS_USED -DOSDIABPPC -DADC_INTERRUPT_TYPE=MCAL_ISR_TYPE_NONE -DCAN_INTERRUPT_TYPE=MCAL_ISR_TYPE_NONE -DGPT_INTERRUPT_TYPE=MCAL_ISR_TYPE_NONE -DICU_INTERRUPT_TYPE=MCAL_ISR_TYPE_NONE -DLIN_INTERRUPT_TYPE=MCAL_ISR_TYPE_NONE -DPWM_INTERRUPT_TYPE=MCAL_ISR_TYPE_NONE -DSPI_INTERRUPT_TYPE=MCAL_ISR_TYPE_NONE -DTGT_DBG -DTGT_APP -DCFG_CFG -DCFG_CAN -DCFG_CSL -DCFG_MCU -DCFG_DUT -DCFG_MEM -DCFG_MOV -DCFG_GPI -DCFG_GPO -DCFG_ADC -DCFG_SED -DCFG_FRY -DCFG_LPM -DCFG_ETH -IC:\GW_MCU\tools\wr\mpc5748_wr594\diab\5.9.4.2\include -Ibsw\mcal\mcalAS\inc -I. lib\lzma\Alloc.c -o lib\lzma\Alloc.o
..\tools\wr\mpc5748_wr594\diab\5.9.4.2\WIN32\bin\dcc.exe -tPPCVLEES:simple -u__lear_calypso_memory_init -Wl,-Xremove-unused-sections -Wl,-Xunused-sections-list -lc -Wl,-m6 -Wm bsw/mcal/mcalm/linkerDescriptionVLE_App.dld -o out\app\BmwBdc2018GwmDutApp.elf out/app\objToLink.inl 1>out/app/BmwBdc2018GwmDutApp.map
dld: warning: Undefined symbol '__HEAP_END' in file 'sbrk.o(C:\GW_MCU\tools\wr\mpc5748_wr594\diab\5.9.4.2\PPCVLEE\libchar.a)'
dld: warning: Undefined symbol '__HEAP_START' in file 'sbrk.o(C:\GW_MCU\tools\wr\mpc5748_wr594\diab\5.9.4.2\PPCVLEE\libchar.a)'
dld: error: Undefined symbols found - no output written
This error is proper to diab compiler and here is what i've found in documentation:
Dynamic Memory Allocation - the heap, malloc( ), sbrk( )
malloc( ) allocates memory from a heap managed by function sbrk( ) in src/sbrk.c.
There are two ways to create the heap:
■ Define __HEAP_START and __HEAP_END, typically in a linker command file.
See the files conf/default.dld, conf/sample.dld, and 25.6 Command File
Structure, p.419 for examples.
■ Recompile sbrk.c as follows:
dcc -ttarget -c -D SBRK_SIZE=n sbrk.c
where n is the size of the desired heap in bytes.
I'm not the author of either source code of target neither LZMA SDK in C.
What i have understood is that the LZMA encoder allocate at least 1Mb of RAM for the encoder and The MPC5748 provide only 768Kb of RAM.
So i have tagged the question to LZMA and diab compiler(No tag found) , only someone how worked in both could help me
UPDATE :
i removed the problem in dld: warning: Undefined symbol 'LzmaEncProps_Init' in file 'lib/lzma/LzmaLib.o'by including the corresponding source file into my makefile however the HEAP problem persist.
The problem disapeared However the apps doesn't run
Using trace32 debugger i was able to diagnostic the source of this error:
at line
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
The line returns empty p->probs so it seems that alloc has not been able to allocate all the needed size
Thanks

Maybe malloc is not allowed in the MCU that you are using, try to use static allocation or implement your own malloc.
You can found a usefull explanation here:
https://www.quora.com/Why-is-malloc-harmful-in-embedded-systems

Related

ESP8266: What can I do to overcome "section `.text' will not fit in region `iram1_0_seg'"?

What are general measures against the .text region not fitting into "iram1_0_seg" when linking for the ESP8266 using the xtensa GCC based toolchain?
I guess that the ESP8266s RAM is not big enough to hold certain functions. However, what can I do to move as many functions into flash as possible?
Here is an example of what the linker returns:
/home/user/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-gcc -I/home/user/git/esp-open-sdk/sdk/include -I/home/user/git/esp-open-sdk/sdk/include/json -I/home/user/git/mart3/src/RTMain/ESP8266TargetGroup -Os -D__ESP8266__ -std=c99 -pedantic -Wall -Wpointer-arith -pipe -Wno-unused-parameter -Wno-unused-variable -Os -g -O2 -Wpointer-arith -Wundef -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH -ffunction-sections -fdata-sections -L/home/user/.arduino15/packages/esp8266/hardware/esp8266/2.0.0/tools/sdk/lib -L/home/user/.arduino15/packages/esp8266/hardware/esp8266/2.0.0/tools/sdk/ld -Teagle.flash.512k0.ld -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--gc-sections src/code/CMakeFiles/FX6CodeObj.dir/FX6Generated/src-gen/fxfu___program1.c.obj src/code/CMakeFiles/FX6CodeObj.dir/FX6Generated/src/emptyHello/fxfu___helloart.c.obj src/code/CMakeFiles/FX6CodeObj.dir/FXStd/FXRTMain.c.obj src/code/CMakeFiles/FX6CodeObj.dir/FXStd/NamedList.c.obj -o src/ARTApp/ARTApp.out -Wl,--start-group src/ART/libART.a -lm -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig -lwps -lcrypto -laxtls -Wl,--end-group
/home/user/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: src/ARTApp/ARTApp.out section `.text' will not fit in region `iram1_0_seg'
collect2: error: ld returned 1 exit status
I don't know about Arduino but if you were to program using the Espressif libraries found here https://github.com/esp8266/esp8266-wiki/raw/master/sdk/ then they have a lot of Macros for things such as that.
As an example the "main" of the ESP is put into flash using the following line.
void ICACHE_FLASH_ATTR user_init(){
If you trace the ICACHE... command you will find this define
#define ICACHE_FLASH_ATTR __attribute__((section(".irom0.text")))
If you then look through how espressif sets up the memory sections https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map .irom0.text is labelled as the flash memory. Basically anything with the ICACHE... command is loaded into flash memory anything without is not.
Again not sure how to translate this to Arduino code but it might be time to move away from the Arduino libraries if you are running out of flash space. You didn't specify which ESP breakout you are using and my mind may be playing tricks on me but I believe the ESP12-e uses a newer chip which has more flash memory then say the ESP01, just another option.
It is a little late to answer the question but I thought others may be interested in a possible solution. This is what I have done to figure out about the iram1_0_seg overflow error on ESP8266 nonos sdk based firmware.
In order to find out what functions are actually allocated in the iram1_0_seg section run the following command:
$ xtensa-lx106-elf-nm -av yourprogram.elf | uniq -u | grep "^4010*"
The 'yourprogram.elf' of course needs to be replaced with the name of your firmware elf file. All iram1_0_seg functions are in the range of 4010xxxx addresses, hence the grep 4010. Obviously, this command can only be executed when the elf has been generated. If the elf file can not be generated due to the iram1_0_seg overflow error, then it is necessary to remove some code. Or roll back to a version of your code that was still fitting and did not have the iram1_0_seg overflow error.
The output of the above nm command will end with a line such as:
$ 4010680c A _text_end
The iram1_0_seg is limited to 0x8000 bytes on the ESP8266. In the above example, I have '0x680c' bytes allocated and therefore there is enough room. The nm command will list all functions allocated in the iram1_0_seg segment. Please look which of the functions are maybe not needed to be allocated in RAM. Most functions can run out of FLASH, but if you don't mark them with ICACHE_FLASH_ATTR, then the functions end up in RAM (and use up the 0x8000 bytes).
In case you see functions that should be in FLASH (but aren't), that actually come from the standard libraries libc.a or libgcc.a, then you have a good chance to make room in the iram1_0_seg segment. Let's take the example of memcpy, which is available in rom already and should not be needed at all in any library. The reason why it is anyway pulled from libc.a is due to the precedence that libraries take over PROVIDE statements in the linker script. Take a look at your eagle.rom.addr.v6.ld file (in your /esp-open-sdk/sdk/ld folder). In there you see the PROVIDE(memcpy=..) statement.
This tells you that memcpy is available in ROM. So, how to use the ROM function instead of the libc.a version? The easiest way is to simply remove memcpy from libc.a so that the linker takes the rom function. To be safe, I'm suggesting to make a copy of libc.a before, just in case something goes wrong. The following commands need to be executed in the library folder (where libc.a is located) in order to remove memcpy:
$ cp libc.a libc2.a
$ ar d libc2.a lib_a-memcpy.o
After you have changed your Makefile to link with -lc2 instead of -lc, the 'memcpy' function will be taken from ROM. Check with the above nm command to see that it was successful. memcpy should be no more listed in the 401 list. And maybe repeat with other libc.a functions (e,g, 'memcmp', 'strlen', 'strcpy', 'strcmp', ...).
This is how I brought the iram1_0_seg usage down to 0x680c bytes.
Similar procedure can be done with libgcc.a functions: __muldf3, __mulsf3, __umulsidi3, ...
You can try to change the memory allocation scheme by choosing another option in the Tools > MMU section. For example choose '16KB cache + 48KB IRAM (IRAM)' instead of '32KB cache + 32KB IRAM (balanced)'.

Static linking creates Segmentation Fault error

I have a problem linking my C application statically. All libraries exist (.a) and just a month ago I was able to static link my application without an error. But as soon as I activate the static linking option in eclipse, I can compile without an error but when I try to run it, I receive an "Segmentation Error" and it stops.
I tried to debug and that is what eclipse is showing me:
No source available for "_start() at 0x4017f7"
No source available for "__libc_start_main() at 0x522389"
No source available for "__libc_csu_init() at 0x5228f7"
No source available for "frame_dummy() at 0x4018bd"
No source available for "__register_frame_info_bases() at 0x52194b"
No source available for "0x0"
I use the following libraries: -lgcrypt -lgpg-error -lmxml -lpthread -lrt. Any ideas what the problem could be? I can also post the gdb traces, but its long.
Linker command:
Invoking: Invoking: GCC C Linker
gcc -static -o "X - Client" ./src/lib/stopwatch-0.2/stopwatch.o ./src/lib/rscode-1.3/berlekamp.o ./src/lib/rscode-1.3/crcgen.o ./src/lib/rscode-1.3/galois.o ./src/lib/rscode-1.3/rs.o ./src/lib/Salsa20/ecrypt.o ./src/lib/helper-Client.o ./src/PoR-Client.o -lgcrypt -lgpg-error -lmxml -lpthread -lrt
Finished building target: X - Client
This is probably not a problem with the linking. You probably have a problem with reading uninitialized memory, or reading and writing past the end of an array.
What happens in such cases is that on one build the memory you are reading just happens to be set to a non-crashing value ( e.g. you read past the end of an array into an area that has zeroes ), but then in another build the data structures are in a different order and now you are reading from something with unexpected values.
Or you could in one build be writing past the end into a data structure that you don't need any more, and this build, the thing past the end of the array is critical.
Also check if your program runs differently on debug vs. optimized builds. Optimization changes the layout, padding and initialization of data structures. ( e.g. debug builds will for example typically zero all memory, and stack frames are padded out with debugging data ).
I strongly suggest you run your program through a tool like valgrind. It will find these kinds of problems for you.

ld: access beyond end of merged section

i'm trying to link a simple c program on an arm debian machine (a raspberry pi) and when linking the ogject file the linker returns me the error in the subject.
my program is as simple as
simple.c:
int main(){
int a = 2;
int b = 3;
int c = a+b;
}
i compile it with
$>gcc -o simple.obj simple.c
and then link it with
$>ld -o simple.elf simple.obj
ld: simple.obj: access beyond end of merged section (33872)
i can't understand why...
if i try to read the elf file with objdump -d it doesn't manage to decompile the .text section (it only prints address, value, .word and again value preceded by 0x) but the binary data is the same as the one i get from the decompiled simple.obj.
the only difference is in the loading start (and consequent) addresses of the binary data: the elf file starts at 0x8280, the object file starts at 0x82a0.
what does all this mean?
EDIT:
this is the dump for the obj file: http://pastebin.com/YZ94kRk4
and this is the dump for the elf file: http://pastebin.com/3C3sWqrC
i tried compiling with -c option that makes gcc stop after assembly time (it already did the linking part) but now i have a different problem: it says that there is no _start section in my object file...
the new dumps are:
simple.obj: http://pastebin.com/t0TqmgPa
simple.elf: http://pastebin.com/qD35cnqw
You are misunderstanding the effect of the commands you ran. If you run:
$ gcc -o simple.obj simple.c
it already creates the program you want to run, it's already linked. You don't need to link it again, especially by running ld directly unless you know what you are doing. Even if its extension is obj, it doesn't matter, it's just the name of the file, but the content of the file is already a complete Linux program. So if you run:
$ ./simple.obj
it will execute your code.
You usually don't call ld directly, but instead you use gcc as a front-end to compile and link. This is because gcc takes care of linking also important libraries that you are not linking such as the startup code, and that's the reason why your second attempt resulted in "no _start section" or something like that.
Could you print the output of the objdump -d command?
Btw, notice that 33872 == 0x8450.
I am not familiar with raspberry PI's memory map, so if you'r following any tutorials about this or have some other resource to help me help you out - it would be great :)

Can I modify the dynamic linker and use without recompiling the glibc?

I am trying to modify the dynamic linker provided in the libc6(2.15-0ubuntu20.2) on a 64 bit Ubuntu machine.
So currently my code is using the same version of the glibc library. (I have downloaded the source code for the same and working on it). My question is that is it possible to modify and build only the linker source code which is present in glibc\elf\ directory without building the entire glibc library.
And if it is possible how can I make my test program to switch using the new version of dynamic linker that I have build myself instead of using the default unmodified linker.
Any pointers or suggestions are highly appreciated.
(If any more information is needed please let me know)
EDIT::
#constantius
I followed the steps in the post linked by you to build ld.so.
But I am getting following error on the make and I checked ld.so is not there in the elf.
The error is::
/var/services/homes/abhi/test/ld/eglibc-build/elf/librtld.os: In function `generic_getcwd':
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:356: undefined reference to `__closedir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:368: undefined reference to `__fdopendir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:384: undefined reference to `__readdir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:397: undefined reference to `rewinddir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:528: undefined reference to `__closedir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:490: undefined reference to `__closedir'
collect2: error: ld returned 1 exit status
make[2]: *** [/var/services/homes/abhi/test/ld/eglibc-build/elf/ld.so] Error 1
make[2]: Leaving directory `/var/services/homes/abhi/test/ld/eglibc-2.15/elf'
make[1]: *** [elf/subdir_lib] Error 2
make[1]: Leaving directory `/var/services/homes/abhi/test/ld/eglibc-2.15'
make: *** [all] Error 2
NOTE With the same infrastructure I can build and install the full GLIBC so I dont think there is an error with the infrastructure.
-- I guess the error is some where related to editing Makeconfig to all-subdirs = csu elf gmon io misc posix setjmp signal stdlib string time.
--Any suggestions on this..
SOLVED
Need to add dirent in the all-subdirs list in addition to what we edited before
Thanks
Citing this page. In case you don't get something, comment please — I'll try to explain.
Building
To compile Glibc (ld.so cannot be compiled independently) download and unpack Glibc source tarball.
1 Make sure the version of Glibc you downloaded is the same as the system's current one.
2 Make sure the environmental variable LD_RUN_PATH is not set.
3 Read the INSTALL and make sure all necessary tool chains (Make, Binutils, etc) are up-to-date.
4 Make sure the file system you are doing the compilation is case sensitive, or you will see weird errors like
/scratch/elf/librtld.os: In function `process_envvars':
/tmp/glibc-2.x.y/elf/rtld.c:2718: undefined reference to `__open'
...
5 ld.so should be compiled with the optimization flag on (-O2 is the default). Failing to do so will end up with weird errors (see Question 1.23 in FAQ)
6 Suppose Glibc is unpacked at
/tmp/glibc-2.x.y/
Then edit /tmp/glibc-2.x.y/Makefile.in: Un-comment the line
# PARALLELMFLAGS = -j 4
and change 4 to an appropriate number.
7 Since we are only interested in ld.so and not the whole Glibc, we only want to build the essential source files needed by ld.so. To do so, edit /tmp/glibc-2.x.y/Makeconfig: Find the line started with
all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
...
and change it to
all-subdirs = csu elf gmon io misc posix setjmp signal stdlib string time
8 Find a scratch directory, say /scratch. Then
$ cd /scratch
$ /tmp/glibc-2.x.y/configure --prefix=/scratch --disable-profile
$ gmake
Since we are not building the entire Glibc, when the gmake stops (probably with some errors), check if /scratch/elf/ld.so exists or not.
ld.so is a static binary, which means it has its own implementation of standard C routines (e.g. memcpy, strcmp, etc) It has its own printf-like routine called _dl_debug_printf.
Testing
You can run the ld-linux.so directly. It will complain that this is probably not what you want (but you want exactly this) and offer you list of options with which you can run it. See also man ld-linux.so for debugging flags, i.e. there's LD_DEBUG environment variable you can define to see ld-linux.so debugging output.
While I'm not clear on whether the build system for glibc makes doing this easy, there's no fundamental reason why you can't build and use the glibc dynamic linker without building libc.so. I would peruse the top-level Makefile for ways to make this work.
As for testing it, there are two methods:
Explicitly invoke the dynamic linker to run a program, as in:
./ld-linux.so.2 a.out args ...
When linking your program, specify an alternate dynamic linker pathname (which will get stored in its PT_INTERP program header) by passing this option to the compiler driver:
-Wl,-dynamic-linker,/path/to/alternate/ld-linux.so.2

Using talloc in an embedded project

I would like to be able to use talloc in an embedded project I am working on, but have been unable to determine how I go about incorporating it into my development environment. The environment in question is a vendor-supplied Windows IDE that uses ARM GCC 4.4.1, and I am using it to target an ARM7 device.
I have gotten to the stage where the compiler is complaining about conflicting types:
In file included from .\talloc-2.0.8\talloc.c:33:
.\talloc-2.0.8\lib\replace/replace.h:626: error: conflicting types for 'ptrdiff_t'
c:\program files (x86)\cypress\psoc creator\2.2\psoc creator\import\gnu_cs\arm\4.4.1\bin\../lib/gcc/arm-none-eabi/4.4.1/include/stddef.h:149: note: previous declaration of 'ptrdiff_t' was here
.\talloc-2.0.8\lib\replace/replace.h:848: error: conflicting types for 'useconds_t'
c:\program files (x86)\cypress\psoc creator\2.2\psoc creator\import\gnu_cs\arm\4.4.1\bin\../lib/gcc/arm-none-eabi/4.4.1/../../../../arm-none-eabi/include/sys/types.h:253: note: previous declaration of 'useconds_t' was here
.\talloc-2.0.8\talloc.c:123: error: expected specifier-qualifier-list before 'uint8_t'
I noticed that replace.h tries to include a file called config.h that does not exist in the talloc source tree - a problem I got around by creating a blank file by that name. Is the idea to use config.h to inform talloc what functions are already defined by the system? Is this just a matter of using the #define directive to prevent replace.h from trying to replace existing types?
Given that this is the first time I have attempted to use code that I did not write myself in a project, I am somewhat confused as to how to go about reconciling these conflicts.
config.h should be generated automatically. For tmalloc, it's done by waf (python-based build system).
$ python ./buildtools/bin/waf configure
Checking for program gcc or cc : /usr/lib/ccache/gcc
Checking for program cpp : /usr/bin/cpp
Checking for program ar : /usr/bin/ar
Checking for program ranlib : /usr/bin/ranlib
Checking for gcc : ok
Checking for program git : /usr/bin/git
Check for -MD : yes
....
$ python ./buildtools/bin/waf build
.....

Resources