
    `ia9                        d Z ddlmZ ddlZddlZddlZddlZddlZddlm	Z	 	 dddZ
ddZedk    r ej         e                       dS dS )a  Utility script to embed CUBIN data into existing object files.

This script takes an object file containing C++ code that uses TVM_FFI_EMBED_CUBIN
and embeds the CUBIN binary data directly into it, creating a new combined object file.

Usage:
    python -m tvm_ffi.utils.embed_cubin         --output-obj new_obj.o         --input-obj old_obj.o         --cubin my-cubin.cubin         --name my_module

The output object file will contain both:
- The original C++ code from input-obj
- The embedded CUBIN data with symbols:
    __tvm_ffi__cubin_<name>
    __tvm_ffi__cubin_<name>_end

These symbols are accessed in C++ code using:
    TVM_FFI_EMBED_CUBIN(my_module);
    )annotationsN)PathF
cubin_pathr   input_obj_pathoutput_obj_pathnamestrverboseboolreturnNonec                   |                                  st          d|            |                                 st          d|           |r~t          d|  d|                                 j         d           t          d| d|                                j         d           t          d|            t          d|            t          j                    5 }t          |          }|d	| d
z  }|                    | 	                                           |d| dz  }dddddt          |          t          |j                  g}	|rFt          d           t          dd                    |	                      t          d|            t          j        |	t          |          dd          }
|
j        dk    rg|
j                            d          }|
j                            d          }t'          d|
j         dd                    |	           d| d|           |r1|
j        r*t          d|
j                            d                      |r1|
j        r*t          d |
j                            d                      d!d"d#d$d%t          |          g}|r4t          d&           t          dd                    |                      t          j        |dd'          }
|
j        dk    rg|
j                            d          }|
j                            d          }t'          d(|
j         dd                    |           d| d|           |r1|
j        r*t          d|
j                            d                      |r1|
j        r*t          d |
j                            d                      |d| d)z  }d!d*d+d,d-| d.| d,d-| d/| d0t          |          t          |          g	}|r4t          d1           t          dd                    |                      t          j        |dd'          }
|
j        dk    rg|
j                            d          }|
j                            d          }t'          d2|
j         dd                    |           d| d|           |r1|
j        r*t          d|
j                            d                      |r1|
j        r*t          d |
j                            d                      dddt          |          t          |          t          |          g}|r4t          d3           t          dd                    |                      t          j        |dd'          }
|
j        dk    rg|
j                            d          }|
j                            d          }t'          d4|
j         dd                    |           d| d|           |r1|
j        r*t          d|
j                            d                      |r1|
j        r*t          d |
j                            d                      d!d5d6| d5d6| d0t          |          g}|r4t          d7           t          dd                    |                      t          j        |dd'          }
|
j        dk    rg|
j                            d          }|
j                            d          }t'          d8|
j         dd                    |           d| d|           |r1|
j        r*t          d|
j                            d                      |r1|
j        r*t          d |
j                            d                      d9d9d9           n# 1 swxY w Y   |r~t          d:|            t          d;           t          d<|j                    t          d=           t          d>| d?           t          d>| d@           t          dA           d9S d9S )Bu  Embed a CUBIN file into an existing object file.

    This function takes a CUBIN binary file and merges it into an existing object
    file that contains C++ code using TVM_FFI_EMBED_CUBIN. The result is a new
    object file containing both the original code and the embedded CUBIN data.

    The process involves:
    1. Creating an intermediate CUBIN object file using `ld -r -b binary`
    2. Adding `.note.GNU-stack` section to CUBIN object for security
    3. Using `objcopy` to rename symbols to the format expected by TVM-FFI:
       - _binary_<filename>_start → __tvm_ffi__cubin_<name>
       - _binary_<filename>_end → __tvm_ffi__cubin_<name>_end
    4. Using `ld -r` (relocatable link) to merge the CUBIN object with the input object
    5. Localizing the symbols to prevent conflicts when multiple object files use the same name

    Parameters
    ----------
    cubin_path : Path
        Path to the input CUBIN file.
    input_obj_path : Path
        Path to the existing object file containing C++ code with TVM_FFI_EMBED_CUBIN.
    output_obj_path : Path
        Path to the output object file (will contain both code and CUBIN data).
    name : str
        Name used in the TVM_FFI_EMBED_CUBIN macro (e.g., "my_module").
        This name must match the name used in the C++ code.
    verbose : bool, optional
        If True, print detailed command output. Default is False.

    Raises
    ------
    FileNotFoundError
        If the input CUBIN file or input object file does not exist.
    RuntimeError
        If `ld` or `objcopy` commands fail.

    Examples
    --------
    In Python,

    ```python
    embed_cubin(
        Path("kernel.cubin"),
        Path("old.o"),
        Path("new.o"),
        "my_kernels",
    )
    ```

    Then in C++ code,

    ```C++
    TVM_FFI_EMBED_CUBIN(my_kernels);
    auto kernel = TVM_FFI_EMBED_CUBIN_GET_KERNEL(my_kernels, "kernel_name");
    ```

    (in the source that was compiled to old.o).

    zCUBIN file not found: zInput object file not found: zInput CUBIN: z (z bytes)zInput object: zOutput object: zSymbol name: 	embedded_z.cubincubin_z.oldz-rz-bbinaryz-oz.
[Step 1/4] Creating CUBIN object file with ldz	Command:  zWorking directory: TF)cwdcapture_outputcheckr   zutf-8zld (binary) failed with status z

Command: z	
stdout: z	
stderr: zstdout: zstderr: objcopyz--add-sectionz.note.GNU-stack=/dev/nullz--set-section-flagsz.note.GNU-stack=noload,readonlyz<
[Step 1.5/4] Adding .note.GNU-stack section to CUBIN object)r   r   z/objcopy (add stack section) failed with status z
_renamed.oz--rename-sectionz/.data=.rodata,alloc,load,readonly,data,contentsz--redefine-sym_binary_embedded_z_cubin_start=__tvm_ffi__cubin_z_cubin_end=__tvm_ffi__cubin__endz/
[Step 2/4] Renaming CUBIN symbols with objcopyzobjcopy failed with status z6
[Step 3/4] Merging objects with ld (relocatable link)zld (merge) failed with status z--localize-symbol__tvm_ffi__cubin_z$
[Step 4/4] Localizing CUBIN symbolsz.objcopy (localize symbols) failed with status Nu0   
✓ Successfully created combined object file: z  Contains:z    - Original code from z-    - Embedded CUBIN data with local symbols:z        __tvm_ffi__cubin_z (local)z_end (local)z4    - .note.GNU-stack section (non-executable stack))existsFileNotFoundErrorprintstatst_sizetempfileTemporaryDirectoryr   write_bytes
read_bytesr	   r   join
subprocessrun
returncodestderrdecodestdoutRuntimeError)r   r   r   r   r
   tmpdirtmp_path
temp_cubin	cubin_objld_binary_cmdresultr(   r*   objcopy_stack_cmdcubin_obj_renamedobjcopy_cmdld_merge_cmdobjcopy_localize_cmds                     m/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/tvm_ffi/utils/embed_cubin.pyembed_cubinr8   2   si
   D  G E E EFFF  "" R P P PQQQ &NjNNJOO,=,=,ENNNOOOW~WW1D1D1F1F1NWWWXXX111222$d$$%%% 
	$	&	& e>&<<  8D 8 8 88
z4466777 00000	tT8T3y>>3zK_K_` 	4CDDD7chh}55778882223333x==QU]bccc!!]))'22F]))'22F$&2C $ $HH]33$ $!$ $ "$ $    	>v} 	><V]11'::<<=== 	>v} 	><V]11'::<<=== '!-	NN
  	=QRRR;chh'899;;<<< 1$eTTT!!]))'22F]))'22F$&BS $ $HH%677$ $!$ $ "$ $    	>v} 	><V]11'::<<=== 	>v} 	><V]11'::<<=== %'@'@'@'@@=JJJDJJLLL$LLL	NN!""

  	7DEEE5chh{3355666DNNN!!]))'22F]))'22F$f.? $ $HH[11$ $!$ $ "$ $    	>v} 	><V]11'::<<=== 	>v} 	><V]11'::<<===   !""
  	8KLLL6chh|4466777TOOO!!]))'22F]))'22F$1B $ $HH\22$ $!$ $ "$ $    	>v} 	><V]11'::<<=== 	>v} 	><V]11'::<<===
 &&&****   
  	@9:::>chh';<<>>??? 4TQVWWW!!]))'22F]))'22F$AR $ $HH%9::$ $!$ $ "$ $    	>v} 	><V]11'::<<=== 	>v} 	><V]11'::<<===Ke> e> e> e> e> e> e> e> e> e> e> e> e> e> e>N  FS/SSTTTm?.*=??@@@=>>>8$888999<$<<<===DEEEEEF Fs    [%___intc                 |   t          j        ddt           j        d          } |                     dt          ddd	           |                     d
