diff --git a/builder b/builder index 517fe9a..c6c6a97 100755 --- a/builder +++ b/builder @@ -26,6 +26,7 @@ export CCACHE_SLOPPINESS="pch_defines,time_macros" export ASAN_OPTIONS=check_initialization_order=1 LSAN_OPTIONS=suppressions=$(pwd)/.ignore_sanitize export LSAN_OPTIONS +export LDFLAGS="-fuse-ld=lld" # The `builder` script is supposed to be run from the # root of the source tree @@ -103,15 +104,11 @@ function clean() { } function run() { - pushed_build LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) "$BUILD_DIR"/src/serenec/serenec "$@" - popd_build } function repl() { - pushed_build LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) "$BUILD_DIR"/src/serene-repl/serene-repl "$@" - popd_build } function memcheck() { diff --git a/docs/videos.org b/docs/videos.org index 6ce4dc9..940a9ab 100644 --- a/docs/videos.org +++ b/docs/videos.org @@ -494,7 +494,8 @@ Source code -> IR X -> IR Y -> IR Z -> ... -> Target Code } #+END_SRC -* Episode 11 - Lowering SLIR +* DONE Episode 11 - Lowering SLIR +CLOSED: [2021-11-01 Mon 15:14] ** Overview - What is a Pass? - Pass Manager @@ -508,3 +509,52 @@ This framework allows for transforming a set of illegal operations to a set of l *** Rewrite Patterns *** Type Converter ** Full vs Partial Conversion +* Episode 12 - Target code generation +** Updates: +*** JIT work +*** Emacs dev mode +** So far.... +** Next Step +*** Compile to object files +*** Link object files to create an executable +** What is an object file? +*** Symbols +- A pair of a name and a value +- Value of a *defined symbol* is an offset in the =Content= +- *undefined symbols* +*** Relocations +Are computation to perform on the =Content=. For example, "set +this location in the contents to the value of this symbol plus this addend". + +Linker will apply all the *relocations* in an object file on link time and if +it can not resolve an undefined symbol most of the time it will raise an +error (depending on the relocation and the symbol). + +*** Contents +- Are what memory should look like during the execution +- Have a size +- Have a type +- Have an array of bytes +- Has sections like: + + .text: The target code generated by the compiler + + .data: The values of initialized variables + + .rdata: Static unnamed data like literal strings, protocol tables and .... + + .bss: Uninitialized variables (the content can be omitted or striped and assume + to contain only zeros) +** Linking process +During the linking process, linker assigns an address to each *defined* symbol +and tries to =resolve= *undefined* symbols +*** Linker will +- reads the object files +- reads the contents + + as raw data + + figures out the length + + reads the symbols and create a symbol table + + link undefined symbols to their definitions (possibly from other obj fils or libs) + + decide where all the content should go in the memory + + sort them based on the *type* + + concat them together + + apply relocations + + write the result to a file as an executable +** AOT vs JIT +** Let's look at some code diff --git a/src/serenec/serenec.cpp b/src/serenec/serenec.cpp index 8868304..3ba2b73 100644 --- a/src/serenec/serenec.cpp +++ b/src/serenec/serenec.cpp @@ -85,7 +85,7 @@ static cl::opt outputFile( static cl::opt outputDir("b", cl::desc("The absolute path to the build directory"), - cl::value_desc("filename"), cl::Required); + cl::value_desc("dir"), cl::Required); static cl::opt emitAction( "emit", cl::desc("Select what to dump."), cl::init(Compile), @@ -159,6 +159,7 @@ int dumpAsObject(Namespace &ns) { llvm::raw_fd_ostream dest(destObjFilePath, ec, llvm::sys::fs::OF_None); if (ec) { + llvm::errs() << "Could not open file: " << destObjFilePath; llvm::errs() << "Could not open file: " << ec.message(); return 1; } @@ -189,24 +190,26 @@ int dumpAsObject(Namespace &ns) { args.push_back("-o"); args.push_back(destFile.c_str()); - d.setCheckInputsExist(false); + d.setCheckInputsExist(true); std::unique_ptr compilation; compilation.reset(d.BuildCompilation(args)); if (!compilation) { + llvm::errs() << "can't create the compilation!\n"; return 1; } llvm::SmallVector> failCommand; - // compilation->ExecuteJobs(compilation->getJobs(), failCommand); d.ExecuteCompilation(*compilation, failCommand); + if (failCommand.empty()) { llvm::outs() << "Done!\n"; } else { llvm::errs() << "Linking failed!\n"; + failCommand.front().second->Print(llvm::errs(), "\n", false); } } @@ -228,7 +231,7 @@ int main(int argc, char *argv[]) { // default to the current working dir if (outputDir == "-") { llvm::errs() << "Error: The build directory is not set. Did you forget to " - "use '-build-dir'?\n"; + "use '-b'?\n"; return 1; }