После tcc_compile_string есть ли способ получить длину области кода? - PullRequest
0 голосов
/ 09 ноября 2018

Для исследования и демонстрации попробовал смешать немного tcc и udis86. Это из GnuCOBOL, так что нет реального доступа к заголовкам C или членам структуры TCCState, но это можно сделать с небольшой ручной работой и / или предварительной обработкой текста, чтобы получить правильные значения ширины и смещения.

tcc, собранный с --disable-static, для создания разделяемой библиотеки. udis86 прямо из репозитория Fedora.

  *> tcc-udis  tcc as libtcc.so, and udis86 for some disassembly
  *> Tectonics:
  *>  cobc -xj -g tcc-udis.cob -ltcc -ludis86
  *>
   >>SOURCE FORMAT IS FREE
   identification division.
   program-id. sample.

   environment division.
   configuration section.
   repository.
       function all intrinsic.

   REPLACE ==newline== BY ==& x"0a" &==.

   data division.
   working-storage section.

   01 TCC-OUTPUT-MEMORY constant as 1.
   01 TCC-RELOCATE-AUTO usage pointer.

   01 tcc usage pointer.
   01 rc usage binary-long.
   01 prog-entry usage program-pointer.

   01 udis pic x(632).                    *> sizeof(ud_t)
   01 ud-translate usage program-pointer. *> AT&T or INTEL
   01 code-size usage binary-long.
   01 formatted usage pointer.              
   01 running-offset pic 9999.
   01 spacer pic x(32).                   *> max 16 byte instruction

   01 prog.  05 value
     "#include <stdio.h>"                                   newline
     "int hello() { printf(""%s"", ""Hello, tcc\n""); }"
   .

   procedure division.

   call "tcc_new" returning tcc
   if tcc equal null then
       display "error: tcc_new failed" upon syserr
       goback
   end-if

   call "tcc_set_output_type" using by value tcc TCC-OUTPUT-MEMORY
       returning rc
   if rc not equal zero then
       display "error: tcc_set_output_type " rc upon syserr
       goback
   end-if

   call "tcc_compile_string" using by value tcc by reference prog
       returning rc
   if rc not equal zero then
       display "error: tcc_compile_string " rc upon syserr
       goback
   end-if

  *> in C this is set to (void*)1
   set TCC-RELOCATE-AUTO up by 1
   call "tcc_relocate" using by value tcc
       by value TCC-RELOCATE-AUTO
       returning rc
   if rc not equal zero then
       display "error: tcc_relocate " rc upon syserr
       goback
   end-if

   call "tcc_get_symbol" using by value tcc by reference "hello"
       returning prog-entry
   if prog-entry equal null then
       display "error: tcc_get_symbol hello " upon syserr
       goback
   end-if

   call prog-entry 

   move 43 to code-size       
   perform disassemble
   display space

   set prog-entry to entry "cob_embed_python"
   move 23 to code-size       
   perform disassemble

   call "tcc_delete" using by value tcc returning omitted
   goback.

  *> take a look at some disassembly
   disassemble.
   call "ud_init" using udis
   call "ud_set_mode" using udis by value 64   *> 64bit
   call "ud_set_vendor" using udis by value 2  *> Any
   call "ud_set_input_buffer" using udis value prog-entry code-size

   set ud-translate to entry "ud_translate_att"
   call "ud_set_syntax" using udis by value ud-translate

   move 0 to running-offset
   call "ud_disassemble" using udis returning rc
   perform until rc equal zero

       call "ud_insn_hex" using udis returning formatted
       display running-offset space content-of(formatted)
           spacer(1:32 - rc * 2) with no advancing

       add rc to running-offset

       call "ud_insn_asm" using udis returning formatted
       display space content-of(formatted)

       call "ud_disassemble" using udis returning rc
   end-perform
   .
   end program sample.

Udis ud_set_input_buffer хочет размер. Было бы неплохо иметь возможность использовать точное значение, определенное tcc и TCC_OUTPUT_MEMORY.

Работает довольно хорошо для изучения, но размер кода, используемый в примере, это всего лишь догадки, за которыми следуют прогоны с последующим подсчетом, за которым следуют изменения исходного кода и другие прогоны. Длина была преднамеренно короткой, чтобы обрезать инструкцию во втором дизассемблировании, как демонстрацию.

prompt$ cobc -xj -g tcc-udis.cob -ltcc -ludis86
Hello, tcc
0000 55                               push %rbp
0001 4889e5                           mov %rsp, %rbp
0004 4881ec00000000                   sub $0x0, %rsp
0011 488d0571100000                   lea 0x1071(%rip), %rax
0018 4889c6                           mov %rax, %rsi
0021 488d0564100000                   lea 0x1064(%rip), %rax
0028 4889c7                           mov %rax, %rdi
0031 b800000000                       mov $0x0, %eax
0036 e817000000                       call 0x40
0041 c9                               leave
0042 c3                               ret

0000 55                               push %rbp
0001 4889e5                           mov %rsp, %rbp
0004 53                               push %rbx
0005 4881ec88010000                   sub $0x188, %rsp
0012 89bd7cfeffff                     mov %edi, -0x184(%rbp)
0018 89b578feff                       invalid

Все это для вопроса в заголовке. Я надеюсь, что это просто проблема, и я упустил очевидное, просматривая заголовки исходного кода tcc.

Иметь хорошее

...