Closed derekbruening closed 3 years ago
Xref #68
Xref #3158
The general approach here is that each exported header should be copied as-is (or possibly with CMake variable expansion, as we do for dr_api.h) from a checked-in header. No more having a script extract pieces from the middle of headers.
This means that we need to extract the public, exported content from the headers and move it to new entirely-exported files.
For headers also used for internal code, the naming convention is xxx_api.h. A header with that name must contain only exported content. A CMake rule DR_export_header
is used to copy it to the build dir's include/ directory and that copy can rename it: e.g., from core/module_api.h
to include/dr_modules.h
.
For headers only used for exported code, we use the same name as the exported header: so core/lib/dr_events.h
.
There are a lot of complications and details to deal with here.
E.g., genapi.pl does s/dcontext_t *\*dcontext/void *drcontext/;
, but w/ the internal header having the full type, the impl files do as well. So if we make the header void, the impl file won't match; do we make it void and add a cast and assume it's zero cost (could cost extra local var slot)?
What about DR_UNS_EXCEPT_TESTS_API for decode_cti? I think we have to put it in decode_api.h and define that token and just have no doxygen header and no dllexport/visible symbol.
What about AVOID_API_EXPORT? I've been trying to just reword to be fine to sit in exported header (not in doxygen comment).
What about API_EXPORT_ONLY? E.g., dr_ir_utils.h including dr_ir_instr.h? Might have to live w/ non-include-what-you-use there.
We'll have to drop not-HAVE_FVISIBILITY support so we can drop genapi.pl -filter and fully get rid of genapi.pl.
My task list showing all the sources of exported content and what I ended up doing with each:
[X] core/annotations.h:/ DR_API EXPORT TOFILE dr_annotation.h / => new file core/annotations_api.h => dr_annotation.h
[X] core/lib/dr_config.h:/ DR_API EXPORT TOFILE dr_config.h / => cleaned up and exported as-is
[X] core/globals.h:/ DR_API EXPORT TOFILE dr_defines.h / => new file core/lib/globals_api.h => dr_defines.h
[X] core/lib/c_defines.h:/ DR_API EXPORT TOFILE dr_defines.h / => new file core/lib/globals_api.h => dr_defines.h
[X] core/lib/globals_shared.h:/ DR_API EXPORT TOFILE dr_defines.h / => new file core/lib/globals_api.h => dr_defines.h
[X] core/lib/globals_shared.h:/ DR_API EXPORT TOFILE dr_defines.h / => new file core/lib/globals_api.h => dr_defines.h
[X] core/lib/globals_shared.h:/ DR_API EXPORT TOFILE dr_defines.h / => new file core/lib/globals_api.h => dr_defines.h
[X] core/lib/globals_shared.h:/ DR_API EXPORT TOFILE dr_defines.h / => new file core/lib/globals_api.h => dr_defines.h
[X] core/lib/instrument_api.h:/ DR_API EXPORT TOFILE dr_events.h / => new file core/lib/dr_events.h => dr_events.h
[X] core/lib/instrument_api.h:/ DR_API EXPORT TOFILE dr_events.h / => new file core/lib/dr_events.h => dr_events.h
[X] core/lib/instrument_api.h:/ DR_API EXPORT TOFILE dr_events.h / => new file core/lib/dr_events.h => dr_events.h
[X] core/lib/instrument_api.h:/ DR_API EXPORT TOFILE dr_events.h / => new file core/lib/dr_events.h => dr_events.h
[X] libutil/dr_frontend.h:/ DR_API EXPORT TOFILE dr_frontend.h /
[X] core/lib/dr_inject.h:/ DR_API EXPORT TOFILE dr_inject.h / => cleaned up and exported as-is
[X] core/arch/arch_exports.h:/ DR_API EXPORT TOFILE dr_ir_instr.h /MAX_INSTR_LENGTH => new file core/ir/encode_api.h => dr_ir_encode.h
[X] core/arch/arch_exports.h:/ DR_API EXPORT TOFILE dr_ir_instr.h /encode* => new file core/ir/encode_api.h => dr_ir_encode.h
[X] core/ir/decode.h:/ DR_API EXPORT TOFILE dr_ir_instr.h / PREFIX_* => moved to instr_api.h
[X] core/ir/disassemble.h:/ DR_API EXPORT TOFILE dr_ir_instr.h / => new file core/ir/disassemble_api.h => dr_ir_disassemble.h
[X] core/ir/instr.h:/ DR_API EXPORT TOFILE dr_ir_instr.h / => new file core/ir/instr_api.h => dr_ir_instr.h
[X] core/ir/instr.h:/ DR_API EXPORT TOFILE dr_ir_instr.h / => new file core/ir/instr_api.h => dr_ir_instr.h
[X] core/ir/instr.h:/ DR_API EXPORT TOFILE dr_ir_instr.h / => new file core/ir/instr_api.h => dr_ir_instr.h
[X] core/ir/instr.h:/ DR_API EXPORT TOFILE dr_ir_instr.h / => new file core/ir/instr_api.h => dr_ir_instr.h
[X] core/ir/instr_inline.h:/ DR_API EXPORT TOFILE dr_ir_instr.h / => new file core/ir/instr_inline_api.h => dr_ir_instr_inline.h
[X] core/arch/arch_exports.h:/ DR_API EXPORT TOFILE dr_ir_instrlist.h /instrlist_encode => new file core/ir/encode_api.h => dr_ir_encode.h
[X] core/ir/disassemble.h:/ DR_API EXPORT TOFILE dr_ir_instrlist.h / => new file core/ir/disassemble_api.h => dr_ir_disassemble.h
[X] core/ir/instr.h:/ DR_API EXPORT TOFILE dr_ir_instrlist.h / expansion => only DR_UNS_API so leaving
[X] core/ir/instrlist.h:/ DR_API EXPORT TOFILE dr_ir_instrlist.h /
[X] core/ir/aarch64/instr_create.h:/ DR_API EXPORT TOFILE dr_ir_macros_aarch64.h / => renamed to instr_create_api.h
[X] core/ir/arm/instr_create.h:/ DR_API EXPORT TOFILE dr_ir_macros_arm.h / => renamed to instr_create_api.h
[X] core/ir/instr_create_shared.h:/ DR_API EXPORT TOFILE dr_ir_macros.h / => renamed to instr_create_shared_api.h
[X] core/ir/x86/instr_create.h:/ DR_API EXPORT TOFILE dr_ir_macros_x86.h / => renamed to instr_create_api.h; small private macros put into new instr_create.h; new instr_create_shared.h created for core/ to include.
[X] core/ir/aarch64/codec.py: '/ DR_API EXPORT TOFILE dr_ir_opcodes_aarch64.h /', => post-build command copies it; updated header guards + annots
[X] core/ir/arm/opcode.h:/ DR_API EXPORT TOFILE dr_ir_opcodes_arm.h / => renamed to opcode_api.h; small non-public content moved to decode.h
[X] core/ir/instr.h:/ DR_API EXPORT TOFILE dr_ir_opcodes.h /
[X] core/ir/x86/opcode.h:/ DR_API EXPORT TOFILE dr_ir_opcodes_x86.h / => renamed to opcode_api.h; small non-public content moved to instr.h and opnd.h
[X] core/ir/decode.h:/ DR_API EXPORT TOFILE dr_ir_opnd.h / OPSZ_* => moved to opnd_api.h
[X] core/ir/disassemble.h:/ DR_API EXPORT TOFILE dr_ir_opnd.h / => new file core/ir/disassemble_api.h => dr_ir_disassemble.h
[X] core/ir/opnd.h:/ DR_API EXPORT TOFILE dr_ir_opnd.h / => new file core/ir/opnd_api.h => dr_ir_opnd.h
[X] core/arch/arch_exports.h:/ DR_API EXPORT TOFILE dr_ir_utils.h / dr_isa_mode_t => new file core/ir/encode_api.h => dr_ir_encode.h
[X] core/ir/decode_fast.h:/ DR_API EXPORT TOFILE dr_ir_utils.h / decode_sizeof* => new file core/ir/decode_api.h => dr_ir_decode.h
[X] core/ir/decode.h:/ DR_API EXPORT TOFILE dr_ir_utils.h /decode*,mode,decoration => new file core/ir/decode_api.h => dr_ir_decode.h
[X] core/ir/disassemble.h:/ DR_API EXPORT TOFILE dr_ir_utils.h / disassemble* => new file core/ir/disassemble_api.h => dr_ir_disassemble.h
[X] core/ir/instr.h:/ DR_API EXPORT TOFILE dr_ir_utils.h / decode_memory_reference_size => moved to decode_api.h
[X] core/lib/instrument_api.h:/ DR_API EXPORT TOFILE dr_ir_utils.h / lots of stuff => new file core/lib/dr_ir_utils.h => dr_ir_utils.h
[X] core/hotpatch.c:/ DR_API EXPORT TOFILE dr_probe.h / => new file core/lib/probe_api.h => dr_probe.h
[X] core/lib/globals_shared.h:/ DR_API EXPORT TOFILE dr_probe.h / dr_probe_status_t => new file core/lib/probe_api.h => dr_probe.h
[X] core/arch/proc.h:/ DR_API EXPORT TOFILE dr_proc.h / => new file core/arch/proc_api.h => dr_proc.h
[X] core/lib/instrument_api.h:/ DR_API EXPORT TOFILE dr_proc.h / => moved to core/lib/dr_ir_utils.h
[X] core/fragment.h:/ DR_API EXPORT TOFILE dr_tools.h / trace dump => new file core/fragment_api.h => dr_tracedump.h
[X] core/lib/instrument_api.h:/ DR_API EXPORT TOFILE dr_tools.h / lots of stuff => new file core/lib/dr_tools.h => dr_tools.h => some went to core/os_api.h => dr_os_utils.h
[X] core/lib/instrument_api.h:/ DR_API EXPORT TOFILE dr_tools.h / adaptive opt => new file core/lib/dr_tools.h => dr_tools.h
[X] core/module_shared.h:/ DR_API EXPORT TOFILE dr_tools.h / module => new file core/module_api.h => dr_modules.h
[X] core/module_shared.h:/ DR_API EXPORT TOFILE dr_tools.h / module => new file core/module_api.h => dr_modules.h
[X] core/os_shared.h:/ DR_API EXPORT TOFILE dr_tools.h / dr_state; app args => new file core/os_api.h => dr_os_utils.h
[X] core/os_shared.h:/ DR_API EXPORT TOFILE dr_tools.h / client aux libs => new file core/os_api.h => dr_os_utils.h
[X] core/os_shared.h:/ DR_API EXPORT TOFILE dr_tools.h / drmemprot* => new file core/os_api.h => dr_os_utils.h
I closed this but perhaps one final thing to consider is splitting up the large instrument.c file, maybe to match the events vs utils header split at least.
Currently DR's public interface headers are constructed from a patchwork of existing internal headers using the genapi.pl script. This issue covers refactoring the headers to properly separate the public interface portions into their own headers that can be directly exported, eliminating the need for a script and simplifying the project.