t          ddd	           |                     dt          ddd	           |                     dt          ddd	           |                     dddd           |                                 }	 t          |j                                                  }t          |j	                                                  }t          |j
                                                  }|j                            dd           t          ||||j        |j                   |j        st!          d|            dS # t"          $ r)}t!          d| t$          j                   Y d}~dS d}~wt(          $ r)}t!          d| t$          j                   Y d}~dS d}~wt*          $ r<}t!          d| t$          j                   t-          j                     Y d}~dS d}~ww xY w) z-Main entry point for the embed_cubin utility.z#python -m tvm_ffi.utils.embed_cubinzNEmbed CUBIN data into existing object files that use TVM_FFI_EMBED_CUBIN macroa  
Examples:
  # Basic usage
  python -m tvm_ffi.utils.embed_cubin \
      --output-obj new.o \
      --input-obj old.o \
      --cubin kernel.cubin \
      --name my_kernels

  # With verbose output
  python -m tvm_ffi.utils.embed_cubin \
      --output-obj new.o \
      --input-obj old.o \
      --cubin kernel.cubin \
      --name my_kernels \
      --verbose

Workflow:
  1. Compile C++ code that uses TVM_FFI_EMBED_CUBIN to create old.o
  2. Compile CUDA kernel to CUBIN (e.g., using nvcc or NVRTC)
  3. Use this tool to merge them into new.o
  4. Link new.o into your final shared library

