Example #1
0
std::string JITDebugRegisterer::MakeELF(const Function *F, DebugInfo &I) {
    // Stack allocate an empty module with an empty LLVMContext for the ELFWriter
    // API.  We don't use the real module because then the ELFWriter would write
    // out unnecessary GlobalValues during finalization.
    LLVMContext Context;
    Module M("", Context);

    // Make a buffer for the ELF in memory.
    std::string Buffer;
    raw_string_ostream O(Buffer);
    ELFWriter EW(O, TM);
    EW.doInitialization(M);

    // Copy the binary into the .text section.  This isn't necessary, but it's
    // useful to be able to disassemble the ELF by hand.
    ELFSection &Text = EW.getTextSection(const_cast<Function *>(F));
    Text.Addr = (uint64_t)I.FnStart;
    // TODO: We could eliminate this copy if we somehow used a pointer/size pair
    // instead of a vector.
    Text.getData().assign(I.FnStart, I.FnEnd);

    // Copy the exception handling call frame information into the .eh_frame
    // section.  This allows GDB to get a good stack trace, particularly on
    // linux x86_64.  Mark this as a PROGBITS section that needs to be loaded
    // into memory at runtime.
    ELFSection &EH = EW.getSection(".eh_frame", ELF::SHT_PROGBITS,
                                   ELF::SHF_ALLOC);
    // Pointers in the DWARF EH info are all relative to the EH frame start,
    // which is stored here.
    EH.Addr = (uint64_t)I.EhStart;
    // TODO: We could eliminate this copy if we somehow used a pointer/size pair
    // instead of a vector.
    EH.getData().assign(I.EhStart, I.EhEnd);

    // Add this single function to the symbol table, so the debugger prints the
    // name instead of '???'.  We give the symbol default global visibility.
    ELFSym *FnSym = ELFSym::getGV(F,
                                  ELF::STB_GLOBAL,
                                  ELF::STT_FUNC,
                                  ELF::STV_DEFAULT);
    FnSym->SectionIdx = Text.SectionIdx;
    FnSym->Size = I.FnEnd - I.FnStart;
    FnSym->Value = 0;  // Offset from start of section.
    EW.SymbolList.push_back(FnSym);

    EW.doFinalization(M);
    O.flush();

    // When trying to debug why GDB isn't getting the debug info right, it's
    // awfully helpful to write the object file to disk so that it can be
    // inspected with readelf and objdump.
    if (JITEmitDebugInfoToDisk) {
        std::string Filename;
        raw_string_ostream O2(Filename);
        O2 << "/tmp/llvm_function_" << I.FnStart << "_" << F->getNameStr() << ".o";
        O2.flush();
        std::string Errors;
        raw_fd_ostream O3(Filename.c_str(), Errors);
        O3 << Buffer;
        O3.close();
    }

    return Buffer;
}
Example #2
0
File: pkcs1.c Project: zlxy/plan9
/*
 * Hash OIDs
 *
 * SHA1 = 1.3.14.3.2.26
 * MDx = 1.2.840.113549.2.x
 */
#define O0(a,b)	((a)*40+(b))
#define O2(x)	\
	(((x)>>7)&0x7F)|0x80, \
	((x)&0x7F)
#define O3(x)	\
	(((x)>>14)&0x7F)|0x80, \
	(((x)>>7)&0x7F)|0x80, \
	((x)&0x7F)
uchar oidsha1[] = { O0(1, 3), 14, 3, 2, 26 };
uchar oidmd2[] = { O0(1, 2), O2(840), O3(113549), 2, 2 };
uchar oidmd5[] = { O0(1, 2), O2(840), O3(113549), 2, 5 };

/*
 *	DigestInfo ::= SEQUENCE {
 *		digestAlgorithm AlgorithmIdentifier,
 *		digest OCTET STRING
 *	}
 *
 * except that OpenSSL seems to sign
 *
 *	DigestInfo ::= SEQUENCE {
 *		SEQUENCE{ digestAlgorithm AlgorithmIdentifier, NULL }
 *		digest OCTET STRING
 *	}
 *