github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/debug/elf/file.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 /* 6 パッケージelfは、ELFオブジェクトファイルへのアクセスを実装します。 7 8 # セキュリティ 9 10 このパッケージは敵対的な入力に対して強化されるように設計されておらず、 11 https://go.dev/security/policy の範囲外です。特に、オブジェクトファイルを解析する際には基本的な 12 検証のみが行われます。そのため、信頼できない入力を解析する際には注意が必要です。なぜなら、 13 形式が不正なファイルを解析すると、大量のリソースを消費したり、パニックを引き起こす可能性があるからです。 14 */ 15 package elf 16 17 import ( 18 "github.com/shogo82148/std/debug/dwarf" 19 "github.com/shogo82148/std/encoding/binary" 20 "github.com/shogo82148/std/errors" 21 "github.com/shogo82148/std/io" 22 ) 23 24 // FileHeaderはELFファイルヘッダーを表します。 25 type FileHeader struct { 26 Class Class 27 Data Data 28 Version Version 29 OSABI OSABI 30 ABIVersion uint8 31 ByteOrder binary.ByteOrder 32 Type Type 33 Machine Machine 34 Entry uint64 35 } 36 37 // Fileは開いているELFファイルを表します。 38 type File struct { 39 FileHeader 40 Sections []*Section 41 Progs []*Prog 42 closer io.Closer 43 gnuNeed []verneed 44 gnuVersym []byte 45 } 46 47 // SectionHeaderは単一のELFセクションヘッダーを表します。 48 type SectionHeader struct { 49 Name string 50 Type SectionType 51 Flags SectionFlag 52 Addr uint64 53 Offset uint64 54 Size uint64 55 Link uint32 56 Info uint32 57 Addralign uint64 58 Entsize uint64 59 60 // FileSizeは、ファイル内のこのセクションのサイズをバイト単位で表します。 61 // セクションが圧縮されている場合、FileSizeは圧縮データのサイズであり、 62 // Size(上記)は非圧縮データのサイズです。 63 FileSize uint64 64 } 65 66 // Sectionは、ELFファイル内の単一のセクションを表します。 67 type Section struct { 68 SectionHeader 69 70 // ReadAtメソッドのためにReaderAtを埋め込みます。 71 // ReadとSeekを避けるために、SectionReaderを直接埋め込まないでください。 72 // クライアントがReadとSeekを使用したい場合は、 73 // 他のクライアントとのシークオフセットの競合を避けるために 74 // Open()を使用する必要があります。 75 // 76 // セクションがランダムアクセス形式で簡単に利用できない場合、 77 // ReaderAtはnilになる可能性があります。例えば、圧縮されたセクションは 78 // ReaderAtがnilになるかもしれません。 79 io.ReaderAt 80 sr *io.SectionReader 81 82 compressionType CompressionType 83 compressionOffset int64 84 } 85 86 // DataはELFセクションの内容を読み取り、返します。 87 // セクションがELFファイル内で圧縮されて保存されていても、 88 // Dataは非圧縮データを返します。 89 // 90 // [SHT_NOBITS] セクションの場合、Dataは常に非nilのエラーを返します。 91 func (s *Section) Data() ([]byte, error) 92 93 // Openは、ELFセクションを読み取る新しいReadSeekerを返します。 94 // セクションがELFファイル内で圧縮されて保存されていても、 95 // ReadSeekerは非圧縮データを読み取ります。 96 // 97 // [SHT_NOBITS] セクションの場合、開いたリーダーへのすべての呼び出しは 98 // 非nilのエラーを返します。 99 func (s *Section) Open() io.ReadSeeker 100 101 // ProgHeaderは、単一のELFプログラムヘッダーを表します。 102 type ProgHeader struct { 103 Type ProgType 104 Flags ProgFlag 105 Off uint64 106 Vaddr uint64 107 Paddr uint64 108 Filesz uint64 109 Memsz uint64 110 Align uint64 111 } 112 113 // Progは、ELFバイナリ内の単一のELFプログラムヘッダーを表します。 114 type Prog struct { 115 ProgHeader 116 117 // ReadAtメソッドのためにReaderAtを埋め込みます。 118 // ReadとSeekを避けるために、SectionReaderを直接埋め込まないでください。 119 // クライアントがReadとSeekを使用したい場合は、 120 // 他のクライアントとのシークオフセットの競合を避けるために 121 // Open()を使用する必要があります。 122 io.ReaderAt 123 sr *io.SectionReader 124 } 125 126 // Openは、ELFプログラム本体を読み取る新しいReadSeekerを返します。 127 func (p *Prog) Open() io.ReadSeeker 128 129 // Symbolは、ELFシンボルテーブルセクションのエントリを表します。 130 type Symbol struct { 131 Name string 132 Info, Other byte 133 Section SectionIndex 134 Value, Size uint64 135 136 // VersionとLibraryは、動的シンボルテーブルにのみ存在します。 137 Version string 138 Library string 139 } 140 141 type FormatError struct { 142 off int64 143 msg string 144 val any 145 } 146 147 func (e *FormatError) Error() string 148 149 // Openは [os.Open] を使用して指定された名前のファイルを開き、ELFバイナリとしての使用を準備します。 150 func Open(name string) (*File, error) 151 152 // Closeは [File] を閉じます。 153 // [File] が [Open] ではなく [NewFile] を直接使用して作成された場合、 154 // Closeは何も影響を与えません。 155 func (f *File) Close() error 156 157 // SectionByTypeは、指定されたタイプを持つf内の最初のセクションを返します。 158 // そのようなセクションがない場合はnilを返します。 159 func (f *File) SectionByType(typ SectionType) *Section 160 161 // NewFileは、基礎となるリーダー内のELFバイナリにアクセスするための新しい [File] を作成します。 162 // ELFバイナリは、ReaderAtの位置0で開始することが期待されます。 163 func NewFile(r io.ReaderAt) (*File, error) 164 165 // ErrNoSymbolsは、[File.Symbols] と [File.DynamicSymbols] によって返されます。 166 // ファイルにそのようなセクションがない場合に返されます。 167 var ErrNoSymbols = errors.New("no symbol section") 168 169 // Sectionは、指定された名前を持つセクションを返します。 170 // そのようなセクションがない場合はnilを返します。 171 func (f *File) Section(name string) *Section 172 173 func (f *File) DWARF() (*dwarf.Data, error) 174 175 // Symbolsは、fのシンボルテーブルを返します。シンボルは、f内に出現する順序でリストされます。 176 // 177 // Go 1.0との互換性のため、Symbolsはインデックス0のnullシンボルを省略します。 178 // シンボルをsymtabとして取得した後、外部から供給されたインデックスxは 179 // symtab[x]ではなく、symtab[x-1]に対応します。 180 func (f *File) Symbols() ([]Symbol, error) 181 182 // DynamicSymbolsは、fの動的シンボルテーブルを返します。シンボルは、f内に出現する順序でリストされます。 183 // 184 // fがシンボルバージョンテーブルを持っている場合、返される [File.Symbols] は 185 // 初期化された [Version] とLibraryフィールドを持ちます。 186 // 187 // [File.Symbols] との互換性のため、[File.DynamicSymbols] はインデックス0のnullシンボルを省略します。 188 // シンボルをsymtabとして取得した後、外部から供給されたインデックスxは 189 // symtab[x]ではなく、symtab[x-1]に対応します。 190 func (f *File) DynamicSymbols() ([]Symbol, error) 191 192 type ImportedSymbol struct { 193 Name string 194 Version string 195 Library string 196 } 197 198 // ImportedSymbolsは、動的ロード時に他のライブラリによって満たされることが期待される 199 // バイナリfによって参照されるすべてのシンボルの名前を返します。 200 // 弱いシンボルは返しません。 201 func (f *File) ImportedSymbols() ([]ImportedSymbol, error) 202 203 // ImportedLibrariesは、動的リンク時にバイナリとリンクされることが期待される 204 // バイナリfによって参照されるすべてのライブラリの名前を返します。 205 func (f *File) ImportedLibraries() ([]string, error) 206 207 // DynStringは、ファイルの動的セクションで指定されたタグにリストされている文字列を返します。 208 // 209 // タグは、文字列値を取るものでなければなりません:[DT_NEEDED]、[DT_SONAME]、[DT_RPATH]、または 210 // [DT_RUNPATH]。 211 func (f *File) DynString(tag DynTag) ([]string, error) 212 213 // DynValueは、ファイルの動的セクションで指定されたタグにリストされている値を返します。 214 func (f *File) DynValue(tag DynTag) ([]uint64, error)