Rename symbols in web assembly binary file - c

I need a way to rename certain symbols in a WebAssembly binary archive file that were compiled from C files by emscripten.
When using gcc I can use the objcopy --redefine-sym command, but that gives me objcopy: libname.bc: file format not recognized
I also tried llvm-objcopy, but that gave me llvm-objcopy: error: unsupported object file format
Running llvm-nm did work on it however.
Running file gives libname.bc: WebAssembly (wasm) binary module version 0x1 (MVP)

tldr; I'm not sure there is any easy way to do this today.
Renaming in source code and recompiling is the only way I can think of doing this, and you probably have some reason why you can't do that?
Support for WebAssembly in llvm-objcopy is only partial, and was only added recently: https://reviews.llvm.org/D70970. So some parts of objcopy maybe work with but you would need llvm 11.
However I don't believe --redefine-sym is implemented yet, even on tip of tree.
If this was a normal WebAssembly binary you could just convert it to wat, edit it, and convert it back, but sadly with wasm object files that are extra custom sections that do not survive round trips.

You have the change the names in the export section
https://webassembly.github.io/spec/core/binary/modules.html#binary-exportsec
but if binary editing is to hard then translate your wasm into wabt then you can make the change with text editor and convert back from wabt into wasm

Related

Linking object files of differing types

I am trying to link object files which had originally been created by two different assemblers. We have some legacy assembly code that was compiled into object files using an old MRI assembler for the 68332 processor. We are developing a new application with the GNU Binutils m68k v2.24. We would like to use the original object files as built by the old assembler without change. I have configured our build environment to do this. For historic reasons, our build environment links into three output formats: Srecord, ieee, and ELF. When I run this is succeeding without error for the Srecord and ieee formats. However, for the ELF output format, I receive the following errors:
m68k-elf-ld: failed to merge target specific data of file
As a result the Elf file is not created.
I am first trying to understand what this error message might mean but I was not able to. If anyone knows the GNU Binutils ld documentation enough to point me to where the error definition is defined I would appreciate this.
I have actually loaded our target and run the Srecord output. It seems to pass many tests the same as before so it appears that it is running to some degree.
It looks like our legacy object files may be in coff format format. I would guess that this is the problem. Is there any way to convert a coff file to ELF format?
Thanks in advance for any support.
It looks like our legacy object files may be in coff format format. I would guess that this is the problem. Is there any way to convert a coff file to ELF format?
objcopy can be used to convert between formats. However, to do this it has to have been configured to understand both formats. You can check what formats it accepts with objcopy --info (a shortened list appears at the end of objcopy --help).
If you objcopy doesn't support the required formats, then you'll have to build binutils yourself.

Compiling object file from an intermediate file of gcc

By using the -fdump-tree-* flag , one can dump some intermediate format file during compilation of a source code file. My question is if one can use that intermediate file as an input to gcc to get the final object file.
I'm asking this because I want to add some code to the intermediate file of the gimple (obtained by using the flag -fdump-tree-gimple) format. Sure I can use hooks and add my own pass, but I don't want to get to that level of complexity yet. I just want to give gcc my modified intermediate file, so it can start its compilation from there and give me the final object file. Any ideas how to achieve this?
GIMPLE was a binary internal format which is hard to dump fully and reload back correctly. Comparing with LLVM, LLVM IR was designed to be dumpable and reloadable into usual file (text and binary format of such files are fully-convertible from each to other). You can run Clang fronted to emit LLVMIR, then start opt program with some optimizations, then with other, and there will be LLVM IR bitcode files between phases. And then you can start codegeneration from IR bitcode into native code (even, in theory, into not the same platform, see PNaCl project).
There are some projects of dumping/reloading internal representation of GCC. I know such project was created to integrate gcc with commercial compiler tool. The author can't just link commercial code with gcc, because gcc is VIRAL (it will infect any linked code with anti-commercial GPL). So, author wrote a GPL dumper/loader of GIMPLE to some external (xml) format; the proprietary tool was able to read and translate this XML into other XML of the same format and then it was reloaded back with GPL tool.
In newer gcc you have an option of writing a plugin, which is VIRAL (23.2.1) in terms of GPL. Plugin will operate on in-memory representation of program and there will be no problem of dumping/reloading GIMPLE via external file.
There are some plugins which may be configured/may use user-supplied program, e.g MELT (Lisp) and GCC Python (Python). Some list of gcc plugins is there
There's no built-in facility to translate the text GIMPLE representation back to original GIMPLE internal representation.
You'll need to use custom front-end (such as suggested GIMPLE FE) to make sense of dumped GIMPLE.

Using PARI library for C

