?? out.c
字號:
/* out.c: Output functions for each type of piece. * * Copyright (C) 1999-2001 by Brian Raiter, under the GNU General * Public License. No warranty. See COPYING for details. */#include <stdio.h>#include <string.h>#include "gen.h"#include "elf.h"#include "elftoc.h"#include "addr.h"#include "pieces.h"#include "shdrtab.h"#include "dynamic.h"#include "outbasic.h"#include "outtools.h"#include "out.h"/* The beginning of every successful output. */static char const *cprolog = "#include <stddef.h>\n" "#include \"elf.h\"\n" "\n";/* All the macro definitions available for use in the output. */#include "names.h"/* The output functions that go with each piece type. */static int (*outfunctions[P_COUNT])(pieceinfo const*, void const*);/* Outputs a section header index. */static void outshdrname(int shndx){ char const *str; if ((str = getshdrname(shndx))) out(str); else out(getname(shndx, section));}/* The output function for pieces of type P_UNCLAIMED, P_BYTES, or * P_SECTION. The contents are output either as a literal string, an * array of character values, or an array of hexadecimal byte values. * The last will be used if the contents contain an excess of * non-graphic, non-ASCII characters. Otherwise, one of the first two * representations will be selected based on whether or not the * contents appear to be null-terminated. */static int bytesout(pieceinfo const *piece, void const *ptr){ char const *str = ptr; char const *s; int i, n, fullsize, size; fullsize = piece->size; if (!fullsize) return TRUE; for (size = fullsize ; size > 0 && !str[size - 1] ; --size) ; if (!size) { out("{ 0 }"); return TRUE; } if (fullsize - size < 16) size = fullsize; n = stringsize(str, size); if (n * 2 > size * 3) { beginblock(TRUE); for (i = 0, s = str ; i < size ; ++i, ++s) outf("0x%02X", (unsigned char)*s); if (size < fullsize) outf("/* 0x00 x %d */", fullsize - size); endblock(); } else if (size < fullsize || str[size - 1]) { beginblock(TRUE); for (i = 0, s = str ; i < size ; ++i, ++s) out(cqchar(*s)); if (size < fullsize) outf("/* 0x00 x %d */", fullsize - size); endblock(); } else outstring(str, size - 1); return TRUE;}/* The output functions for pieces of type P_HALVES. The contents will * be output as an array of hexadecimal or integer values, depending * on the range and average of the values. */static int halvesout(pieceinfo const *piece, void const *ptr){ Elf32_Half const *half; char const *fmt = NULL; unsigned int sum; int i, fullsize, size; fullsize = piece->size / sizeof *half; half = ptr; for (size = fullsize ; size > 0 && !half[size - 1] ; --size) ; if (!size) { out("{ 0 }"); return TRUE; } if (fullsize - size < 8) size = fullsize; sum = 0; for (i = 0, half = ptr ; i < size ; ++i, ++half) { if (*half > 0xFF) { fmt = "0x%04X"; break; } sum += *half; } if (!fmt) fmt = sum / size < 16 ? "%u" : "0x%02X"; beginblock(TRUE); for (i = 0, half = ptr ; i < size ; ++i, ++half) outf(fmt, (unsigned int)*half); if (size < fullsize) { char buf[32]; sprintf(buf, "/* %s x %%d */", fmt); outf(buf, 0, fullsize - size); } endblock(); return TRUE;}/* The output functions for pieces of type P_WORDS. The contents will * be output as an array of hexadecimal or integer values, depending * on the range and average of the values. */static int wordsout(pieceinfo const *piece, void const *ptr){ Elf32_Word const *word; char const *fmt = NULL; unsigned int sum; int i, fullsize, size; fullsize = piece->size / sizeof *word; word = ptr; for (size = fullsize ; size > 0 && !word[size - 1] ; --size) ; if (!size) { out("{ 0 }"); return TRUE; } if (fullsize - size < 8) size = fullsize; sum = 0; for (i = 0, word = ptr ; i < size ; ++i, ++word) { if (*word > 0xFFFF) { fmt = "0x%08lX"; break; } sum += *word; } if (!fmt) fmt = sum / size < 256 ? "%lu" : "0x%04lX"; beginblock(TRUE); for (i = 0, word = ptr ; i < size ; ++i, ++word) outf(fmt, (unsigned long)*word); if (size < fullsize) { char buf[32]; sprintf(buf, "/* %s x %%d */", fmt); outf(buf, 0, fullsize - size); } endblock(); return TRUE;}/* The output function for pieces of type P_NOTE. Most of the note * section is mainly free-form in nature, the only constraint being * alignment. It is displayed as an array of values, with line breaks * to indicate the beginning of a note header. */static int noteout(pieceinfo const *piece, void const *ptr){ Elf32_Word const *word = ptr; int i, n; beginblock(TRUE); i = 0; while (i < piece->size / 4) { n = (word[i] + word[i + 1] + 3) / 4; linebreak(); outint(word[i++]); outint(word[i++]); outword(word[i++]); while (n-- && i < piece->size / 4) outf("0x%08lX", (unsigned long)word[i++]); } endblock(); return TRUE;}/* The output function for pieces of type P_HASH. The hash section is * simply displayed as an array of integers, with line breaks * indicating the starts of the bucket and chain arrays. */static int hashout(pieceinfo const *piece, void const *ptr){ Elf32_Word const *word = ptr; Elf32_Shdr const *shdr; int i, n; beginblock(TRUE); n = piece->size / sizeof *word; if (n < 2 || (int)(word[0] + word[1] + 2) != n) { for (i = 0 ; i < n ; ++i, ++word) outint(*word); } else { outint(word[0]); i = piecenum; if (word[1] && piece->shndx && (shdr = getshdr(piece->shndx)) && shdr->sh_link) { for (i = 0 ; i < piecenum ; ++i) if (pieces[i].shndx == (int)(shdr->sh_link)) break; } if (i < piecenum && word[1] * sizeof(Elf32_Sym) == (size_t)pieces[i].size) outf("sizeof %s.%s / sizeof(Elf32_Sym)", varname, pieces[i].name); else outint(word[1]); linebreak(); for (i = 0 ; i < (int)word[0] ; ++i) outint(word[i + 2]); linebreak(); for (i = 0 ; i < (int)word[1] ; ++i) outint(word[i + word[0] + 2]); } endblock(); return TRUE;}/* The output functions for pieces of type P_SYMTAB. The contents are * interpreted as an array of Elf32_Sym structures. */static int symsout(pieceinfo const *piece, void const *ptr){ Elf32_Sym const *sym; unsigned int i; beginblock(TRUE); for (i = 0, sym = ptr ; i < piece->size / sizeof *sym ; ++i, ++sym) { beginblock(FALSE); outint(sym->st_name); out(getaddrstr(sym->st_value, NULL)); outint(sym->st_size); outf("ELF32_ST_INFO(%s, %s)", getname(ELF32_ST_BIND(sym->st_info), symbind), getname(ELF32_ST_TYPE(sym->st_info), symtype)); outint(sym->st_other); outshdrname(sym->st_shndx); endblock(); } endblock(); return TRUE;}/* The output function for pieces of type P_DYNAMIC. The contents are * displayed as an array of Elf32_Dyn structures. A first pass is used * to make connections between entries that have related information. */static int dynout(pieceinfo const *piece, void const *ptr){ char addrs[N_DT_COUNT][128]; int shndx[N_DT_COUNT]; Elf32_Dyn const *dyn; unsigned int i; int n, done; memset(addrs, 0, sizeof addrs); memset(shndx, 0, sizeof shndx); for (i = 0, dyn = ptr ; i < piece->size / sizeof *dyn ; ++i, ++dyn) { switch (dyn->d_tag) { case DT_STRTAB: strcpy(addrs[N_DT_STRTAB], getaddrstr(dyn->d_un.d_ptr, &shndx[N_DT_STRSZ])); break; case DT_REL: strcpy(addrs[N_DT_REL], getaddrstr(dyn->d_un.d_ptr, &shndx[N_DT_RELSZ])); break; case DT_RELA: strcpy(addrs[N_DT_RELA], getaddrstr(dyn->d_un.d_ptr, &shndx[N_DT_RELASZ])); break; case DT_JMPREL: strcpy(addrs[N_DT_JMPREL], getaddrstr(dyn->d_un.d_ptr, &shndx[N_DT_PLTRELSZ])); break; case DT_SYMINFO: strcpy(addrs[N_DT_SYMINFO], getaddrstr(dyn->d_un.d_ptr, &shndx[N_DT_SYMINSZ])); break; case DT_INIT_ARRAY: strcpy(addrs[N_DT_INIT_ARRAY], getaddrstr(dyn->d_un.d_ptr, &shndx[N_DT_INIT_ARRAYSZ])); break; case DT_FINI_ARRAY: strcpy(addrs[N_DT_FINI_ARRAY], getaddrstr(dyn->d_un.d_ptr, &shndx[N_DT_FINI_ARRAYSZ])); break; case DT_PREINIT_ARRAY: strcpy(addrs[N_DT_PREINIT_ARRAY], getaddrstr(dyn->d_un.d_ptr, &shndx[N_DT_PREINIT_ARRAYSZ])); break; } } beginblock(TRUE); for (i = 0, dyn = ptr ; i < piece->size / sizeof *dyn ; ++i, ++dyn) { done = FALSE; beginblock(FALSE); out(getname(dyn->d_tag, dyntag)); n = getdyntagid(dyn->d_tag); if (n <= 0) { outf("{ %ld }", dyn->d_un.d_val); done = TRUE; } else if (*addrs[n]) { outf("{ %s }", addrs[n]); done = TRUE; } else if (shndx[n]) { outf("{ %s }", getsizestr(dyn->d_un.d_val, shndx[n])); done = TRUE; } else { switch (n) { case N_DT_FLAGS: outf("{ %s }", getflags(dyn->d_un.d_val, dynflag)); done = TRUE; break; case N_DT_FLAGS_1: outf("{ %s }", getflags(dyn->d_un.d_val, dynflag1)); done = TRUE; break; case N_DT_FEATURE_1: outf("{ %s }", getflags(dyn->d_un.d_val, dynftrf1)); done = TRUE; break; case N_DT_POSFLAG_1: outf("{ %s }", getflags(dyn->d_un.d_val, dynposf1)); done = TRUE; break; case N_DT_RELAENT: if (dyn->d_un.d_val == sizeof(Elf32_Rela)) { out("{ sizeof(Elf32_Rela) }"); done = TRUE; } break; case N_DT_RELENT: if (dyn->d_un.d_val == sizeof(Elf32_Rel)) { out("{ sizeof(Elf32_Rel) }"); done = TRUE; } break; case N_DT_SYMENT: if (dyn->d_un.d_val == sizeof(Elf32_Sym)) { out("{ sizeof(Elf32_Sym) }"); done = TRUE; } break; case N_DT_SYMINENT:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -