Bug 1080291 (part 1) - Remove foldelf.cpp. r=glandium.
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 08 Oct 2014 18:56:42 -0700
changeset 234580 0913bc62172b7b6c6ebf1fb46cae79ef969195c6
parent 234579 facebebfea4d76e4b03bdb5ab7ce2c27ec38070e
child 234581 90c895fa9a9da2d9a7afceef4c6e5fd70ed0318d
push id611
push userraliiev@mozilla.com
push dateMon, 05 Jan 2015 23:23:16 +0000
treeherdermozilla-release@345cd3b9c445 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1080291
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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 *~
-