I've got all the source code for PARI, but i'm not sure how to use it/generate the pari library. Up to now, i've had to add a couple header files for things such as complex numbers using #include <complex.h>, so I figure it is the same idea for using PARI.
I add pari.h's path in my compiler and #include <pari.h> works, but creates a massive list of other errors including mostly "expected ')' before numeric constant" inside of paricfg.h.
I'm definitely doing it wrong. I know there's some semi-automated way to create a library file to import in using linux commands, but i'm using windows, and i'm not sure I can run the necessary files via cmd.
How can i utilize PARI?
Did you build the library before trying to use it? If you didn't, take a look at the INSTALL file or one of the README files.
To be able to build this type of library on Windows you'll need either MinGW or Cygwin. Although after a quick look at the README.WIN file, MinGW seems to be out of the question. You might also want to consider installing a Linux distro in a VM and using that to build and run your application.

Can text documents and other files get packaged into C executable

My C application relies on some files to copy over. Will the files be contained in the executable and not as stand-alone files? Would it have to be linked statically? I am using Eclipse CDT if it matters.
There are several ways you can link file data into an executable. A platform like Windows allows you to link data into an executable as a "resource" and provides APIs to access those resources (this is how icons and other objects are bound into a Windows executable). This is probably the best way to do it if your platform supports it - support for it is built right into the IDEs.
At a lower level, you might be able to use the linker to directly link a file into an executable as an addressable object:
Embedding binary blobs using gcc mingw
And finally, if you're dealing with a more primitive system like some embedded platforms, you can run your file through something that converts it into source for C array of bytes:
Embed image in code, without using resource section or external images
Unless you do something special, no, the files will not be included in your executable. Is there a reason you can't distribute the text files with your application?
If you want to bake the files into your executable, you can bake them in constant strings:
const char myTextFileData[] = "the text of the file goes here";
Of course, you'll have to preprocess your text files into C source files (remembering to properly escape quotes, backslashes, newlines, and other control characters). Alternatively you can use a tool such as objcopy to convert the file data directly into an object file and then link that object file into your executable.
No. The executable contains only the output from the compiler and linker. Any ancillary files your program requires must be packaged separately.

How to visualise a graph of C structs that contain / point to one another?

I am using Ubuntu 10.04, and studying programming of kernel objects.
I have come across some rather complicated structs which I have difficulties reading, so I thought I'd try to find some tool that can help me visualise them.
Only thing I could find so far is VCG, which has a C Struct Visualization Example, which looks like this:
which looks like something I'd like to use.
First thing, is that the last VCG packaged for Ubuntu is vcg (1.30debian-6) in hardy - but the .deb package can be downloaded and installed in Ubuntu Lucid without problems.
However, it seems this package is only a VCG viewer (similar to vcgviewer, I'd guess). The vcgviewer page notes:
To generate compiler graph data with newest gcc compilers use:
gcc -g -da -dv -fdump-tree-original-raw -fdump-tree-all-all
So, apparently I'd have to use those switches along with gcc while compiling, to generate .vcg graph files from the C source.
The problem, however, is that I'm building a kernel module, which only references the Linux headers - as I try to avoid as much as I can the recompilation of entire kernel. And it seems, as soon as I try to use -fdump-tree-... switches in that context (kernel module), gcc wants to start compiling the rest of the kernel too! (and obviously fails, in both compilation and generation of .vcg graphs - as I don't have the kernel sources, only headers)
So my question is - is there a tool, that would produce .vcg or .dot graphs of structs - simply using a plain text header file as input? (it would not have to resolve all dependencies - simply those in header files in same directory)
EDIT: it is actually not that important for me that the backend is .vcg or .dot in particular, I mentioned them just because I've found them so far; any sort of software that would allow similar struct visualization, regardless of backend, is welcome :)
PS: Note that if you do not want to use VCG viewers for viewing .vcg graphs, you can convert the .vcg format to a .dot format, and use graphviz instead for the visualisation. What worked for me is to use graph-easy - search.cpan.org for perl - which first got packaged in Ubuntu with Maverick edition, as libgraph-easy-perl (however, the .deb file can - again - be downloaded and installed without problems in Lucid). libgraph-easy-perl installs a graph-easy script, which then allows to do stuff like:
graph-easy test.vcg --as_dot | dot -Tpng -o test.vcg.png
See also "[graphviz-interest] VCG files" and "Diego Novillo - Re: can't find VCG viewer" for another vcg-to-dot script (which, unfortunately, didn't work for me).
I have had good experiences with using doxygen for that task. It is designed to create documentation out of annotated source files, but it can already give you a lot of things without the annotations, including various graphs.
Doxygen uses dot for the graph creation.
I've managed to successfully build a kernel module with vcg generation by doing the following:
Creating a linked copy of the kernel source or header directory using cp -al /usr/src/linux-srcdir /tmp/tmp-srcdir since gcc wants to write to the current working directory.
Adding EXTRA_CFLAGS="-g -da -dv -fdump-tree-original-raw -fdump-tree-all-all" to the make command line eg. -C /tmp/tmp-srcdir M=pwdEXTRA_CFLAGS="-g -da -dv -fdump-tree-original-raw -fdump-tree-all-all". the vcg files are generated in /tmp/tmp-srcdir

Resources