I'm new to LLVM and I'm trying to set it up to target a low level embedded device with no OS. Therefore the final program needs to perform variable initialization and be located at a certain address location. Here is my basic flow: Compile C to bytecode: $ llvm-gcc -emit-llvm -c src1.c src2.c src3.c Consolidate to one bytecode file: $ llvm-link -o all.o src1.c src2.o src3.o Emit assembly code: $ llc -march=ppc32 -o all.s all.o Assemble to machine code: $ powerpc-eabi-as -o all.elf all.s Relocate sections to target specific addresses: $ powerpc-eabi-ld -T sections.ld -o relocated.elf all.elf ... then convert to an s-record and flash the device. A few questions... 1. Is this the right approach? 2. Does llvm-gcc insert initialization code? It doesn't look like it, but I may be missing something. 3. What is the difference between llvm-link and llvm-ld? Does llvm-link do inter module optimization? 4. Can llvm-link or llvm-ld perform any memory placement, or does this fall on binutils ld? Thanks for any help! -Tom
On Fri, Mar 12, 2010 at 9:10 PM, Tom Hawkins <tomahawkins at gmail.com> wrote:> I'm new to LLVM and I'm trying to set it up to target a low level > embedded device with no OS. Therefore the final program needs to > perform variable initialization and be located at a certain address > location. Here is my basic flow: > > Compile C to bytecode: > $ llvm-gcc -emit-llvm -c src1.c src2.c src3.c > > Consolidate to one bytecode file: > $ llvm-link -o all.o src1.c src2.o src3.o > > Emit assembly code: > $ llc -march=ppc32 -o all.s all.o > > Assemble to machine code: > $ powerpc-eabi-as -o all.elf all.s > > Relocate sections to target specific addresses: > $ powerpc-eabi-ld -T sections.ld -o relocated.elf all.elf > > ... then convert to an s-record and flash the device. > > A few questions... > > 1. Is this the right approach?You're trying to shoehorn LLVM into an environment it isn't really set up for; if you've compiled llvm-gcc as a cross-compiler targeting ppc32, then it should work roughly as well as it would work with gcc. If llvm-gcc is an x86 compiler, you're likely to run into issues; see http://llvm.org/docs/FAQ.html#platformindependent .> 2. Does llvm-gcc insert initialization code? It doesn't look like it, > but I may be missing something.Initialization for what, exactly? Is your toolchain not capable of setting up writable data sections correctly?> 3. What is the difference between llvm-link and llvm-ld? Does > llvm-link do inter module optimization?If you want to break down the process into steps as small as possible, just use llvm-link. llvm-ld is a combination of llvm-link and opt -std-link-opts and optionally llc+as+ld.> 4. Can llvm-link or llvm-ld perform any memory placement, or does this > fall on binutils ld?What do you expect llc to output? llvm-link is not a linker in the same way that ld is. -Eli
>> 2. Does llvm-gcc insert initialization code? It doesn't look like it, >> but I may be missing something. > > Initialization for what, exactly? Is your toolchain not capable of > setting up writable data sections correctly?I think Tom was referring to the initialization code that copy data sections and initialized zero-init variables from rom to ram. Generally this code is found as an object file which you can link with your code object file. This is not generated code but on the contrary handwritten assembly code. - Christophe
Hi, Tom Hawkins kirjoitti:> I'm new to LLVM and I'm trying to set it up to target a low level > embedded device with no OS. Therefore the final program needs to> perform variable initialization and be located at a certain address > location. Here is my basic flow: We also have an embedded osless target (see http://tce.cs.tut.fi) using LLVM very successfully. However, our target is not "pure and clean" LLVM backend as we generate backends on the fly to allow easy and fast target customization. LLVM code generation framework is used in our toolchain for instruction selection and register allocation but we do our own instruction scheduling and "bundling" + the final assembly phase that generates the bit images to be uploaded to the instruction memory and data memory. Also the data memory layout is generated in our own code, that's where the start address of data memory is fixed.> 2. Does llvm-gcc insert initialization code? It doesn't look like it, > but I may be missing something.How those images are to be uploaded/loaded/initialized in the final device is not the problem of the compiler but a runtime loader of some kind, thus target platform (and memory system) dependent. You can generate an initializer code for the data memory which in effect is then a simple "program loader" that copies the initial values from a non-volatile memory (or some other source, from where ever you want to initialize the program) to the RAM before starting the actual main program. This can be a simple (assembly written) loop in crt0 before calling main, for example. In a multiprocess operating system env this would be the responsibility of the process initialization routines (the exec() syscall?). Or you can have the data memory initialized by a host processor before it starts your slave processor. As you see, it all depends on your embedded platform, thus it's clearly not the compiler's responsibility. -- Pekka Jääskeläinen