Bug 1080291 (part 1) - Remove foldelf.cpp. r=glandium.
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 08 Oct 2014 18:56:42 -0700
changeset 210045 0913bc62172b7b6c6ebf1fb46cae79ef969195c6
parent 210044 facebebfea4d76e4b03bdb5ab7ce2c27ec38070e
child 210046 90c895fa9a9da2d9a7afceef4c6e5fd70ed0318d
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersglandium
bugs1080291
milestone35.0a1
Bug 1080291 (part 1) - Remove foldelf.cpp. r=glandium.
tools/footprint/foldelf.cpp
tools/footprint/foldelf.mk
deleted file mode 100644
--- a/tools/footprint/foldelf.cpp
+++ /dev/null
@@ -1,319 +0,0 @@
-/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* This program reads an ELF file and computes information about
- * redundancies. 
- */
-
-#include <algorithm>
-#include <fstream>
-#include <string>
-#include <vector>
-#include <map>
-#include <elf.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-//----------------------------------------------------------------------
-
-char* opt_type    = "func";
-char* opt_section = ".text";
-
-//----------------------------------------------------------------------
-
-static void
-hexdump(ostream& out, const char* bytes, size_t count)
-{
-    hex(out);
-
-    size_t off = 0;
-    while (off < count) {
-        out.form("%08lx: ", off);
-
-        const char* p = bytes + off;
-
-        int j = 0;
-        while (j < 16) {
-            out.form("%02x", p[j++] & 0xff);
-            if (j + off >= count)
-                break;
-
-            out.form("%02x ", p[j++] & 0xff);
-            if (j + off >= count)
-                break;
-        }
-
-        // Pad
-        for (; j < 16; ++j)
-            out << ((j%2) ? "   " : "  ");
-
-        for (j = 0; j < 16; ++j) {
-            if (j + off < count)
-                out.put(isprint(p[j]) ? p[j] : '.');
-        }
-
-        out << endl;
-        off += 16;
-    }
-}
-
-//----------------------------------------------------------------------
-
-int
-verify_elf_header(const Elf32_Ehdr* hdr)
-{
-    if (hdr->e_ident[EI_MAG0] != ELFMAG0
-        || hdr->e_ident[EI_MAG1] != ELFMAG1
-        || hdr->e_ident[EI_MAG2] != ELFMAG2
-        || hdr->e_ident[EI_MAG3] != ELFMAG3) {
-        cerr << "not an elf file" << endl;
-        return -1;
-    }
-
-    if (hdr->e_ident[EI_CLASS] != ELFCLASS32) {
-        cerr << "not a 32-bit elf file" << endl;
-        return -1;
-    }
-
-    if (hdr->e_ident[EI_DATA] != ELFDATA2LSB) {
-        cerr << "not a little endian elf file" << endl;
-        return -1;
-    }
-
-    if (hdr->e_ident[EI_VERSION] != EV_CURRENT) {
-        cerr << "incompatible version" << endl;
-        return -1;
-    }
-
-    return 0;
-}
-
-//----------------------------------------------------------------------
-
-class elf_symbol : public Elf32_Sym
-{
-public:
-    elf_symbol(const Elf32_Sym& sym)
-    { ::memcpy(static_cast<Elf32_Sym*>(this), &sym, sizeof(Elf32_Sym)); }
-
-    friend bool operator==(const elf_symbol& lhs, const elf_symbol& rhs) {
-        return 0 == ::memcmp(static_cast<const Elf32_Sym*>(&lhs),
-                             static_cast<const Elf32_Sym*>(&rhs),
-                             sizeof(Elf32_Sym)); }
-};
-
-//----------------------------------------------------------------------
-
-static const char*
-st_bind(unsigned char info)
-{
-    switch (ELF32_ST_BIND(info)) {
-    case STB_LOCAL:      return "local";
-    case STB_GLOBAL:     return "global";
-    case STB_WEAK:       return "weak";
-    default:             return "unknown";
-    }
-}
-
-static const char*
-st_type(unsigned char info)
-{
-    switch (ELF32_ST_TYPE(info)) {
-    case STT_NOTYPE:     return "none";
-    case STT_OBJECT:     return "object";
-    case STT_FUNC:       return "func";
-    case STT_SECTION:    return "section";
-    case STT_FILE:       return "file";
-    default:             return "unknown";
-    }
-}
-
-static unsigned char
-st_type(const char* type)
-{
-    if (strcmp(type, "none") == 0) {
-        return STT_NOTYPE;
-    }
-    else if (strcmp(type, "object") == 0) {
-        return STT_OBJECT;
-    }
-    else if (strcmp(type, "func") == 0) {
-        return STT_FUNC;
-    }
-    else {
-        return 0;
-    }
-}
-
-//----------------------------------------------------------------------
-
-typedef vector<elf_symbol> elf_symbol_table;
-typedef map< basic_string<char>, elf_symbol_table > elf_text_map;
-
-void
-process_mapping(char* mapping, size_t size)
-{
-    const Elf32_Ehdr* ehdr = reinterpret_cast<Elf32_Ehdr*>(mapping);
-    if (verify_elf_header(ehdr) < 0)
-        return;
-
-    // find the section headers
-    const Elf32_Shdr* shdrs = reinterpret_cast<Elf32_Shdr*>(mapping + ehdr->e_shoff);
-
-    // find the section header string table, .shstrtab
-    const Elf32_Shdr* shstrtabsh = shdrs + ehdr->e_shstrndx;
-    const char* shstrtab = mapping + shstrtabsh->sh_offset;
-
-    // find the sections we care about
-    const Elf32_Shdr *symtabsh, *strtabsh, *textsh;
-    int textndx;
-
-    for (int i = 0; i < ehdr->e_shnum; ++i) {
-        basic_string<char> name(shstrtab + shdrs[i].sh_name);
-        if (name == opt_section) {
-            textsh = shdrs + i;
-            textndx = i;
-        }
-        else if (name == ".symtab") {
-            symtabsh = shdrs + i;
-        }
-        else if (name == ".strtab") {
-            strtabsh = shdrs + i;
-        }
-    }
-
-    // find the .strtab
-    char* strtab = mapping + strtabsh->sh_offset;
-
-    // find the .text
-    char* text = mapping + textsh->sh_offset;
-    int textaddr = textsh->sh_addr;
-
-    // find the symbol table
-    int nentries = symtabsh->sh_size / sizeof(Elf32_Sym);
-    Elf32_Sym* symtab = reinterpret_cast<Elf32_Sym*>(mapping + symtabsh->sh_offset);
-
-    // look for symbols in the .text section
-    elf_text_map textmap;
-
-    for (int i = 0; i < nentries; ++i) {
-        const Elf32_Sym* sym = symtab + i;
-        if (sym->st_shndx == textndx &&
-            ELF32_ST_TYPE(sym->st_info) == st_type(opt_type) &&
-            sym->st_size) {
-            basic_string<char> functext(text + sym->st_value - textaddr, sym->st_size);
-
-            elf_symbol_table& syms = textmap[functext];
-            if (syms.end() == find(syms.begin(), syms.end(), elf_symbol(*sym)))
-                syms.insert(syms.end(), *sym);
-        }
-    }
-
-    int uniquebytes = 0, totalbytes = 0;
-    int uniquecount = 0, totalcount = 0;
-
-    for (elf_text_map::const_iterator entry = textmap.begin();
-         entry != textmap.end();
-         ++entry) {
-        const elf_symbol_table& syms = entry->second;
-
-        if (syms.size() <= 1)
-            continue;
-
-        int sz = syms.begin()->st_size;
-        uniquebytes += sz;
-        totalbytes += sz * syms.size();
-        uniquecount += 1;
-        totalcount += syms.size();
-
-        for (elf_symbol_table::const_iterator sym = syms.begin(); sym != syms.end(); ++sym)
-            cout << strtab + sym->st_name << endl;
-
-        dec(cout);
-        cout << syms.size() << " copies of " << sz << " bytes";
-        cout << " (" << ((syms.size() - 1) * sz) << " redundant bytes)" << endl;
-
-        hexdump(cout, entry->first.data(), entry->first.size());
-        cout << endl;
-    }
-
-    dec(cout);
-    cout << "bytes unique=" << uniquebytes << ", total=" << totalbytes << endl;
-    cout << "entries unique=" << uniquecount << ", total=" << totalcount << endl;
-}
-
-void
-process_file(const char* name)
-{
-    int fd = open(name, O_RDWR);
-    if (fd >= 0) {
-        struct stat statbuf;
-        if (fstat(fd, &statbuf) >= 0) {
-            size_t size = statbuf.st_size;
-
-            void* mapping = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
-            if (mapping != MAP_FAILED) {
-                process_mapping(static_cast<char*>(mapping), size);
-                munmap(mapping, size);
-            }
-        }
-        close(fd);
-    }
-}
-
-static void
-usage()
-{
-    cerr << "foldelf [--section=<section>] [--type=<type>] [file ...]\n\
-   --section, -s  the section of the ELF file to scan; defaults\n\
-                  to ``.text''. Valid values include any section\n\
-                  of the ELF file.\n\
-   --type, -t     the type of object to examine in the section;\n\
-                  defaults to ``func''. Valid values include\n\
-                  ``none'', ``func'', or ``object''.\n";
-
-}
-
-static struct option opts[] = {
-    { "type",    required_argument, 0, 't' },
-    { "section", required_argument, 0, 's' },
-    { "help",    no_argument,       0, '?' },
-    { 0,         0, 0, 0 }
-};
-    
-int
-main(int argc, char* argv[])
-{
-    while (1) {
-        int option_index = 0;
-        int c = getopt_long(argc, argv, "t:s:", opts, &option_index);
-
-        if (c < 0) break;
-
-        switch (c) {
-        case 't':
-            opt_type = optarg;
-            break;
-
-        case 's':
-            opt_section = optarg;
-            break;
-
-        case '?':
-            usage();
-            break;
-        }
-    }
-
-    for (int i = optind; i < argc; ++i)
-        process_file(argv[i]);
-
-    return 0;
-}
deleted file mode 100644
--- a/tools/footprint/foldelf.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-foldelf: foldelf.cpp
-	$(CXX) -O -o foldelf foldelf.cpp
-
-clean:
-	rm -f *.o test *.test foldelf *~
-