fixes for A2
mostly include some things that should and remove some things that shouldn't have been included in the handout (yes this does hint at some places that need to be touched for A2)
This commit is contained in:
69
user/imgbuilder.cc
Normal file
69
user/imgbuilder.cc
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <format>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <print>
|
||||
#include <vector>
|
||||
|
||||
constexpr size_t block_size = 4096;
|
||||
const uint8_t zeros[block_size] = {};
|
||||
|
||||
template <class... Args>
|
||||
static void die(std::format_string<Args...> fmt, Args &&...args) {
|
||||
auto msg = std::format(fmt, std::forward<Args>(args)...);
|
||||
perror(msg.c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void writeBuffer(const void *data, size_t size) {
|
||||
std::cout.write(reinterpret_cast<const char *>(data), size);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
std::println(stderr, "usage: {} <list of flat binaries>\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
} else if (argc > 1000) {
|
||||
std::println(stderr, "Only a maximum of 1000 apps are supported\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// HEADER: Number of apps + size of each app
|
||||
std::array<uint32_t, block_size / sizeof(uint32_t)> size{0};
|
||||
size[0] = static_cast<uint32_t>(argc - 1);
|
||||
|
||||
for (size_t i = 1; i < argc; ++i) {
|
||||
struct stat sb;
|
||||
if (stat(argv[i], &sb) != 0) die("stat");
|
||||
// 4 GB Limit
|
||||
if (sb.st_size >= UINT32_MAX) {
|
||||
errno = EFBIG;
|
||||
die("stat");
|
||||
}
|
||||
size[i] = sb.st_size;
|
||||
}
|
||||
writeBuffer(size.data(), block_size);
|
||||
|
||||
// DATA: Each App
|
||||
for (size_t i = 1; i < argc; ++i) {
|
||||
std::vector<char> buf(size[i]);
|
||||
std::ifstream input(argv[i], std::ios::binary);
|
||||
if (!input) die("fopen");
|
||||
|
||||
input.read(buf.data(), size[i]);
|
||||
|
||||
writeBuffer(buf.data(), size[i]);
|
||||
|
||||
// Fill to block size, if required
|
||||
if (size[i] % block_size != 0)
|
||||
writeBuffer(zeros, block_size - (size[i] % block_size));
|
||||
}
|
||||
|
||||
std::cout.flush();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
73
user/init.cc
Normal file
73
user/init.cc
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <../libsys/stub.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void _init();
|
||||
extern void _fini();
|
||||
extern void main();
|
||||
|
||||
extern void (*__preinit_array_start[])();
|
||||
extern void (*__preinit_array_end[])();
|
||||
extern void (*__init_array_start[])();
|
||||
extern void (*__init_array_end[])();
|
||||
extern void (*__fini_array_start[])();
|
||||
extern void (*__fini_array_end[])();
|
||||
[[gnu::used]] [[noreturn]] void start() {
|
||||
const unsigned int preinit_size =
|
||||
__preinit_array_end - __preinit_array_start;
|
||||
for (unsigned int i = 0; i != preinit_size; ++i)
|
||||
(*__preinit_array_start[i])();
|
||||
|
||||
const unsigned int init_size = __init_array_end - __init_array_start;
|
||||
for (unsigned int i = 0; i != init_size; ++i) (*__init_array_start[i])();
|
||||
|
||||
main();
|
||||
|
||||
const unsigned int fini_size = __fini_array_end - __fini_array_start;
|
||||
for (unsigned int i = 0; i != fini_size; ++i) (*__fini_array_start[i])();
|
||||
|
||||
sys_exit();
|
||||
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
// additional C++ stuff
|
||||
void __cxa_pure_virtual() {
|
||||
// pure virtual error
|
||||
}
|
||||
|
||||
// For libraries
|
||||
int __cxa_atexit(void (*func)(void *), void *arg, void *dso_handle) {
|
||||
(void)func;
|
||||
(void)arg;
|
||||
(void)dso_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
void *operator new([[maybe_unused]] __SIZE_TYPE__ n) {
|
||||
return reinterpret_cast<void *>(0xdeadbeef);
|
||||
}
|
||||
|
||||
void *operator new[]([[maybe_unused]] __SIZE_TYPE__ n) {
|
||||
return reinterpret_cast<void *>(0xdeadbeef);
|
||||
}
|
||||
|
||||
void operator delete[](void *ptr) { operator delete(ptr); }
|
||||
|
||||
void operator delete[](void *ptr, [[maybe_unused]] __SIZE_TYPE__ size) {
|
||||
operator delete(ptr);
|
||||
}
|
||||
|
||||
void operator delete([[maybe_unused]] void *ptr) {}
|
||||
|
||||
void operator delete(void *ptr, [[maybe_unused]] __SIZE_TYPE__ size) {
|
||||
operator delete(ptr);
|
||||
}
|
||||
Reference in New Issue
Block a user