I built a SoC written in Verilog, compiled the c code into a binary file and initialized the SoC ROM with it. In order to design an error injection, I needed to be able to artificially specify the ROM address after the assembly of an instruction such as printf ("123"). Is there a way to do this, for example, using inline assembly?
There might be a very hacky and unreliable way that happens to work in a debug build, relying on assumptions about how compilers work. IDK why you'd want to do it; you can't jump there from outside the function. If you just want to be able to set a breakpoint, normally you can do that by line number with debug info.
printf("123")
can't compile to a single instruction. There will be some that set up a pointer arg, and one or more that actually do a call printf
or equivalent. In a debug build those will be contiguous block, otherwise they might not be.
In a debug build (optimization disabled), if you use inline asm to emit a label in the middle of your C function, like asm(".globl foo; foo:" ::: "memory")
, it will probably be right before the block of instructions corresponding to the next C statement. (In an optimized build, the instructions corresponding to one C statement won't be in a contiguous block, and there'd be no way to do anything like what you're asking, except maybe with C goto
labels like foo:
and using GNU C labels-as-values to take their address. But I don't think you could control their address with the linker since you wouldn't know an asm symbol name.)
You can use a linker script to place the start of the .text
section at a certain address. Something like . = 0x401000
before emitting the segment that maps the sections you want.
If you compute that address like . = 0x401000 - (symbol - start_of_text)
, using the distance of the symbol from the start of the section, then the symbol should end up at the address you want.
You can put individual functions in their own section so you can play with layout in the linker (gcc -ffunction-sections
) so you could do that on a per-function basis.
I wouldn't recommend doing this. If something you're designing relies on this to work correctly, design it differently. This is horrible.