summaryrefslogtreecommitdiff
path: root/soltools/adjustvisibility/adjustvisibility.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'soltools/adjustvisibility/adjustvisibility.cxx')
-rw-r--r--soltools/adjustvisibility/adjustvisibility.cxx315
1 files changed, 0 insertions, 315 deletions
diff --git a/soltools/adjustvisibility/adjustvisibility.cxx b/soltools/adjustvisibility/adjustvisibility.cxx
deleted file mode 100644
index 3e204cb55..000000000
--- a/soltools/adjustvisibility/adjustvisibility.cxx
+++ /dev/null
@@ -1,315 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_soltools.hxx"
-
-/*
- * adjustvisibilty -- a tool to adjust the visibility of the so called
- * 'fix and continue' globalized symbols generated by
- * the Sun Studio 8 compiler from 'DEFAULT' to 'HIDDEN'
- *
- * References: "Linker and Libraries Guide", Solaris 9 documentation
- * "Stabs Interface", SunStudio 8 documentation
- */
-
-#include <string>
-#include <iostream>
-#include <exception>
-#include <stdexcept>
-#include <cerrno>
-#include <fcntl.h>
-#include <unistd.h>
-#include <libelf.h>
-#include <gelf.h>
-#include <utime.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <limits>
-#include <stdio.h>
-
-// Note: There is no GELF_ST_VISIBILITY macro in gelf.h, we roll our own.
-#define GELF_ST_VISIBILITY(o) ((o)&0x3) // See "Linker and Libraries Guide".
-
-// See "Linker and Libraries Guide", ELF object format description.
-static const char* SymbolType[STT_NUM] = {
- "NOTYPE",
- "OBJECT",
- "FUNC ",
- "SECT ",
- "FILE ",
- "COMM ",
- "TLS "
-};
-
-static const char* SymbolBinding[STB_NUM] = {
- "LOCAL ",
- "GLOBAL",
- "WEAK "
-};
-
-static const char* SymbolVisibility[4] = { // Note: There is no STV_NUM macro
- "DEFAULT ",
- "INTERNAL ",
- "HIDDEN ",
- "PROTECTED"
-};
-
-class ElfError : public std::exception
-{
- public:
- ElfError(const std::string& rFile, const std::string& rMessage);
- ~ElfError() throw() {};
- virtual const char* what() const throw() { return m_sMessage.c_str(); }
-
- private:
- std::string m_sMessage;
-};
-
-ElfError::ElfError(const std::string& rFile, const std::string& rMessage)
-{
- if ( rFile != "" ) {
- m_sMessage = rFile;
- m_sMessage += ": ";
- }
- m_sMessage += rMessage;
- const char *pElfMsg = elf_errmsg(0);
- if ( pElfMsg ) {
- m_sMessage += ": ";
- m_sMessage += pElfMsg;
- }
-}
-
-void initElfLib()
-{
- if ( elf_version(EV_CURRENT) == EV_NONE) {
- throw ElfError("", "elf_version() failed");
- }
- return;
-}
-
-bool isFixAndContinueSymbol(const std::string& rSymbol)
-{
- // The globalized 'fix and continue' symbols have the following
- // form, see "Stabs interface", page 164:
- // {.$}X{ABC}uniquepattern[.function_name][EQUIVn][.variable_name]
- char c0 = rSymbol[0];
- char c1 = rSymbol[1];
- char c2 = rSymbol[2];
- if ( c0 == '.' || c0 == '$' ) {
- if ( c1 == 'X' ) {
- if ( c2 == 'A' || c2 == 'B' || c2 == 'C' || c2 == 'D' ) {
- return true;
- }
- }
- }
- return false;
-}
-
-void adjustVisibility( const std::string& rFile, int fd, bool bVerbose)
-{
- if ( bVerbose ) {
- std::cout << "File: " << rFile << ": adjusting 'fix and continue' symbol visibility\n";
- }
-
- try {
- Elf* pElf;
- if ((pElf = elf_begin(fd, ELF_C_RDWR, 0)) == NULL) {
- throw ElfError(rFile, "elf_begin() failed");
- }
- // Check if file is ELF file.
- if ( elf_kind(pElf) != ELF_K_ELF ) {
- throw ElfError(rFile, "elf_kind() failed, file is not an ELF object file");
- }
-
- // Iterate over sections.
- Elf_Scn* pScn = 0;
- while ( (pScn = elf_nextscn(pElf, pScn)) != 0 ) {
- GElf_Shdr aShdr;
- if ( gelf_getshdr(pScn, &aShdr) == 0 ) {
- throw ElfError(rFile, "gelf_getshdr() failed");
- }
- if ( aShdr.sh_type != SHT_SYMTAB ) {
- continue;
- }
- // Section is a symbol section. Get the assiociated data.
- Elf_Data* pSymbolData;
- if ( (pSymbolData = elf_getdata(pScn, 0)) == NULL ) {
- throw ElfError(rFile, "elf_getdata() failed");
- }
- // Iterate over symbol table.
- GElf_Xword nSymbols = aShdr.sh_size / aShdr.sh_entsize;
- if ( nSymbols > std::numeric_limits< int >::max() )
- {
- throw ElfError(rFile, "too many symbols");
- }
- for ( int nIndex = 0; nIndex < nSymbols; ++nIndex) {
- // Get symbol.
- GElf_Sym aSymbol;
- if ( gelf_getsym(pSymbolData, nIndex, &aSymbol) == NULL )
- {
- throw ElfError(rFile, "gelf_getsym() failed");
- }
- std::string sSymbolName(elf_strptr(pElf, aShdr.sh_link, aSymbol.st_name));
- if ( isFixAndContinueSymbol(sSymbolName) ) {
- // Get the symbol visibility.
- unsigned int nSymbolVisibility = GELF_ST_VISIBILITY(aSymbol.st_other);
- if ( bVerbose ) {
- // Get the symbol type and binding.
- unsigned int nSymbolType = GELF_ST_TYPE(aSymbol.st_info);
- unsigned int nSymbolBind = GELF_ST_BIND(aSymbol.st_info);
- std::cout << "Symbol: " << sSymbolName << ", "
- << "Type: ";
- if ( SymbolType[nSymbolType] ) {
- std::cout << SymbolType[nSymbolType];
- } else {
- std::cout << nSymbolType;
- }
- std::cout << ", Binding: ";
- if ( SymbolBinding[nSymbolBind] ) {
- std::cout << SymbolBinding[nSymbolBind];
- } else {
- std::cout << nSymbolBind;
- }
- std::cout << ", Visibility: ";
- if ( SymbolVisibility[nSymbolVisibility] ) {
- std::cout << SymbolVisibility[nSymbolVisibility];
- } else {
- std::cout << nSymbolVisibility;
- }
- std::cout << "-> " << SymbolVisibility[STV_HIDDEN] << "\n";
- }
- // Toggle visibility to "hidden".
- aSymbol.st_other = GELF_ST_VISIBILITY(STV_HIDDEN);
- // Write back symbol data to underlying structure.
- if ( gelf_update_sym(pSymbolData, nIndex, &aSymbol) == NULL )
- {
- throw ElfError(rFile, "gelf_update_sym() failed");
- }
- }
- }
- }
- // Write changed object file to disk.
- if ( elf_update(pElf, ELF_C_WRITE) == -1 ) {
- throw ElfError(rFile, "elf_update() failed");
- }
- elf_end(pElf);
-
- } catch (ElfError& e) {
- close(fd);
- throw;
- }
- return;
-}
-
-void processObject(const std::string& rFile, bool bPreserve, bool bVerbose)
-{
- int fd;
- struct stat aStatBuf;
-
- if ((fd = open(rFile.c_str(), O_RDWR)) == -1) {
- std::string sMessage("adjustVisibilty() failed: can't open file ");
- sMessage += rFile;
- sMessage += ": ";
- sMessage += std::strerror(errno);
- throw std::runtime_error(sMessage);
- }
-
- if ( bPreserve ) {
- if ( fstat(fd, &aStatBuf) == -1) {
- close(fd);
- std::string sMessage("adjustVisibilty() failed: can't stat file ");
- sMessage += rFile;
- sMessage += ": ";
- sMessage += std::strerror(errno);
- throw std::runtime_error(sMessage);
- }
- }
-
- adjustVisibility(rFile, fd, bVerbose);
-
- close(fd);
-
- if ( bPreserve ) {
- struct utimbuf aUtimBuf = {aStatBuf.st_atime, aStatBuf.st_mtime};
- if ( utime(rFile.c_str(), &aUtimBuf) == -1 ) {
- std::string sMessage("adjustVisibilty() failed: can't reset timestamp ");
- sMessage += rFile;
- sMessage += ": ";
- sMessage += std::strerror(errno);
- throw std::runtime_error(sMessage);
- }
- }
- return;
-}
-
-int main(int argc, char* argv[])
-{
- int c;
- bool bPreserve = false;
- bool bVerbose = false;
-
- while ( (c = getopt(argc, argv, "pv")) != -1 ) {
- switch(c) {
- case 'p':
- bPreserve = true;
- break;
- case 'v':
- bVerbose = true;
- break;
- case '?':
- std::cerr << "Unrecognized option: -" << optopt << "\n";
- break;
- default:
- break;
- }
- }
-
- if ( optind == argc ) {
- std::cout << "usage: " << argv[0] << " [-pv] <elf-object> ...\n";
- std::cout << " -p preserve time stamps\n";
- std::cout << " -v verbose\n";
- return 1;
- }
-
- try {
- initElfLib();
-
- for ( ; optind < argc; optind++ ) {
- processObject(std::string(argv[optind]), bPreserve, bVerbose);
- }
-
- } catch (std::exception& e) {
- std::cerr << argv[0] << ": " << e.what() << "\n";
- return 1;
- }
-
- return 0;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */