2013-03-05 31 views
7

Tôi đang học định dạng ELF ngay bây giờ. Tôi phải mã một fonction nm đơn giản (không có các tùy chọn). Tôi đã in trên đầu ra giá trị của biểu tượng và tên của biểu tượng.Cách hiển thị loại ký hiệu như lệnh nm?

Dưới đây là đầu ra nm:

value    type name 
0000000000600e30 D  __DTOR_END__ 

tôi có cùng một, nhưng nếu không có sự 'type'. Tôi đang sử dụng cấu trúc ELF64_Sym, như sau:

typedef struct { 
    Elf64_Word  st_name; 
    unsigned char st_info; 
    unsigned char st_other; 
    Elf64_Half  st_shndx; 
    Elf64_Addr  st_value; 
    Elf64_Xword  st_size; 
} Elf64_Sym; 

Tôi biết rằng tôi phải sử dụng biến st_info và macro này:

#define ELF64_ST_TYPE(info)   ((info) & 0xf) 

để có được kiểu của biểu tượng. Nhưng, loại biểu tượng có thể là một vĩ mô như sau:

NAME   VALUE 
STT_NOTYPE  0 
STT_OBJECT  1 
STT_FUNC  2 
STT_SECTION  3 
STT_FILE  4 
STT_LOPROC  13 
STT_HIOPROC  15 

Và tôi muốn biết là làm thế nào tôi có thể nhận được từ các macro này để chữ in bằng nm, ví dụ:

U, u, A, a, T, t, R, r, W, w 
+0

Tuyên bố 'chuyển đổi', có lẽ? –

+0

Đưa người đàn ông này vào tài khoản man nm (1): http://linux.die.net/man/1/nm – EGOrecords

Trả lời

6

Ok Tôi đã thực hiện một số nghiên cứu và đây là chức năng của tôi để có được ký tự chính xác tùy thuộc vào biểu tượng. Vui lòng thêm/chỉnh sửa một số ký tự.

char   print_type(Elf64_Sym sym, Elf64_Shdr *shdr) 
{ 
    char c; 

    if (ELF64_ST_BIND(sym.st_info) == STB_GNU_UNIQUE) 
    c = 'u'; 
    else if (ELF64_ST_BIND(sym.st_info) == STB_WEAK) 
    { 
     c = 'W'; 
     if (sym.st_shndx == SHN_UNDEF) 
     c = 'w'; 
    } 
    else if (ELF64_ST_BIND(sym.st_info) == STB_WEAK && ELF64_ST_TYPE(sym.st_info) == STT_OBJECT) 
    { 
     c = 'V'; 
     if (sym.st_shndx == SHN_UNDEF) 
     c = 'v'; 
    } 
    else if (sym.st_shndx == SHN_UNDEF) 
    c = 'U'; 
    else if (sym.st_shndx == SHN_ABS) 
    c = 'A'; 
    else if (sym.st_shndx == SHN_COMMON) 
    c = 'C'; 
    else if (shdr[sym.st_shndx].sh_type == SHT_NOBITS 
     && shdr[sym.st_shndx].sh_flags == (SHF_ALLOC | SHF_WRITE)) 
    c = 'B'; 
    else if (shdr[sym.st_shndx].sh_type == SHT_PROGBITS 
     && shdr[sym.st_shndx].sh_flags == SHF_ALLOC) 
    c = 'R'; 
    else if (shdr[sym.st_shndx].sh_type == SHT_PROGBITS 
     && shdr[sym.st_shndx].sh_flags == (SHF_ALLOC | SHF_WRITE)) 
    c = 'D'; 
    else if (shdr[sym.st_shndx].sh_type == SHT_PROGBITS 
     && shdr[sym.st_shndx].sh_flags == (SHF_ALLOC | SHF_EXECINSTR)) 
    c = 'T'; 
    else if (shdr[sym.st_shndx].sh_type == SHT_DYNAMIC) 
    c = 'D'; 
    else 
    c = '?'; 
    if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL && c != '?') 
    c += 32; 
    return c; 
} 

Tôi đang thiếu s, n, p và i. Tôi khá chắc chắn rằng 'R' không tốt. Tôi sẽ chỉnh sửa nó khi tôi tìm thấy nó.

3

Các ELF64_ST_TYPE không không phải ánh xạ trực tiếp vào các chữ cái mà nm in.

Để thực hiện ánh xạ, bạn cần chú ý đến cả hai mục ELF64_ST_BIND, phần mà biểu tượng đề cập đến. Ví dụ:

bool weak = (ELF64_ST_BIND(sym) == STB_WEAK); 
bool unresolved = (sym->st_shndx == SHN_UNDEF); 

if (unresolved) { 
    printf(" %c ", weak ? 'w' : 'U'); 
} 

cho t vs T, bạn sẽ muốn xem xét ELF64_ST_BIND(sym) == STB_LOCAL hoặc ELF64_ST_BIND(sym) == STB_GLOBAL, bạn sẽ muốn tìm hiểu xem phần tham chiếu bởi st_shndx là một "văn bản" một (có SHF_EXECINSTR trong cờ của nó).

P.S. Theo như tôi biết, không có u. Nếu trang nm của bạn có danh sách u, tôi tò mò muốn biết loại biểu tượng đó là gì.

+0

Cảm ơn bạn, đây là những gì tôi cần làm. Tôi đang sử dụng macro ELF64_ST_BIND để tìm hiểu xem biểu tượng là cục bộ toàn cục (MIN hoặc MAJ) và sau đó với loại phần và cờ phần tôi nhận được một số ký tự như, B, D, T. Nhưng vẫn còn nhiều ký tự hơn để tìm ! Tôi sẽ tiếp tục và đăng tất cả các kết quả. Đây là con người nm với tất cả các nhân vật: http://linux.die.net/man/1/nm –

+0

@ JérémieCharrier Ah, tôi quên: 'u' là' ELF64_ST_BIND (sym) == STB_GNU_UNIQUE'. –

Các vấn đề liên quan