compiling SALL calcs for SCD6000 without WindRiver

Schneider released the SCD6000 RTU a while ago now, and while it has come with some good improvements, it has also come with a couple of shitty regressions. One of these shitty regressions is the use of the propriety Wind River C compiler for the compilation of SALL files. I'm guessing that this decision was made because Wind River makes VxWorks, which I believe is the operating system that runs on the SCD RTUs.  However because Wind River is based on GCC, and I don't want to pay many thousands of dollars for a compiler I only use a handful of times a year, I wondered if it was possible to use instead the very free GNU ARM embedded toolchain?

Now I don't actually have any SCD6000 hardware to test on, so this is just what I have come up with so far, and hopefully one day I'll get a chance to test it. On the other hand, if anyone out there wants to test this for me then please do so and let me know the results!

First, lets examine the process of how a SALL file is transformed into an elf binary.

  1. SALL file is converted into a C file.
    For SCD5200 RTUs this is done using the sall.exe file, located in C:\Program Files (x86)\Foxboro\RTU Station\utils\CalcsRTU_SALL\<firmware version>\buildsal\. You can run the program from the command line by using the following syntax: sall.exe infile.sal outfile.c errorfile.
    For SCD6000 RTUs this functionality is built into a dll file that is called directly from RTU Station.
  2. Compile and link the files into an elf file.
    For SCD5200 RTUs this is done with the Watcom compiler, and for SCD6000 RTUs this is done with the Wind River compiler. In both cases a make file is used to invoke the compiler and linker.

A batch file performs steps 1 and 2 for SCD5200 RTUS, and for SCD6000 RTU Station performs step 1 and then calls a batch file to perform step 2.  Now that we know the process, we need to invoke it ourselves without RTU Station.  This means,

  1. Call the sall.dll (without RTU Station) to convert the SALL file into C code
  2. Translate the make file, compiler and linker options from Wind River into GCC compiler and linker options.

Calling sall.dll

sall.dll is a java dll, which means that it was designed to work with a specific java class. The easiest way to call it is to create a new java program with a class of the same name, and call the dll in the way it was intended. To find out what the class is called, and find out the parameters for it we can open up the SysCfg.jar file in jd-gui

We can modify this class as follows and recompile it into our own jar file.

I'll leave out the details regarding compiling the jar file, check out the script in the github repo if you're interested.

To generate the C file from the SALL source, run the java program using the syntax

java -jar SallDLL location_of_sall.dll firmware_version sall_source c_file err_file

Note that I haven't added any error handling to the jar, so if you do anything silly it will just exit and print the exception message.

Compiling the C code

To compile the code we need to translate all of the Wind River compiler options to GCC compiler options.  Many of them are the same, but there are some that are different, and some additional ones that we need to add for GCC that aren't required for Wind River.

WindRiver option GCC option Explanation
-t ARMV7  -march=armv7 Target platform
L  -mlittle-endian Use little-endian format
S Software floating point
-lc  -nostartfiles -nostdlib To cause the linker to search for libc.a for an external reference
-D_SAL_ -D_SAL_ Pre-define macro _SAL_
-Xkeep-assembly-file Always create and keep an assembly(.s) file
-I. -I. Add the current directory to the search path for system include files
-Xstruct-min-align=1 Set minimum structure member alignment to 1
-Xstruct-max-align=4 Set maximum structure member alignment to 4
-Xalign-functions=4  -falign-functions=4 Align each function on an address boundary divisible by 4
 -Xsize-opt  -Os Optimize for size rather than speed
 -Xenum-is-int Specify enum type as integer
 -Xelf-rela To use RELA relocation information format for ELF output
 -r2 Links the program as usual, but creates relocation tables to make it possible for an intelligent loader to relocate the program to another address
 -m2 Generate a more detailed link map of the input and output sections, including symbols and addresses
 -Bt=0  -Ttext 0 Set address for text section, which allocates .text section to the address 0
 -N  -N The .data section is placed immediately after the .text section
 -e calcmain  -e calcmain Defining a default entry point address to calcmain
 -V Display current version of the driver
 --specs=nosys.specs  Disable semihosting support
 -fno-inline Don't inline functions.  Probably don't need this.
 -T ldscript Use a custom linker script.  I have only used this to disable the exporting of symbols such as __data_start because it was overwriting the exports of other symbols.

Rolling all of these into one command, we arrive at:

arm-none-eabi-gcc -D_SAL_ -I. --specs=nosys.specs -march=armv7-a -mlittle-endian -Ttext 0 -Os -N -e calcmain -nostartfiles -nostdlib -fno-inline -falign-functions=4 -marm -T ldscript go_scd6000.c out.c -o out.elf

Summary

To make things easy, I have created a batch file 1101207_E.bat that performs the SALL to C conversion, compiling and linking in one for firmware 1101207-E.  Before using, there are a couple of things you need to download.

  1. The files from the github repo
  2. GNU Embedded ARM compiler
  3. 32bit Java runtime environment (should already have one if RTU Station is installed)
  4. 32bit JDK if you want to compile the SallDLL.jar file manually

Check that the paths in setenv.bat match those on your system, then from the command line call 1101207_E.bat <salfile>.  Make sure that the current directory is set to the location of your SALL file, it's easiest to copy the SALL file into the same directory as the batch file.  The output elf will be created in the same directory.

| October 20th, 2017 | Posted in Foxboro, Reversing, SCADA |

Leave a Reply