Usage in C++ code (source compiled to old.o):
  TVM_FFI_EMBED_CUBIN(my_kernels);
  auto kernel = TVM_FFI_EMBED_CUBIN_GET_KERNEL(my_kernels, "kernel_name");

Requirements:
  - GNU binutils (ld and objcopy) must be available in PATH
  - Linux/Unix platform (Windows uses different embedding mechanisms)
        )progdescriptionformatter_classepilogz--output-objTPATHz%Output object file path (e.g., new.o))typerequiredmetavarhelpz--input-objzIInput object file path containing TVM_FFI_EMBED_CUBIN usage (e.g., old.o)z--cubinz*Input CUBIN file path (e.g., kernel.cubin)z--nameNAMEz9Name used in TVM_FFI_EMBED_CUBIN macro (e.g., my_kernels)z-vz	--verbose
store_truezPrint detailed command output)actionrC   )parentsexist_oku   ✓ Created r   zError: )fileN      zUnexpected error:    )argparseArgumentParserRawDescriptionHelpFormatteradd_argumentr	   
parse_argsr   cubinresolve	input_obj
output_objparentmkdirr8   r   r
   r   r   sysr(   r+   	Exception	traceback	print_exc)parserargsr   r   r   es         r7   mainr_   2  s   $2d <	# # #FJ 4     X     9     H     ,	     D$*%%--//
dn--5577t//7799 	$$TD$AAAJDLYYY| 	4222333q   mmm#*----qqqqq   mmm#*----qqqqq   &1&&SZ8888qqqqqs1   CF 
H;GH;G22H;?1H66H;__main__)F)r   r   r   r   r   r   r   r	   r
   r   r   r   )r   r9   )__doc__
__future__r   rM   r%   rX   r    rZ   pathlibr   r8   r_   __name__exit     r7   <module>rh      s   $ , # " " " " "      



            }F }F }F }F }F@h h h hV zCHTTVV rg   