X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Fgold.h;h=9154792f9b883fafa59989bb8ab473667ad70210;hb=4f83758119ddf0f114477760d79bdde7bbc76835;hp=25f6c0c77120cde54b27e8095f441aa31e65a30b;hpb=75f2446ec3c13eca3fe0c7cfdbb232e760d36596;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/gold.h b/gold/gold.h index 25f6c0c771..9154792f9b 100644 --- a/gold/gold.h +++ b/gold/gold.h @@ -1,6 +1,6 @@ // gold.h -- general definitions for gold -*- C++ -*- -// Copyright 2006, 2007 Free Software Foundation, Inc. +// Copyright (C) 2006-2020 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -26,166 +26,60 @@ #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 - -#elif defined(HAVE_EXT_HASH_MAP) && defined(HAVE_EXT_HASH_SET) - -#include -#include -#include - -#define Unordered_set __gnu_cxx::hash_set -#define Unordered_map __gnu_cxx::hash_map +#include +#include +#include +#include +#include -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 - -// The fallback is to just use set and map. - -#include -#include - -#define Unordered_set std::set -#define Unordered_map std::map - -#endif - -#ifndef HAVE_PREAD -extern "C" ssize_t pread(int, void*, size_t, off_t); -#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; // 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. @@ -201,13 +95,32 @@ gold_error(const char* msg, ...) ATTRIBUTE_PRINTF_1; 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 issue an error at the location of a // reloc. template extern void gold_error_at_location(const Relocate_info*, size_t, off_t, const char* format, ...) - ATTRIBUTE_PRINTF_4; + TEMPLATE_ATTRIBUTE_PRINTF_4; // This function is called to issue a warning at the location of a // reloc. @@ -215,24 +128,45 @@ template extern void gold_warning_at_location(const Relocate_info*, size_t, off_t, const char* format, ...) - ATTRIBUTE_PRINTF_4; + TEMPLATE_ATTRIBUTE_PRINTF_4; -// This function is called to report an undefined symbol. +// 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(const Symbol*, - const Relocate_info*, - size_t, off_t); +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; @@ -249,33 +183,131 @@ print_version(bool print_short); 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)