minix/commands/gcov-pull/gcov-pull.c
Gianluca Guida cc17b27a2b Build NetBSD libc library in world in ELF mode.
3 sets of libraries are built now:
  . ack: all libraries that ack can compile (/usr/lib/i386/)
  . clang+elf: all libraries with minix headers (/usr/lib/)
  . clang+elf: all libraries with netbsd headers (/usr/netbsd/)

Once everything can be compiled with netbsd libraries and headers, the
/usr/netbsd hierarchy will be obsolete and its libraries compiled with
netbsd headers will be installed in /usr/lib, and its headers
in /usr/include. (i.e. minix libc and current minix headers set
will be gone.)

To use the NetBSD libc system (libraries + headers) before
it is the default libc, see:
   http://wiki.minix3.org/en/DevelopersGuide/UsingNetBSDCode
This wiki page also documents the maintenance of the patch
files of minix-specific changes to imported NetBSD code.

Changes in this commit:
  . libsys: Add NBSD compilation and create a safe NBSD-based libc.
  . Port rest of libraries (except libddekit) to new header system.
  . Enable compilation of libddekit with new headers.
  . Enable kernel compilation with new headers.
  . Enable drivers compilation with new headers.
  . Port legacy commands to new headers and libc.
  . Port servers to new headers.
  . Add <sys/sigcontext.h> in compat library.
  . Remove dependency file in tree.
  . Enable compilation of common/lib/libc/atomic in libsys
  . Do not generate RCSID strings in libc.
  . Temporarily disable zoneinfo as they are incompatible with NetBSD format
  . obj-nbsd for .gitignore
  . Procfs: use only integer arithmetic. (Antoine Leca)
  . Increase ramdisk size to create NBSD-based images.
  . Remove INCSYMLINKS handling hack.
  . Add nbsd_include/sys/exec_elf.h
  . Enable ELF compilation with NBSD libc.
  . Add 'make nbsdsrc' in tools to download reference NetBSD sources.
  . Automate minix-port.patch creation.
  . Avoid using fstavfs() as it is *extremely* slow and unneeded.
  . Set err() as PRIVATE to avoid name clash with libc.
  . [NBSD] servers/vm: remove compilation warnings.
  . u32 is not a long in NBSD headers.
  . UPDATING info on netbsd hierarchy
  . commands fixes for netbsd libc
2011-06-24 11:46:30 +02:00

133 lines
3 KiB
C

/*
* gcov-pull - Request gcov data from server and write it to gcda files
* Author: Anton Kuijsten
*/
#include <fcntl.h>
#include <stdio.h>
#include <lib.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#ifndef __NBSD_LIBC
#include <alloca.h>
#endif
#include <string.h>
#include <assert.h>
#include <minix/gcov.h>
#define BUFF_SZ (4 * 1024 * 1024) /* 4MB */
int read_int(void);
char *buff_p;
/* helper function to read int from the buffer */
int read_int(void)
{
int res;
memcpy(&res, buff_p, sizeof(int));
buff_p += sizeof(int);
return res;
}
int main(int argc, char *argv[])
{
FILE *fd = NULL;
int i, server_nr, command, size, result;
char buff[BUFF_SZ]; /* Buffer for all the metadata and file data sent */
message msg; /* message sent to vfs */
if(argc!=2 || sscanf(argv[1], "%d", &server_nr)!=1) {
fprintf(stderr, "Usage: %s <pid>\n", argv[0]);
return 1;
}
/*
When making a GCOV call to a server, the gcov library linked into
the server will try to write gcov data to disk. This writing is
normally done with calls to the vfs, using stdio library calls.
This is not correct behaviour for servers, especially vfs itself.
Therefore, the server catches those attempts. The messages used for
this communication are stored in a buffer. When the gcov operation
is done, the buffer is copied from the server to this user space,
from where the calls are finally made to the vfs. GCOV calls to the
various servers are all routed trough vfs. For more information, see
the <minix/gcov.h> header file.
*/
/* visit complete buffer, so vm won't has to
manage the pages while flushing
*/
memset(buff, 'a', sizeof(buff));
buff_p = buff;
result = gcov_flush_svr(buff_p, BUFF_SZ, server_nr);
if(result >= BUFF_SZ) {
fprintf(stderr, "Too much data to hold in buffer: %d\n", result);
fprintf(stderr, "Maximum: %d\n", BUFF_SZ);
return 1;
}
if(result < 0) {
fprintf(stderr, "Call failed\n");
return 1;
}
/* At least GCOVOP_END opcode expected. */
if(result < sizeof(int)) {
fprintf(stderr, "Invalid gcov data from pid %d\n", server_nr);
return 1;
}
/* Only GCOVOP_END is valid but empty. */
if(result == sizeof(int)) {
fprintf(stderr, "no gcov data.\n");
return 0;
}
/* Iterate through the system calls contained in the buffer,
* and execute them
*/
while((command=read_int()) != GCOVOP_END) {
char *fn;
switch(command) {
case GCOVOP_OPEN:
size = read_int();
fn = buff_p;
if(strchr(fn, '/')) {
fn = strrchr(fn, '/');
assert(fn);
fn++;
}
assert(fn);
if(!(fd = fopen(fn, "w+"))) {
perror(buff_p);
exit(1);
}
buff_p += size;
break;
case GCOVOP_CLOSE:
if(!fd) {
fprintf(stderr, "bogus close\n");
exit(1);
}
fclose(fd);
fd = NULL;
break;
case GCOVOP_WRITE:
size = read_int();
fwrite(buff_p, size, 1, fd);
buff_p += size;
break;
default:
fprintf(stderr, "bogus command %d in buffer.\n",
command);
exit(1);
}
}
return 0;
}