Hiển thị thông tin Debug của Loader-Linker trong Linux
Linux
77
Linker
1
Loader
1
C
27
White

Phùng Văn Tú viết ngày 21/12/2016

Gần đây, gặp một số vấn đề về Loader-Linker giữa môi trường build và môi trường chạy trong Cross-Compiling.
Mình xin note lại mấy cái. Định để TIL thì hơi dài nên viết tài post mới vậy.

Có thể bất kì chương nào trong Linux cũng vậy. Nhưng chỉ xét một chường trình được build bằng C thì
một chương trình sẽ được chạy 2 cách dưới đây

1. Chương trình hoàn toàn là tĩnh

  • Không có symbol nào cần phải được (resolved) trước khi chạy.
  • Không yêu cầu bất cứ một thư viện run-time nào.
  • Kernel cứ thế load vào, rồi nhảy đến vị trí của Program Entry là chạy.
  • Có kích thước lớn
  • Để build được nó thì các thư viện phụ thuộc khi build cũng phải có phiên bản static. Lấy ví dụ HelloWorld
#include<stdio.h>
int main(int argc, char *args[])
{
        printf("Hello, Ajinomoto \n");
        return 0;
}

Khi build tĩnh bằng (hầu như phải có -static)

gcc -o helloworld_static helloworld.c -static

Kích thước file chạy sẽ như sau:

$ ls -liah helloworld_static
2910638 -rwxrwxr-x 1 duser duser 717K Dec  9 13:37 helloworld_static

717KB cho HelloWorld trên Ubuntu 14.04

Kiểm tra bằng objdump:

$ objdump -p helloworld_static

helloworld_static:     file format elf32-i386

Program Header:
    LOAD off    0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
         filesz 0x000a0c77 memsz 0x000a0c77 flags r-x
    LOAD off    0x000a0f40 vaddr 0x080e9f40 paddr 0x080e9f40 align 2**12
         filesz 0x00001040 memsz 0x000023c4 flags rw-
    NOTE off    0x000000f4 vaddr 0x080480f4 paddr 0x080480f4 align 2**2
         filesz 0x00000044 memsz 0x00000044 flags r--
     TLS off    0x000a0f40 vaddr 0x080e9f40 paddr 0x080e9f40 align 2**2
         filesz 0x00000010 memsz 0x00000028 flags r--
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4
         filesz 0x00000000 memsz 0x00000000 flags rw-
   RELRO off    0x000a0f40 vaddr 0x080e9f40 paddr 0x080e9f40 align 2**0
         filesz 0x000000c0 memsz 0x000000c0 flags r--

Nhìn có vẻ khó hiểu, như chỉ để ý thấy chỉ có phần Program Header mà không còn phần nào khác.

2. Chương trình là động

  • Chứa symbol cần được phân giải trước khi chạy.
  • Hầu như các command trên Linux đều là dạng này.
  • Loader-Linker (có đường dẫn tuyệt đối) được ghi bên trong file chạy tức là nếu yêu cầu loader-linker /lib/ld-linux.so.2 mà môi trường chạy không có thì sẽ có lỗi rất lạ kiểu Không tìm thấy file, hoặc định dạng lỗi, etc.
  • Tên của thư viện phụ thuộc (không có đường dẫn) được ghi bên trong file chạy.
  • Kích thước file chạy nhỏ.

Tiếp tục thử với Hello World

gcc -o helloworld helloworld.c

Kiểm tra kích thước file chạy:

$ ls -liah helloworld_dynamic
2910636 -rwxrwxr-x 1 duser duser 7.2K Dec  9 13:37 helloworld_dynamic

7.2K cho HelloWorld

Kiểm tra bằng objdump:

$ objdump -p helloworld_dynamic

helloworld_dynamic:     file format elf32-i386

Program Header:
    PHDR off    0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
         filesz 0x00000120 memsz 0x00000120 flags r-x
  INTERP off    0x00000154 vaddr 0x08048154 paddr 0x08048154 align 2**0
         filesz 0x00000013 memsz 0x00000013 flags r--
    LOAD off    0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
         filesz 0x000005c0 memsz 0x000005c0 flags r-x
    LOAD off    0x00000f08 vaddr 0x08049f08 paddr 0x08049f08 align 2**12
         filesz 0x00000118 memsz 0x0000011c flags rw-
 DYNAMIC off    0x00000f14 vaddr 0x08049f14 paddr 0x08049f14 align 2**2
         filesz 0x000000e8 memsz 0x000000e8 flags rw-
    NOTE off    0x00000168 vaddr 0x08048168 paddr 0x08048168 align 2**2
         filesz 0x00000044 memsz 0x00000044 flags r--
