cuobjdump_to_ptxplus — CUDA Binary Disassembly Tool
PTX + ELF + SASS → PTXPlus Binary Translation
Converts NVIDIA cuobjdump output (PTX, ELF sections, and SASS disassembly) into PTXPlus format — an extended PTX that preserves native SASS instruction scheduling. This enables GPGPU-Sim to model the GPU's native ISA more accurately than pure PTX simulation.
Bison/Flex Binary Translation PTXPlus SASS Parsing
💡 What is cuobjdump_to_ptxplus?
Analogy: Imagine a Rosetta Stone that takes three ancient scripts — PTX (the high-level virtual ISA), ELF (the binary structure), and SASS (the native machine code) — and merges them into a single enriched document (PTXPlus) that preserves the scheduling wisdom of the hardware compiler while remaining readable by the simulator. Each Lex/Yacc grammar is a specialized decoder for one of these "scripts."
Architecture
flowchart LR
subgraph Inputs["Input Files"]
I1[".ptx file\nPTX instructions"]
I2[".elf file\nELF binary sections"]
I3[".sass file\nSASS disassembly"]
end
subgraph Parsers["Bison/Flex Parsers"]
P1["ptx.l / ptx.y\nptx_parse()"]
P2["elf.l / elf.y\nelf_parse()"]
P3["sass.l / sass.y\nsass_parse()"]
P4["header.l / header.y\nHeader directives"]
end
subgraph Core["Merge Engine"]
M1["cuobjdumpInstList\nsetRealTexList()"]
M2["cuobjdumpInstList\nprintCuobjdumpPtxPlusList()"]
end
subgraph Output["Output"]
O1[".ptxplus file\nPTX + native scheduling"]
end
I1 --> P1
I2 --> P2
I3 --> P3
P1 --> M1
P2 --> M1
P4 --> M1
P3 --> M1
M1 --> M2
M2 --> O1
Translation Pipeline
flowchart TD S1["main() opens 4 files:\nptx, sass, elf, ptxplus_out"] --> S2["elf_parse()\nExtract ELF structure and sections"] S2 --> S3["ptx_parse()\nParse PTX instructions and directives\nBuild g_headerList + g_instList"] S3 --> S4["setRealTexList()\nCopy texture refs from header to inst list"] S4 --> S5["sass_parse()\nParse SASS instructions and schedules"] S5 --> S6["printHeaderInstList()\nEmit //HEADER section"] S6 --> S7["printCuobjdumpPtxPlusList()\nMerge PTX ops + SASS scheduling"] S7 --> S8["Output: PTXPlus file\nPTX with native instruction ordering"]
🚶 Step-by-Step Narrated Walkthrough
Follow a single cuobjdump_to_ptxplus ptx.file sass.file elf.file out.ptxplus invocation:
- File Opening —
main()opens 4 files: the PTX source, SASS disassembly, ELF binary, and the output PTXPlus file. - ELF Parsing —
elf_parse()uses the elf.l/elf.y grammar to extract binary section structure, identifying code and data segments. - PTX Parsing —
ptx_parse()uses ptx.l/ptx.y to tokenize and parse PTX instructions intocuobjdumpInstobjects, building two lists:g_headerList(directives) andg_instList(instructions). - Error Check — If
g_error_detectedis set during PTX parsing, the tool aborts with an assertion failure. - Texture Mapping —
g_instList→setRealTexList(g_headerList→getRealTexList())copies texture reference names from the header directives into the instruction list for correct texture operand resolution. - SASS Parsing —
sass_parse()uses sass.l/sass.y to parse the native GPU assembly, attaching scheduling information and instruction ordering to the existing instruction list. - Header Emission —
g_headerList→printHeaderInstList()writes the//HEADERsection containing PTX directives, version info, and declarations. - Instruction Merging —
g_instList→printCuobjdumpPtxPlusList(g_headerList)emits the//INSTRUCTIONSsection, merging PTX operations with SASS-derived scheduling. - Output Complete — The PTXPlus file is closed and ready for loading by the simulator via
gpgpu_ptx_sim_load_ptx_from_filename().
Key Classes & Structures
| # | Class / Struct | File | Description |
|---|---|---|---|
| 1 | cuobjdumpInst | cuobjdumpInst.h/.cc | Single instruction with: m_label, m_base (mnemonic), m_predicate, m_baseModifiers, m_typeModifiers, m_operands, m_predicateModifiers. Method printCuobjdumpPtxPlus() emits PTXPlus format. |
| 2 | cuobjdumpInstList | cuobjdumpInstList.h/.cc | Container for instruction sequences. Methods: setRealTexList() (map texture refs), printHeaderInstList() (header), printCuobjdumpPtxPlusList() (full output), getRealTexList(). |
| 3 | g_instList | cuobjdump_to_ptxplus.cc | Global instruction list — holds parsed SASS + merged PTX instructions. |
| 4 | g_headerList | cuobjdump_to_ptxplus.cc | Global header list — holds PTX directives, declarations, and texture references. |
| 5 | ptx_parser (Bison) | ptx.y | Grammar rules for PTX instruction format: opcodes, modifiers, operands, labels. |
| 6 | elf_parser (Bison) | elf.y | Grammar rules for ELF section headers, program headers, and symbol tables. |
| 7 | sass_parser (Bison) | sass.y | Grammar rules for SASS assembly: native opcodes, register operands, scheduling hints. |
| 8 | header_parser (Bison) | header.y | Grammar rules for PTX header directives (.version, .target, .entry, etc.). |
| 9 | ptx_lexer (Flex) | ptx.l | Tokenizer for PTX source: recognises instruction mnemonics, registers, literals. |
| 10 | sass_lexer (Flex) | sass.l | Tokenizer for SASS disassembly: recognises native GPU opcodes and register names. |
Key Functions
| Function | File | Purpose |
|---|---|---|
main() | cuobjdump_to_ptxplus.cc | Driver: opens files, runs 3 parsers, emits PTXPlus |
elf_parse() | elf.y (generated) | Bison entry — parses ELF binary sections |
ptx_parse() | ptx.y (generated) | Bison entry — parses PTX instructions into cuobjdumpInst |
sass_parse() | sass.y (generated) | Bison entry — parses SASS disassembly with scheduling |
output() | cuobjdump_to_ptxplus.cc | Writes text to ptxplus_out file |
fileToString() | cuobjdump_to_ptxplus.cc | Reads entire file into a std::string |
setRealTexList() | cuobjdumpInstList.cc | Copies texture reference list from header to instruction list |
printHeaderInstList() | cuobjdumpInstList.cc | Emits PTX header directives section |
printCuobjdumpPtxPlusList() | cuobjdumpInstList.cc | Emits merged PTXPlus instructions |
printCuobjdumpPtxPlus() | cuobjdumpInst.cc | Emits a single instruction in PTXPlus format |
printCuobjdumpOperands() | cuobjdumpInst.cc | Formats instruction operands for output |
Lex/Yacc Grammar Structure
| Grammar | Lexer | Parser | Input Format | Output |
|---|---|---|---|---|
| PTX | ptx.l | ptx.y | PTX assembly instructions | cuobjdumpInst objects in g_instList + g_headerList |
| ELF | elf.l | elf.y | ELF section dump | Binary structure metadata |
| SASS | sass.l | sass.y | SASS native disassembly | Scheduling info merged into g_instList |
| Header | header.l | header.y | PTX header directives | Version, target, entry declarations |
Module Interactions
| Interacts With | Direction | Mechanism | Purpose |
|---|---|---|---|
| libcuda | ← caller | extract_code_using_cuobjdump() | Invoked during __cudaRegisterFatBinary() when PTXPlus mode is enabled |
| NVIDIA cuobjdump | ← input | File I/O | Reads PTX/ELF/SASS files produced by $CUDA_INSTALL_PATH/bin/cuobjdump |
| PTX parser (cuda-sim) | → output | gpgpu_ptx_sim_load_ptx_from_filename() | Output PTXPlus file is loaded by the simulator's PTX parser |
| gpgpusim.config | ← config | -gpgpu_ptx_convert_to_ptxplus 1 | Config knob that triggers this tool during binary registration |
Code Snippets
Main Driver — cuobjdump_to_ptxplus.cc
// cuobjdump_to_ptxplus.cc — main translation driver
cuobjdumpInstList *g_instList = new cuobjdumpInstList();
cuobjdumpInstList *g_headerList = new cuobjdumpInstList();
int main(int argc, char* argv[]) {
// Usage: cuobjdump_to_ptxplus ptx sass elf ptxplus_out
sass_in = fopen(argv[2], "r");
ptx_in = fopen(argv[1], "r");
elf_in = fopen(argv[3], "r");
ptxplus_out = fopen(argv[4], "w");
elf_parse(); // Parse ELF structure
ptx_parse(); // Parse PTX → g_instList + g_headerList
assert(!g_error_detected);
// Map texture references from PTX header
g_instList->setRealTexList(g_headerList->getRealTexList());
sass_parse(); // Parse SASS + merge scheduling
// Emit PTXPlus output
output("//HEADER\n");
g_headerList->printHeaderInstList();
output("//END HEADER\n\n\n");
output("//INSTRUCTIONS\n");
g_instList->printCuobjdumpPtxPlusList(g_headerList);
output("//END INSTRUCTIONS\n");
return 0;
}
cuobjdumpInst — Instruction Data Structure
// cuobjdumpInst.h — single instruction representation
class cuobjdumpInst {
protected:
std::string m_label; // instruction label
std::list<std::string>* m_predicate; // predicate register
std::string m_base; // mnemonic (add, mov, ld, etc.)
std::list<std::string>* m_baseModifiers; // .rn, .ftz, .sat, etc.
std::list<std::string>* m_typeModifiers; // .f32, .u64, .s16, etc.
std::list<std::string>* m_operands; // destination + sources
std::list<std::string>* m_predicateModifiers;
public:
void setBase(const char* mnemonic);
void addOperand(const char* operand);
void printCuobjdumpPtxPlus(); // emit in PTXPlus format
};
Usage
# Manual invocation (normally called automatically by the simulator)
cuobjdump_to_ptxplus kernel.ptx kernel.sass kernel.elf output.ptxplus
# Enable in simulator config
-gpgpu_ptx_convert_to_ptxplus 1
# The simulator invokes this tool during __cudaRegisterFatBinary()
# when CUDA >= 4.0 and the config knob is enabled
Directory Map
Source tree for cuobjdump_to_ptxplus
cuobjdump_to_ptxplus/
├── cuobjdump_to_ptxplus.cc ← 143 lines — main driver: open files, run parsers, emit output
├── cuobjdumpInst.h ← cuobjdumpInst class declaration
├── cuobjdumpInst.cc ← cuobjdumpInst methods: print, format, accessors
├── cuobjdumpInstList.h ← cuobjdumpInstList class declaration
├── cuobjdumpInstList.cc ← Container methods: merge, emit, texture mapping
├── ptx.l ← Flex lexer for PTX instruction tokenization
├── ptx.y ← Bison parser for PTX grammar
├── ptx_parser.h ← Shared PTX parser declarations
├── elf.l ← Flex lexer for ELF section format
├── elf.y ← Bison parser for ELF binary structure
├── sass.l ← Flex lexer for SASS native disassembly
├── sass.y ← Bison parser for SASS instructions
├── header.l ← Flex lexer for PTX header directives
├── header.y ← Bison parser for header (.version, .target)
└── Makefile ← Builds cuobjdump_to_ptxplus executable
Glossary
| Term | Definition |
|---|---|
| PTXPlus | Extended PTX format that preserves native instruction scheduling from SASS assembly |
| SASS | Streaming Assembler — NVIDIA's native GPU instruction set architecture (the "real" ISA) |
| ELF | Executable and Linkable Format — standard binary container format for compiled GPU code |
| cuobjdump | NVIDIA tool to dump PTX/SASS/ELF sections from compiled CUDA binaries (.cubin, .fatbin) |
| Bison | GNU parser generator (LALR) — generates C code from grammar rules in .y files |
| Flex | Fast lexical analyzer generator — generates C tokenizers from patterns in .l files |