X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Fgold.h;h=d16a4f683d6e93c060c8a5b53b1ba2af456392d3;hb=c0c3707ff46ccfb78ea175dd42d628d8c90dca8b;hp=288d9eb937bf0272f2d1bb84780b5f499fcdbcf4;hpb=91da9340ccc0b222d729c9f775b2d4ec1480ee75;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/gold.h b/gold/gold.h index 288d9eb937..d16a4f683d 100644 --- a/gold/gold.h +++ b/gold/gold.h @@ -1,155 +1,77 @@ // gold.h -- general definitions for gold -*- C++ -*- -#ifndef GOLD_GOLD_H - -#include "config.h" -#include "ansidecl.h" - -#ifdef ENABLE_NLS -# include -# define _(String) gettext (String) -# ifdef gettext_noop -# define N_(String) gettext_noop (String) -# else -# define N_(String) (String) -# endif -#else -# define gettext(Msgid) (Msgid) -# define dgettext(Domainname, Msgid) (Msgid) -# define dcgettext(Domainname, Msgid, Category) (Msgid) -# define textdomain(Domainname) while (0) /* nothing */ -# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */ -# define _(String) (String) -# define N_(String) (String) -#endif - -// Figure out how to get a hash set and a hash map. - -#if defined(HAVE_TR1_UNORDERED_SET) && defined(HAVE_TR1_UNORDERED_MAP) - -#include -#include - -// We need a template typedef here. - -#define Unordered_set std::tr1::unordered_set -#define Unordered_map std::tr1::unordered_map +// Copyright (C) 2006-2019 Free Software Foundation, Inc. +// Written by Ian Lance Taylor . -#elif defined(HAVE_EXT_HASH_MAP) && defined(HAVE_EXT_HASH_SET) +// This file is part of gold. -#include -#include -#include +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. -#define Unordered_set __gnu_cxx::hash_set -#define Unordered_map __gnu_cxx::hash_map +// This program 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 General Public License for more details. -namespace __gnu_cxx -{ - -template<> -struct hash -{ - size_t - operator()(std::string s) const - { return __stl_hash_string(s.c_str()); } -}; - -template -struct hash -{ - size_t - operator()(T* p) const - { return reinterpret_cast(p); } -}; - -} - -#else +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. -// The fallback is to just use set and map. +#ifndef GOLD_GOLD_H +#define GOLD_GOLD_H -#include -#include +#include "config.h" +#include "ansidecl.h" -#define Unordered_set std::set -#define Unordered_map std::map +#include +#include +#include +#include +#include -#endif +#include "system.h" namespace gold { -// This is a hack to work around a problem with older versions of g++. -// The problem is that they don't support calling a member template by -// specifying the template parameters. It works to pass in an -// argument for argument dependent lookup. - -// To use this, the member template method declaration should put -// ACCEPT_SIZE or ACCEPT_SIZE_ENDIAN after the last parameter. If the -// method takes no parameters, use ACCEPT_SIZE_ONLY or -// ACCEPT_SIZE_ENDIAN_ONLY. - -// When calling the method, instead of using fn, use fn -// SELECT_SIZE_NAME or SELECT_SIZE_ENDIAN_NAME. And after the last -// argument, put SELECT_SIZE(size) or SELECT_SIZE_ENDIAN(size, -// big_endian). If there is only one argment, use the _ONLY variants. - -#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS - -#define SELECT_SIZE_NAME(size) -#define SELECT_SIZE(size) -#define SELECT_SIZE_ONLY(size) -#define ACCEPT_SIZE -#define ACCEPT_SIZE_ONLY -#define ACCEPT_SIZE_EXPLICIT(size) - -#define SELECT_SIZE_ENDIAN_NAME(size, big_endian) -#define SELECT_SIZE_ENDIAN(size, big_endian) -#define SELECT_SIZE_ENDIAN_ONLY(size, big_endian) -#define ACCEPT_SIZE_ENDIAN -#define ACCEPT_SIZE_ENDIAN_ONLY -#define ACCEPT_SIZE_ENDIAN_EXPLICIT(size, big_endian) - -#else // !defined(HAVE_MEMBER_TEMPLATE_SPECIFICATIONS) - -template -class Select_size { }; -template -class Select_size_endian { }; - -#define SELECT_SIZE_NAME(size) -#define SELECT_SIZE(size) , Select_size() -#define SELECT_SIZE_ONLY(size) Select_size() -#define ACCEPT_SIZE , Select_size -#define ACCEPT_SIZE_ONLY Select_size -#define ACCEPT_SIZE_EXPLICIT(size) , Select_size - -#define SELECT_SIZE_ENDIAN_NAME(size, big_endian) -#define SELECT_SIZE_ENDIAN(size, big_endian) \ - , Select_size_endian() -#define SELECT_SIZE_ENDIAN_ONLY(size, big_endian) \ - Select_size_endian() -#define ACCEPT_SIZE_ENDIAN , Select_size_endian -#define ACCEPT_SIZE_ENDIAN_ONLY Select_size_endian -#define ACCEPT_SIZE_ENDIAN_EXPLICIT(size, big_endian) \ - , Select_size_endian - -#endif // !defined(HAVE_MEMBER_TEMPLATE_SPECIFICATIONS) - -} // End namespace gold. -namespace gold -{ +// General declarations. class General_options; class Command_line; -class Input_argument_list; class Dirsearch; class Input_objects; +class Mapfile; +class Symbol; class Symbol_table; class Layout; +class Task; class Workqueue; class Output_file; +template +struct Relocate_info; + +// Exit status codes. + +enum Exit_status +{ + GOLD_OK = EXIT_SUCCESS, + GOLD_ERR = EXIT_FAILURE, + GOLD_FALLBACK = EXIT_FAILURE + 1 +}; + +// Some basic types. For these we use lower case initial letters. + +// For an offset in an input or output file, use off_t. Note that +// this will often be a 64-bit type even for a 32-bit build. + +// The size of a section if we are going to look at the contents. +typedef size_t section_size_type; + +// An offset within a section when we are looking at the contents. +typedef ptrdiff_t section_offset_type; // The name of the program as used in error messages. extern const char* program_name; @@ -157,23 +79,94 @@ extern const char* program_name; // This function is called to exit the program. Status is true to // exit success (0) and false to exit failure (1). extern void -gold_exit(bool status) ATTRIBUTE_NORETURN; +gold_exit(Exit_status status) ATTRIBUTE_NORETURN; + +// This function is called to emit an error message and then +// immediately exit with failure. +extern void +gold_fatal(const char* format, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1; + +// This function is called to issue an error. This will cause gold to +// eventually exit with failure. +extern void +gold_error(const char* msg, ...) ATTRIBUTE_PRINTF_1; + +// This function is called to issue a warning. +extern void +gold_warning(const char* msg, ...) ATTRIBUTE_PRINTF_1; + +// This function is called to print an informational message. +extern void +gold_info(const char* msg, ...) ATTRIBUTE_PRINTF_1; + +// This function is called to emit an error message and then +// immediately exit with fallback status (e.g., when +// --incremental-update fails and the link needs to be restarted +// with --incremental-full). +extern void +gold_fallback(const char* format, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1; + +// Work around a bug in gcc 4.3.0. http://gcc.gnu.org/PR35546 . This +// can probably be removed after the bug has been fixed for a while. +#ifdef HAVE_TEMPLATE_ATTRIBUTES +#define TEMPLATE_ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF_4 +#else +#define TEMPLATE_ATTRIBUTE_PRINTF_4 +#endif -// This function is called to emit an unexpected error message and a -// newline, and then exit with failure. If PERRNO is true, it reports -// the error in errno. +// This function is called to issue an error at the location of a +// reloc. +template extern void -gold_fatal(const char* msg, bool perrno) ATTRIBUTE_NORETURN; +gold_error_at_location(const Relocate_info*, + size_t, off_t, const char* format, ...) + TEMPLATE_ATTRIBUTE_PRINTF_4; + +// This function is called to issue a warning at the location of a +// reloc. +template +extern void +gold_warning_at_location(const Relocate_info*, + size_t, off_t, const char* format, ...) + TEMPLATE_ATTRIBUTE_PRINTF_4; + +// This function is called to report an undefined symbol without +// a relocation (e.g., referenced by a dynamic object). SYM is +// the undefined symbol. The file name associated with the SYM +// is used to print a location for the undefined symbol. +extern void +gold_undefined_symbol(const Symbol*); + +// This function is called to report an undefined symbol resulting +// from a relocation. SYM is the undefined symbol. RELINFO is the +// general relocation info. RELNUM is the number of the reloc, +// and RELOFFSET is the reloc's offset. +template +extern void +gold_undefined_symbol_at_location(const Symbol*, + const Relocate_info*, + size_t, off_t); // This is function is called in some cases if we run out of memory. extern void gold_nomem() ATTRIBUTE_NORETURN; +// In versions of gcc before 4.3, using __FUNCTION__ in a template +// function can cause gcc to get confused about whether or not the +// function can return. See http://gcc.gnu.org/PR30988. Use a macro +// to avoid the problem. This can be removed when we no longer need +// to care about gcc versions before 4.3. +#if defined(__GNUC__) && GCC_VERSION < 4003 +#define FUNCTION_NAME static_cast(__FUNCTION__) +#else +#define FUNCTION_NAME __FUNCTION__ +#endif + // This macro and function are used in cases which can not arise if // the code is written correctly. #define gold_unreachable() \ - (gold::do_gold_unreachable(__FILE__, __LINE__, __FUNCTION__)) + (gold::do_gold_unreachable(__FILE__, __LINE__, FUNCTION_NAME)) extern void do_gold_unreachable(const char*, int, const char*) ATTRIBUTE_NORETURN; @@ -182,33 +175,139 @@ extern void do_gold_unreachable(const char*, int, const char*) #define gold_assert(expr) ((void)(!(expr) ? gold_unreachable(), 0 : 0)) +// Print version information. +extern void +print_version(bool print_short); + +// Get the version string. +extern const char* +get_version_string(); + +// Convert numeric types without unnoticed loss of precision. +template +inline To +convert_types(const From from) +{ + To to = from; + gold_assert(static_cast(to) == from); + return to; +} + +// A common case of convert_types<>: convert to section_size_type. +template +inline section_size_type +convert_to_section_size_type(const From from) +{ return convert_types(from); } + // Queue up the first set of tasks. extern void queue_initial_tasks(const General_options&, - const Dirsearch&, + Dirsearch&, const Command_line&, Workqueue*, Input_objects*, Symbol_table*, - Layout*); + Layout*, + Mapfile*); + +// Queue up the set of tasks to be done before +// the middle set of tasks. Only used when garbage +// collection is to be done. +extern void +queue_middle_gc_tasks(const General_options&, + const Task*, + const Input_objects*, + Symbol_table*, + Layout*, + Workqueue*, + Mapfile*); // Queue up the middle set of tasks. extern void queue_middle_tasks(const General_options&, + const Task*, const Input_objects*, Symbol_table*, Layout*, - Workqueue*); + Workqueue*, + Mapfile*); // Queue up the final set of tasks. extern void queue_final_tasks(const General_options&, const Input_objects*, const Symbol_table*, - const Layout*, + Layout*, Workqueue*, Output_file* of); +inline bool +is_prefix_of(const char* prefix, const char* str) +{ + return strncmp(prefix, str, strlen(prefix)) == 0; +} + +const char* const cident_section_start_prefix = "__start_"; +const char* const cident_section_stop_prefix = "__stop_"; + +// Returns true if the name is a valid C identifier +inline bool +is_cident(const char* name) +{ + return (name[strspn(name, + ("0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "_"))] + == '\0'); +} + +// We sometimes need to hash strings. Ideally we should use std::tr1::hash or +// __gnu_cxx::hash on some systems but there is no guarantee that either +// one is available. For portability, we define simple string hash functions. + +template +inline size_t +string_hash(const Char_type* s, size_t length) +{ + // This is the hash function used by the dynamic linker for + // DT_GNU_HASH entries. I compared this to a Fowler/Noll/Vo hash + // for a C++ program with 385,775 global symbols. This hash + // function was very slightly worse. However, it is much faster to + // compute. Overall wall clock time was a win. + const unsigned char* p = reinterpret_cast(s); + size_t h = 5381; + for (size_t i = 0; i < length * sizeof(Char_type); ++i) + h = h * 33 + *p++; + return h; +} + +// Same as above except we expect the string to be zero terminated. + +template +inline size_t +string_hash(const Char_type* s) +{ + const unsigned char* p = reinterpret_cast(s); + size_t h = 5381; + for (size_t i = 0; s[i] != 0; ++i) + { + for (size_t j = 0; j < sizeof(Char_type); j++) + h = h * 33 + *p++; + } + + return h; +} + +// Return whether STRING contains a wildcard character. This is used +// to speed up matching. + +inline bool +is_wildcard_string(const char* s) +{ + return strpbrk(s, "?*[") != NULL; +} + } // End namespace gold. #endif // !defined(GOLD_GOLD_H)