X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Fgold.h;h=9154792f9b883fafa59989bb8ab473667ad70210;hb=df08b5881b4972d78f9a2069955dad5b12bc972e;hp=520f2e3c16f27f9e2506ac6767384cd077c7e808;hpb=9bb53bf8b866ee59d66c14250aee4bfaed0604ca;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/gold.h b/gold/gold.h index 520f2e3c16..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,148 +26,24 @@ #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 +#include +#include +#include +#include +#include -#define Unordered_set __gnu_cxx::hash_set -#define Unordered_map __gnu_cxx::hash_map - -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) // 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; @@ -177,6 +53,15 @@ 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 @@ -194,7 +79,7 @@ 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. @@ -210,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. @@ -224,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; @@ -282,7 +207,20 @@ queue_initial_tasks(const General_options&, 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 @@ -291,7 +229,8 @@ queue_middle_tasks(const General_options&, const Input_objects*, Symbol_table*, Layout*, - Workqueue*); + Workqueue*, + Mapfile*); // Queue up the final set of tasks. extern void @@ -302,6 +241,73 @@ queue_final_tasks(const General_options&, 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)