How to display character type, for example, nm command?

I am studying the ELF format right now. I have to encode a simple nm diagram (without options). I already print the output of the symbol value and the name of the symbol.

Here's the nm output:

value type name 0000000000600e30 D __DTOR_END__ 

I have the same one, but without the "type". I use the ELF64_Sym structure as shown below:

 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; 

I know that I need to use the st_info variable and this macro:

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

to get the type of character. But the character type can be a macro as follows:

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

And I would like to know how I can get letters printed by nm from these macros, for example:

  U, u, A, a, T, t, R, r, W, w 
+7
source share
2 answers

Ok, I did some research, and here is my function to get the correct character based on the character. Feel free to add / edit some characters.

 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; } 

I miss s, n, p and i. I am pretty sure that the "R" is not very good. I will edit it when I find it.

+6
source

ELF64_ST_TYPE does not map directly to the letters nm prints.

To perform the mapping, you need to pay attention to both the ELF64_ST_BIND and the section referenced by the symbol. For example:

 bool weak = (ELF64_ST_BIND(sym) == STB_WEAK); bool unresolved = (sym->st_shndx == SHN_UNDEF); if (unresolved) { printf(" %c ", weak ? 'w' : 'U'); } 

For t vs t you need to look at ELF64_ST_BIND(sym) == STB_LOCAL or ELF64_ST_BIND(sym) == STB_GLOBAL , and you will want to find out if the section referenced by st_shndx is "text" (has SHF_EXECINSTR in its flags).

PS As far as I know, no u . If your nm page contains a list of u , I'm curious to know what type of character is.

+3
source

All Articles