許雅雯
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    2
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # ELF 檔解析 contributed by <`tina0405`> * 延續[學習實作小型作業系統筆記](https://hackmd.io/s/S1Ab0A9pX#ELF-%E8%A7%A3%E6%9E%90),本系統的在運行後,載入的應用程式的檔是excutable ELF 檔,而提供的新服務則是 relocatable ELF,先用以下的圖解釋一下 ELF 的結構([圖片來源](http://www.chuquan.me/2018/05/21/elf-introduce/))。 ![](https://i.imgur.com/g3D5aIM.png) * 針對一份測試應用程式來解析,先編譯成 relocatable ELF 的形式,如上圖介紹會包含: [紅] [ELF header](https://hackmd.io/s/H1G5-o83N#ELF-header) / [黃] 各個 section / [綠] section header table ~~~=c #include <stddef.h> #include <mutex.h> void * thread_run(void *arg); struct thread_mutex mutex; int count = 0; int main() { thread_t thread1; thread_mutex_lock(&mutex); thread_create(&thread1, NULL, thread_run, 0); thread_join(thread1, 0); return 0; } void * thread_run(void *arg) { int i; thread_mutex_unlock(&mutex); return 0; } ~~~ ### ELF header * `user.o` 的 file header 大小為 0x40, 因為結構裡64-bit 的 0x34 為 `e_ehsize`(此header的大小),參考 [ELF 格式](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format),因此只有前0x40 bit 是 file header。 ~~~ ---file header--- 0000000 457f 464c 0102 0001 0000 0000 0000 0000 0000010 0001 00b7 0001 0000 0000 0000 0000 0000 0000020 0000 0000 0000 0000 0430 0000 0000 0000 0000030 0000 0000 0040 0000 0000 0040 000a 0007 ---end of file header--- ~~~ * 經過 [ELF 格式](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format)的對照,其實 header 的 內容就如下,會從這裡知道 header section table 的起始是在 0x430(1072) * readelf -h user.o ~~~ ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: REL (Relocatable file) Machine: AArch64 Version: 0x1 Entry point address: 0x0 Start of program headers: 0 (bytes into file) Start of section headers: 1072 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 0 (bytes) Number of program headers: 0 Size of section headers: 64 (bytes) Number of section headers: 10 Section header string table index: 7 ~~~ * 從 0x430 往下找, section headers 共有 10個,然後每個 0x40, index 7 為 section header string table,對照[ELF 格式裡 section header 格式](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format),發現位在在 0x3e0,找到 section header string table(下方.shstrtab) 後可以對照每個 section header 的名字,下方已先標上。 ~~~ --- 0 0000430 0000 0000 0000 0000 0000 0000 0000 0000 * --- 1 .text section 0000470 0020 0000 0001 0000 0006 0000 0000 0000 0000480 0000 0000 0000 0000 0040 0000 0000 0000 0000490 006c 0000 0000 0000 0000 0000 0000 0000 00004a0 0004 0000 0000 0000 0000 0000 0000 0000 --- 2 .rela.text 00004b0 001b 0000 0004 0000 0040 0000 0000 0000 00004c0 0000 0000 0000 0000 02f0 0000 0000 0000 00004d0 00f0 0000 0000 0000 0008 0000 0001 0000 00004e0 0008 0000 0000 0000 0018 0000 0000 0000 --- 3 .data 00004f0 0026 0000 0001 0000 0003 0000 0000 0000 0000500 0000 0000 0000 0000 00ac 0000 0000 0000 0000510 0000 0000 0000 0000 0000 0000 0000 0000 0000520 0001 0000 0000 0000 0000 0000 0000 0000 --- 4 .bss 0000530 002c 0000 0008 0000 0003 0000 0000 0000 0000540 0000 0000 0000 0000 00ac 0000 0000 0000 0000550 0004 0000 0000 0000 0000 0000 0000 0000 * --- 5 .comment 0000570 0031 0000 0001 0000 0030 0000 0000 0000 0000580 0000 0000 0000 0000 00ac 0000 0000 0000 0000590 003c 0000 0000 0000 0000 0000 0000 0000 00005a0 0001 0000 0000 0000 0001 0000 0000 0000 --- 6 --- .note.GNU-stack 00005b0 003a 0000 0001 0000 0000 0000 0000 0000 00005c0 0000 0000 0000 0000 00e8 0000 0000 0000 00005d0 0000 0000 0000 0000 0000 0000 0000 0000 00005e0 0001 0000 0000 0000 0000 0000 0000 0000 --- 7 .shstrtab section 00005f0 0011 0000 0003 0000 0000 0000 0000 0000 0000600 0000 0000 0000 0000 03e0 0000 0000 0000 0000610 004a 0000 0000 0000 0000 0000 0000 0000 0000620 0001 0000 0000 0000 0000 0000 0000 0000 --- 8 .symtab = symbol table 0000630 0001 0000 0002 0000 0000 0000 0000 0000 0000640 0000 0000 0000 0000 00e8 0000 0000 0000 0000650 0198 0000 0000 0000 0009 0000 0009 0000 0000660 0008 0000 0000 0000 0018 0000 0000 0000 --- 9 .strtab 0000670 0009 0000 0003 0000 0000 0000 0000 0000 0000680 0000 0000 0000 0000 0280 0000 0000 0000 0000690 006a 0000 0000 0000 0000 0000 0000 0000 00006a0 0001 0000 0000 0000 0000 0000 0000 0000 ~~~ * 之後就可裡用 section header 裡的資訊(地址、大小等)找到 section 在哪,下面先標上 header 名稱。 ~~~ ---start of .text--- 0000040 7bfd a9be 03fd 9100 0000 9000 0000 9100 0000050 0000 9400 0000 9000 0001 9100 73a0 9100 0000060 0003 5280 03e2 aa01 0001 d280 0000 9400 0000070 1fa0 b940 0001 5280 0000 9400 0000 5280 0000080 7bfd a8c2 03c0 d65f 7bfd a9be 03fd 9100 0000090 0fa0 f900 0000 9000 0000 9100 0000 9400 00000a0 0000 d280 7bfd a8c2 03c0 d65f ---end of .text--- ---start of .comment--- 4700 4343 00000b0 203a 5528 7562 746e 2f75 694c 616e 6f72 00000c0 3520 342e 302e 362d 6275 6e75 7574 7e31 00000d0 3631 302e 2e34 2939 3520 342e 302e 3220 00000e0 3130 3036 3036 0039 ---end of .comment--- ---symbol table--- 0000 0000 0000 0000 00000f0 0000 0000 0000 0000 0000 0000 0000 0000 0000100 0001 0000 0004 fff1 0000 0000 0000 0000 0000110 0000 0000 0000 0000 0000 0000 0003 0001 0000120 0000 0000 0000 0000 0000 0000 0000 0000 0000130 0000 0000 0003 0003 0000 0000 0000 0000 0000140 0000 0000 0000 0000 0000 0000 0003 0004 0000150 0000 0000 0000 0000 0000 0000 0000 0000 0000160 0008 0000 0000 0004 0000 0000 0000 0000 0000170 0000 0000 0000 0000 000b 0000 0000 0001 0000180 0000 0000 0000 0000 0000 0000 0000 0000 0000190 0000 0000 0003 0006 0000 0000 0000 0000 00001a0 0000 0000 0000 0000 0000 0000 0003 0005 00001b0 0000 0000 0000 0000 0000 0000 0000 0000 00001c0 000e 0000 0011 fff2 0008 0000 0000 0000 00001d0 0020 0000 0000 0000 0014 0000 0011 0004 00001e0 0000 0000 0000 0000 0004 0000 0000 0000 00001f0 001a 0000 0012 0001 0000 0000 0000 0000 0000200 0048 0000 0000 0000 001f 0000 0010 0000 0000210 0000 0000 0000 0000 0000 0000 0000 0000 0000220 0031 0000 0012 0001 0048 0000 0000 0000 0000230 0024 0000 0000 0000 003c 0000 0010 0000 0000240 0000 0000 0000 0000 0000 0000 0000 0000 0000250 004a 0000 0010 0000 0000 0000 0000 0000 0000260 0000 0000 0000 0000 0056 0000 0010 0000 0000270 0000 0000 0000 0000 0000 0000 0000 0000 --- end of symbol table --- --- .strtab --- 0000280 7500 6573 2e72 0063 6424 2400 0078 756d .user.c.$d.$x.mu 0000290 6574 0078 6f63 6e75 0074 616d 6e69 7400 tex.count.main.t 00002a0 7268 6165 5f64 756d 6574 5f78 6f6c 6b63 hread_mutex_lock 00002b0 7400 7268 6165 5f64 7572 006e 6874 6572 .thread_run.thre 00002c0 6461 635f 6572 7461 0065 6874 6572 6461 ad_create.thread 00002d0 6a5f 696f 006e 6874 6572 6461 6d5f 7475 _join.thread_mut 00002e0 7865 755f 6c6e 636f 006b 0000 0000 0000 ex_unlock....... --- .rela.text --- 00002f0 0008 0000 0000 0000 0113 0000 0009 0000 0000300 0000 0000 0000 0000 000c 0000 0000 0000 0000310 0115 0000 0009 0000 0000 0000 0000 0000 0000320 0010 0000 0000 0000 011b 0000 000c 0000 0000330 0000 0000 0000 0000 0014 0000 0000 0000 0000340 0113 0000 000d 0000 0000 0000 0000 0000 0000350 0018 0000 0000 0000 0115 0000 000d 0000 0000360 0000 0000 0000 0000 002c 0000 0000 0000 0000370 011b 0000 000e 0000 0000 0000 0000 0000 0000380 0038 0000 0000 0000 011b 0000 000f 0000 0000390 0000 0000 0000 0000 0054 0000 0000 0000 00003a0 0113 0000 0009 0000 0000 0000 0000 0000 00003b0 0058 0000 0000 0000 0115 0000 0009 0000 00003c0 0000 0000 0000 0000 005c 0000 0000 0000 00003d0 011b 0000 0010 0000 0000 0000 0000 0000 --- .shstrtab section --- 00003e0 2e00 7973 746d 6261 2e00 7473 7472 6261 ..symtab..strtab 00003f0 2e00 6873 7473 7472 6261 2e00 6572 616c ..shstrtab..rela 0000400 742e 7865 0074 642e 7461 0061 622e 7373 .text..data..bss 0000410 2e00 6f63 6d6d 6e65 0074 6e2e 746f 2e65 ..comment..note. 0000420 4e47 2d55 7473 6361 006b 0000 0000 0000 GNU-stack....... ~~~ * ELF header table: * 雖然指令:`aarch64-linux-gnu-objdump -h user.o` 能觀察出各個 section 的位置和大小,但這部份 -h 不包含 `.symtab`, `.strtab`, `.shstrtab`, `.rela.text` 內部操作的 section, 但學習 kernel module 須用到。 ~~~ Idx Name Size VMA LMA File off Algn 0 .text 0000006c 0000000000000000 0000000000000000 00000040 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .data 00000000 0000000000000000 0000000000000000 000000ac 2**0 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000004 0000000000000000 0000000000000000 000000ac 2**2 ALLOC 3 .comment 0000003c 0000000000000000 0000000000000000 000000ac 2**0 CONTENTS, READONLY 4 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000e8 2**0 CONTENTS, READONLY ~~~ ### ELF 中的 section - [x] .text * 我們會發現因為這個 ELF 還未經過連結,會發現裡面 0xc 的地方 `94000000 bl 0 <thread_mutex_lock>` 還不知道要 bl 的地址,所以先寫 0, add 的地方因為還沒放置變數,因此也先空著,這些會在之後 .rela.text 作介紹 ~~~ Disassembly of section .text: 0000000000000000 <main>: 0: a9be7bfd stp x29, x30, [sp,#-32]! 4: 910003fd mov x29, sp 8: 90000000 adrp x0, 20 <main+0x20> c: 91000000 add x0, x0, #0x0 10: 94000000 bl 0 <thread_mutex_lock> 14: 90000000 adrp x0, 48 <thread_run> 18: 91000001 add x1, x0, #0x0 1c: 910073a0 add x0, x29, #0x1c 20: 52800003 mov w3, #0x0 // #0 24: aa0103e2 mov x2, x1 28: d2800001 mov x1, #0x0 // #0 2c: 94000000 bl 0 <thread_create> 30: b9401fa0 ldr w0, [x29,#28] 34: 52800001 mov w1, #0x0 // #0 38: 94000000 bl 0 <thread_join> 3c: 52800000 mov w0, #0x0 // #0 40: a8c27bfd ldp x29, x30, [sp],#32 44: d65f03c0 ret 0000000000000048 <thread_run>: 48: a9be7bfd stp x29, x30, [sp,#-32]! 4c: 910003fd mov x29, sp 50: f9000fa0 str x0, [x29,#24] 54: 90000000 adrp x0, 20 <main+0x20> 58: 91000000 add x0, x0, #0x0 5c: 94000000 bl 0 <thread_mutex_unlock> 60: d2800000 mov x0, #0x0 // #0 64: a8c27bfd ldp x29, x30, [sp],#32 68: d65f03c0 ret ~~~ - [x] .comment: 這個部份帶的資訊用 ascii code 轉換放置旁邊 ~~~ Contents of section .comment: 0000 00474343 3a202855 62756e74 752f4c69 .GCC: (Ubuntu/Li 0010 6e61726f 20352e34 2e302d36 7562756e naro 5.4.0-6ubun 0020 7475317e 31362e30 342e3929 20352e34 tu1~16.04.9) 5.4 0030 2e302032 30313630 36303900 .0 20160609. ~~~ - [x] .symtab = symbol table * 64-bit 裡面的結構 symbol 的結構: 也就是一個 symbol 應該要帶有的資訊,一個 symbol 24 byte,至於各個名稱的解釋放置下面。 ~~~ typedef struct { Elf64_Word st_name; /* (4 bytes) Symbol name */ unsigned char st_info; /* (1 byte) Symbol type and binding */ unsigned char st_other; /* (1 byte) Symbol visibility */ Elf64_Section st_shndx; /* (2 bytes) Section index */ Elf64_Addr st_value; /* (8 bytes) Symbol value */ Elf64_Xword st_size; /* (8 bytes) Symbol size */ } Elf64_Sym; ~~~ * 以下是 symbol table 原始的 object code ~~~ ---symbol table--- 0000 0000 0000 0000 00000f0 0000 0000 0000 0000 0000 0000 0000 0000 - 0000100 0001 0000 0004 fff1 0000 0000 0000 0000 0000110 0000 0000 0000 0000 - 0000 0000 0003 0001 0000120 0000 0000 0000 0000 0000 0000 0000 0000 - 0000130 0000 0000 0003 0003 0000 0000 0000 0000 0000140 0000 0000 0000 0000 - 0000 0000 0003 0004 0000150 0000 0000 0000 0000 0000 0000 0000 0000 - 0000160 0008 0000 0000 0004 0000 0000 0000 0000 0000170 0000 0000 0000 0000 - 000b 0000 0000 0001 0000180 0000 0000 0000 0000 0000 0000 0000 0000 - 0000190 0000 0000 0003 0006 0000 0000 0000 0000 00001a0 0000 0000 0000 0000 - 0000 0000 0003 0005 00001b0 0000 0000 0000 0000 0000 0000 0000 0000 - mutex 00001c0 000e 0000 0011 fff2 0008 0000 0000 0000 00001d0 0020 0000 0000 0000 - count 0014 0000 0011 0004 00001e0 0000 0000 0000 0000 0004 0000 0000 0000 - main 00001f0 001a 0000 0012 0001 0000 0000 0000 0000 0000200 0048 0000 0000 0000 - 001f 0000 0010 0000 0000210 0000 0000 0000 0000 0000 0000 0000 0000 - 0000220 0031 0000 0012 0001 0048 0000 0000 0000 0000230 0024 0000 0000 0000 - 003c 0000 0010 0000 0000240 0000 0000 0000 0000 0000 0000 0000 0000 - 0000250 004a 0000 0010 0000 0000 0000 0000 0000 0000260 0000 0000 0000 0000 - 0056 0000 0010 0000 0000270 0000 0000 0000 0000 0000 0000 0000 0000 --- end of symbol table --- ~~~ * 以上的 byte 數剛好分成 17 組,如下表: ~~~ Symbol table '.symtab' contains 17 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS user.c 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 3: 0000000000000000 0 SECTION LOCAL DEFAULT 3 4: 0000000000000000 0 SECTION LOCAL DEFAULT 4 5: 0000000000000000 0 NOTYPE LOCAL DEFAULT 4 $d 6: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 $x 7: 0000000000000000 0 SECTION LOCAL DEFAULT 6 8: 0000000000000000 0 SECTION LOCAL DEFAULT 5 9: 0000000000000008 32 OBJECT GLOBAL DEFAULT COM mutex 10: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 count 11: 0000000000000000 72 FUNC GLOBAL DEFAULT 1 main 12: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND thread_mutex_lock 13: 0000000000000048 36 FUNC GLOBAL DEFAULT 1 thread_run 14: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND thread_create 15: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND thread_join 16: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND thread_mutex_unlock ~~~ * 拿第 13 組 thread_run 來作解釋(因為是 little endian 記得要倒過來): * st_name(4 byte): `0000 0031` * st_info(1 byte): `12` * 這部份帶有兩個訊息,參考 [File format](https://docs.oracle.com/cd/E19683-01/816-1386/6m7qcoblj/index.html#chapter7-27): ~~~c= #define ELF64_ST_BIND(info) ((info) >> 4) #define ELF64_ST_TYPE(info) ((info) & 0xf) #define ELF64_ST_INFO(bind, type) (((bind)<<4)+((type)&0xf)) ~~~ * 低位(symbol type):`1` GLOBAL * 高位(binding): `2` FUNCTION * st_other(1 byte): `00` ,參考 [File format](https://docs.oracle.com/cd/E19683-01/816-1386/6m7qcoblj/index.html#chapter7-27): ~~~ 00 - STV_DEFAULT The visibility of symbols with the STV_DEFAULT attribute is as specified by the symbol's binding type. That is, global and weak symbols are visible outside of their defining component, the executable file or shared object. Local symbols are hidden. Global and weak symbols can also be preempted, that is, they may by interposed by definitions of the same name in another component. ~~~ * st_shndx(2 bytes): `0001` * 00-SHT_NULL: 沒定義等待跟其他檔案連結 * 01-SHT_PROGBITS: 在這份檔案內 * st_value(8 bytes): `0000 0000 0000 0048` * 程式從 48 開始 * st_size(8 bytes):`0000 0000 0000 0024` * 程式的大小 24,6 行指令,1 行 4 bytes。 ~~~ 0000220 0031 0000 0012 0001 0048 0000 0000 0000 0000230 0024 0000 0000 0000 ~~~ - [ ] .strtab ~~~ --- .strtab --- 0000280 7500 6573 2e72 0063 6424 2400 0078 756d .user.c.$d.$x.mu 0000290 6574 0078 6f63 6e75 0074 616d 6e69 7400 tex.count.main.t 00002a0 7268 6165 5f64 756d 6574 5f78 6f6c 6b63 hread_mutex_lock 00002b0 7400 7268 6165 5f64 7572 006e 6874 6572 .thread_run.thre 00002c0 6461 635f 6572 7461 0065 6874 6572 6461 ad_create.thread 00002d0 6a5f 696f 006e 6874 6572 6461 6d5f 7475 _join.thread_mut 00002e0 7865 755f 6c6e 636f 006b 0000 0000 0000 ex_unlock....... ~~~ - [ ] .rela.text * 結構 ~~~c= typedef struct { Elf64_Addr r_offset; /*8 bytes*/ Elf64_Xword r_info; /*8 bytes*/ Elf64_Sxword r_addend; /*8 bytes*/ } Elf64_Rela; ~~~ * .rela.text ~~~ 00002f0 0008 0000 0000 0000 0113 0000 0009 0000 0000300 0000 0000 0000 0000 - 000c 0000 0000 0000 0000310 0115 0000 0009 0000 0000 0000 0000 0000 - 0000320 0010 0000 0000 0000 011b 0000 000c 0000 0000330 0000 0000 0000 0000 - 0014 0000 0000 0000 0000340 0113 0000 000d 0000 0000 0000 0000 0000 - 0000350 0018 0000 0000 0000 0115 0000 000d 0000 0000360 0000 0000 0000 0000 - 002c 0000 0000 0000 0000370 011b 0000 000e 0000 0000 0000 0000 0000 - 0000380 0038 0000 0000 0000 011b 0000 000f 0000 0000390 0000 0000 0000 0000 - 0054 0000 0000 0000 00003a0 0113 0000 0009 0000 0000 0000 0000 0000 - 00003b0 0058 0000 0000 0000 0115 0000 0009 0000 00003c0 0000 0000 0000 0000 - 005c 0000 0000 0000 00003d0 011b 0000 0010 0000 0000 0000 0000 0000 ~~~ * relocation text 資訊: offset 表示在原程式中的哪, info 裡包含了,在 symbol 中的 index 和 type ~~~ c= tina@tina-X550VB:~/Hw/raspberry-pi3-mini-os/9.ldaxr+cache_on/testcode/mutex_testina@tina-X550VB:~/Hw/raspberry-pi3-mini-os/9.ldaxr+cache_on/testcode/mutex_tesm$ readelf -r user.o Relocation section '.rela.text' at offset 0x2f0 contains 10 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000008 000900000113 R_AARCH64_ADR_PRE 0000000000000008 mutex + 0 00000000000c 000900000115 R_AARCH64_ADD_ABS 0000000000000008 mutex + 0 000000000010 000c0000011b R_AARCH64_CALL26 0000000000000000 thread_mutex_lock + 0 000000000014 000d00000113 R_AARCH64_ADR_PRE 0000000000000048 thread_run + 0 000000000018 000d00000115 R_AARCH64_ADD_ABS 0000000000000048 thread_run + 0 00000000002c 000e0000011b R_AARCH64_CALL26 0000000000000000 thread_create + 0 000000000038 000f0000011b R_AARCH64_CALL26 0000000000000000 thread_join + 0 000000000054 000900000113 R_AARCH64_ADR_PRE 0000000000000008 mutex + 0 000000000058 000900000115 R_AARCH64_ADD_ABS 0000000000000008 mutex + 0 00000000005c 00100000011b R_AARCH64_CALL26 0000000000000000 thread_mutex_unlock + 0 ~~~ - [x] .shstrtab: 提供給 section header table 去利用 offset 找尋名稱。 ~~~ --- .shstrtab section --- 00003e0 2e00 7973 746d 6261 2e00 7473 7472 6261 ..symtab..strtab 00003f0 2e00 6873 7473 7472 6261 2e00 6572 616c ..shstrtab..rela 0000400 742e 7865 0074 642e 7461 0061 622e 7373 .text..data..bss 0000410 2e00 6f63 6d6d 6e65 0074 6e2e 746f 2e65 ..comment..note. 0000420 4e47 2d55 7473 6361 006b 0000 0000 0000 GNU-stack....... ~~~ * 拿 section header table 中的 .text 舉例, `0x20` 為 offset, 對照上表 `0x00003e0 + 0x20 = 0x0000400`, 即為 `.text`: ~~~ --- 1 .text section 0000470 0020 0000 0001 0000 0006 0000 0000 0000 0000480 0000 0000 0000 0000 0040 0000 0000 0000 0000490 006c 0000 0000 0000 0000 0000 0000 0000 00004a0 0004 0000 0000 0000 0000 0000 0000 0000 ~~~ ### Linker to relocate * 我們從 relocation text 留給我們的資訊上發現, 有 10 筆資料樣填入,我會將第一筆和第二筆一起看,因為他們是有關係的: ~~~ Offset Info Type Sym. Value Sym. Name + Addend 000000000008 000900000113 R_AARCH64_ADR_PRE 0000000000000008 mutex + 0 00000000000c 000900000115 R_AARCH64_ADD_ABS 0000000000000008 mutex + 0 ~~~ * 比較未經過 relocation 的檔案, 0x8 和 0xc 目前都先未填 ~~~ 0: a9be7bfd stp x29, x30, [sp,#-32]! 4: 910003fd mov x29, sp 8: 90000000 adrp x0, 20 <main+0x20> c: 91000000 add x0, x0, #0x0 10: 94000000 bl 0 <thread_mutex_lock> 14: 90000000 adrp x0, 48 <thread_run> 18: 91000001 add x1, x0, #0x0 1c: 910073a0 add x0, x29, #0x1c .... ~~~ * 下方為 linker 後的 ELF 片段([完整的連結](https://hackmd.io/s/H1G5-o83N#linker-%E5%BE%8C%E7%9A%84%E5%AE%8C%E6%95%B4-ELF)), 因為 linker 知道 mutex這個 data 被放置 0x188, 因此 basic + offset 的方式,`x0` 先載入 `adrp x0, 0 <main>`, 再放置 `add x0, x0, #0x188` * 註: 0x188 = 392(十進位), 392*4 = 1568(十進位) = 0x620, 故機器碼為 `91062000` ~~~c= 0000000000000000 <main>: 0: a9be7bfd stp x29, x30, [sp,#-32]! 4: 910003fd mov x29, sp 8: 90000000 adrp x0, 0 <main> c: 91062000 add x0, x0, #0x188 10: 94000050 bl 150 <thread_mutex_lock> 14: 90000000 adrp x0, 0 <main> 18: 91012001 add x1, x0, #0x48 1c: 910073a0 add x0, x29, #0x1c ... ~~~ * `bl` 的對應,我們看未連結的機器碼 `10: 94000000 bl 0 <thread_mutex_lock>`, 因為 linker 把另一份有 thread_mutex_lock(.text)的 relocation elf, 一起重新配置, 已經知道放置 thread_mutex_lock 的 addr 是 0x150 * 註: 0x150 - 0x10(pc) = 0x140 = 320(十進位), 32/4(指令4-byte) = 80(十進位) = 0x50,故0x10 行重新填入 `10: 94000050` ### linker 後的完整 ELF ~~~c= 0000000000000000 <main>: 0: a9be7bfd stp x29, x30, [sp,#-32]! 4: 910003fd mov x29, sp 8: 90000000 adrp x0, 0 <main> c: 91062000 add x0, x0, #0x188 10: 94000050 bl 150 <thread_mutex_lock> 14: 90000000 adrp x0, 0 <main> 18: 91012001 add x1, x0, #0x48 1c: 910073a0 add x0, x29, #0x1c 20: 52800003 mov w3, #0x0 // #0 24: aa0103e2 mov x2, x1 28: d2800001 mov x1, #0x0 // #0 2c: 94000025 bl c0 <thread_create> 30: b9401fa0 ldr w0, [x29,#28] 34: 52800001 mov w1, #0x0 // #0 38: 94000028 bl d8 <thread_join> 3c: 52800000 mov w0, #0x0 // #0 40: a8c27bfd ldp x29, x30, [sp],#32 44: d65f03c0 ret 0000000000000048 <thread_run>: 48: a9be7bfd stp x29, x30, [sp,#-32]! 4c: 910003fd mov x29, sp 50: f9000fa0 str x0, [x29,#24] 54: 90000000 adrp x0, 0 <main> 58: 91062000 add x0, x0, #0x188 5c: 94000040 bl 15c <thread_mutex_unlock> 60: d2800000 mov x0, #0x0 // #0 64: a8c27bfd ldp x29, x30, [sp],#32 68: d65f03c0 ret 000000000000006c <user_delay>: 6c: f1000400 subs x0, x0, #0x1 70: 54ffffe1 b.ne 6c <user_delay> 74: d65f03c0 ret 0000000000000078 <call_sys_write>: 78: 52800008 mov w8, #0x0 // #0 7c: d4000001 svc #0x0 80: d65f03c0 ret 0000000000000084 <call_sys_write_int>: 84: 528000a8 mov w8, #0x5 // #5 88: d4000001 svc #0x0 8c: d65f03c0 ret 0000000000000090 <call_sys_exit>: 90: 52800048 mov w8, #0x2 // #2 94: d4000001 svc #0x0 98: d65f03c0 ret 000000000000009c <call_sys_fork>: 9c: 52800028 mov w8, #0x1 // #1 a0: d4000001 svc #0x0 a4: d65f03c0 ret 00000000000000a8 <call_sys_led>: a8: 52800068 mov w8, #0x3 // #3 ac: d4000001 svc #0x0 b0: d65f03c0 ret 00000000000000b4 <call_sys_read>: b4: 52800088 mov w8, #0x4 // #4 b8: d4000001 svc #0x0 bc: d65f03c0 ret 00000000000000c0 <thread_create>: c0: 528000c8 mov w8, #0x6 // #6 c4: d4000001 svc #0x0 c8: d65f03c0 ret 00000000000000cc <thread_self>: cc: 528000e8 mov w8, #0x7 // #7 d0: d4000001 svc #0x0 d4: d65f03c0 ret 00000000000000d8 <thread_join>: d8: 52800108 mov w8, #0x8 // #8 dc: d4000001 svc #0x0 e0: d65f03c0 ret 00000000000000e4 <thread_cond_signal>: e4: 52800148 mov w8, #0xa // #10 e8: d4000001 svc #0x0 ec: d65f03c0 ret 00000000000000f0 <call_sys_list>: f0: 52800168 mov w8, #0xb // #11 f4: d4000001 svc #0x0 f8: d65f03c0 ret 00000000000000fc <call_sys_cd>: fc: 52800188 mov w8, #0xc // #12 100: d4000001 svc #0x0 104: d65f03c0 ret 0000000000000108 <call_sys_dump>: 108: 528001a8 mov w8, #0xd // #13 10c: d4000001 svc #0x0 110: d65f03c0 ret 0000000000000114 <call_sys_root>: 114: 528001c8 mov w8, #0xe // #14 118: d4000001 svc #0x0 11c: d65f03c0 ret 0000000000000120 <call_sys_mod>: 120: 528001e8 mov w8, #0xf // #15 124: d4000001 svc #0x0 128: d65f03c0 ret 000000000000012c <call_sys_send>: 12c: 52800208 mov w8, #0x10 // #16 130: d4000001 svc #0x0 134: d65f03c0 ret 0000000000000138 <call_sys_recv>: 138: 52800228 mov w8, #0x11 // #17 13c: d4000001 svc #0x0 140: d65f03c0 ret 0000000000000144 <thread_mutex_trylock>: 144: 52800248 mov w8, #0x12 // #18 148: d4000001 svc #0x0 14c: d65f03c0 ret 0000000000000150 <thread_mutex_lock>: 150: 52800248 mov w8, #0x12 // #18 154: d4000001 svc #0x0 158: d65f03c0 ret 000000000000015c <thread_mutex_unlock>: 15c: 52800268 mov w8, #0x13 // #19 160: d4000001 svc #0x0 164: d65f03c0 ret 0000000000000168 <thread_equal>: 168: eb01001f cmp x0, x1 16c: 54000060 b.eq 178 <eq> 170: d2800000 mov x0, #0x0 // #0 174: 14000002 b 17c <neq> 0000000000000178 <eq>: 178: d2800020 mov x0, #0x1 // #1 000000000000017c <neq>: 17c: d65f03c0 ret Disassembly of section .bss: 0000000000000180 <count>: ... 0000000000000188 <mutex>: ... Disassembly of section .comment: 0000000000000000 <.comment>: 0: 3a434347 ccmn w26, w3, #0x7, mi 4: 62552820 .inst 0x62552820 ; undefined 8: 75746e75 .inst 0x75746e75 ; undefined c: 6e694c2f uqshl v15.8h, v1.8h, v9.8h 10: 206f7261 .inst 0x206f7261 ; undefined 14: 2e342e35 uqsub v21.8b, v17.8b, v20.8b 18: 75362d30 .inst 0x75362d30 ; undefined 1c: 746e7562 .inst 0x746e7562 ; undefined 20: 317e3175 adds w21, w11, #0xf8c, lsl #12 24: 34302e36 cbz w22, 605e8 <mutex+0x60460> 28: 2029392e .inst 0x2029392e ; undefined 2c: 2e342e35 uqsub v21.8b, v17.8b, v20.8b 30: 30322030 adr x16, 64435 <mutex+0x642ad> 34: 36303631 tbz w17, #6, 6f8 <mutex+0x570> 38: Address 0x0000000000000038 is out of bounds. ~~~ * 簡易的了解以下 3 點,終於要進入實做的部份[載入,連結與重配置](https://hackmd.io/wvADYU_3Sg2-VzHIibUSCg): * elf 如何配置 * 重填 rela.text 的 addr * 對照 symbol table 填 value ### Reference * [Implementing Loadable Kernel Modules for Linux](http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/DDJ/1995/9505/9505a/9505a.htm) * https://myao0730.blogspot.com/2015/09/csapplinking.html * https://stac47.github.io/c/relocation/elf/tutorial/2018/03/01/understanding-relocation-elf.html * http://opass.logdown.com/posts/248172-linker-loader-library * http://www.cjwind.idv.tw/Static-Link/ * http://www.cjwind.idv.tw/Static-Link/

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully