+// This task handles writing out data which is not part of a section
+// or segment.
+
+class Write_data_task : public Task
+{
+ public:
+ Write_data_task(const Layout* layout, const Symbol_table* symtab,
+ const Target* target, Output_file* of,
+ Task_token* final_blocker)
+ : layout_(layout), symtab_(symtab), target_(target), of_(of),
+ final_blocker_(final_blocker)
+ { }
+
+ // The standard Task methods.
+
+ Is_runnable_type
+ is_runnable(Workqueue*);
+
+ Task_locker*
+ locks(Workqueue*);
+
+ void
+ run(Workqueue*);
+
+ private:
+ const Layout* layout_;
+ const Symbol_table* symtab_;
+ const Target* target_;
+ Output_file* of_;
+ Task_token* final_blocker_;
+};
+
+// This task handles writing out the global symbols.
+
+class Write_symbols_task : public Task
+{
+ public:
+ Write_symbols_task(const Symbol_table* symtab, const Target* target,
+ const Stringpool* sympool, const Stringpool* dynpool,
+ Output_file* of, Task_token* final_blocker)
+ : symtab_(symtab), target_(target), sympool_(sympool), dynpool_(dynpool),
+ of_(of), final_blocker_(final_blocker)
+ { }
+
+ // The standard Task methods.
+
+ Is_runnable_type
+ is_runnable(Workqueue*);
+
+ Task_locker*
+ locks(Workqueue*);
+
+ void
+ run(Workqueue*);
+
+ private:
+ const Symbol_table* symtab_;
+ const Target* target_;
+ const Stringpool* sympool_;
+ const Stringpool* dynpool_;
+ Output_file* of_;
+ Task_token* final_blocker_;
+};
+
+// This task function handles closing the file.
+
+class Close_task_runner : public Task_function_runner
+{
+ public:
+ Close_task_runner(Output_file* of)
+ : of_(of)
+ { }
+
+ // Run the operation.
+ void
+ run(Workqueue*);
+
+ private:
+ Output_file* of_;
+};
+
+// A small helper function to align an address.
+
+inline uint64_t
+align_address(uint64_t address, uint64_t addralign)
+{
+ if (addralign != 0)
+ address = (address + addralign - 1) &~ (addralign - 1);
+ return address;
+}
+