jos-style Makefrags and directories

上级 451f323d
#
# XXX compiling user progs with -mcmodel=kernel
#
# Custom config file? Otherwise use defaults. # Custom config file? Otherwise use defaults.
-include config.mk -include config.mk
Q ?= @ Q ?= @
...@@ -30,159 +26,47 @@ NM = $(TOOLPREFIX)nm ...@@ -30,159 +26,47 @@ NM = $(TOOLPREFIX)nm
OBJCOPY = $(TOOLPREFIX)objcopy OBJCOPY = $(TOOLPREFIX)objcopy
STRIP = $(TOOLPREFIX)strip STRIP = $(TOOLPREFIX)strip
# XXX(sbw)
# -nostdinc -nostdinc++
COMFLAGS = -static -fno-builtin -fno-strict-aliasing -O2 -Wall \ COMFLAGS = -static -fno-builtin -fno-strict-aliasing -O2 -Wall \
-g -MD -m64 -Werror -fms-extensions -mno-sse \ -g -MD -m64 -Werror -fms-extensions -mno-sse \
-mcmodel=large -mno-red-zone -I$(QEMUSRC) -fno-omit-frame-pointer \ -mno-red-zone -Iinclude -I$(QEMUSRC) -fno-omit-frame-pointer \
-DHW_$(HW) -include param.h -include compiler.h -DXV6 -DHW_$(HW) -include param.h -include include/compiler.h -DXV6
COMFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector) COMFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
CFLAGS := $(COMFLAGS) -std=c99 $(CFLAGS) CFLAGS := $(COMFLAGS) -std=c99 $(CFLAGS)
CXXFLAGS := $(COMFLAGS) -std=c++0x -Wno-sign-compare -fno-exceptions -fno-rtti $(CXXFLAGS) CXXFLAGS := $(COMFLAGS) -std=c++0x -Wno-sign-compare -fno-exceptions -fno-rtti $(CXXFLAGS)
ASFLAGS = -m64 -gdwarf-2 -MD ASFLAGS = -Iinclude -m64 -gdwarf-2 -MD
LDFLAGS = -m elf_x86_64 LDFLAGS = -m elf_x86_64
OBJS = \ all:
async.o \
bio.o \ include net/Makefrag
bootdata.o \ include lib/Makefrag
cga.o \ include bin/Makefrag
cilk.o \ include kernel/Makefrag
condvar.o \ include tools/Makefrag
console.o \
cpprt.o \
crange.o \
e1000.o \
exec.o \
file.o \
fmt.o \
fs.o \
ioapic.o \
lapic.o \
hwvm.o \
hz.o \
kalloc.o \
kmalloc.o \
kbd.o \
main.o \
memide.o \
mp.o \
net.o \
pci.o \
picirq.o \
pipe.o \
proc.o \
prof.o \
gc.o \
rnd.o \
sampler.o \
sched.o \
spinlock.o \
swtch.o \
string.o \
syscall.o \
sysfile.o \
sysproc.o \
uart.o \
vm.o \
trap.o \
trapasm.o \
wq.o \
incbin.o
OBJS := $(addprefix $(O)/, $(OBJS))
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o
ULIB := $(addprefix $(O)/, $(ULIB))
UPROGS= \
_cat \
_echo \
_init \
_forkexectree \
_forkexecbench \
_forktree \
_login \
_ls \
_mapbench \
_maptest \
_sh \
_thrtest \
_halt \
_time \
_sleep \
_dirbench \
_usertests \
_lockstat \
_preadtest \
_perf
UPROGS := $(addprefix $(O)/, $(UPROGS))
all: $(O)/kernel
include net.mk
$(O)/kernel: $(O) $(O)/boot.o $(OBJS)
@echo " LD $@"
$(Q)$(LD) $(LDFLAGS) -T kernel.ld -z max-page-size=4096 -e start \
-o $@ $(O)/boot.o $(OBJS)
$(O):
$(Q)mkdir $(O)
$(Q)mkdir $(O)/net
$(O)/%.o: %.c $(O)/%.o: %.c
@echo " CC $@" @echo " CC $@"
$(Q)mkdir -p $(@D)
$(Q)$(CC) $(CFLAGS) -c -o $@ $< $(Q)$(CC) $(CFLAGS) -c -o $@ $<
$(O)/%.o: %.cc $(O)/%.o: %.cc
@echo " CXX $@" @echo " CXX $@"
$(Q)$(CXX) $(CXXFLAGS) -c -o $@ $< $(Q)mkdir -p $(@D)
$(Q)$(CXX) $(CXXFLAGS) $(XXFLAGS) -c -o $@ $<
$(O)/incbin.o: ASFLAGS+=-DMAKE_OUT=$(O)
$(O)/incbin.o: $(O)/initcode $(O)/bootother $(O)/fs.img
$(O)/%.o: %.S
@echo " CC $@"
$(Q)$(CC) $(ASFLAGS) -c -o $@ $<
$(O)/initcode: TTEXT = 0x0
$(O)/bootother: TTEXT = 0x7000
$(O)/%: %.S
@echo " CC $@"
$(Q)$(CC) $(CFLAGS) -nostdinc -I. -c $< -o $@.o
$(Q)$(LD) $(LDFLAGS) -N -e start -Ttext $(TTEXT) -o $@.out $@.o
$(Q)$(OBJCOPY) -S -O binary $@.out $@
xv6memfs.img: bootblock kernelmemfs xv6memfs.img: bootblock kernelmemfs
dd if=/dev/zero of=xv6memfs.img count=10000 dd if=/dev/zero of=xv6memfs.img count=10000
dd if=bootblock of=xv6memfs.img conv=notrunc dd if=bootblock of=xv6memfs.img conv=notrunc
dd if=kernelmemfs of=xv6memfs.img seek=1 conv=notrunc dd if=kernelmemfs of=xv6memfs.img seek=1 conv=notrunc
$(O)/_%.unstripped: $(O)/%.o $(ULIB) $(O)/fs.img: $(O)/tools/mkfs README $(UPROGS)
@echo " LD $@"
$(Q)$(LD) $(LDFLAGS) -N -e main -Ttext 0x100000 -o $@ $^
$(O)/_%: $(O)/_%.unstripped
@echo " STRIP $@"
$(Q)$(STRIP) -o $@ $<
$(O)/mkfs: mkfs.c fs.h
gcc -m32 -Werror -Wall -o $@ mkfs.c
$(O)/perf-report: perf-report.cc sampler.h
$(CXX) -std=c++0x -m64 -Werror -Wall -o $@ perf-report.cc
$(O)/fs.img: $(O)/mkfs README $(UPROGS)
@echo " MKFS $@" @echo " MKFS $@"
$(Q)$(O)/mkfs $@ README $(UPROGS) $(Q)$(O)/tools/mkfs $@ README $(UPROGS)
mscan.syms: $(O)/kernel
$(NM) -S $< > $@
mscan.kern: $(O)/kernel
cp $< $@
-include *.d .PRECIOUS: $(O)/%.o
-include $(O)/*.d
.PRECIOUS: $(O)/%.o $(O)/_%.unstripped
.PHONY: clean qemu gdb rsync .PHONY: clean qemu gdb rsync
## ##
...@@ -192,14 +76,20 @@ QEMUOPTS = -smp $(QEMUSMP) -m 512 -serial mon:stdio -nographic \ ...@@ -192,14 +76,20 @@ QEMUOPTS = -smp $(QEMUSMP) -m 512 -serial mon:stdio -nographic \
-net user -net nic,model=e1000 \ -net user -net nic,model=e1000 \
-redir tcp:2323::23 -redir tcp:8080::80 -redir tcp:2323::23 -redir tcp:8080::80
qemu: $(O)/kernel qemu: $(KERN)
$(QEMU) $(QEMUOPTS) -kernel $(O)/kernel $(QEMU) $(QEMUOPTS) -kernel $(KERN)
gdb: $(O)/kernel gdb: $(KERN)
$(QEMU) $(QEMUOPTS) -kernel $(O)/kernel -S -s $(QEMU) $(QEMUOPTS) -kernel $(KERN) -S -s
## ##
## mtrace ## mtrace
## ##
mscan.syms: $(KERN)
$(NM) -S $< > $@
mscan.kern: $(KERN)
cp $< $@
MTRACEOPTS = -rtc clock=vm -mtrace-enable -mtrace-file mtrace.out \ MTRACEOPTS = -rtc clock=vm -mtrace-enable -mtrace-file mtrace.out \
-mtrace-quantum 100 -mtrace-quantum 100
mtrace.out: mscan.kern mscan.syms mtrace.out: mscan.kern mscan.syms
...@@ -212,8 +102,8 @@ mscan.out: $(QEMUSRC)/mtrace-tools/mscan mtrace.out ...@@ -212,8 +102,8 @@ mscan.out: $(QEMUSRC)/mtrace-tools/mscan mtrace.out
mscan.sorted: mscan.out $(QEMUSRC)/mtrace-tools/sersec-sort mscan.sorted: mscan.out $(QEMUSRC)/mtrace-tools/sersec-sort
$(QEMUSRC)/mtrace-tools/sersec-sort < $< > $@ $(QEMUSRC)/mtrace-tools/sersec-sort < $< > $@
rsync: $(O)/kernel rsync: $(KERN)
rsync -avP $(O)/kernel amsterdam.csail.mit.edu:/tftpboot/$(HW)/kernel.xv6 rsync -avP $(KERN) amsterdam.csail.mit.edu:/tftpboot/$(HW)/kernel.xv6
clean: clean:
rm -fr $(O) rm -fr $(O)
UPROGS= \
cat \
echo \
init \
forkexectree \
forkexecbench \
forktree \
login \
ls \
mapbench \
maptest \
sh \
thrtest \
halt \
time \
sleep \
dirbench \
usertests \
lockstat \
preadtest \
perf
ifeq ($(HAVE_LWIP),y)
UPROGS += \
telnetd \
httpd
endif
UPROGS := $(addprefix $(O)/bin/, $(UPROGS))
$(O)/bin/%.unstripped: $(O)/bin/%.o $(ULIB)
@echo " LD $@"
$(Q)mkdir -p $(@D)
$(Q)$(LD) $(LDFLAGS) -N -e main -Ttext 0x100000 -o $@ $^
$(O)/bin/%: $(O)/bin/%.unstripped
@echo " STRIP $@"
$(Q)mkdir -p $(@D)
$(Q)$(STRIP) -o $@ $<
.PRECIOUS: $(O)/bin/%.o $(O)/bin/%.unstripped
-include $(O)/bin/*.d
// Boot loader.
//
// Part of the boot sector, along with bootasm.S, which calls bootmain().
// bootasm.S has put the processor into protected 32-bit mode.
// bootmain() loads an ELF kernel image from the disk starting at
// sector 1 and then jumps to the kernel entry routine.
#include "types.h"
#include "elf.h"
#include "amd64.h"
#include "memlayout.h"
#define SECTSIZE 512
void readseg(uchar*, uint, uint);
void
bootmain(void)
{
struct elfhdr *elf;
struct proghdr *ph, *eph;
void (*entry)(void);
uchar *pa;
elf = (struct elfhdr*)0x10000; // scratch space
// Read 1st page off disk
readseg((uchar*)elf, 4096, 0);
// Is this an ELF executable?
if(elf->magic != ELF_MAGIC)
return; // let bootasm.S handle error
// Load each program segment (ignores ph flags).
ph = (struct proghdr*)((uchar*)elf + elf->phoff);
eph = ph + elf->phnum;
for(; ph < eph; ph++){
pa = (uchar*)ph->pa;
readseg(pa, ph->filesz, ph->offset);
if(ph->memsz > ph->filesz)
stosb(pa + ph->filesz, 0, ph->memsz - ph->filesz);
}
// Call the entry point from the ELF header.
// Does not return!
entry = (void(*)(void))(elf->entry & 0xFFFFFF); // XXX get ridd off 0xFFFFF
entry();
}
void
waitdisk(void)
{
// Wait for disk ready.
while((inb(0x1F7) & 0xC0) != 0x40)
;
}
// Read a single sector at offset into dst.
void
readsect(void *dst, uint offset)
{
// Issue command.
waitdisk();
outb(0x1F2, 1); // count = 1
outb(0x1F3, offset);
outb(0x1F4, offset >> 8);
outb(0x1F5, offset >> 16);
outb(0x1F6, (offset >> 24) | 0xE0);
outb(0x1F7, 0x20); // cmd 0x20 - read sectors
// Read data.
waitdisk();
insl(0x1F0, dst, SECTSIZE/4);
}
// Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
// Might copy more than asked.
void
readseg(uchar* va, uint count, uint offset)
{
uchar* eva;
eva = va + count;
// Round down to sector boundary.
va -= offset % SECTSIZE;
// Translate from bytes to sectors; kernel starts at sector 1.
offset = (offset / SECTSIZE) + 1;
// If this is too slow, we could read lots of sectors at a time.
// We'd write more to memory than asked, but it doesn't matter --
// we load in increasing order.
for(; va < eva; va += SECTSIZE, offset++)
readsect(va, offset);
}
// The kernel layout is:
//
// text
// rodata
// data
// bss
//
// Conventionally, Unix linkers provide pseudo-symbols
// etext, edata, and end, at the end of the text, data, and bss.
// For the kernel mapping, we need the address at the beginning
// of the data section, but that's not one of the conventional
// symbols, because the convention started before there was a
// read-only rodata section between text and data.
//
// To get the address of the data section, we define a symbol
// named data and make sure this is the first object passed to
// the linker, so that it will be the first symbol in the data section.
//
// Alternative approaches would be to parse our own ELF header
// or to write a linker script, but this is simplest.
.data
.align 4096
.globl data
data:
.word 1
OBJS = \
async.o \
bio.o \
bootdata.o \
cga.o \
cilk.o \
condvar.o \
console.o \
cpprt.o \
crange.o \
e1000.o \
exec.o \
file.o \
fmt.o \
fs.o \
ioapic.o \
lapic.o \
hwvm.o \
hz.o \
kalloc.o \
kmalloc.o \
kbd.o \
main.o \
memide.o \
mp.o \
net.o \
pci.o \
picirq.o \
pipe.o \
proc.o \
prof.o \
gc.o \
rnd.o \
sampler.o \
sched.o \
spinlock.o \
swtch.o \
string.o \
syscall.o \
sysfile.o \
sysproc.o \
uart.o \
vm.o \
trap.o \
trapasm.o \
wq.o \
incbin.o
OBJS := $(addprefix $(O)/kernel/, $(OBJS))
KERN = $(O)/kernel.elf
all: $(KERN)
$(KERN): $(O)/kernel/boot.o $(OBJS) $(LDEPS) kernel/kernel.ld
@echo " LD $@"
$(Q)mkdir -p $(@D)
$(Q)$(LD) $(LDFLAGS) -T kernel/kernel.ld -z max-page-size=4096 -e start \
-o $@ $(O)/kernel/boot.o $(OBJS) -L$(O) $(LFLAGS)
$(O)/kernel/%.o: lib/%.cc
@echo " CXX $@"
$(Q)mkdir -p $(@D)
$(Q)$(CXX) $(CXXFLAGS) -c -o $@ $<
$(O)/kernel/%.o: CFLAGS+=-mcmodel=large
$(O)/kernel/%.o: CXXFLAGS+=-mcmodel=large
$(O)/kernel/incbin.o: ASFLAGS+=-DMAKE_OUT=$(O)
$(O)/kernel/incbin.o: $(O)/kernel/initcode $(O)/kernel/bootother $(O)/fs.img
$(O)/kernel/%.o: kernel/%.S
@echo " CC $@"
$(Q)mkdir -p $(@D)
$(Q)$(CC) $(ASFLAGS) -c -o $@ $<
$(O)/kernel/initcode: TTEXT = 0x0
$(O)/kernel/bootother: TTEXT = 0x7000
$(O)/kernel/%: kernel/%.S
@echo " CC $@"
$(Q)mkdir -p $(@D)
$(Q)$(CC) $(CFLAGS) -nostdinc -I. -c $< -o $@.o
$(Q)$(LD) $(LDFLAGS) -N -e start -Ttext $(TTEXT) -o $@.out $@.o
$(Q)$(OBJCOPY) -S -O binary $@.out $@
.PRECIOUS: $(O)/kernel/%.o
-include $(O)/kernel/*.d
...@@ -10,6 +10,6 @@ ...@@ -10,6 +10,6 @@
_##name##_size:; \ _##name##_size:; \
.quad _##name##_end - _##name##_start .quad _##name##_end - _##name##_start
include_bin(initcode,initcode) include_bin(kernel/initcode,initcode)
include_bin(bootother,bootother) include_bin(kernel/bootother,bootother)
include_bin(fs.img,fs_img) include_bin(fs.img,fs_img)
#include "param.h"
#include "types.h" #include "types.h"
#include "kernel.hh" #include "kernel.hh"
#include "cpu.hh" #include "cpu.hh"
......
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o
ULIB := $(addprefix $(O)/lib/, $(ULIB))
$(O)/lib/%.o: lib/%.S
@echo " CC $@"
$(Q)$(CC) $(ASFLAGS) -c -o $@ $<
.PRECIOUS: $(O)/lib/%.o
-include $(O)/lib/*.d
...@@ -8,20 +8,19 @@ ifeq ($(HAVE_LWIP),y) ...@@ -8,20 +8,19 @@ ifeq ($(HAVE_LWIP),y)
-include $(O)/lwip/src/core/ipv4/*.d -include $(O)/lwip/src/core/ipv4/*.d
-include $(O)/net/*.d -include $(O)/net/*.d
OBJS += $(O)/liblwip.a LDEPS += $(O)/liblwip.a
UPROGS += \ LFLAGS += -llwip
$(O)/_telnetd \
$(O)/_httpd
CFLAGS += -Ilwip/src/include -Inet -Ilwip/src/include/ipv4 -I. -DLWIP CFLAGS += -Ilwip/src/include -Inet -Ilwip/src/include/ipv4 -DLWIP
CXXFLAGS += -Ilwip/src/include -Inet -Ilwip/src/include/ipv4 -I. -DLWIP CXXFLAGS += -Ilwip/src/include -Inet -Ilwip/src/include/ipv4 -DLWIP
LWIP_CFLAGS = $(COMFLAGS) -std=c99 \ LWIP_CFLAGS = $(COMFLAGS) -std=c99 \
-Wno-attributes \ -Wno-attributes \
-Wno-address \ -Wno-address \
-Wno-char-subscripts \ -Wno-char-subscripts \
-Wno-unused-but-set-variable \ -Wno-unused-but-set-variable \
-Wno-format -Wno-format \
-mcmodel=large
LWIP_INCLUDES := \ LWIP_INCLUDES := \
-Ilwip/src/include \ -Ilwip/src/include \
...@@ -65,6 +64,9 @@ LWIP_SRCFILES += \ ...@@ -65,6 +64,9 @@ LWIP_SRCFILES += \
LWIP_OBJFILES := $(patsubst %.c, $(O)/%.o, $(LWIP_SRCFILES)) LWIP_OBJFILES := $(patsubst %.c, $(O)/%.o, $(LWIP_SRCFILES))
LWIP_OBJFILES := $(patsubst %.S, $(O)/%.o, $(LWIP_OBJFILES)) LWIP_OBJFILES := $(patsubst %.S, $(O)/%.o, $(LWIP_OBJFILES))
$(O)/net/%.o: CFLAGS+=-mcmodel=large
$(O)/net/%.o: CXXFLAGS+=-mcmodel=large
$(O)/net/%.o: net/%.c $(O)/net/%.o: net/%.c
@echo " CC $@" @echo " CC $@"
$(Q)mkdir -p $(@D) $(Q)mkdir -p $(@D)
......
#!/usr/bin/perl
use POSIX qw(strftime);
if($ARGV[0] eq "-h"){
shift @ARGV;
$h = $ARGV[0];
shift @ARGV;
}else{
$h = $ARGV[0];
}
$page = 0;
$now = strftime "%b %e %H:%M %Y", localtime;
@lines = <>;
for($i=0; $i<@lines; $i+=50){
print "\n\n";
++$page;
print "$now $h Page $page\n";
print "\n\n";
for($j=$i; $j<@lines && $j<$i +50; $j++){
$lines[$j] =~ s!//DOC.*!!;
print $lines[$j];
}
for(; $j<$i+50; $j++){
print "\n";
}
$sheet = "";
if($lines[$i] =~ /^([0-9][0-9])[0-9][0-9] /){
$sheet = "Sheet $1";
}
print "\n\n";
print "$sheet\n";
print "\n\n";
}
struct qnode {
volatile void *next;
volatile char locked;
__padout__;
};
typedef struct {
struct qnode *v __mpalign__;
const char *name;
} qlock_t;
static inline void
ql_init(qlock_t *l, const char *name)
{
l->v = NULL;
l->name = name;
}
static inline void
ql_lock(qlock_t *l, volatile struct qnode *mynode)
{
struct qnode *predecessor;
pushcli();
mtlock(l);
mynode->next = NULL;
predecessor = (struct qnode *)xchg((u64 *)&l->v, (u64)mynode);
if (predecessor) {
mynode->locked = 1;
barrier();
predecessor->next = mynode;
while (mynode->locked)
rep_nop();
}
mtacquired(l);
}
static inline int
ql_trylock(qlock_t *l, volatile struct qnode *mynode)
{
int r;
mynode->next = NULL;
pushcli();
r = cmpswap((long *)&l->v, 0, (long)mynode);
if (!r)
popcli();
return r;
}
static inline void
ql_unlock(qlock_t *l, volatile struct qnode *mynode)
{
if (!mynode->next) {
if (cmpswap((long *)&l->v, (long)mynode, 0)) {
mtunlock(l);
popcli();
return;
}
while (!mynode->next)
rep_nop();
}
((struct qnode *)mynode->next)->locked = 0;
mtunlock(l);
popcli();
}
/*
This file defines a Promela model for xv6's
acquire, release, sleep, and wakeup, along with
a model of a simple producer/consumer queue.
To run:
spinp sleep1.p
(You may need to install Spin, available at http://spinroot.com/.)
After a successful run spin prints something like:
unreached in proctype consumer
(0 of 37 states)
unreached in proctype producer
(0 of 23 states)
After an unsuccessful run, the spinp script prints
an execution trace that causes a deadlock.
The safe body of producer reads:
acquire(lk);
x = value; value = x + 1; x = 0;
wakeup(0);
release(lk);
i = i + 1;
If this is changed to:
x = value; value = x + 1; x = 0;
acquire(lk);
wakeup(0);
release(lk);
i = i + 1;
then a deadlock can happen, because the non-atomic
increment of value conflicts with the non-atomic
decrement in consumer, causing value to have a bad value.
Try this.
If it is changed to:
acquire(lk);
x = value; value = x + 1; x = 0;
release(lk);
wakeup(0);
i = i + 1;
then nothing bad happens: it is okay to wakeup after release
instead of before, although it seems morally wrong.
*/
#define ITER 4
#define N 2
bit lk;
byte value;
bit sleeping[N];
inline acquire(x)
{
atomic { x == 0; x = 1 }
}
inline release(x)
{
assert x==1;
x = 0
}
inline sleep(cond, lk)
{
assert !sleeping[_pid];
if
:: cond ->
skip
:: else ->
atomic { release(lk); sleeping[_pid] = 1 };
sleeping[_pid] == 0;
acquire(lk)
fi
}
inline wakeup()
{
w = 0;
do
:: w < N ->
sleeping[w] = 0;
w = w + 1
:: else ->
break
od
}
active[N] proctype consumer()
{
byte i, x;
i = 0;
do
:: i < ITER ->
acquire(lk);
sleep(value > 0, lk);
x = value; value = x - 1; x = 0;
release(lk);
i = i + 1;
:: else ->
break
od;
i = 0;
skip
}
active[N] proctype producer()
{
byte i, x, w;
i = 0;
do
:: i < ITER ->
acquire(lk);
x = value; value = x + 1; x = 0;
release(lk);
wakeup();
i = i + 1;
:: else ->
break
od;
i = 0;
skip
}
#!/bin/sh
if [ $# != 1 ] || [ ! -f "$1" ]; then
echo 'usage: spinp file.p' 1>&2
exit 1
fi
rm -f $1.trail
spin -a $1 || exit 1
cc -DSAFETY -DREACH -DMEMLIM=500 -o pan pan.c
pan -i
rm pan.* pan
if [ -f $1.trail ]; then
spin -t -p $1
fi
The source listing is preceded by a cross-reference that lists every defined
constant, struct, global variable, and function in xv6. Each entry gives,
on the same line as the name, the line number (or, in a few cases, numbers)
where the name is defined. Successive lines in an entry list the line
numbers where the name is used. For example, this entry:
swtch 2358
0317 2128 2166 2357 2358
indicates that swtch is defined on line 2358 and is mentioned on five lines
on sheets 03, 21, and 23.
The numbers to the left of the file names in the table are sheet numbers.
The source code has been printed in a double column format with fifty
lines per column, giving one hundred lines per sheet (or page).
Thus there is a convenient relationship between line numbers and sheet numbers.
$(O)/tools/mkfs: tools/mkfs.c include/fs.h
$(Q)mkdir -p $(@D)
gcc -m32 -Werror -Wall -I. -o $@ $<
$(O)/tools/perf-report: tools/perf-report.cc include/sampler.h
$(Q)mkdir -p $(@D)
g++ -std=c++0x -m64 -Werror -Wall -I. -o $@ $<
all: $(O)/tools/perf-report
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
#include <assert.h> #include <assert.h>
#define stat xv6_stat // avoid clash with host struct stat #define stat xv6_stat // avoid clash with host struct stat
#include "types.h" #include "include/types.h"
#include "fs.h" #include "include/fs.h"
#include "stat.h" #include "include/stat.h"
int nblocks = 4067; int nblocks = 4067;
int ninodes = 200; int ninodes = 200;
......
...@@ -10,12 +10,13 @@ ...@@ -10,12 +10,13 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <unordered_map> #include <unordered_map>
#include <map> #include <map>
#include "types.h" #include "include/types.h"
#include "sampler.h" #include "include/sampler.h"
static void __attribute__((noreturn)) static void __attribute__((noreturn))
edie(const char* errstr, ...) edie(const char* errstr, ...)
...@@ -176,7 +177,6 @@ main(int ac, char **av) ...@@ -176,7 +177,6 @@ main(int ac, char **av)
struct stat buf; struct stat buf;
char *x; char *x;
int fd; int fd;
int i;
if (ac < 3) if (ac < 3)
edie("usage: %s sample-file elf-file", av[0]); edie("usage: %s sample-file elf-file", av[0]);
...@@ -205,7 +205,7 @@ main(int ac, char **av) ...@@ -205,7 +205,7 @@ main(int ac, char **av)
header = (struct logheader*)x; header = (struct logheader*)x;
std::unordered_map<u64, int> map; std::unordered_map<u64, int> map;
for (i = 0; i < header->ncpus; i++) { for (u32 i = 0; i < header->ncpus; i++) {
struct pmuevent *p; struct pmuevent *p;
struct pmuevent *q; struct pmuevent *q;
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论