Currently, I am working on llvm tool which generates an ELF file with code and additional symbols. So the problem is the lack of the proper ways to emit some data to a specific section. I would like to fill .data with bytes in a target-independent manner, but can’t find a way to do that.
Tried methods
I’ve tried working with my own MCStremer object. It seems that the only way to correctly create section is to pass MCStreamer object to AsmPrinter after emitting custom data, but AsmPrinter owns it, so I can’t place my pass to the same PassManager as the AsmPrinter. If there was some way to pass ownership of MCStreamer from custom pass to AsmPrinter pass then my problem would be solved.
Another way I came up with is to separate PassManager into two. The first one contains passes that generate code and additional data to emit and write bytes to custom section. The second one contains only the AsmPrinter. This method allows me to pass reference to MCStreamer to my emitter, run first PM and then create AsmPrinter with my streamer. After some attempts I’ve came to the conclusion that the first PM flushes all generated instructions and I can’t pass them to the second PM.
Is there any way to emit bytes to custom section and generate code in another one? (it is desirable that this approach be targeted-independent)
I always find the CodeGen/MC hierarchies to be a bit confusing, but I think MCStreamer might be too low level for something like this. I’d expect higher level code to use the switchSection method to set the section you want, then you can emit whatever you like to it.
We do this on OpenVMS. In most cases, we just create a global variable at the module-level in a specific section with an initializer. It does create a symbol to the ELF symbol table by the way. We also put code into custom sections based on syntax in our various languages (like BLISS) using the normal “setSection” on the llvm::Function pointer returned by Function::Create.
Thank you for the answer. I thought that there is no high level way to fill custom section, so MCStremer was the only option. @JohnReagan proposed a solution with global variables and I think it suits me.
Thank you for the answer. This solutions is suitable for my task. If possible, could you please answer whether you have done something with this globals to reduce symbol table size?
In general, I want a linker-visible name/label to reference the section since I need to use the address in another section. Having a progbits section without a label would just get collected up with other progbits section into a load segment but how do you know where it was finally allocated?
However, there are some places where we have extra symbols in the ELF symbol table that aren’t needed. It hasn’t been a factor yet, but we’ll want to revisit it in the future.