Building an array in a section from multiple object files

Hi,

As part of working on XRay, I’m trying to accomplish the following: create a section that contains an array of entries pertaining to the instrumentation map (nop sleds) in an object file, and have those merged into a single section in the final binary where the contents are concatenated. The trick though is I’d like to be able to reference the whole array with a single symbol (or two, one to mark the start and the other to mark the end). I’m trying to get this to work initially on x86 and Linux (ELF).

What I’ve got currently in http://reviews.llvm.org/D19904 creates this section (.xray_instr_map) and defines two globals in that section named “__xray_instr_map” and “__xray_instr_map_end”. The problem inevitably with this approach is that having multiple object files have these definitions cause issues with multiple definition violations at link time.

I think the solution involves having COMDAT sections per-function that has the instrumentation points, then have those concatenated into a single .xray_instr_map section.

What I’m not sure about is how to define the “__xray_instr_map” and “__xray_instr_map” symbols such that they refer to the contents of the section in the final binary.

Thoughts?

If you give your section a valid C identifier name, i.e. something like “xray_instr_map” (no period), the linker will synthesize symbols named “__start_xray_instr_map” and “__stop_xray_instr_map”, which will point to the start and end of the combined section.

Peter

Awesome, thanks Peter!

Cheers

Just to close this out, I’ve updated http://reviews.llvm.org/D19904 to use named ELF groups per-function, and have the runtime library use __start_xray_instr_map and __stop_xray_instr_map as weak symbols from the C++ side. I’ve sent a patch to make creating these COMDAT/Group sections easier when lowering through the MCStreamer interface (http://reviews.llvm.org/D21743).

Cheers

Dean Michael Berris via llvm-dev <llvm-dev@lists.llvm.org> writes:

Just to close this out, I've updated http://reviews.llvm.org/D19904 to use
named ELF groups per-function, and have the runtime library use
__start_xray_instr_map and __stop_xray_instr_map as weak symbols from the
C++ side.

In case you're not aware, the __start_/__stop_ trick isn't portable.
You may want to look at compiler-rt/lib/profile/InstrProfilingPlatform*.c.
There, we do the __start_ trick for linux and freebsd, a similar trick
for darwin, and fall back to a static registration scheme elsewhere.

Thanks Justin – I assumed it couldn’t be portable. :slight_smile:

I fully expect to play many different tricks on many different platforms too to make this work.

Cheers