+// This class represents the output file.
+
+class Output_file
+{
+ public:
+ Output_file(const char* name);
+
+ // Indicate that this is a temporary file which should not be
+ // output.
+ void
+ set_is_temporary()
+ { this->is_temporary_ = true; }
+
+ // Try to open an existing file. Returns false if the file doesn't
+ // exist, has a size of 0 or can't be mmaped. This method is
+ // thread-unsafe. If BASE_NAME is not NULL, use the contents of
+ // that file as the base for incremental linking.
+ bool
+ open_base_file(const char* base_name, bool writable);
+
+ // Open the output file. FILE_SIZE is the final size of the file.
+ // If the file already exists, it is deleted/truncated. This method
+ // is thread-unsafe.
+ void
+ open(off_t file_size);
+
+ // Resize the output file. This method is thread-unsafe.
+ void
+ resize(off_t file_size);
+
+ // Close the output file (flushing all buffered data) and make sure
+ // there are no errors. This method is thread-unsafe.
+ void
+ close();
+
+ // Return the size of this file.
+ off_t
+ filesize()
+ { return this->file_size_; }
+
+ // Return the name of this file.
+ const char*
+ filename()
+ { return this->name_; }
+
+ // We currently always use mmap which makes the view handling quite
+ // simple. In the future we may support other approaches.
+
+ // Write data to the output file.
+ void
+ write(off_t offset, const void* data, size_t len)
+ { memcpy(this->base_ + offset, data, len); }
+
+ // Get a buffer to use to write to the file, given the offset into
+ // the file and the size.
+ unsigned char*
+ get_output_view(off_t start, size_t size)
+ {
+ gold_assert(start >= 0
+ && start + static_cast<off_t>(size) <= this->file_size_);
+ return this->base_ + start;
+ }
+
+ // VIEW must have been returned by get_output_view. Write the
+ // buffer to the file, passing in the offset and the size.
+ void
+ write_output_view(off_t, size_t, unsigned char*)
+ { }
+
+ // Get a read/write buffer. This is used when we want to write part
+ // of the file, read it in, and write it again.
+ unsigned char*
+ get_input_output_view(off_t start, size_t size)
+ { return this->get_output_view(start, size); }
+
+ // Write a read/write buffer back to the file.
+ void
+ write_input_output_view(off_t, size_t, unsigned char*)
+ { }
+
+ // Get a read buffer. This is used when we just want to read part
+ // of the file back it in.
+ const unsigned char*
+ get_input_view(off_t start, size_t size)
+ { return this->get_output_view(start, size); }
+
+ // Release a read bfufer.
+ void
+ free_input_view(off_t, size_t, const unsigned char*)
+ { }
+
+ private:
+ // Map the file into memory or, if that fails, allocate anonymous
+ // memory.
+ void
+ map();
+
+ // Allocate anonymous memory for the file.
+ bool
+ map_anonymous();
+
+ // Map the file into memory.
+ bool
+ map_no_anonymous(bool);
+
+ // Unmap the file from memory (and flush to disk buffers).
+ void
+ unmap();
+
+ // File name.
+ const char* name_;
+ // File descriptor.
+ int o_;
+ // File size.
+ off_t file_size_;
+ // Base of file mapped into memory.
+ unsigned char* base_;
+ // True iff base_ points to a memory buffer rather than an output file.
+ bool map_is_anonymous_;
+ // True if base_ was allocated using new rather than mmap.
+ bool map_is_allocated_;
+ // True if this is a temporary file which should not be output.
+ bool is_temporary_;
+};
+