EH_FRAME off    0x000004e4 vaddr 0x080484e4 paddr 0x080484e4 align 2**2
         filesz 0x0000002c memsz 0x0000002c flags r--
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4
         filesz 0x00000000 memsz 0x00000000 flags rw-
   RELRO off    0x00000f08 vaddr 0x08049f08 paddr 0x08049f08 align 2**0
         filesz 0x000000f8 memsz 0x000000f8 flags r--

Dynamic Section:
  NEEDED               libc.so.6
  INIT                 0x080482b0
  FINI                 0x080484b4
  INIT_ARRAY           0x08049f08
  INIT_ARRAYSZ         0x00000004
  FINI_ARRAY           0x08049f0c
  FINI_ARRAYSZ         0x00000004
  GNU_HASH             0x080481ac
  STRTAB               0x0804821c
  SYMTAB               0x080481cc
  STRSZ                0x0000004a
  SYMENT               0x00000010
  DEBUG                0x00000000
  PLTGOT               0x0804a000
  PLTRELSZ             0x00000018
  PLTREL               0x00000011
  JMPREL               0x08048298
  REL                  0x08048290
  RELSZ                0x00000008
  RELENT               0x00000008
  VERNEED              0x08048270
  VERNEEDNUM           0x00000001
  VERSYM               0x08048266

Version References:
  required from libc.so.6:
    0x0d696910 0x00 02 GLIBC_2.0

3. Hiển thị thông về loader-linker

Khi chương trình động bất kì được chạy, một program sẽ được kernel gọi lên để load và link các thư viện động.
Chương trình đó đương nhiên phải tĩnh. Tạm gọi nó là loader-linker.

Thường sẽ nằm ở /lib/ld.ABC.so trong hệ thống.

Loader-linker này sẽ tìm các thư viện được yêu cầu từ Search Path, sau đó link lại để tạo ra chương trình chạy.
Search Path này được cấu thành từ nhiều loại như: từ các path được đặt bên trong /etc/ld.so.conf, từ biến LD_LIBRARY_PATH, etc. Xem thêm tại: ld.so

Một cách để xem các thông tin debug của loader-linker này:
Giả sử với HelloWorld ở trên:

$ LD_DEBUG=help ./helloworld_dynamic
Valid options for the LD_DEBUG environment variable are:

  libs        display library search paths
  reloc       display relocation processing
  files       display progress for input file
  symbols     display symbol table processing
  bindings    display information about symbol binding
  versions    display version dependencies
  scopes      display scope information
  all         all previous options combined
  statistics  display relocation statistics
  unused      determined unused DSOs
  help        display this help message and exit

To direct the debugging output into a file instead of standard output
a filename can be specified using the LD_DEBUG_OUTPUT environment variable.

Trên là Help, ta thử với libs sẽ có kết quả như sau:

$ LD_DEBUG=libs ./helloworld_dynamic
      7066:     find library=libc.so.6 [0]; searching
      7066:      search cache=/etc/ld.so.cache
      7066:       trying file=/lib/i386-linux-gnu/libc.so.6
      7066:
      7066:
      7066:     calling init: /lib/i386-linux-gnu/libc.so.6
      7066:
      7066:
      7066:     initialize program: ./helloworld_dynamic
      7066:
      7066:
      7066:     transferring control: ./helloworld_dynamic
      7066:
Hello, Ajinomoto
      7066:
      7066:     calling fini: ./helloworld_dynamic [0]
      7066:
Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Phùng Văn Tú

13 bài viết.
66 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
22 8
Chúng ta thường nghe nhiều đến Unicode, UTF8, UTF16, hay ShiftJS. Trong bài này chỉ xin làm rõ những khái niệm này để khi gặp phải vấn đề về Chars...
Phùng Văn Tú viết hơn 2 năm trước
22 8
White
18 6
4 thành phần của Embedded Linux Ta biết rằng Linux chạy ở khắp nơi từ siêu máy tính, máy chủ, máy để bàn (máy xách tay), điện thoại (android)...ch...
Phùng Văn Tú viết 9 tháng trước
18 6
White
17 2
Gần đây tôi có dịp đụng vào CMake, nên có tìm hiểu một chút về nó. Hy vọng có ích cho anh em. Nó cung cấp tính năng sinh ra Makefile một cách hiệu...
Phùng Văn Tú viết hơn 2 năm trước
17 2
Bài viết liên quan
White
1 0
sudo du sh
t viết gần 2 năm trước
1 0
Male avatar
32 10
Thời kỳ mới đi làm tôi nghĩ cứ phải gõ thật nhiều cho quen cho nhớ nhưng lâu dần việc đó cho cảm giác thật nhàm chán. Hiện giờ, những gì tôi hay là...
manhdung viết gần 3 năm trước
32 10
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
13 bài viết.
66 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!