📄 elf.c
字号:
{ newsect->lma += phdr->p_paddr - phdr->p_vaddr; break; } } } } hdr->bfd_section = newsect; elf_section_data (newsect)->this_hdr = *hdr; return true;}/*INTERNAL_FUNCTION bfd_elf_find_sectionSYNOPSIS struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name);DESCRIPTION Helper functions for GDB to locate the string tables. Since BFD hides string tables from callers, GDB needs to use an internal hook to find them. Sun's .stabstr, in particular, isn't even pointed to by the .stab section, so ordinary mechanisms wouldn't work to find it, even if we had some.*/struct elf_internal_shdr *bfd_elf_find_section (abfd, name) bfd *abfd; char *name;{ Elf_Internal_Shdr **i_shdrp; char *shstrtab; unsigned int max; unsigned int i; i_shdrp = elf_elfsections (abfd); if (i_shdrp != NULL) { shstrtab = bfd_elf_get_str_section (abfd, elf_elfheader (abfd)->e_shstrndx); if (shstrtab != NULL) { max = elf_elfheader (abfd)->e_shnum; for (i = 1; i < max; i++) if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name)) return i_shdrp[i]; } } return 0;}const char *const bfd_elf_section_type_names[] = { "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB", "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE", "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",};/* ELF relocs are against symbols. If we are producing relocateable output, and the reloc is against an external symbol, and nothing has given us any additional addend, the resulting reloc will also be against the same symbol. In such a case, we don't want to change anything about the way the reloc is handled, since it will all be done at final link time. Rather than put special case code into bfd_perform_relocation, all the reloc types use this howto function. It just short circuits the reloc if producing relocateable output against an external symbol. */bfd_reloc_status_typebfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) bfd *abfd ATTRIBUTE_UNUSED; arelent *reloc_entry; asymbol *symbol; PTR data ATTRIBUTE_UNUSED; asection *input_section; bfd *output_bfd; char **error_message ATTRIBUTE_UNUSED;{ if (output_bfd != (bfd *) NULL && (symbol->flags & BSF_SECTION_SYM) == 0 && (! reloc_entry->howto->partial_inplace || reloc_entry->addend == 0)) { reloc_entry->address += input_section->output_offset; return bfd_reloc_ok; } return bfd_reloc_continue;}/* Print out the program headers. */boolean_bfd_elf_print_private_bfd_data (abfd, farg) bfd *abfd; PTR farg;{ FILE *f = (FILE *) farg; Elf_Internal_Phdr *p; asection *s; bfd_byte *dynbuf = NULL; p = elf_tdata (abfd)->phdr; if (p != NULL) { unsigned int i, c; fprintf (f, _("\nProgram Header:\n")); c = elf_elfheader (abfd)->e_phnum; for (i = 0; i < c; i++, p++) { const char *s; char buf[20]; switch (p->p_type) { case PT_NULL: s = "NULL"; break; case PT_LOAD: s = "LOAD"; break; case PT_DYNAMIC: s = "DYNAMIC"; break; case PT_INTERP: s = "INTERP"; break; case PT_NOTE: s = "NOTE"; break; case PT_SHLIB: s = "SHLIB"; break; case PT_PHDR: s = "PHDR"; break; default: sprintf (buf, "0x%lx", p->p_type); s = buf; break; } fprintf (f, "%8s off 0x", s); fprintf_vma (f, p->p_offset); fprintf (f, " vaddr 0x"); fprintf_vma (f, p->p_vaddr); fprintf (f, " paddr 0x"); fprintf_vma (f, p->p_paddr); fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align)); fprintf (f, " filesz 0x"); fprintf_vma (f, p->p_filesz); fprintf (f, " memsz 0x"); fprintf_vma (f, p->p_memsz); fprintf (f, " flags %c%c%c", (p->p_flags & PF_R) != 0 ? 'r' : '-', (p->p_flags & PF_W) != 0 ? 'w' : '-', (p->p_flags & PF_X) != 0 ? 'x' : '-'); if ((p->p_flags &~ (PF_R | PF_W | PF_X)) != 0) fprintf (f, " %lx", p->p_flags &~ (PF_R | PF_W | PF_X)); fprintf (f, "\n"); } } s = bfd_get_section_by_name (abfd, ".dynamic"); if (s != NULL) { int elfsec; unsigned long link; bfd_byte *extdyn, *extdynend; size_t extdynsize; void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); fprintf (f, _("\nDynamic Section:\n")); dynbuf = (bfd_byte *) bfd_malloc (s->_raw_size); if (dynbuf == NULL) goto error_return; if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, (file_ptr) 0, s->_raw_size)) goto error_return; elfsec = _bfd_elf_section_from_bfd_section (abfd, s); if (elfsec == -1) goto error_return; link = elf_elfsections (abfd)[elfsec]->sh_link; extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn; swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in; extdyn = dynbuf; extdynend = extdyn + s->_raw_size; for (; extdyn < extdynend; extdyn += extdynsize) { Elf_Internal_Dyn dyn; const char *name; char ab[20]; boolean stringp; (*swap_dyn_in) (abfd, (PTR) extdyn, &dyn); if (dyn.d_tag == DT_NULL) break; stringp = false; switch (dyn.d_tag) { default: sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag); name = ab; break; case DT_NEEDED: name = "NEEDED"; stringp = true; break; case DT_PLTRELSZ: name = "PLTRELSZ"; break; case DT_PLTGOT: name = "PLTGOT"; break; case DT_HASH: name = "HASH"; break; case DT_STRTAB: name = "STRTAB"; break; case DT_SYMTAB: name = "SYMTAB"; break; case DT_RELA: name = "RELA"; break; case DT_RELASZ: name = "RELASZ"; break; case DT_RELAENT: name = "RELAENT"; break; case DT_STRSZ: name = "STRSZ"; break; case DT_SYMENT: name = "SYMENT"; break; case DT_INIT: name = "INIT"; break; case DT_FINI: name = "FINI"; break; case DT_SONAME: name = "SONAME"; stringp = true; break; case DT_RPATH: name = "RPATH"; stringp = true; break; case DT_SYMBOLIC: name = "SYMBOLIC"; break; case DT_REL: name = "REL"; break; case DT_RELSZ: name = "RELSZ"; break; case DT_RELENT: name = "RELENT"; break; case DT_PLTREL: name = "PLTREL"; break; case DT_DEBUG: name = "DEBUG"; break; case DT_TEXTREL: name = "TEXTREL"; break; case DT_JMPREL: name = "JMPREL"; break; case DT_BIND_NOW: name = "BIND_NOW"; break; case DT_INIT_ARRAY: name = "INIT_ARRAY"; break; case DT_FINI_ARRAY: name = "FINI_ARRAY"; break; case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break; case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break; case DT_RUNPATH: name = "RUNPATH"; stringp = true; break; case DT_FLAGS: name = "FLAGS"; break; case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break; case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break; case DT_CHECKSUM: name = "CHECKSUM"; break; case DT_PLTPADSZ: name = "PLTPADSZ"; break; case DT_MOVEENT: name = "MOVEENT"; break; case DT_MOVESZ: name = "MOVESZ"; break; case DT_FEATURE: name = "FEATURE"; break; case DT_POSFLAG_1: name = "POSFLAG_1"; break; case DT_SYMINSZ: name = "SYMINSZ"; break; case DT_SYMINENT: name = "SYMINENT"; break; case DT_CONFIG: name = "CONFIG"; stringp = true; break; case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = true; break; case DT_AUDIT: name = "AUDIT"; stringp = true; break; case DT_PLTPAD: name = "PLTPAD"; break; case DT_MOVETAB: name = "MOVETAB"; break; case DT_SYMINFO: name = "SYMINFO"; break; case DT_RELACOUNT: name = "RELACOUNT"; break; case DT_RELCOUNT: name = "RELCOUNT"; break; case DT_FLAGS_1: name = "FLAGS_1"; break; case DT_VERSYM: name = "VERSYM"; break; case DT_VERDEF: name = "VERDEF"; break; case DT_VERDEFNUM: name = "VERDEFNUM"; break; case DT_VERNEED: name = "VERNEED"; break; case DT_VERNEEDNUM: name = "VERNEEDNUM"; break; case DT_AUXILIARY: name = "AUXILIARY"; stringp = true; break; case DT_USED: name = "USED"; break; case DT_FILTER: name = "FILTER"; stringp = true; break; } fprintf (f, " %-11s ", name); if (! stringp) fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val); else { const char *string; string = bfd_elf_string_from_elf_section (abfd, link, dyn.d_un.d_val); if (string == NULL) goto error_return; fprintf (f, "%s", string); } fprintf (f, "\n"); } free (dynbuf); dynbuf = NULL; } if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL) || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL)) { if (! _bfd_elf_slurp_version_tables (abfd)) return false; } if (elf_dynverdef (abfd) != 0) { Elf_Internal_Verdef *t; fprintf (f, _("\nVersion definitions:\n")); for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef) { fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx, t->vd_flags, t->vd_hash, t->vd_nodename); if (t->vd_auxptr->vda_nextptr != NULL) { Elf_Internal_Verdaux *a; fprintf (f, "\t"); for (a = t->vd_auxptr->vda_nextptr; a != NULL; a = a->vda_nextptr) fprintf (f, "%s ", a->vda_nodename); fprintf (f, "\n"); } } } if (elf_dynverref (abfd) != 0) { Elf_Internal_Verneed *t; fprintf (f, _("\nVersion References:\n")); for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref) { Elf_Internal_Vernaux *a; fprintf (f, _(" required from %s:\n"), t->vn_filename); for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) fprintf (f, " 0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash, a->vna_flags, a->vna_other, a->vna_nodename); } } return true; error_return: if (dynbuf != NULL) free (dynbuf); return false;}/* Display ELF-specific fields of a symbol. */voidbfd_elf_print_symbol (abfd, filep, symbol, how) bfd *abfd; PTR filep; asymbol *symbol; bfd_print_symbol_type how;{ FILE *file = (FILE *) filep; switch (how) { case bfd_print_symbol_name: fprintf (file, "%s", symbol->name); break; case bfd_print_symbol_more: fprintf (file, "elf "); fprintf_vma (file, symbol->value); fprintf (file, " %lx", (long) symbol->flags); break; case bfd_print_symbol_all: { const char *section_name; const char *name = NULL; struct elf_backend_data *bed; unsigned char st_other; section_name = symbol->section ? symbol->section->name : "(*none*)"; bed = get_elf_backend_data (abfd); if (bed->elf_backend_print_symbol_all) name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol); if (name == NULL) { name = symbol->name; bfd_print_symbol_vandf ((PTR) file, symbol); } fprintf (file, " %s\t", section_name); /* Print the "other" value for a symbol. For common symbols, we've already printed the size; now print the alignment. For other symbols, we have no specified alignment, and we've printed the address; now print the size. */ fprintf_vma (file, (bfd_is_com_section (symbol->section) ? ((elf_symbol_type *) symbol)->internal_elf_sym.st_value : ((elf_symbol_type *) symbol)->internal_elf_sym.st_size)); /* If we have version information, print it. */ if (elf_tdata (abfd)->dynversym_section != 0 && (elf_tdata (abfd)->dynverdef_section != 0 || elf_tdata (abfd)->dynverref_section != 0)) { unsigned int vernum; const char *version_string; vernum = ((elf_symbol_type *) symbol)->version & VERSYM_VERSION; if (vernum == 0) version_string = ""; else if (vernum == 1) version_string = "Base"; else if (vernum <= elf_tdata (abfd)->cverdefs) version_string = elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; else { Elf_Internal_Verneed *t; version_string = ""; for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref) { Elf_Internal_Vernaux *a; for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) { if (a->vna_other == vernum) { version_string = a->vna_nodename; break; } } } } if ((((elf_symbol_type *) symbol)->version & VERSYM_HIDDEN) == 0) fprintf (file, " %-11s", version_string); else { int i; fprintf (file, " (%s)", version_string); for (i = 10 - strlen (version_string); i > 0; --i) putc (' ', file); } } /* If the st_other field is not zero, print it. */ st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other; switch (st_other) { case 0: break; case STV_INTERNAL: fprintf (file, " .internal"); break; case STV_HIDDEN: fprintf (file, " .hidden"); break; case STV_PROTECTED: fprintf (file, " .protected"); break; default: /* Some other non-defined flags are also present, so print everything hex. */ fprintf (file, " 0x%02x", (unsigned int) st_other); } fprintf (file, " %s", name); } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -