How to print the compiled instructions in V8 engine? - v8

I have compiled the v8_hello_world sample and it could print "hello world" in the console. I know that V8 compiles the JavaScript with JIT, but I want to print the detailed message such as instructions it compiled. And I also want to know the types of these instructions, so what should I do?
Thank you very much~

Depending on the type(s) of generated code you're interested in, you'll have to pass the corresponding flag(s) to V8:
--print-code prints unoptimized machine code (created by "full codegen", the unoptimizing compiler)
--print-bytecode prints bytecode (created by the "Ignition" interpreter)
--print-opt-code prints optimized machine code (created by either the "Crankshaft" or "TurboFan" optimizing compilers)
These flags (and many others) are documented by --help. Since major changes to the execution pipeline are currently ongoing, depending on which version of V8 you're using, you might see the same function compiled by different compilers.
If you use the developer shell d8, you can pass these flags directly on the command-line. In your own embedding application, you can use v8::V8::SetFlagsFromCommandLine to pass argc and argv to V8. In d8.cc you can see an example for how to handle some flags yourself and pass on others to V8.
Update one year later: "full codegen" and "Crankshaft" are gone. --print-bytecode still prints bytecode, --print-opt-code prints optimized machine code (now always from "Turbofan"). --print-code has less to do than before, but is still useful for generated regexp code and wasm code.

Related

Unable to view symbols when debugging GNU Fortran in LLDB

This is a follow-up question to a question posted previously on stack overflow.
When I compile with the -g (or -gdwarf-2) flag in GNU Fortran (GNU Fortran (MacPorts gcc5 5.3.0_0) 5.3.0) I am unable to examine symbols. If I use the "frame variable" command I do not get the list of local variables. If I use the "print" command with a symbol, nothing is printed.
I can get breakpoints to work by using the appropriate name (I look at the output from nm to get the mangled name). The source code is displayed in the debugger, so lldb is understanding at least some of the debugging information.
lldb has no support for Fortran at present. In particular, since lldb relies on the clang/swift type system representations, which also don't support Fortran, the expression parser won't work at all. There is Go support that gets frame variable working without having to make a full Go clang frontend. That same path could be followed to get some Fortran support. But there's nobody working on this that I am aware of.

How to compile P4 from source code?

I am a student in Computer Science, and I am learning programming with Pascal.
I have found an interesting Pascal compiler, P4 (http://homepages.cwi.nl/~steven/pascal/).
To know more about Pascal, I am trying to compile their source code, but I failed.
In this web page, they said:
Compile pcom.p and pint.p with a Pascal compiler. You obviously have to have a Pascal compiler already. This gives you a Pascal compiler (pcom) that produces P4 code, and an interpreter (pint) that runs P4 code.
To use the compiler, run pcom with the Pascal program as standard input. This produces any diagnostics on standard output, and its code on a Pascal file that is called prr. Check with your Pascal compiler how this gets assigned to a file in the filestore. You may have to change the lines 'rewrite(prr)' in pcom.p and pint.p and 'reset(prd)' in pint.p for your compiler, for instance to "rewrite(prr, 'prr')" etc.
To run the resulting code, run pint with the prr output produced by pcom as input for the file 'prd', and input for the compiled Pascal program on standard input.
I have compiled it with Free Pascal (on https://ideone.com/), but failed too.
Free Pascal Compiler version 2.6.4+dfsg-4 [2014/10/14] for i386
Copyright (c) 1993-2014 by Florian Klaempfl and others
Target OS: Linux for i386
Compiling pcom.p
pcom.p(1,3) Warning: Unsupported switch "$L"
pcom.p(88,23) Fatal: Syntax error, ":" expected but ")" found
Fatal: Compilation aborted
Error: /usr/bin/ppc386 returned an error exitcode (normal if you did not specify a source file to be compiled)
I don't know how to compile this source code in Windows machine, because I know Pascal language only.
Can I compile it with Turbo Pascal (without any requirement) on Windows XP? Can you remove some part of script for Pascal compiling only?
Free Pascal's Florian has been working getting Scott Moore's P5 compiler (which is a P4 compiler accepting a larger subset of Pascal) to work with FPC's ISO mode for old sources. However it will work (mostly) only in development versions (including the upcoming "stable" branch 3.0.x).
I tried last summer and it compiled and generally worked with FPC 3.x and the -Miso parameter (to select ISO style dialects). IIRC the last thing fixed was ISO style parameter transfer.
I quickly tried the referenced P4 compiler version and it seems to stumble on a few spots with "comment this" comments related to switching back and fro from ISO Mode. If I comment those files, pint compiles. (and then you could run the original bytecode if necessary)
pcom then still stumbles on taking the ord() of a pointer, which is obviously not very portable either, but unfortunately with 20+ occurrences that have to be replaced with ord(ptrint()).
pcom still doesn't compile then, FPC doesn't like passing union fields to VAR parameters. Working around that with a variable and the source compiles, 15 minutes total.
The fixed sourcecode with extra mode statements is at http://www.stack.nl/~marcov/files/p4fixed.zip but requires (as yet unreleased) FPC 3.0 or newer.
The resulting EXE binary can compile the original pcom source to bootstrap itself to bytecode.
You want to get an ISO 7185 compliant compiler to compile that. It is true that Pascal-P4 (the proper name) was written prior to the ISO 7185 standard. However, the adaption to the standard is generally less of a change set than adaption to a dielect.
You will find that work already done and documented at:
http://sourceforge.net/projects/pascalp4/
It specifies use of GPC. However, as Marco said, it is possible with more work to adapt to FPC, and I believe the FPC folks are improving the ISO 7185 capability of their compiler.
Having said that, I'm not sure why Pascal-P4 would be an interesting target. Pascal-P4 was a subset compiler, meaning an incomplete implementation of Pascal. You will find a complete implementation as Pascal-P5:
http://sourceforge.net/projects/pascalp5/
And I believe it has less portability issues as well.
Good luck.

Can I mix arm-eabi with arm-elf?

I have a product which bootloader and application are compiled using a compiler (gnuarm GCC 4.1.1) that generates "arm-elf".
The bootloader and application are segregated in different FLASH memory areas in the linker script.
The application has a feature that enables it to call the bootloader (as a simple c-function with 2 parameters).
I need to be able to upgrade existing products around the world, and I can safely do this using always the same compiler.
Now I'd like to be able to compile this product application using a new GCC version that outputs arm-eabi.
Everything will be fine for new products, where both application and bootloader are compiled using the same toolchain, but what happens with existing products?
If I flash a new application, compiled with GCC 4.6.x and arm-none-eabi, will my application still be able to call the bootloader function from the old arm-elf bootloader?
Furthermore, not directly related to the above question, can I mix object files compiled with arm-elf into a binary compiled with arm-eabi?
EDIT:
I think is good to make clear I am building for a bare metal ARM7, if it makes any difference...
No. An ABI is the magic that makes binaries compatible. The Application Binary Interface determines various conventions on how to communicate with other libraries/applications. For example, an ABI will define calling convention, which makes implicit assumptions about things like which registers are used for passing arguments to C functions, and how to deal with excess arguments.
I don't know the exact differences between EABI and ABI, but you can find some of them by reading up on EABI. Debian's page mentions the syscall convention is different, along with some alignment changes.
Given the above, of course, you cannot mix arm-elf and arm-eabi objects.
The above answer is given on the assumption that you talk to the bootloader code in your main application. Given that the interface may be very simple (just a function call with two parameters), it's possible that it might work. It'd be an interesting experiment to try. However, it is not ** guaranteed** to work.
Please keep in mind you do not have to use EABI. You can generate an arm-elf toolchain with gcc 4.6 just as well as with older versions. Since you're using a binary toolchain on windows, you may have more of a challenge. I'd suggest investigating crosstool-ng, which works quite well on Linux, and may work okay on cygwin to build the appropriate toolchain.
There is always the option of making the call to bootloader in inline assembly, in which case you can adhere to any calling standard you need :).
However, besides the portability issue it introduces, this approach will also make two assumptions about your bootloader and application:
you are able to detect in your app that a particular device has a bootloader built with your non-EABI toolchain, as you can only call the older type bootloader using the assembly code.
the two parameters you mentioned are used as primitive data by your bootloader. Should the bootloader use them, for example, as pointers to structs then you could be facing issues with incorrect alignment, padding and so forth.
I Think that this will be OK. I did a migration something like this myself, from what I remember I only ran into a problem to do with handling division.
This is the best info I can find about the differences, it suggests that if you don't have struct alignment issues, you may be OK.

assembly programming in Emacs how to?

assembly programming in Emacs how to?
I want Emacs to do following things
1. assembling
2. run the just before made program inside Emacs
3. debugging with watching flags and registers as like ollydbg or softice
4. decompile executable file for see what assembly codes are made by c
but I don't know how to do this
could somebody let me know ?
Which operating system (and machine architecture) are you using? I think that's quite essential information for questions about assembly programming.
I'll try to answer your four points anyway:
Just run your assembler (e.g. as) from M-x compile.
Run it from a shell buffer or from shell-command (bound to M-!).
Emacs' built-in graphical debugging support is started with M-x gdb. You may have to look for some external debugger support package if GDB is not suitable for your purposes.
For disassembling object code, I'd use GDB. But I think if you have the C sources, it would be better to compile them with the -S flag to see the assembly code emitted by the compiler instead of what can be reconstructed from the machine code.
Since you mention SoftICE, I'm assuming you're on windows.
(Good old times, by the way. If anybody ever used SoftICE on windows 9x, he/she will know what I mean :)
I don't use Emacs, but here's how to get started:
Get the tools you need to assemble your program (ie: at least, the assembler and the linker). On windows, the MASM package comes with everything you need : http://www.masm32.com/
Figure out wich commands you need to compile a simple hello world.
Configure Emacs so that it runs the above commands for you

Lua compiled scripts on Mac OS X - Intel vs PPC

Been using Lua 5.0 in a Mac OS X universal binary app for some years. Lua scripts are compiled using luac and the compiled scripts are bundled with the app. They have worked properly in Tiger and Leopard, Intel or PPC.
To avoid library problems at the time, I simply added the Lua src tree to my Xcode project and compiled as is, with no problems.
It was time to update to a more modern version of Lua so I replaced my source tree with that of 5.1.4. I rebuilt luac using make macosx (machine is running Leopard on Intel).
Uncompiled scripts work properly in Tiger and Leopard, Intel and PPC, as always.
However, now compiled scripts fail to load on PPC machines.
So I rebuilt luac with the 'ansi' flag, and recompiled my scripts. Same error. Similarly, a build flag of 'generic' produced no joy.
Can anyone please advise on what I can do next?
Lua's compiled scripts are pretty much the raw bytecode dumped out after a short header. The header documents some of the properties of the platform used to compile the bytecode, but the loader only verifies that the current platform has the same properties.
Unfortunately, this creates problems when loading bytecode compiled on another platform, even if compiled by the very same version of Lua. Of course, scripts compiled by different versions of Lua cannot be expected to work, and since the version number of Lua is included in the bytecode header, the attempt to load them is caught by the core.
The simple answer is to just not compile scripts. If Lua compiles the script itself, you only have to worry about possible version mismatches between Lua cores in your various builds of your application, and that isn't hard to deal with.
Actually supporting a full cross compatibility for compiled bytecode is not easy. In that email, Mike Pall identified the following issues:
Endianess: swap on output as needed.
sizeof(size_t), affects huge string constants: check for overflow when
downgrading.
sizeof(int), affectsMAXARG_Bx and MAXARG_sBx: check for overflow when
downgrading.
typeof(lua_Number): easy in C, but only when the host and the target
follow the same FP standard; precision
loss when upgrading (rare case);
warn about non-integer numbers when
downgrading to int32.
From all the discussions that I've seen about this issue on the mailing list, I see two likely viable approaches, assuming that you are unwilling to consider just shipping the uncompiled Lua scripts.
The first would be to fix the byte order as the compiled scripts are loaded. That turns out to be easier to do than you'd expect, as it can be done by replacing the low-level function that reads the script file without recompiling the core itself. In fact, it can even be done in pure Lua, by supplying your own chunk reader function to lua_load(). This should work as long as the only compatibility issue over your platforms is byte order.
The second is to patch the core itself to use a common representation for compiled scripts on all platforms. This has been described as possible by Luiz Henrique de Figueiredo:
....
I'm convinced that the best route to
byte order or cross-compiling is
third-party dump/undump pairs. The
files ldump.c and lundump.c are
completely replaceable; they export a
single, well-defined, entry point. The
format of precompiled chunks is not
sacred at all; you can use any format,
as long as ldump.c and lundump.c agree
about it. (For instance, Rici Lake is
considering writing a text format for
precompiled chunks.)
....
Personally, I'd recommend giving serious consideration to not pre-compiling the scripts and thus avoid the platform portability issues entirely.
Edit: I've updated my description of the bytecode header thanks to lhf's comment. I hadn't read this part of the Lua source yet, and I probably should have checked it before being quite so assertive about what information is or is not present in the header.
Here is the fragment from lundump.c that forms a copy of the header matching the running platform for comparison to the bytecode being loaded. It is simply compared with memcmp() for an exact match to the header from the file, so any mismatch will cause the stock loader (luaU_undump()) to reject the file.
/*
* make header
*/
void luaU_header (char* h)
{
int x=1;
memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
h+=sizeof(LUA_SIGNATURE)-1;
*h++=(char)LUAC_VERSION;
*h++=(char)LUAC_FORMAT;
*h++=(char)*(char*)&x; /* endianness */
*h++=(char)sizeof(int);
*h++=(char)sizeof(size_t);
*h++=(char)sizeof(Instruction);
*h++=(char)sizeof(lua_Number);
*h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
}
As can be seen, the header is 12 bytes long and contains a signature (4 bytes, "<esc>Lua"), version and format codes, a flag byte for endianness, sizes of the types int, size_t, Instruction, and lua_Number, and a flag indicating whether lua_Number is an integral type.
This allows most platform distinctions to be caught, but doesn't attempt to catch every way in which platforms can differ.
I still stand by the recommendations made above: first, ship compilable sources; or second, customize ldump.c and lundump.c to store and load a common format, with the additional note that any custom format should redefine the LUAC_FORMAT byte of the header so as to not be confused with the stock bytecode format.
You may want to use a patched bytecode loader that supports different endianness.
See this.
I would have commented on RBerteig's post, but I apparently don't have enough reputation yet to be able to do so. In working on bringing LuaRPC up to speed with Lua 5.1.x AND making it work with embedded targets, I've been modifying the ldump.c and lundump.c sources to make them both a bit more flexible. The embedded Lua project (eLua) already had some of the patches you can find on the Lua list, but I've added a bit more to make lundump a little more friendly to scripts compiled on different architectures. There's also cross-compilation support provided so that you can build for targets differing from the host system (see luac.c in the same directory as the links below).
If you're interested in checking out the modifications, you can find them in the eLua source repository:
http://svn.berlios.de/wsvn/elua/trunk/src/lua/lundump.c
http://svn.berlios.de/wsvn/elua/trunk/src/lua/lundump.h
http://svn.berlios.de/wsvn/elua/trunk/src/lua/ldump.c
Standard Disclaimer:
I make no claim that the modifications are perfect or work in every situation. If you use it and find anything broken, I'd be glad to hear about it so that it can be fixed.
Lua bytecode is not portable. You should ship source scripts with your application.
If download size is a concern, they are generally shorter than the bytecode form.
If intellectual property is a concern, you can use a code obfuscator, and keep in mind that disassembling Lua bytecode is anything but difficult.
If loading time is a concern, you can precompile the sources locally in your installation script.
I conjecture that you compiled the scripts on an Intel box.
Compiled scripts are wildly unportable. If you really want to precompile scripts, you'll need to include two versions of each compiled script: one for Intel and one for PPC. Your app will have to interrogate which program it's running on and use the correct compiled script.
I don't have enough reputation to comment, so I have to provide this as an answer instead even though it's not an appropriate answer to the question asked. Sorry.
There is an Lua Obfuscator available here:
http://www.capprime.com/CapprimeLuaObfuscator/CapprimeLuaObfuscator.aspx
Full disclosure: I am the author of the obfuscator and I am aware it is not perfect. Feedback is welcome and encouraged (there is a feedback page available from the above page).

Resources