Télécharger
Développer
Compte
Télécharger
Développer
Connexion
Mot de passe oublié ?
Créer un compte
Langue
Aide
Langue
Aide
×
Connexion
Nom du compte
Mot de passe
×
Mot de passe oublié ?
Traduction statut du Français
Catégorie :
Logiciel
Peuple
PersonalForge
Magazine
Wiki
Recherche
OSDN
>
Trouver un logiciel
>
Développement de logiciels
>
Debuggers
>
Dr.Deamon64
>
Wiki
>
.debug_lineセクションの構造と読み方(中身編)
Dr.Deamon64
Fork
Description
Résumé du projet
Dashboard - Développeur
Page Web
Développeurs
Galerie d'images
Liste des flux RSS
Activité
Statistiques
Historique
Téléchargements
List of Releases
Stats
Code Source
Liste des dépôts de code
Git
drdeamon64
CVS
Voir le référentiel
Ticket
Liste des tickets
Liste des Jalons
Liste des types
Liste des composants
Liste des tickets/RSS fréquemment utilisés
Soumettre un nouveau ticket
Documents
Page de garde
Index du titre
Modifications récentes
Communication
Forums
Liste des forums
Forum des développeurs (1)
Forum d’aide (1)
Discussion-Ouverte (1)
Listes de diffusion
Liste de ML
Nouvelles
edit
|
Title Index
|
Recent Changes
|
おしながき
ELFファイルフォーマット
.eh_frameセクションの構造と読み方
DWARFファイルフォーマット
DWARFって何?
ELFセクションとの関係
LEB128な数の表現
デバッグ情報とDIE(.debug_info/.debug_abbrevセクションの概要)
.debug_abbrevセクションの構造と読み方
データ形式(DW_FORM_zzzz)一覧と意味、格納データの構造
.debug_infoセクションの構造と読み方 (ついでに".debug_str"もね)
TAG名(DW_TAG_xxxx)一覧と値、意味
TAG詳細(その01)
Compile Unit編
TAG詳細(その02)
関数編
TAG詳細(その03)
C++例外/テンプレート関数編
TAG詳細(その04)
インライン関数編
TAG詳細(その05)
仲介関数、語彙ブロック、gotoラベル、with文編
TAG詳細(その06)
変数/関数の引数/定数編
TAG詳細(その07)
共通ブロック/ネームリスト編
TAG詳細(その08)
基本型、不特定型、型修飾子、typedef編
TAG詳細(その09)
配列、enum編
TAG詳細(その10)
構造体、union、クラス編
TAG詳細(その11)
オブジェクト指向言語編(Interface、Friend)
TAG詳細(その12)
オブジェクト指向言語編2 (クラスのメンバ関数、クラステンプレート)
TAG詳細(その13)
ポインタ編
TAG詳細(その14)
C/C++以外言語固有編1
TAG詳細(その15)
C/C++以外言語固有編2+いずれにも該当しないケース
Attribute名(DW_AT_yyyy)一覧と値、意味
Attribute詳細(その01)
エンコード形式、パック10進、固定小数点編
DWARF_expressionな表現:その1
DWARF_expressionな表現:その2(LocationDescription)
.debug_locセクションの構造(LocationLists)
.debug_rangesセクションの構造(CodeAddress&Range)
.debug_lineセクションの構造と読み方
.debug_lineセクションの構造と読み方(中身編)
.debug_frameセクションの構造
.debug_frameセクションの構造:CIE編
.debug_frameセクションの構造:FDE編
.debug_frameセクションの構造:DW_CFA命令編
.debug_frameセクションの構造:INTEL64(amd64)での例の解析1
.debug_frameセクションの構造:INTEL64(amd64)での例の解析2
.debug_arangesセクションの構造
.debug_pubnames/.debug_pubtypesセクションの構造
.debug_macinfoセクションの構造
.debug_macinfoセクションの構造:解析編
NCURSESライブラリ
NCURSES Programing HOWTO ワタクシ的ほんやく
1. Introduction
2. Hello World !!!
3. The Gory Details
4. Initialization
5. A Word about Windows
6. Output functions
7. Input functions
8. Attributes
9. Windows
10. Colors
11. Interfacing with the key board
12.マウス操作
13. Screen Manipulation
14. Miscellaneous features
15. Other libraries
16.パネルライブラリ
17. Menus Library
18.フォームライブラリ
Tools and Widget Libraries
Just For Fun !!!
References
その他、自分メモ
NCURSES雑多な自分メモ01
最近の更新 (Recent Changes)
2019-09-24
DWARF_expressionな表現:その1
2013-10-10
18.フォームライブラリ
2013-10-03
NCURSES雑多な自分メモ01
2013-10-01
SideBar
NCURSESライブラリ
2013-09-29
16.パネルライブラリ
Prev:
.debug_lineセクションの構造と読み方
Next:
.debug_frameセクションの構造
目次に戻る:
DWARFファイルフォーマット
.debug_lineセクションの構造と読み方
ヘッダ編からずいぶん長くなっちゃったので、分割。
んで、次に中身------------
さてさて、ようやっと、中身ですな。んで、これが厄介。 ので、ちょっとずずメモメモ。
まず概要
ヘッダの後は、Cソースとアセンブラの関係を示す「命令」がバイト単位で並んでる。
DWARFでの、Cソースとアセンブラの関係は、簡単に言うと「バイトな命令で書かれたDWARF言語でのプログラム」で表現されている。
このプログラムは、DWARFが勝手に決めた「DWARFなんちゃってコンピュータ?」の上で動作する。(もちろん、仮想な世界)
この「DWARFなんちゃってコンピュータ」は、レジスタをもっている。(いくつも)
このレジスタ、詳細は後述だが、確実に覚えとかにゃらんのは「Cソースの行番号」「アセンブラのアドレス」がある。
で、この「DWARF言語の命令」でもって、「Cソースの行番号」「アセンブラのアドレス」をつらつらいじってくわけみたいです。(x86のeipレジスタみたいなもんですね。あ、よーはプログラムカウンタか)
すなわち、解析したいなら、またしても「DWARF命令逆アセンブラ」を作らにゃならん。(もぉINTEL64の逆アセンブラでこりごりじゃー)
次にレジスター
とりあえず、分かってるレジスタを以下にカキコ
"line" : こいつは、Cソースの行番号っす。
"address" : こいつは、アセンブラのアドレスです。
"file" : 今対象としてる、Cソースのファイル名。ヘッダで決まっちゃうらしいです。
"basic_block" : Boolean型 Cソースの複数行がアセンブラの複数行に対応してそれ以上分割無理ってケースの場合の、対応する最初のアセンブラ命令かどうかってフラグみたい。Breakpoint向けか?
"prologue_end" : Boolean型 関数にBreakpointを仕掛けた場合の、関数内の最初のアセンブラ命令の1つ前、の時Trueっぽい。それ以外は全部false <2011/10/20判明追記>
"epilogue_begin" : Boolean型 関数内の最後の命令の「1つ次」のアセンブラ命令ならTrueらしい。関数から戻る際には、コンパイラさんが泣けて来るほどいろいろ関数脱出のためのお世話してくれますが、このお世話命令の最初を示すためで、やっぱり関数Breakpoint設定時の対応っぽい。<2011/10/20判明追記>
"column" : 符号なし整数。ソースコード中の、今着目している列番号が入るレジスタみたい。なお、最初の列番号は1です。(0じゃねーぞって、僕のとっておき(=reserve)使うんじゃねって書いてあります) <2011/10/20判明追記>
"isa" : Instruction Set Architecture の略らしい=(今のアドレスの)アセンブラ命令のアーキテクチャ、を示す値。通常、1つのCPUでは1つのアーキテクチャ(アセンブラの文法)だから、0固定だよねきっと。(でも
PlayStation3
なcellとかNintedoDSとか、ヘテロジニアスマルチコアCPUはこれ値持つのかな?) <2011/10/20追記>
他にもあるっぽい。(鋭意規格書探検中)
んでもって、文法?
まず、命令には"Special Opcodes君"と"Standard Opcodesちゃん"の2種類ある。
"Special Opocodes君"
これこそが、Cソースとアセンブラの対応、すなわち、レジスタ"line"/"address"をいじくりまわす=値を足しまくる命令。
"Special=特別"とか言ってるけど、実はこいつはフツーの命令。
で、凄いのが、コレ!なんと、この"Special Opcodes"は、ヘッダの"line_base","line_range","opcode_base"の値から、Cソースファイル毎に計算式で命令作っちゃてるのです。
数式はコレ。
"Special Opcodes" = ( Cソースの行数増分 - "line_base" ) + ( "line_range" * アセンブラアドレスの増分 ) + "opcode_base"
要は、例えば、
Cソースは今13行目の intvalue = 5; な行として、次の行7行目に移ったとする。(6行目はお決まり?の空行)
この場合、"line"=5 から 7 になるので、Cソースの行数増分=2じゃ。
アセンブラアドレスの増分は、call 0x80040564 の命令から、mov rax,
r16
へ移るとして、5バイト増えるとする。(callが1byteかどうか正確には忘れたが....)
この場合、"address" = 0x80040564 から、0x80040569 へ5Byte増える。
"line_base"=2, "line_range"=8, "opcode_base"=13 (0dh), "minimun instruction length" = 1とする。
この場合の命令Byte = ( 2 - 2 ) + ( 8 * 5 ) + 0dh = 0 + 28h + 0dh = 35h になる。
すなわち、中身に35hが登場したら、その時は、Cのソースを2行進めて、アセンブラは5バイト進めるってことになる。(逆算)
良く考えてるよねこれ。(実は、値設定次第では、なんとアセンブラを戻すこともできる。これはCPU投機実行対策。ま、CPUだってたまには投げやりに仕事したいだろーから許してあげよう)
ホンで、逆算する場合の式です。(頭のえー人は上の式で逆算できるんかもね。僕はむりー。
アセンブラアドレス増分 = ( ( 中身のByte - "opcode_base" ) / "line_range" ) * "minimum_instruction_length"
Cソース行数増分 = "line_base" + ( ( 中身のByte - "opcode_base" ) % "line_range" ) ※ %は割算余りっす。
物は試し。検算です。
アセンブラアドレス増分 = ( ( 35h - 0dh ) / 8 ) * 1 = 5 ! (せーかい)
Cソース行数増分 = 2 + ( ( 35h - 0dh ) % 8 ) = 2! (せーかい)
"Standard Opcodesちゃん"
名前は「標準」なんだけど、こいつらこそある意味、特殊な命令
0x01〜"opcode_base"-1 の値までに、それぞれ命令が割り振られていて、命令コードは固定です。
ということで、しゃーないか、イッコづつ見るのだ。
DW_LNS_copy : 命令コード:0x01、引数: ありませーん
規格書には「今のレジスタ値でもって(Cソースとアセンブラアドレスの関係表に)1行追加する。さらに"basic_block"、"prologue_end""epilogue_begin"をfalseにする」とあるが、実際どー振舞ってくれるのかが、意味不明。
なんか、ダミー命令っぽいんかなぁ。これ。
DW_LNS_advance_pc : 命令コード: 0x02、引数: uLEB128
これは簡単。アセンブラアドレス"address"に対して、引数uLEB128 * "minimun_instruction_length" 分を強制的に加える命令。要するに、アセンブラアドレスだけ強制的に進めたいときのおまじない。
DW_LNS_advance_line : 命令コード: 0x03、引数: sLEB128
これも簡単。今度は、Cソースの行数"line"に、引数の値を足す。ポイントは、sLEB128=signed! なことで、Cソースは投機実行のせいで前に戻ることもできるよ(負数もあり)ってこと。
DW_LNS_set_file : 命令コード: 0x04、引数: uLEB128
これは、今着目しているファイルの番号を操作する時に使うもので、レジスタ"file"に引数uLEBを格納する。
ちなみに、ファイルの番号は、ヘッダのおケツのファイル名指定で複数ファイル名指定があったときの番号らしいです。
これの引数"unsigned"でした+引数はレジスタに足すのではなく、そのまま格納じゃった(2011/10/30修正)
DW_LNS_set_column : 命令コード : 0x05、引数: sLEB128
レジスタ"column"に引数の値を格納する命令。
要するに、Cソースの着目する列番号操作できるみたい。(でも何に使うんだろCの場合。。。。COBOLとか向けなのかな)
これも、引数はunsignedで、レジスタ足しではなく、「格納」でした。。。(2011/10/30修正)
DW_LNS_negate_stmt : 命令コード : 0x06、引数: なし
今のアセンブラアドレスはBreakpointになれるかどうかを示す"stmt"レジスタの値を逆にする命令。今falseならTrueになって、Breakpoint張ってもえーよって教えてくれる。(逆もしかり)
DW_LNS_set_basic_block : 命令コード 0x07、引数: なし
レジスタ"basic_block"の値を強制的に"True"にして、複数ソース行が複数アセンブラ命令に対応しているケースの場合に発行して、先頭を示すのだ。じゃ、どうやってfalseにするんだ!これは
SpecialOpcodes
は発行したら全部falseになることでやるのです。
DW_LNS_const_add_pc : 命令コード : 0x08、引数: なし
これはちと複雑で、「上のSpecial Opcodeが0xff(255)の時に"address"に加算される値」*「"minimum_instruction_length"」で計算される値を、レジスタ"address"に足し込む命令。でも目的は簡単で、Special Opcodesで対応できる"address"の増加分よりももっと大きな値を一時的に"address"に足したくなった場合、この命令をつかって増やせるってこと。
DW_LNS_fixed_advance_pc : 命令コード : 0x09、引数: uhalf = unsigned short(16bit)
レジスタ"address"に引数uhalfの値を強制的に足し込みます。意味的にはDW_LNS_advance_pcとおんなじ。(表現方法の違い)
DW_LNS_set_prologue_end : 命令コード : 0x0a、引数: なし
レジスタ"prologue_end"にTrueをセットします。意味はレジスタ説明の欄で。ちなみに、falseにするのはSpecial Opcodes発行でなっちゃいます。
DW_LNS_set_epilogue_begin: 命令コード: 0x0b、引数: なし
レジスタ"epilogue_begin"をTrueにします。意味はレジスタ説明欄で。
DW_LNS_set_isa : 命令コード: 0x0c、引数: uLEB128
レジスタ"isa"に、引数のuLEB128を足し込む命令。通常は使わないっぽいね。
(2011/10/30 ちょろっと修正)
Prev:
.debug_lineセクションの構造と読み方
Next:
.debug_frameセクションの構造
目次に戻る:
DWARFファイルフォーマット