diff --git a/bolt/CMakeLists.txt b/bolt/CMakeLists.txt index cfb1a91da32b..fc75bcbe9844 100644 --- a/bolt/CMakeLists.txt +++ b/bolt/CMakeLists.txt @@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} CodeGen Core + DebugInfoDWARF MC MCDisassembler MCParser diff --git a/bolt/Exceptions.cpp b/bolt/Exceptions.cpp index 6722d96aafd9..18988669853e 100644 --- a/bolt/Exceptions.cpp +++ b/bolt/Exceptions.cpp @@ -45,119 +45,6 @@ PrintExceptions("print-exceptions", } // namespace opts -namespace { - -/// Read an unsigned LEB128 value from data, advancing it past the value. -uintptr_t readULEB128(const uint8_t *&Data) { - uintptr_t Result = 0; - uintptr_t Shift = 0; - unsigned char Byte; - - do { - Byte = *Data++; - Result |= (Byte & 0x7f) << Shift; - Shift += 7; - } while (Byte & 0x80); - - return Result; -} - -/// Read a signed LEB128 value from data, advancing it past the value. -uintptr_t readSLEB128(const uint8_t *&Data) { - uintptr_t Result = 0; - uintptr_t Shift = 0; - unsigned char Byte; - - do { - Byte = *Data++; - Result |= (Byte & 0x7f) << Shift; - Shift += 7; - } while (Byte & 0x80); - - if ((Byte & 0x40) && (Shift < (sizeof(Result) << 3))) { - Result |= (~0 << Shift); - } - - return Result; -} - -/// Read and return a T from data, advancing it past the read item. -template -T readValue(const uint8_t *&Data) { - T Val; - memcpy(&Val, Data, sizeof(T)); - Data += sizeof(T); - return Val; -} - -/// Read an encoded DWARF value from data, advancing it past any data read. This -/// function was adapted from the ExceptionDemo.cpp example in llvm. -uintptr_t readEncodedPointer(const uint8_t *&Data, uint8_t Encoding) { - uintptr_t Result = 0; - auto const Start = Data; - - if (Encoding == DW_EH_PE_omit) - return Result; - - // first get value - switch (Encoding & 0x0F) { - case DW_EH_PE_absptr: - Result = readValue(Data); - break; - case DW_EH_PE_uleb128: - Result = readULEB128(Data); - break; - case DW_EH_PE_sleb128: - Result = readSLEB128(Data); - break; - case DW_EH_PE_udata2: - Result = readValue(Data); - break; - case DW_EH_PE_udata4: - Result = readValue(Data); - break; - case DW_EH_PE_udata8: - Result = readValue(Data); - break; - case DW_EH_PE_sdata2: - Result = readValue(Data); - break; - case DW_EH_PE_sdata4: - Result = readValue(Data); - break; - case DW_EH_PE_sdata8: - Result = readValue(Data); - break; - default: - llvm_unreachable("not implemented"); - } - - // then add relative offset - switch (Encoding & 0x70) { - case DW_EH_PE_absptr: - // do nothing - break; - case DW_EH_PE_pcrel: - Result += reinterpret_cast(Start); - break; - case DW_EH_PE_textrel: - case DW_EH_PE_datarel: - case DW_EH_PE_funcrel: - case DW_EH_PE_aligned: - default: - llvm_unreachable("not implemented"); - } - - // then apply indirection - if (Encoding & 0x80 /*DW_EH_PE_indirect*/) { - Result = *((uintptr_t*)Result); - } - - return Result; -} - -} // namespace - // readLSDA is reading and dumping the whole .gcc_exception_table section // at once. // diff --git a/bolt/llvm-flo.cpp b/bolt/llvm-flo.cpp index 238e0b6d08bd..02ba000f4943 100644 --- a/bolt/llvm-flo.cpp +++ b/bolt/llvm-flo.cpp @@ -19,6 +19,7 @@ #include "DataReader.h" #include "Exceptions.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" @@ -105,6 +106,10 @@ static cl::opt DumpData("dump-data", cl::desc("dump parsed flo data and exit (debugging)"), cl::Hidden); +static cl::opt +DumpEHFrame("dump-eh-frame", cl::desc("dump parsed .eh_frame (debugging)"), + cl::Hidden); + static cl::opt PrintAll("print-all", cl::desc("print functions after each stage"), cl::Hidden); @@ -464,6 +469,13 @@ static void OptimizeFile(ELFObjectFileBase *File, const DataReader &DR) { } } + // Process debug sections. + std::unique_ptr DwCtx(new DWARFContextInMemory(*File)); + if (opts::DumpEHFrame) { + const auto *Frames = DwCtx->getEHFrame(); + Frames->dump(outs()); + } + // Disassemble every function and build it's control flow graph. for (auto &BFI : BinaryFunctions) { BinaryFunction &Function = BFI.second;