static void elf_syms(FILE* out,const char* libfile) { struct stat statbuf; printf("LIBFILE \"%s\"\n", libfile); int fd = open(libfile, O_RDONLY, 0); if (!fd) { printf("Failed to open file \"%s\"\n", libfile); return; } if (fstat(fd, &statbuf) < 0) { printf("Failed to fstat file \"%s\"\n", libfile); return; } { void* data = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); close(fd); if (data == (void*)-1) { printf("Failed to mmap file \"%s\"\n", libfile); return; } //printf("MMap: %08p, %08X\n",data,statbuf.st_size); int dynsym=-1; int dynstr=-1; int strtab=-1; int symtab=-1; if (elf_checkFile(data)>=0) { int scnt=elf_getNumSections(data); for (int si=0;si<scnt;si++) { uint32_t section_type = elf_getSectionType(data, si); uint64_t section_link = elf_getSectionLink(data, si); switch (section_type) { case SHT_DYNSYM: fprintf(stderr, "DYNSYM"); dynsym = si; if (section_link < scnt) dynstr = section_link; break; case SHT_SYMTAB: fprintf(stderr, "SYMTAB"); symtab = si; if (section_link < scnt) strtab = section_link; break; default: break;; } } } else { printf("Invalid elf file\n"); } // Use SHT_SYMTAB if available insteaf of SHT_DYNSYM // (there is more info here): if (symtab >= 0 && strtab >= 0) { dynsym = symtab; dynstr = strtab; } if (dynsym >= 0) { prof_head(out,"libsym",libfile); // printf("Found dymsym %d, and dynstr %d!\n",dynsym,dynstr); elf_symbol* sym=(elf_symbol*)elf_getSection(data,dynsym); elf64_symbol* sym64 = (elf64_symbol*) sym; bool elf32 = ((struct Elf32_Header*)data)->e_ident[EI_CLASS] == ELFCLASS32; size_t symbol_size = elf32 ? sizeof(elf_symbol) : sizeof(elf64_symbol); int symcnt = elf_getSectionSize(data,dynsym) / symbol_size; for (int i=0; i < symcnt; i++) { uint64_t st_value = elf32 ? sym[i].st_value : sym64[i].st_value; uint32_t st_name = elf32 ? sym[i].st_name : sym64[i].st_name; uint16_t st_shndx = elf32 ? sym[i].st_shndx : sym64[i].st_shndx; uint16_t st_type = (elf32 ? sym[i].st_info : sym64[i].st_info) & 0xf; uint64_t st_size = elf32 ? sym[i].st_size : sym64[i].st_size; if (st_type == STT_FUNC && st_value && st_name && st_shndx) { char* name=(char*)elf_getSection(data,dynstr);// sym[i].st_shndx // printf("Symbol %d: %s, %08" PRIx64 ", % " PRIi64 " bytes\n", // i, name + st_name, st_value, st_size); //PRIx64 & friends not in android ndk (yet?) fprintf(out,"%08x %d %s\n", (int)st_value, (int)st_size, name + st_name); } } } else { printf("No dynsym\n"); } munmap(data,statbuf.st_size); } }
void elf_syms(FILE* out,const char* libfile) { struct stat statbuf; printf("LIBFILE \"%s\"\n", libfile); int fd = open(libfile, O_RDONLY, 0); if (!fd) { printf("Failed to open file \"%s\"\n", libfile); return; } if (fstat(fd, &statbuf) < 0) { printf("Failed to fstat file \"%s\"\n", libfile); return; } { void* data = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); close(fd); if (data == (void*)-1) { printf("Failed to mmap file \"%s\"\n", libfile); return; } //printf("MMap: %08p, %08X\n",data,statbuf.st_size); int dynsym=-1; int dynstr=-1; /* Section: 2 -> .dynsym Section: 3 -> .dynstr */ if (elf_checkFile(data)>=0) { int scnt=elf_getNumSections(data); for (int si=0;si<scnt;si++) { if (strcmp(".dynsym",elf_getSectionName(data,si))==0) dynsym=si; if (strcmp(".dynstr",elf_getSectionName(data,si))==0) dynstr=si; } } else { printf("Invalid elf file\n"); } if (dynsym >= 0) { prof_head(out,"libsym",libfile); // printf("Found dymsym %d, and dynstr %d!\n",dynsym,dynstr); elf_symbol* sym=(elf_symbol*)elf_getSection(data,dynsym); int symcnt=elf_getSectionSize(data,dynsym)/sizeof(elf_symbol); for (int i=0;i<symcnt;i++) { if (sym[i].st_value && sym[i].st_name && sym[i].st_shndx) { char* name=(char*)elf_getSection(data,dynstr);// sym[i].st_shndx // printf("Symbol %d: %s, %08X, %d bytes\n",i,name+sym[i].st_name,sym[i].st_value,sym[i].st_size); fprintf(out,"%08X %d %s\n",sym[i].st_value,sym[i].st_size,name+sym[i].st_name); } } } else { printf("No dynsym\n"); } munmap(data,statbuf.st_size); } }