X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Fgold.h;h=90f1f7d1f4ecfbf6ae53c5ef387b0d6e55223963;hb=41cbeecc3c135adf06568c9cc566fce385cc3c06;hp=14d4aeec987e9ba1129d0db42b159e2242c8bbf6;hpb=82dcae9de0f7ca290bba97b6dfb8449e1a2e27fb;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/gold.h b/gold/gold.h index 14d4aeec98..90f1f7d1f4 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 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -26,6 +26,25 @@ #include "config.h" #include "ansidecl.h" +#include +#include +#include +#include + +#ifndef ENABLE_NLS + // The Solaris version of locale.h always includes libintl.h. If we + // have been configured with --disable-nls then ENABLE_NLS will not + // be defined and the dummy definitions of bindtextdomain (et al) + // below will conflict with the defintions in libintl.h. So we + // define these values to prevent the bogus inclusion of libintl.h. +# define _LIBINTL_H +# define _LIBGETTEXT_H +#endif + +// Always include first to avoid conflicts with the macros +// used when ENABLE_NLS is not defined. +#include + #ifdef ENABLE_NLS # include # define _(String) gettext (String) @@ -46,7 +65,8 @@ // Figure out how to get a hash set and a hash map. -#if defined(HAVE_TR1_UNORDERED_SET) && defined(HAVE_TR1_UNORDERED_MAP) +#if defined(HAVE_TR1_UNORDERED_SET) && defined(HAVE_TR1_UNORDERED_MAP) \ + && defined(HAVE_TR1_UNORDERED_MAP_REHASH) #include #include @@ -55,6 +75,9 @@ #define Unordered_set std::tr1::unordered_set #define Unordered_map std::tr1::unordered_map +#define Unordered_multimap std::tr1::unordered_multimap + +#define reserve_unordered_map(map, n) ((map)->rehash(n)) #elif defined(HAVE_EXT_HASH_MAP) && defined(HAVE_EXT_HASH_SET) @@ -64,6 +87,7 @@ #define Unordered_set __gnu_cxx::hash_set #define Unordered_map __gnu_cxx::hash_map +#define Unordered_multimap __gnu_cxx::hash_multimap namespace __gnu_cxx { @@ -86,6 +110,8 @@ struct hash } +#define reserve_unordered_map(map, n) ((map)->resize(n)) + #else // The fallback is to just use set and map. @@ -95,6 +121,9 @@ struct hash #define Unordered_set std::set #define Unordered_map std::map +#define Unordered_multimap std::multimap + +#define reserve_unordered_map(map, n) #endif @@ -102,79 +131,56 @@ struct hash extern "C" ssize_t pread(int, void*, size_t, off_t); #endif -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) +#ifndef HAVE_FTRUNCATE +extern "C" int ftruncate(int, off_t); +#endif -} // End namespace gold. +#ifndef HAVE_MREMAP +#define MREMAP_MAYMOVE 1 +extern "C" void *mremap(void *, size_t, size_t, int, ...); +#endif + +#ifndef HAVE_FFSLL +extern "C" int ffsll(long long); +#endif + +#if !HAVE_DECL_MEMMEM +extern "C" void *memmem(const void *, size_t, const void *, size_t); +#endif + +#if !HAVE_DECL_STRNDUP +extern "C" char *strndup(const char *, size_t); +#endif 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; + +// 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; @@ -184,21 +190,85 @@ extern const char* program_name; extern void gold_exit(bool status) ATTRIBUTE_NORETURN; -// 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 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_fatal(const char* msg, bool perrno) ATTRIBUTE_NORETURN; +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; + +// 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, ...) + 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; @@ -207,33 +277,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" + "ABCDEFGHIJKLMNOPWRSTUVWXYZ" + "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)