예제 #1
0
파일: codegen.cpp 프로젝트: lameiro/pyston
    virtual void NotifyObjectEmitted(const llvm::object::ObjectFile& Obj,
                                     const llvm::RuntimeDyld::LoadedObjectInfo& L) {
        static StatCounter code_bytes("code_bytes");
        code_bytes.log(Obj.getData().size());

        llvm_error_code code;
        for (const auto& sym : Obj.symbols()) {
            llvm::object::section_iterator section(Obj.section_end());
            code = sym.getSection(section);
            assert(!code);
            bool is_text;
#if LLVMREV < 219314
            code = section->isText(is_text);
            assert(!code);
#else
            is_text = section->isText();
#endif
            if (!is_text)
                continue;

            llvm::StringRef name;
            code = sym.getName(name);
            assert(!code);
            uint64_t size;
            code = sym.getSize(size);
            assert(!code);

            if (name == ".text")
                continue;


            uint64_t sym_addr = L.getSymbolLoadAddress(name);
            assert(sym_addr);

            g.func_addr_registry.registerFunction(name.data(), (void*)sym_addr, size, NULL);
        }
    }
예제 #2
0
    virtual void NotifyObjectEmitted(const llvm::object::ObjectFile& Obj,
                                     const llvm::RuntimeDyld::LoadedObjectInfo& L) {
        std::unique_ptr<llvm::DIContext> Context(llvm::DIContext::getDWARFContext(Obj));

        assert(g.cur_cf);

        uint64_t func_addr = 0; // remains 0 until we find a function

        // Search through the symbols to find the function that got JIT'ed.
        // (We only JIT one function at a time.)
        for (const auto& sym : Obj.symbols()) {
            llvm::object::SymbolRef::Type SymType;
            if (sym.getType(SymType) || SymType != llvm::object::SymbolRef::ST_Function)
                continue;

            llvm::StringRef Name;
            uint64_t Size;
            if (sym.getName(Name) || sym.getSize(Size))
                continue;

            // Found a function!
            assert(!func_addr);
            func_addr = L.getSymbolLoadAddress(Name);
            assert(func_addr);

// TODO this should be the Python name, not the C name:
#if LLVMREV < 208921
            llvm::DILineInfoTable lines = Context->getLineInfoForAddressRange(
                func_addr, Size, llvm::DILineInfoSpecifier::FunctionName | llvm::DILineInfoSpecifier::FileLineInfo
                                     | llvm::DILineInfoSpecifier::AbsoluteFilePath);
#else
            llvm::DILineInfoTable lines = Context->getLineInfoForAddressRange(
                func_addr, Size,
                llvm::DILineInfoSpecifier(llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
                                          llvm::DILineInfoSpecifier::FunctionNameKind::LinkageName));
#endif
            if (VERBOSITY() >= 3) {
                for (int i = 0; i < lines.size(); i++) {
                    printf("%s:%d, %s: %lx\n", lines[i].second.FileName.c_str(), lines[i].second.Line,
                           lines[i].second.FunctionName.c_str(), lines[i].first);
                }
            }

            assert(g.cur_cf->code_start == 0);
            g.cur_cf->code_start = func_addr;
            g.cur_cf->code_size = Size;
            cf_registry.registerCF(g.cur_cf);
        }

        assert(func_addr);

        // Libunwind support:
        bool found_text = false, found_eh_frame = false;
        uint64_t text_addr = -1, text_size = -1;
        uint64_t eh_frame_addr = -1, eh_frame_size = -1;

        for (const auto& sec : Obj.sections()) {
            llvm::StringRef name;
            llvm_error_code code = sec.getName(name);
            assert(!code);

            uint64_t addr, size;
            if (name == ".eh_frame") {
                assert(!found_eh_frame);
                eh_frame_addr = L.getSectionLoadAddress(name);
                eh_frame_size = sec.getSize();

                if (VERBOSITY() >= 2)
                    printf("eh_frame: %lx %lx\n", eh_frame_addr, eh_frame_size);
                found_eh_frame = true;
            } else if (name == ".text") {
                assert(!found_text);
                text_addr = L.getSectionLoadAddress(name);
                text_size = sec.getSize();

                if (VERBOSITY() >= 2)
                    printf("text: %lx %lx\n", text_addr, text_size);
                found_text = true;
            }
        }

        assert(found_text);
        assert(found_eh_frame);
        assert(text_addr == func_addr);

        registerDynamicEhFrame(text_addr, text_size, eh_frame_addr, eh_frame_size);
    }