静岡旅行
サッカー観戦ついでに一泊二日で静岡に行った。
1日目
はい。 pic.twitter.com/S20zkLrsT3
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
シンカンセンスゴクタカイアイス pic.twitter.com/ZXI8ZT7RQ5
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
勝ったので最高でした。パトリックのゴールシーンではゴール裏みな狂喜乱舞して最高だったし最高だった。
お通しがきた pic.twitter.com/1cwGGoCPNm
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
大庄水産です。
大トロです pic.twitter.com/vqnLJK9tVb
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
この注ぎ方はおかしい… pic.twitter.com/WNhtJg3P1q
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
カマトロスペアリブ大勝利 pic.twitter.com/gPFw6szM8s
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
なめろう追加です pic.twitter.com/IVu0M96GYQ
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
二軒目 pic.twitter.com/6FmeHWubfm
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
静岡おでん満喫した pic.twitter.com/vJjk1RI3Er
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
3軒目 pic.twitter.com/0bhb0JH8Lg
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
飲み納めかな pic.twitter.com/E8wmV1aAng
— くそでかいイリエワニがみたい! (@shitsyndrome) 2017年9月23日
2日目
写真とかないけど、駿府城跡と日本平動物園に行った。 日本平動物園はレッサーパンダとかジャガーとかゴマフアザラシが間近でみれて最高だった。
まとめ
静岡とにかく飯美味いし街並みもきれいだし最高なのでまた行きたい。
Rustでバイナリなライブラリ
最近いじるときにどっかに情報まとめとくといいかな、と思い。他にもあれば是非教えてください。
- gimli-rs/gimli - DWARFを扱うためのライブラリ。DWARFってだいたいでかいのでlazy, zero-copyで扱いやすいのは期待してる。
- m4b/goblin - ELF/Mach-O/pe 形式のバイナリを扱うためのライブラリ。
- m4b/bingrep - 色付きのreadelf的な。セクションごとにみたりとかはできなそう。
- das-labor/panopticon - GUIなdisassmebler。
- nrc/xmas-elf - ELFのパーサ。
- philipc/ddbug - gimliを使ってデバッグ情報をいいかんじに出力してくれるやつ。
- fitzgen/cpp_demangle - C++のdemangleするやつ。C++でできたバイナリを扱いたいときに。
- willglynn/pdb - PDB扱えるらしい、けどWindows使ってないのでさわってない。
- endeav0r/falcon - 使ったことないけど、なんかよさそう。
- CensoredUsername/dynasm-rs - ちょっと毛色は違うけど便利なやつ。
binutilsでどういうオプション使うの?というはなし
manみて適切なの使えば?というはなしなんだろうけど、まあとっかかりとかあるし。
objdump
だいたい -Cd(S) もしくは -Cdr(S)をつかってる気がする。Dだと -C dlang
とかつける。でもわりとその場その場で変えてるような気もする。
nm
-f はポータブルじゃないので、–format=posix とかにしてる。
hexdump
-C くらい?使い込んでないだけかも。
size
意外と知らない人もいるけど、なかなか便利なやつ。(マイコンとかだとサイズ気になる)
単にサイズ知りたいときは10進数にしてる。
$ arm-none-eabi-size -d examples/itm/itm.bin text data bss dec hex filename 8716 436 20 9172 23d4 examples/itm/itm.bin
セクション毎でみたいときは、だいたい -Ax にして16進数にしてる。
$ arm-none-eabi-size -Ax examples/itm/itm.bin examples/itm/itm.bin : section size addr .isr_vector 0x188 0x8000000 .text 0x174 0x8000188 .rodata 0x2098 0x80002fc .bss 0x14 0x20000000 .data 0x8 0x8002394 .got 0x18 0x800239c .got.plt 0xc 0x80023b4 .debug_str 0x62f 0x0 .debug_loc 0x226 0x0 .debug_abbrev 0x372 0x0 .debug_info 0x9ba 0x0 .debug_ranges 0xc0 0x0 .debug_macinfo 0x3 0x0 .debug_pubnames 0x273 0x0 .debug_pubtypes 0x1b1 0x0 .comment 0x12 0x0 .ARM.attributes 0x45 0x0 .debug_frame 0x1a0 0x0 .debug_line 0x2c4 0x0 Total 0x42f7
readelf
これこそいろいろ使いわけるような。でも -l と -S と -h は使用率高い気する。
あとCortex-Mだと -A オプションとか。
$ arm-none-eabi-readelf -A examples/led/led.bin Attribute Section: aeabi File Attributes Tag_conformance: "2.09" Tag_CPU_name: "cortex-m4" Tag_CPU_arch: v7E-M Tag_CPU_arch_profile: Microcontroller Tag_THUMB_ISA_use: Thumb-2 Tag_FP_arch: VFPv4-D16 Tag_ABI_PCS_RW_data: PC-relative Tag_ABI_PCS_RO_data: PC-relative Tag_ABI_PCS_GOT_use: GOT-indirect Tag_ABI_FP_denormal: Needed Tag_ABI_FP_exceptions: Needed Tag_ABI_FP_number_model: IEEE 754 Tag_ABI_align_needed: 8-byte Tag_ABI_align_preserved: 8-byte, except leaf SP Tag_ABI_HardFP_use: SP only Tag_ABI_VFP_args: VFP registers Tag_ABI_optimization_goals: Prefer Speed Tag_CPU_unaligned_access: v6 Tag_FP_HP_extension: Allowed Tag_ABI_FP_16bit_format: IEEE 754
gdb
だいたい -q -iex “set auto-load safe-path ./” で、もろもろは.gdbinitに書いてる。
リンカのメモリコマンド
大半のリンカスクリプトでは、リンク先のようにメモリコマンドに (rwx) のように記述されている。(stm32のやつとか)
リンカのメモリコマンドの仕様は以下のようになっている。
The attr string must consist only of the following characters:
R Read-only section
W Read/write section
X Executable section
おそらく、多くの人が r=read, w=write という風に誤解しているのだろう。
LDCでのvolatileのはなし
LDCはpragmaを利用してLLVMのコード生成時にvolatileLoad/volatileStoreのハンドリングをしてる。
ここではvolatileLoadの呼び出し/コード生成までみていく。
core.bitopモジュールは、LDCコンパイラを使うときは特に指定しなくても pragma(LDC_intrinsic, “ldc.bitop.vld”) を指定して volatileLoad の宣言をしている。
// druntime - src/core/bitop.d version (LDC) { pragma(LDC_intrinsic, "ldc.bitop.vld") ubyte volatileLoad(ubyte* ptr); pragma(LDC_intrinsic, "ldc.bitop.vld") ushort volatileLoad(ushort* ptr); pragma(LDC_intrinsic, "ldc.bitop.vld") uint volatileLoad(uint* ptr); pragma(LDC_intrinsic, "ldc.bitop.vld") ulong volatileLoad(ulong* ptr); pragma(LDC_intrinsic, "ldc.bitop.vst") void volatileStore(ubyte* ptr, ubyte value); pragma(LDC_intrinsic, "ldc.bitop.vst") void volatileStore(ushort* ptr, ushort value); pragma(LDC_intrinsic, "ldc.bitop.vst") void volatileStore(uint* ptr, uint value); pragma(LDC_intrinsic, "ldc.bitop.vst") void volatileStore(ulong* ptr, ulong value); } ...
宣言の一覧はこれ。
// ldc - gen/dpragma.d extern (C++) enum LDCPragma : int { LLVMnone = 0, // Not an LDC pragma. LLVMignore, // Pragma has already been processed in DtoGetPragma, ignore. LLVMintrinsic, LLVMglobal_crt_ctor, LLVMglobal_crt_dtor, LLVMno_typeinfo, LLVMalloca, LLVMva_start, LLVMva_copy, LLVMva_end, LLVMva_arg, LLVMinline_asm, LLVMinline_ir, LLVMfence, LLVMatomic_store, LLVMatomic_load, LLVMatomic_cmp_xchg, LLVMatomic_rmw, LLVMbitop_bt, LLVMbitop_btc, LLVMbitop_btr, LLVMbitop_bts, LLVMbitop_vld, LLVMbitop_vst, LLVMextern_weak };
Dコードから命令に落とすところはこうなっている。素朴。
bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e, DValue *&result) { ... if (fndecl->llvmInternal == LLVMbitop_vld) { if (e->arguments->dim != 1) { e->error("bitop.vld intrinsic expects 1 argument"); fatal(); } // TODO: Check types Expression *exp1 = (*e->arguments)[0]; LLValue *ptr = DtoRVal(exp1); result = new DImValue(e->type, DtoVolatileLoad(ptr)); return true; } ...
ここでLLVMの中間コード生成するところに渡している。あとはごにょごにょやってLLVM IRを生成してるだけ。(だけ、とは)
LLValue *DtoVolatileLoad(LLValue *src, const char *name) { llvm::LoadInst *ld = gIR->ir->CreateLoad(src, name); ld->setVolatile(true); return ld; }
たとえば、ARM Cortex-Mとかでベアメタル環境で volatileLoad/volatileStore がほしければ core.bitop の定義をそのままもってくるとよい。
D言語をプロダクションに使うには、ということを考える
D言語のコードを社のレポジトリにpushした。(まだmasterにmergeされていないので、先走り気味かもしれない)
D言語を使った理由は使いたかったというのもあるが、今回のケースでは
- 使う箇所が部分的(言語はわりとなんでもいいところ)
- 標準でjsonを扱うためのライブラリがついている(まあ今時の言語だとだいたいありそうな,Rustは標準でなかったので外れた)
- バイナリを置けばいいだけのほうが楽そう(共有ライブラリのバージョンや置き場所の問題があるので、distroが同じという前提はあった)
- 静的型チェックがある(これはチームの文化として)
- それなりに安定して使える(NimとかCrystalとかPonyとかはこのへんで省かれる)
このへんを満たしているという点で、D言語を使うことが合理的な判断だったというところがある。この場合golangでよかった気がするけれど。
ユースケースを満たせばいいってものでもなく、D言語がチームで受け入れられるか、という点も大事になる。
チーム内での評価は
- Pros
- Cons
- パターンマッチがない
- 直和型がない(std.variantは、まあ…)
といった感じ。OCamlとかHaskellが好まれるチーム文化があるけれど、C++も書くチームなので受け入れられやすい。気がする。
D言語投入ありきで考えて、プロダクション投入するには、
- 小さく独立した部分ではじめる(動く状態を作ることが大事。時間かけるとけっきょくだれかにPythonとかで書かれてしまう)
- チームの文化に合致するか見定める(けっきょく他の人がレビューしないって言ったら別の言語で書くしかない)
この2点に集約される気がする。