descriptors.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. // descriptors.cc -- manage file descriptors for gold
  2. // Copyright (C) 2008-2015 Free Software Foundation, Inc.
  3. // Written by Ian Lance Taylor <iant@google.com>.
  4. // This file is part of gold.
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 3 of the License, or
  8. // (at your option) any later version.
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. // MA 02110-1301, USA.
  17. #include "gold.h"
  18. #include <cerrno>
  19. #include <cstdio>
  20. #include <cstring>
  21. #include <fcntl.h>
  22. #include <unistd.h>
  23. #include "debug.h"
  24. #include "parameters.h"
  25. #include "options.h"
  26. #include "gold-threads.h"
  27. #include "descriptors.h"
  28. #include "binary-io.h"
  29. // O_CLOEXEC is only available on newer systems.
  30. #ifndef O_CLOEXEC
  31. #define O_CLOEXEC 0
  32. #endif
  33. // Very old systems may not define FD_CLOEXEC.
  34. #ifndef FD_CLOEXEC
  35. #define FD_CLOEXEC 1
  36. #endif
  37. static inline void
  38. set_close_on_exec(int fd ATTRIBUTE_UNUSED)
  39. {
  40. // Mingw does not define F_SETFD.
  41. #ifdef F_SETFD
  42. fcntl(fd, F_SETFD, FD_CLOEXEC);
  43. #endif
  44. }
  45. namespace gold
  46. {
  47. // Class Descriptors.
  48. // The default for limit_ is meant to simply be large. It gets
  49. // adjusted downward if we run out of file descriptors.
  50. Descriptors::Descriptors()
  51. : lock_(NULL), initialize_lock_(&this->lock_), open_descriptors_(),
  52. stack_top_(-1), current_(0), limit_(8192 - 16)
  53. {
  54. this->open_descriptors_.reserve(128);
  55. }
  56. // Open a file.
  57. int
  58. Descriptors::open(int descriptor, const char* name, int flags, int mode)
  59. {
  60. // We don't initialize this until we are called, because we can't
  61. // initialize a Lock until we have parsed the options to find out
  62. // whether we are running with threads. We can be called before
  63. // options are valid when reading a linker script.
  64. bool lock_initialized = this->initialize_lock_.initialize();
  65. gold_assert(lock_initialized || descriptor < 0);
  66. if (is_debugging_enabled(DEBUG_FILES))
  67. this->limit_ = 8;
  68. if (descriptor >= 0)
  69. {
  70. Hold_lock hl(*this->lock_);
  71. gold_assert(static_cast<size_t>(descriptor)
  72. < this->open_descriptors_.size());
  73. Open_descriptor* pod = &this->open_descriptors_[descriptor];
  74. if (pod->name == name
  75. || (pod->name != NULL && strcmp(pod->name, name) == 0))
  76. {
  77. gold_assert(!pod->inuse);
  78. pod->inuse = true;
  79. if (descriptor == this->stack_top_)
  80. {
  81. this->stack_top_ = pod->stack_next;
  82. pod->stack_next = -1;
  83. pod->is_on_stack = false;
  84. }
  85. gold_debug(DEBUG_FILES, "Reused existing descriptor %d for \"%s\"",
  86. descriptor, name);
  87. return descriptor;
  88. }
  89. }
  90. while (true)
  91. {
  92. // We always want to set the close-on-exec flag; we don't
  93. // require callers to pass it.
  94. flags |= O_CLOEXEC;
  95. // Always open the file as a binary file.
  96. flags |= O_BINARY;
  97. int new_descriptor = ::open(name, flags, mode);
  98. if (new_descriptor < 0
  99. && errno != ENFILE
  100. && errno != EMFILE)
  101. {
  102. if (descriptor >= 0 && errno == ENOENT)
  103. {
  104. {
  105. Hold_lock hl(*this->lock_);
  106. gold_error(_("file %s was removed during the link"), name);
  107. }
  108. errno = ENOENT;
  109. }
  110. gold_debug(DEBUG_FILES, "Opened new descriptor %d for \"%s\"",
  111. new_descriptor, name);
  112. return new_descriptor;
  113. }
  114. if (new_descriptor >= 0)
  115. {
  116. // If we have any plugins, we really do need to set the
  117. // close-on-exec flag, even if O_CLOEXEC is not defined.
  118. // FIXME: In some cases O_CLOEXEC may be defined in the
  119. // header file but not supported by the kernel.
  120. // Unfortunately there doesn't seem to be any obvious way to
  121. // detect that, as unknown flags passed to open are ignored.
  122. if (O_CLOEXEC == 0
  123. && parameters->options_valid()
  124. && parameters->options().has_plugins())
  125. set_close_on_exec(new_descriptor);
  126. {
  127. Hold_optional_lock hl(this->lock_);
  128. if (static_cast<size_t>(new_descriptor)
  129. >= this->open_descriptors_.size())
  130. this->open_descriptors_.resize(new_descriptor + 64);
  131. Open_descriptor* pod = &this->open_descriptors_[new_descriptor];
  132. pod->name = name;
  133. pod->stack_next = -1;
  134. pod->inuse = true;
  135. pod->is_write = (flags & O_ACCMODE) != O_RDONLY;
  136. pod->is_on_stack = false;
  137. ++this->current_;
  138. if (this->current_ >= this->limit_)
  139. this->close_some_descriptor();
  140. gold_debug(DEBUG_FILES, "Opened new descriptor %d for \"%s\"",
  141. new_descriptor, name);
  142. return new_descriptor;
  143. }
  144. }
  145. // We ran out of file descriptors.
  146. {
  147. Hold_optional_lock hl(this->lock_);
  148. this->limit_ = this->current_ - 16;
  149. if (this->limit_ < 8)
  150. this->limit_ = 8;
  151. if (!this->close_some_descriptor())
  152. gold_fatal(_("out of file descriptors and couldn't close any"));
  153. }
  154. }
  155. }
  156. // Release a descriptor.
  157. void
  158. Descriptors::release(int descriptor, bool permanent)
  159. {
  160. Hold_optional_lock hl(this->lock_);
  161. gold_assert(descriptor >= 0
  162. && (static_cast<size_t>(descriptor)
  163. < this->open_descriptors_.size()));
  164. Open_descriptor* pod = &this->open_descriptors_[descriptor];
  165. if (permanent
  166. || (this->current_ > this->limit_ && !pod->is_write))
  167. {
  168. if (::close(descriptor) < 0)
  169. gold_warning(_("while closing %s: %s"), pod->name, strerror(errno));
  170. pod->name = NULL;
  171. --this->current_;
  172. }
  173. else
  174. {
  175. pod->inuse = false;
  176. if (!pod->is_write && !pod->is_on_stack)
  177. {
  178. pod->stack_next = this->stack_top_;
  179. this->stack_top_ = descriptor;
  180. pod->is_on_stack = true;
  181. }
  182. }
  183. gold_debug(DEBUG_FILES, "Released descriptor %d for \"%s\"",
  184. descriptor, pod->name);
  185. }
  186. // Close some descriptor. The lock is held when this is called. We
  187. // close the descriptor on the top of the free stack. Note that this
  188. // is the opposite of an LRU algorithm--we close the most recently
  189. // used descriptor. That is because the linker tends to cycle through
  190. // all the files; after we release a file, we are unlikely to need it
  191. // again until we have looked at all the other files. Return true if
  192. // we closed a descriptor.
  193. bool
  194. Descriptors::close_some_descriptor()
  195. {
  196. int last = -1;
  197. int i = this->stack_top_;
  198. while (i >= 0)
  199. {
  200. gold_assert(static_cast<size_t>(i) < this->open_descriptors_.size());
  201. Open_descriptor* pod = &this->open_descriptors_[i];
  202. if (!pod->inuse && !pod->is_write)
  203. {
  204. if (::close(i) < 0)
  205. gold_warning(_("while closing %s: %s"), pod->name, strerror(errno));
  206. --this->current_;
  207. gold_debug(DEBUG_FILES, "Closed descriptor %d for \"%s\"",
  208. i, pod->name);
  209. pod->name = NULL;
  210. if (last < 0)
  211. this->stack_top_ = pod->stack_next;
  212. else
  213. this->open_descriptors_[last].stack_next = pod->stack_next;
  214. pod->stack_next = -1;
  215. pod->is_on_stack = false;
  216. return true;
  217. }
  218. last = i;
  219. i = pod->stack_next;
  220. }
  221. // We couldn't find any descriptors to close. This is weird but not
  222. // necessarily an error.
  223. return false;
  224. }
  225. // Close all the descriptors open for reading.
  226. void
  227. Descriptors::close_all()
  228. {
  229. Hold_optional_lock hl(this->lock_);
  230. for (size_t i = 0; i < this->open_descriptors_.size(); i++)
  231. {
  232. Open_descriptor* pod = &this->open_descriptors_[i];
  233. if (pod->name != NULL && !pod->inuse && !pod->is_write)
  234. {
  235. if (::close(i) < 0)
  236. gold_warning(_("while closing %s: %s"), pod->name, strerror(errno));
  237. gold_debug(DEBUG_FILES, "Closed descriptor %d for \"%s\" (close_all)",
  238. static_cast<int>(i), pod->name);
  239. pod->name = NULL;
  240. pod->stack_next = -1;
  241. pod->is_on_stack = false;
  242. }
  243. }
  244. this->stack_top_ = -1;
  245. }
  246. // The single global variable which manages descriptors.
  247. Descriptors descriptors;
  248. } // End namespace gold.