This commit is contained in:
Kagura 2024-06-12 07:36:23 +08:00
commit dede1e63fe
45 changed files with 5523 additions and 0 deletions

View file

@ -0,0 +1,7 @@
Public speaking is very easy.
0 1 3 6 10 15
0 271
99 3 DrEvil
5 115
6 3 5 2 1 4
47

3
bomblab/bomb126/README Normal file
View file

@ -0,0 +1,3 @@
This is bomb 126.
It belongs to B22040723 (me@kagurach.uk)

8
bomblab/bomb126/a.py Normal file
View file

@ -0,0 +1,8 @@
hex_string = "0x50 0x75 0x62 0x6c 0x69 0x63"
# Split the hex string into individual hex values
hex_values = hex_string.split()
# Convert each hex value to its corresponding character
decoded_string = ''.join([chr(int(hex_val, 16)) for hex_val in hex_values])
print(decoded_string)

BIN
bomblab/bomb126/bomb Executable file

Binary file not shown.

115
bomblab/bomb126/bomb.c Normal file
View file

@ -0,0 +1,115 @@
/***************************************************************************
* Dr. Evil's Insidious Bomb, Version 1.1
* Copyright 2011, Dr. Evil Incorporated. All rights reserved.
*
* LICENSE:
*
* Dr. Evil Incorporated (the PERPETRATOR) hereby grants you (the
* VICTIM) explicit permission to use this bomb (the BOMB). This is a
* time limited license, which expires on the death of the VICTIM.
* The PERPETRATOR takes no responsibility for damage, frustration,
* insanity, bug-eyes, carpal-tunnel syndrome, loss of sleep, or other
* harm to the VICTIM. Unless the PERPETRATOR wants to take credit,
* that is. The VICTIM may not distribute this bomb source code to
* any enemies of the PERPETRATOR. No VICTIM may debug,
* reverse-engineer, run "strings" on, decompile, decrypt, or use any
* other technique to gain knowledge of and defuse the BOMB. BOMB
* proof clothing may not be worn when handling this program. The
* PERPETRATOR will not apologize for the PERPETRATOR's poor sense of
* humor. This license is null and void where the BOMB is prohibited
* by law.
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "support.h"
#include "phases.h"
/*
* Note to self: Remember to erase this file so my victims will have no
* idea what is going on, and so they will all blow up in a
* spectaculary fiendish explosion. -- Dr. Evil
*/
FILE *infile;
int main(int argc, char *argv[])
{
char *input;
/* Note to self: remember to port this bomb to Windows and put a
* fantastic GUI on it. */
/* When run with no arguments, the bomb reads its input lines
* from standard input. */
if (argc == 1) {
infile = stdin;
}
/* When run with one argument <file>, the bomb reads from <file>
* until EOF, and then switches to standard input. Thus, as you
* defuse each phase, you can add its defusing string to <file> and
* avoid having to retype it. */
else if (argc == 2) {
if (!(infile = fopen(argv[1], "r"))) {
printf("%s: Error: Couldn't open %s\n", argv[0], argv[1]);
exit(8);
}
}
/* You can't call the bomb with more than 1 command line argument. */
else {
printf("Usage: %s [<input_file>]\n", argv[0]);
exit(8);
}
/* Do all sorts of secret stuff that makes the bomb harder to defuse. */
initialize_bomb();
printf("Welcome to my fiendish little bomb. You have 6 phases with\n");
printf("which to blow yourself up. Have a nice day!\n");
/* Hmm... Six phases must be more secure than one phase! */
input = read_line(); /* Get input */
phase_1(input); /* Run the phase */
phase_defused(); /* Drat! They figured it out!
* Let me know how they did it. */
printf("Phase 1 defused. How about the next one?\n");
/* The second phase is harder. No one will ever figure out
* how to defuse this... */
input = read_line();
phase_2(input);
phase_defused();
printf("That's number 2. Keep going!\n");
/* I guess this is too easy so far. Some more complex code will
* confuse people. */
input = read_line();
phase_3(input);
phase_defused();
printf("Halfway there!\n");
/* Oh yeah? Well, how good is your math? Try on this saucy problem! */
input = read_line();
phase_4(input);
phase_defused();
printf("So you got that one. Try this one.\n");
/* Round and 'round in memory we go, where we stop, the bomb blows! */
input = read_line();
phase_5(input);
phase_defused();
printf("Good work! On to the next...\n");
/* This phase will never be used, since no one will get past the
* earlier ones. But just in case, make this one extra hard. */
input = read_line();
phase_6(input);
phase_defused();
/* Wow, they got it! But isn't something... missing? Perhaps
* something they overlooked? Mua ha ha ha ha! */
return 0;
}

2001
bomblab/bomb126/linker.txt Normal file

File diff suppressed because it is too large Load diff

1
bomblab/bomb126/res1.txt Normal file
View file

@ -0,0 +1 @@
0x50 0x75 0x62 0x6c 0x69 0x63 0x20 0x73 0x70 0x65 0x61 0x6b 0x69 0x6e 0x67 0x20 0x69 0x73 0x20 0x76 0x65 0x72 0x79 0x20 0x65 0x61 0x73 0x79 0x2e 0x00

430
bomblab/bomb126/strings.txt Normal file
View file

@ -0,0 +1,430 @@
/lib64/ld-linux-x86-64.so.2
xd85
fgets
__printf_chk
read
alarm
write
connect
__memmove_chk
__libc_start_main
__fprintf_chk
strcmp
socket
signal
fopen
strcpy
strtol
strcasecmp
__ctype_b_loc
stdout
puts
gethostname
fflush
close
strlen
sleep
getenv
stdin
gethostbyname
__sprintf_chk
stderr
__errno_location
exit
__isoc99_sscanf
__stack_chk_fail
libc.so.6
GLIBC_2.3
GLIBC_2.7
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.34
GLIBC_2.2.5
__gmon_start__
PTE1
~-ATUS
[]A\
AWAVAUATUSH
D$h1
\$0H
D$8H
T$@H
D$HH
T$PH
D$XH
D$hdH+
x[]A\A]A^A_
ATUSH
[]A\
T$@H
***truncH
ated***
D$h1
D$hdH+
AVAUATUSI
[]A\A]A^
AWAVAUATUSL
D$ L
l$@H
D$(I
Error: CH
lient unI
able to H
create sI
G ockefA
Error: DH
NS is unI
able to H
resolve I
server aI
G(ddrefA
G,ssA
Error: UH
nable toI
connectH
to the I
G servfA
G$erA
Error: RH
esult stI
ring tooH
large. I
IncreaseH
SUBMITRI
_MAXBUF
t`A
Error: CH
lient unI
able to H
read firI
st headeH
r from sI
G0ervefA
[]A\A]A^A_
Error: CH
lient unI
able to H
read staI
tus messH
age fromI
server
Error: CH
lient unI
able to H
write toI
the serI
G(ver
Error: RH
esult stI
ring conH
tains anI
illegalH
or unprI
intable H
characteI
W8fA
G@r.A
t$8L
L$0L
D$(H
|$PH
D$`H
D$XH
L$<H
D$<A
Error: CH
lient unI
able to H
read heaI
ders froH
m serverI
ATUSH
[]A\
Error: CH
lient unH
able to H
create sH
E ockef
Error: DH
NS is unH
able to H
resolve H
server aH
E(ddref
E,ss
APRL
%s: Error: Couldn't open %s
Usage: %s [<input_file>]
That's number 2. Keep going!
Halfway there!
Good work! On to the next...
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
So you got that one. Try this one.
Public speaking is very easy.
Wow! You've defused the secret stage!
So you think you can stop the bomb with ctrl-c, do you?
Initialization error: Running on an illegal host [1]
Initialization error: Running on an illegal host [2]
Your instructor has been notified.
Curses, you've found the secret phase!
But finding it and solving it are quite different...
Congratulations! You've defused the bomb!
Your instructor has been notified and will verify your solution.
Well...
OK. :-)
Invalid phase%s
Initialization error:
defused
exploded
%d:%s:%d:%s
BOOM!!!
The bomb has blown up.
%d %d %d %d %d %d
Error: Premature EOF on stdin
GRADE_BOMB
Error: Input line too long
%d %d %s
DrEvil
angelshark.ics.cs.cmu.edu
makoshark.ics.cs.cmu.edu
whaleshark.ics.cs.cmu.edu
Program timed out after %d seconds
Error: HTTP request failed with error %d: %s
GET /%s/submitr.pl/?userid=%s&userpwd=%s&lab=%s&result=%s&submit=submit HTTP/1.0
Error: Unable to connect to server %s
%%%02X
%s %d %[a-zA-z ]
10.160.106.190
AUTORESULT_STRING=%s
csapp
:*3$"
Kb19YKfveW6pIHQAJWGc
B22040723
GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
<Welcome to my fiendish little bomb. You have 6 phases with
-which to blow yourself up. Have a nice day!
*Phase 1 defused. How about the next one?
That's number 2. Keep going!
Halfway there!
%So you got that one. Try this one.
Good work! On to the next...
:! ;
;!$9
printf
__off_t
_IO_read_ptr
_chain
size_t
_shortbuf
_IO_buf_base
long long unsigned int
GNU C17 11.4.0 -mtune=generic -march=x86-64 -ggdb -O1 -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection
read_line
long long int
phase_defused
_fileno
_IO_read_end
_flags
_IO_buf_end
_cur_column
_IO_codecvt
__printf_chk
_old_offset
infile
initialize_bomb
_IO_marker
stdin
_freeres_buf
_IO_write_ptr
short unsigned int
_IO_save_base
_lock
_flags2
_mode
__builtin_puts
_IO_write_end
_IO_lock_t
_IO_FILE
fopen
_markers
unsigned char
short int
_IO_wide_data
_vtable_offset
exit
input
__off64_t
_IO_read_base
_IO_save_end
__fmt
__pad5
_unused2
argv
phase_1
phase_2
phase_3
phase_4
phase_5
phase_6
_IO_backup_base
argc
_freeres_list
main
_IO_write_base
bomb.c
/home/teacher/CSAPP/bomblab/src
/usr/include/x86_64-linux-gnu/bits
/usr/lib/gcc/x86_64-linux-gnu/11/include
/usr/include/x86_64-linux-gnu/bits/types
/usr/include
stdio2.h
stddef.h
types.h
struct_FILE.h
stdio.h
phases.h
support.h
stdlib.h
<built-in>
crt1.o
__abi_tag
crtstuff.c
deregister_tm_clones
__do_global_dtors_aux
completed.0
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
bomb.c
phases.c
array.0
support.c
sig_handler
driverlib.c
rio_readlineb
__FRAME_END__
_DYNAMIC
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
skip
getenv@GLIBC_2.2.5
phase_defused
strcasecmp@GLIBC_2.2.5
__libc_start_main@GLIBC_2.34
__errno_location@GLIBC_2.2.5
stdout@GLIBC_2.2.5
strcpy@GLIBC_2.2.5
puts@GLIBC_2.2.5
stdin@GLIBC_2.2.5
write@GLIBC_2.2.5
_edata
_fini
strlen@GLIBC_2.2.5
__stack_chk_fail@GLIBC_2.4
num_input_strings
phase_5
initialize_bomb_solve
blank_line
submitr
phase_3
phase_1
invalid_phase
init_driver
alarm@GLIBC_2.2.5
close@GLIBC_2.2.5
node3
read@GLIBC_2.2.5
fgets@GLIBC_2.2.5
explode_bomb
node1
__data_start
strcmp@GLIBC_2.2.5
signal@GLIBC_2.2.5
gethostbyname@GLIBC_2.2.5
node5
__memmove_chk@GLIBC_2.3.4
__gmon_start__
strtol@GLIBC_2.2.5
fun7
__dso_handle
_IO_stdin_used
host_table
func4
string_length
fflush@GLIBC_2.2.5
__isoc99_sscanf@GLIBC_2.7
_end
_dl_relocate_static_pie
secret_phase
infile
sigalrm_handler
init_timeout
__bss_start
userid
main
__printf_chk@GLIBC_2.3.4
read_line
strings_not_equal
phase_4
fopen@GLIBC_2.2.5
phase_6
scratch
driver_post
send_msg
phase_2
gethostname@GLIBC_2.2.5
exit@GLIBC_2.2.5
bomb_id
connect@GLIBC_2.2.5
__TMC_END__
__fprintf_chk@GLIBC_2.3.4
node2
node4
user_password
sleep@GLIBC_2.2.5
node6
_init
read_six_numbers
initialize_bomb
__ctype_b_loc@GLIBC_2.3
stderr@GLIBC_2.2.5
__sprintf_chk@GLIBC_2.3.4
socket@GLIBC_2.2.5
.symtab
.strtab
.shstrtab
.interp
.note.gnu.property
.note.gnu.build-id
.note.ABI-tag
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.plt.sec
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.dynamic
.got
.got.plt
.data
.bss
.comment
.debug_aranges
.debug_info
.debug_abbrev
.debug_line
.debug_str
.debug_line_str
.debug_loclists

131
bomblab/bomb126/symbols.txt Normal file
View file

@ -0,0 +1,131 @@
bomb: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 crt1.o
000000000040038c l O .note.ABI-tag 0000000000000020 __abi_tag
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000401410 l F .text 0000000000000000 deregister_tm_clones
0000000000401440 l F .text 0000000000000000 register_tm_clones
0000000000401480 l F .text 0000000000000000 __do_global_dtors_aux
00000000004057a8 l O .bss 0000000000000001 completed.0
0000000000404e18 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry
00000000004014b0 l F .text 0000000000000000 frame_dummy
0000000000404e10 l O .init_array 0000000000000000 __frame_dummy_init_array_entry
0000000000000000 l df *ABS* 0000000000000000 bomb.c
0000000000000000 l df *ABS* 0000000000000000 phases.c
00000000004031a0 l O .rodata 0000000000000040 array.0
0000000000000000 l df *ABS* 0000000000000000 support.c
0000000000401ab6 l F .text 0000000000000062 sig_handler
0000000000000000 l df *ABS* 0000000000000000 driverlib.c
0000000000402112 l F .text 00000000000000cc rio_readlineb
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000403c30 l O .eh_frame 0000000000000000 __FRAME_END__
0000000000000000 l df *ABS* 0000000000000000
0000000000404e20 l O .dynamic 0000000000000000 _DYNAMIC
00000000004035fc l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR
0000000000405000 l O .got.plt 0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000401d11 g F .text 0000000000000052 skip
0000000000000000 F *UND* 0000000000000000 getenv@GLIBC_2.2.5
0000000000402014 g F .text 00000000000000c8 phase_defused
00000000004052f0 g O .data 0000000000000018 n31
0000000000000000 F *UND* 0000000000000000 strcasecmp@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 __libc_start_main@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 __errno_location@GLIBC_2.2.5
0000000000405780 g O .bss 0000000000000008 stdout@GLIBC_2.2.5
0000000000405100 w .data 0000000000000000 data_start
0000000000405820 g O .bss 0000000000000640 input_strings
0000000000000000 F *UND* 0000000000000000 strcpy@GLIBC_2.2.5
00000000004052d0 g O .data 0000000000000018 n33
0000000000000000 F *UND* 0000000000000000 puts@GLIBC_2.2.5
0000000000405790 g O .bss 0000000000000008 stdin@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 write@GLIBC_2.2.5
0000000000405780 g .data 0000000000000000 _edata
0000000000405170 g O .data 0000000000000018 n44
00000000004051d0 g O .data 0000000000000018 n46
0000000000405190 g O .data 0000000000000018 n42
00000000004051f0 g O .data 0000000000000018 n48
0000000000402c80 g F .fini 0000000000000000 .hidden _fini
0000000000000000 F *UND* 0000000000000000 strlen@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 __stack_chk_fail@GLIBC_2.4
0000000000405810 g O .bss 0000000000000004 num_input_strings
0000000000401815 g F .text 0000000000000097 phase_5
0000000000401ccd g F .text 0000000000000005 initialize_bomb_solve
0000000000401cd2 g F .text 000000000000003f blank_line
00000000004021de g F .text 0000000000000804 submitr
00000000004016aa g F .text 00000000000000bb phase_3
0000000000401614 g F .text 0000000000000024 phase_1
0000000000401b18 g F .text 000000000000002d invalid_phase
0000000000402a12 g F .text 00000000000001f5 init_driver
0000000000000000 F *UND* 0000000000000000 alarm@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 close@GLIBC_2.2.5
0000000000405350 g O .data 0000000000000010 node3
0000000000000000 F *UND* 0000000000000000 read@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 fgets@GLIBC_2.2.5
0000000000401e55 g F .text 0000000000000042 explode_bomb
0000000000405330 g O .data 0000000000000010 node1
0000000000405100 g .data 0000000000000000 __data_start
0000000000000000 F *UND* 0000000000000000 strcmp@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 signal@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 gethostbyname@GLIBC_2.2.5
0000000000405370 g O .data 0000000000000010 node5
0000000000000000 F *UND* 0000000000000000 __memmove_chk@GLIBC_2.3.4
0000000000000000 w *UND* 0000000000000000 __gmon_start__
0000000000000000 F *UND* 0000000000000000 strtol@GLIBC_2.2.5
0000000000401a19 g F .text 0000000000000041 fun7
0000000000405108 g O .data 0000000000000000 .hidden __dso_handle
0000000000403000 g O .rodata 0000000000000004 _IO_stdin_used
0000000000405290 g O .data 0000000000000018 n22
0000000000405380 g O .data 0000000000000400 host_table
0000000000401765 g F .text 000000000000003b func4
0000000000405250 g O .data 0000000000000018 n1
0000000000401b45 g F .text 0000000000000021 string_length
0000000000000000 F *UND* 0000000000000000 fflush@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 __isoc99_sscanf@GLIBC_2.7
0000000000405310 g O .data 0000000000000018 n34
00000000004052b0 g O .data 0000000000000018 n32
0000000000405e60 g .bss 0000000000000000 _end
0000000000401400 g F .text 0000000000000005 .hidden _dl_relocate_static_pie
00000000004013d0 g F .text 0000000000000026 _start
0000000000401a5a g F .text 000000000000005c secret_phase
00000000004057b0 g O .bss 0000000000000008 infile
00000000004020dc g F .text 0000000000000036 sigalrm_handler
00000000004029e2 g F .text 0000000000000030 init_timeout
0000000000405780 g .bss 0000000000000000 __bss_start
0000000000405238 g O .data 000000000000000a userid
00000000004014b6 g F .text 000000000000015e main
0000000000000000 F *UND* 0000000000000000 __printf_chk@GLIBC_2.3.4
0000000000405150 g O .data 0000000000000018 n47
00000000004051b0 g O .data 0000000000000018 n43
0000000000405130 g O .data 0000000000000018 n41
0000000000401edc g F .text 0000000000000138 read_line
0000000000405110 g O .data 0000000000000018 n45
0000000000401b66 g F .text 0000000000000060 strings_not_equal
00000000004017a0 g F .text 0000000000000075 phase_4
0000000000000000 F *UND* 0000000000000000 fopen@GLIBC_2.2.5
00000000004018ac g F .text 000000000000016d phase_6
00000000004057c0 g O .bss 0000000000000050 scratch
0000000000402c07 g F .text 0000000000000077 driver_post
0000000000401d63 g F .text 00000000000000f2 send_msg
0000000000401638 g F .text 0000000000000072 phase_2
0000000000000000 F *UND* 0000000000000000 gethostname@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 exit@GLIBC_2.2.5
0000000000405244 g O .data 0000000000000004 bomb_id
0000000000000000 F *UND* 0000000000000000 connect@GLIBC_2.2.5
0000000000405780 g O .data 0000000000000000 .hidden __TMC_END__
0000000000000000 F *UND* 0000000000000000 __fprintf_chk@GLIBC_2.3.4
0000000000405340 g O .data 0000000000000010 node2
0000000000405360 g O .data 0000000000000010 node4
0000000000405220 g O .data 0000000000000015 user_password
0000000000000000 F *UND* 0000000000000000 sleep@GLIBC_2.2.5
0000000000405210 g O .data 0000000000000010 node6
0000000000401000 g F .init 0000000000000000 .hidden _init
0000000000401e97 g F .text 0000000000000045 read_six_numbers
0000000000405270 g O .data 0000000000000018 n21
0000000000401bc6 g F .text 0000000000000107 initialize_bomb
0000000000000000 F *UND* 0000000000000000 __ctype_b_loc@GLIBC_2.3
00000000004057a0 g O .bss 0000000000000008 stderr@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 __sprintf_chk@GLIBC_2.3.4
0000000000000000 F *UND* 0000000000000000 socket@GLIBC_2.2.5

28
datalab-handout/.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,28 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}

View file

@ -0,0 +1,12 @@
#
# This file contains configuration variables for drivers.
# It was generated by genhdrs.pl. Do not modify it.
#
package Driverhdrs;
$LAB = "datalab";
$SERVER_NAME = "changeme.ics.cs.cmu.edu";
$SERVER_PORT = 8081;
$COURSE_NAME = "csapp";
$AUTOGRADE_TIMEOUT = 0;
1;

View file

@ -0,0 +1,138 @@
###############################################################
# Driverlib.pm - A package of helper functions for Perl drivers
#
# Copyright (c) 2005 David R. O'Hallaron, All rights reserved.
###############################################################
package Driverlib;
use Socket;
# Autogenerated header file with lab-specific constants
use lib ".";
use Driverhdrs;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(
driver_post
);
use strict;
#####
# Public functions
#
#
# driver_post - This is the routine that a driver calls when
# it needs to transmit an autoresult string to the result server.
#
sub driver_post ($$) {
my $userid = shift; # User id for this submission
my $result = shift; # Autoresult string
my $autograded = shift; # Set if called by an autograder
# Echo the autoresult string to stdout if the driver was called
# by an autograder
if ($autograded) {
print "\n";
print "AUTORESULT_STRING=$result\n";
return;
}
# If the driver was called with a specific userid, then submit
# the autoresult string to the result server over the Internet.
if ($userid) {
my $status = submitr($Driverhdrs::SERVER_NAME,
$Driverhdrs::SERVER_PORT,
$Driverhdrs::COURSE_NAME,
$userid,
$Driverhdrs::LAB,
$result);
# Print the status of the transfer
if (!($status =~ /OK/)) {
print "$status\n";
print "Did not send autoresult string to the result server.\n";
exit(1);
}
print "Success: Sent autoresult string for $userid to the result server.\n";
}
}
#####
# Private functions
#
#
# submitr - Sends an autoresult string to the result server
#
sub submitr ($$$$$$) {
my $hostname = shift;
my $port = shift;
my $course = shift;
my $userid = shift;
my $lab = shift;
my $result = shift;
my $internet_addr;
my $enc_result;
my $paddr;
my $line;
my $http_version;
my $errcode;
my $errmsg;
# Establish the connection to the server
socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
$internet_addr = inet_aton($hostname)
or die "Could not convert $hostname to an internet address: $!\n";
$paddr = sockaddr_in($port, $internet_addr);
connect(SERVER, $paddr)
or die "Could not connect to $hostname:$port:$!\n";
select((select(SERVER), $| = 1)[0]); # enable command buffering
# Send HTTP request to server
$enc_result = url_encode($result);
print SERVER "GET /$course/submitr.pl/?userid=$userid&lab=$lab&result=$enc_result&submit=submit HTTP/1.0\r\n\r\n";
# Get first HTTP response line
$line = <SERVER>;
chomp($line);
($http_version, $errcode, $errmsg) = split(/\s+/, $line);
if ($errcode != 200) {
return "Error: HTTP request failed with error $errcode: $errmsg";
}
# Read the remaining HTTP response header lines
while ($line = <SERVER>) {
if ($line =~ /^\r\n/) {
last;
}
}
# Read and return the response from the result server
$line = <SERVER>;
chomp($line);
close SERVER;
return $line;
}
#
# url_encode - Encode text string so it can be included in URI of GET request
#
sub url_encode ($) {
my $value = shift;
$value =~s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg;
return $value;
}
# Always end a module with a 1 so that it returns TRUE
1;

26
datalab-handout/Makefile Normal file
View file

@ -0,0 +1,26 @@
#
# Makefile that builds btest and other helper programs for the CS:APP data lab
#
CC = gcc
CFLAGS = -O -Wall -m32
LIBS = -lm
all: btest fshow ishow
btest: btest.c bits.c decl.c tests.c btest.h bits.h
$(CC) $(CFLAGS) $(LIBS) -o btest bits.c btest.c decl.c tests.c
fshow: fshow.c
$(CC) $(CFLAGS) -o fshow fshow.c
ishow: ishow.c
$(CC) $(CFLAGS) -o ishow ishow.c
# Forces a recompile. Used by the driver program.
btestexplicit:
$(CC) $(CFLAGS) $(LIBS) -o btest bits.c btest.c decl.c tests.c
clean:
rm -f *.o btest fshow ishow *~

140
datalab-handout/README Normal file
View file

@ -0,0 +1,140 @@
***********************
The CS:APP Data Lab
Directions to Students
***********************
Your goal is to modify your copy of bits.c so that it passes all the
tests in btest without violating any of the coding guidelines.
*********
0. Files:
*********
Makefile - Makes btest, fshow, and ishow
README - This file
bits.c - The file you will be modifying and handing in
bits.h - Header file
btest.c - The main btest program
btest.h - Used to build btest
decl.c - Used to build btest
tests.c - Used to build btest
tests-header.c- Used to build btest
dlc* - Rule checking compiler binary (data lab compiler)
driver.pl* - Driver program that uses btest and dlc to autograde bits.c
Driverhdrs.pm - Header file for optional "Beat the Prof" contest
fshow.c - Utility for examining floating-point representations
ishow.c - Utility for examining integer representations
***********************************************************
1. Modifying bits.c and checking it for compliance with dlc
***********************************************************
IMPORTANT: Carefully read the instructions in the bits.c file before
you start. These give the coding rules that you will need to follow if
you want full credit.
Use the dlc compiler (./dlc) to automatically check your version of
bits.c for compliance with the coding guidelines:
unix> ./dlc bits.c
dlc returns silently if there are no problems with your code.
Otherwise it prints messages that flag any problems. Running dlc with
the -e switch:
unix> ./dlc -e bits.c
causes dlc to print counts of the number of operators used by each function.
Once you have a legal solution, you can test it for correctness using
the ./btest program.
*********************
2. Testing with btest
*********************
The Makefile in this directory compiles your version of bits.c with
additional code to create a program (or test harness) named btest.
To compile and run the btest program, type:
unix> make btest
unix> ./btest [optional cmd line args]
You will need to recompile btest each time you change your bits.c
program. When moving from one platform to another, you will want to
get rid of the old version of btest and generate a new one. Use the
commands:
unix> make clean
unix> make btest
Btest tests your code for correctness by running millions of test
cases on each function. It tests wide swaths around well known corner
cases such as Tmin and zero for integer puzzles, and zero, inf, and
the boundary between denormalized and normalized numbers for floating
point puzzles. When btest detects an error in one of your functions,
it prints out the test that failed, the incorrect result, and the
expected result, and then terminates the testing for that function.
Here are the command line options for btest:
unix> ./btest -h
Usage: ./btest [-hg] [-r <n>] [-f <name> [-1|-2|-3 <val>]*] [-T <time limit>]
-1 <val> Specify first function argument
-2 <val> Specify second function argument
-3 <val> Specify third function argument
-f <name> Test only the named function
-g Format output for autograding with no error messages
-h Print this message
-r <n> Give uniform weight of n for all problems
-T <lim> Set timeout limit to lim
Examples:
Test all functions for correctness and print out error messages:
unix> ./btest
Test all functions in a compact form with no error messages:
unix> ./btest -g
Test function foo for correctness:
unix> ./btest -f foo
Test function foo for correctness with specific arguments:
unix> ./btest -f foo -1 27 -2 0xf
Btest does not check your code for compliance with the coding
guidelines. Use dlc to do that.
*******************
3. Helper Programs
*******************
We have included the ishow and fshow programs to help you decipher
integer and floating point representations respectively. Each takes a
single decimal or hex number as an argument. To build them type:
unix> make
Example usages:
unix> ./ishow 0x27
Hex = 0x00000027, Signed = 39, Unsigned = 39
unix> ./ishow 27
Hex = 0x0000001b, Signed = 27, Unsigned = 27
unix> ./fshow 0x15213243
Floating point value 3.255334057e-26
Bit Representation 0x15213243, sign = 0, exponent = 0x2a, fraction = 0x213243
Normalized. +1.2593463659 X 2^(-85)
linux> ./fshow 15213243
Floating point value 2.131829405e-38
Bit Representation 0x00e822bb, sign = 0, exponent = 0x01, fraction = 0x6822bb
Normalized. +1.8135598898 X 2^(-126)

389
datalab-handout/bits.c Normal file
View file

@ -0,0 +1,389 @@
/*
* CS:APP Data Lab
*
* B22040723
*
* bits.c - Source file with your solutions to the Lab.
* This is the file you will hand in to your instructor.
*
* WARNING: Do not include the <stdio.h> header; it confuses the dlc
* compiler. You can still use printf for debugging without including
* <stdio.h>, although you might get a compiler warning. In general,
* it's not good practice to ignore compiler warnings, but in this
* case it's OK.
*/
#if 0
/*
* Instructions to Students:
*
* STEP 1: Read the following instructions carefully.
*/
You will provide your solution to the Data Lab by
editing the collection of functions in this source file.
INTEGER CODING RULES:
Replace the "return" statement in each function with one
or more lines of C code that implements the function. Your code
must conform to the following style:
int Funct(arg1, arg2, ...) {
/* brief description of how your implementation works */
int var1 = Expr1;
...
int varM = ExprM;
varJ = ExprJ;
...
varN = ExprN;
return ExprR;
}
Each "Expr" is an expression using ONLY the following:
1. Integer constants 0 through 255 (0xFF), inclusive. You are
not allowed to use big constants such as 0xffffffff.
2. Function arguments and local variables (no global variables).
3. Unary integer operations ! ~
4. Binary integer operations & ^ | + << >>
Some of the problems restrict the set of allowed operators even further.
Each "Expr" may consist of multiple operators. You are not restricted to
one operator per line.
You are expressly forbidden to:
1. Use any control constructs such as if, do, while, for, switch, etc.
2. Define or use any macros.
3. Define any additional functions in this file.
4. Call any functions.
5. Use any other operations, such as &&, ||, -, or ?:
6. Use any form of casting.
7. Use any data type other than int. This implies that you
cannot use arrays, structs, or unions.
You may assume that your machine:
1. Uses 2s complement, 32-bit representations of integers.
2. Performs right shifts arithmetically.
3. Has unpredictable behavior when shifting if the shift amount
is less than 0 or greater than 31.
EXAMPLES OF ACCEPTABLE CODING STYLE:
/*
* pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
*/
int pow2plus1(int x) {
/* exploit ability of shifts to compute powers of 2 */
return (1 << x) + 1;
}
/*
* pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
*/
int pow2plus4(int x) {
/* exploit ability of shifts to compute powers of 2 */
int result = (1 << x);
result += 4;
return result;
}
FLOATING POINT CODING RULES
For the problems that require you to implement floating-point operations,
the coding rules are less strict. You are allowed to use looping and
conditional control. You are allowed to use both ints and unsigneds.
You can use arbitrary integer and unsigned constants. You can use any arithmetic,
logical, or comparison operations on int or unsigned data.
You are expressly forbidden to:
1. Define or use any macros.
2. Define any additional functions in this file.
3. Call any functions.
4. Use any form of casting.
5. Use any data type other than int or unsigned. This means that you
cannot use arrays, structs, or unions.
6. Use any floating point data types, operations, or constants.
NOTES:
1. Use the dlc (data lab checker) compiler (described in the handout) to
check the legality of your solutions.
2. Each function has a maximum number of operations (integer, logical,
or comparison) that you are allowed to use for your implementation
of the function. The max operator count is checked by dlc.
Note that assignment ('=') is not counted; you may use as many of
these as you want without penalty.
3. Use the btest test harness to check your functions for correctness.
4. Use the BDD checker to formally verify your functions
5. The maximum number of ops for each function is given in the
header comment for each function. If there are any inconsistencies
between the maximum ops in the writeup and in this file, consider
this file the authoritative source.
/*
* STEP 2: Modify the following functions according the coding rules.
*
* IMPORTANT. TO AVOID GRADING SURPRISES:
* 1. Use the dlc compiler to check that your solutions conform
* to the coding rules.
* 2. Use the BDD checker to formally verify that your solutions produce
* the correct answers.
*/
#endif
/* Copyright (C) 1991-2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* This header is separate from features.h so that the compiler can
include it implicitly at the start of every compilation. It must
not itself include <features.h> or any other header that includes
<features.h> because the implicit include comes before any feature
test macros that may be defined in a source file before it first
explicitly includes a system header. GCC knows the name of this
header in order to preinclude it. */
/* glibc's intent is to support the IEC 559 math functionality, real
and complex. If the GCC (4.9 and later) predefined macros
specifying compiler intent are available, use them to determine
whether the overall intent is to support these features; otherwise,
presume an older compiler has intent to support these features and
define these macros by default. */
/* wchar_t uses Unicode 10.0.0. Version 10.0 of the Unicode Standard is
synchronized with ISO/IEC 10646:2017, fifth edition, plus
the following additions from Amendment 1 to the fifth edition:
- 56 emoji characters
- 285 hentaigana
- 3 additional Zanabazar Square characters */
//1
/*
* bitAnd - x&y using only ~ and |
* Example: bitAnd(6, 5) = 4
* Legal ops: ~ |
* Max ops: 8
* Rating: 1
*/
int bitAnd(int x, int y) {
return ~(~x|~y);
}
/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) {
return 1<<31;
}
/*
* isZero - returns 1 if x == 0, and 0 otherwise
* Examples: isZero(5) = 0, isZero(0) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 2
* Rating: 1
*/
int isZero(int x) {
return !x;
}
/*
* isTmin - returns 1 if x is the minimum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmin(int x) {
return !((x^(~x + 1)) + !x);
}
//2
/*
* allOddBits - return 1 if all odd-numbered bits in word set to 1
* where bits are numbered from 0 (least significant) to 31 (most significant)
* Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allOddBits(int x) {
int mask = (0xAA << 8) + 0xAA;
mask = (mask << 16) + mask;
return !(x&mask^mask);
}
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
return (~x)+1;
}
/*
* isNotEqual - return 0 if x == y, and 1 otherwise
* Examples: isNotEqual(5,5) = 0, isNotEqual(4,5) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 6
* Rating: 2
*/
int isNotEqual(int x, int y) {
return !!(x^y);
}
//3
/*
* isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
* Example: isAsciiDigit(0x35) = 1.
* isAsciiDigit(0x3a) = 0.
* isAsciiDigit(0x05) = 0.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 3
*/
int isAsciiDigit(int x) {
return !(x>>4^3)&(!!(~(x>>3)<<29)|!((x>>1)<<30));
}
/*
* conditional - same as x ? y : z
* Example: conditional(2,4,5) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int conditional(int x, int y, int z) {
return (~!!x+1&y)|(~(~!!x+1)&z);
}
/*
* bitMask - Generate a mask consisting of all 1's
* lowbit and highbit
* Examples: bitMask(5,3) = 0x38
* Assume 0 <= lowbit <= 31, and 0 <= highbit <= 31
* If lowbit > highbit, then mask should be all 0's
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int bitMask(int highbit, int lowbit) {
return ~(~0 << highbit << 1) & (~0 << lowbit);
}
//4
/*
* logicalNeg - implement the ! operator, using all of
* the legal operators except !
* Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int logicalNeg(int x) {
return (((~(~x+1))&(~x))>>31)&1;
}
/*
* bitParity - returns 1 if x contains an odd number of 0's
* Examples: bitParity(5) = 0, bitParity(7) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 4
*/
int bitParity(int x) {
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return x & 1;
}
/*
* absVal - absolute value of x
* Example: absVal(-1) = 1.
* You may assume -TMax <= x <= TMax
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 10
* Rating: 4
*/
int absVal(int x) {
int o = x>>31;
return ~o&x|o&(~x+1);
}
//float
/*
* floatScale2 - Return bit-level equivalent of expression 2*f for
* floating point argument f.
* Both the argument and result are passed as unsigned int's, but
* they are to be interpreted as the bit-level representation of
* single-precision floating point values.
* When argument is NaN, return argument
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatScale2(unsigned uf) {
unsigned sign = uf & 0x80000000;
unsigned r = uf & 0x7f800000;
unsigned f = uf & 0x007fffff;
if (r==0x7f800000) return uf;
if (r==0) return sign|uf<<1;
r += 0x800000;
if (r == 0x7f800000)
f = 0;
return sign|r|f;
}
/*
* floatFloat2Int - Return bit-level equivalent of expression (int) f
* for floating point argument f.
* Argument is passed as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point value.
* Anything out of range (including NaN and infinity) should return
* 0x80000000u.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
int floatFloat2Int(unsigned uf) {
int sign = uf >> 31;
int r = ((uf >> 23) & 0xff) - 0x7f;
int f = uf & 0x007fffff | 0x00800000;
int res = 0;
if (r<0) return 0; //0
if (r>30) return 0x80000000; //NaN
if (r<23) res = (f >> (23-r));
else res = (f << (r-23));
return sign? -res:res;
}
/*
* floatPower2 - Return bit-level equivalent of the expression 2.0^x
* (2.0 raised to the power x) for any 32-bit integer x.
*
* The unsigned value that is returned should have the identical bit
* representation as the single-precision floating-point number 2.0^x.
* If the result is too small to be represented as a denorm, return
* 0. If too large, return +INF.
*
* Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatPower2(int x) {
if (x < -149) return 0;
// 非规范化
if (x < -126) return 1 << (149 + x);
// 规范化
if (x < 128)
return (x + 127) << 23;
// inf
return 0x7f800000;
}

72
datalab-handout/bits.h Normal file
View file

@ -0,0 +1,72 @@
/* Copyright (C) 1991-2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* This header is separate from features.h so that the compiler can
include it implicitly at the start of every compilation. It must
not itself include <features.h> or any other header that includes
<features.h> because the implicit include comes before any feature
test macros that may be defined in a source file before it first
explicitly includes a system header. GCC knows the name of this
header in order to preinclude it. */
/* glibc's intent is to support the IEC 559 math functionality, real
and complex. If the GCC (4.9 and later) predefined macros
specifying compiler intent are available, use them to determine
whether the overall intent is to support these features; otherwise,
presume an older compiler has intent to support these features and
define these macros by default. */
/* wchar_t uses Unicode 10.0.0. Version 10.0 of the Unicode Standard is
synchronized with ISO/IEC 10646:2017, fifth edition, plus
the following additions from Amendment 1 to the fifth edition:
- 56 emoji characters
- 285 hentaigana
- 3 additional Zanabazar Square characters */
//1
int bitAnd(int, int);
int test_bitAnd(int, int);
int tmin();
int test_tmin();
int isZero(int);
int test_isZero(int);
int isTmin(int);
int test_isTmin(int);
//2
int allOddBits();
int test_allOddBits();
int negate(int);
int test_negate(int);
int isNotEqual(int, int);
int test_isNotEqual(int, int);
//3
int isAsciiDigit(int);
int test_isAsciiDigit(int);
int conditional(int, int, int);
int test_conditional(int, int, int);
int bitMask(int, int);
int test_bitMask(int, int);
//4
int logicalNeg(int);
int test_logicalNeg(int);
int bitParity(int);
int test_bitParity(int);
int absVal(int);
int test_absVal(int);
//float
unsigned floatScale2(unsigned);
unsigned test_floatScale2(unsigned);
int floatFloat2Int(unsigned);
int test_floatFloat2Int(unsigned);
unsigned floatPower2(int);
unsigned test_floatPower2(int);

BIN
datalab-handout/btest Executable file

Binary file not shown.

583
datalab-handout/btest.c Normal file
View file

@ -0,0 +1,583 @@
/*
* CS:APP Data Lab
*
* btest.c - A test harness that checks a student's solution in bits.c
* for correctness.
*
* Copyright (c) 2001-2011, R. Bryant and D. O'Hallaron, All rights
* reserved. May not be used, modified, or copied without permission.
*
* This is an improved version of btest that tests large windows
* around zero and tmin and tmax for integer puzzles, and zero, norm,
* and denorm boundaries for floating point puzzles.
*
* Note: not 64-bit safe. Always compile with gcc -m32 option.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <signal.h>
#include <setjmp.h>
#include <math.h>
#include "btest.h"
/* Not declared in some stdlib.h files, so define here */
float strtof(const char *nptr, char **endptr);
/*************************
* Configuration Constants
*************************/
/* Handle infinite loops by setting upper limit on execution time, in
seconds */
#define TIMEOUT_LIMIT 10
/* For functions with a single argument, generate TEST_RANGE values
above and below the min and max test values, and above and below
zero. Functions with two or three args will use square and cube
roots of this value, respectively, to avoid combinatorial
explosion */
#define TEST_RANGE 500000
/* This defines the maximum size of any test value array. The
gen_vals() routine creates k test values for each value of
TEST_RANGE, thus MAX_TEST_VALS must be at least k*TEST_RANGE */
#define MAX_TEST_VALS 13*TEST_RANGE
/**********************************
* Globals defined in other modules
**********************************/
/* This characterizes the set of puzzles to test.
Defined in decl.c and generated from templates in ./puzzles dir */
extern test_rec test_set[];
/************************************************
* Write-once globals defined by command line args
************************************************/
/* Emit results in a format for autograding, without showing
and counter-examples */
static int grade = 0;
/* Time out after this number of seconds */
static int timeout_limit = TIMEOUT_LIMIT; /* -T */
/* If non-NULL, test only one function (-f) */
static char* test_fname = NULL;
/* Special case when only use fixed argument(s) (-1, -2, or -3) */
static int has_arg[3] = {0,0,0};
static unsigned argval[3] = {0,0,0};
/* Use fixed weight for rating, and if so, what should it be? (-r) */
static int global_rating = 0;
/******************
* Helper functions
******************/
/*
* Signal - installs a signal handler
*/
typedef void handler_t(int);
handler_t *Signal(int signum, handler_t *handler)
{
struct sigaction action, old_action;
action.sa_handler = handler;
sigemptyset(&action.sa_mask); /* block sigs of type being handled */
action.sa_flags = SA_RESTART; /* restart syscalls if possible */
if (sigaction(signum, &action, &old_action) < 0)
perror("Signal error");
return (old_action.sa_handler);
}
/*
* timeout_handler - SIGALARM hander
*/
sigjmp_buf envbuf;
void timeout_handler(int sig) {
siglongjmp(envbuf, 1);
}
/*
* random_val - Return random integer value between min and max
*/
static int random_val(int min, int max)
{
double weight = rand()/(double) RAND_MAX;
int result = min * (1-weight) + max * weight;
return result;
}
/*
* gen_vals - Generate the integer values we'll use to test a function
*/
static int gen_vals(int test_vals[], int min, int max, int test_range, int arg)
{
int i;
int test_count = 0;
/* Special case: If the user has specified a specific function
argument using the -1, -2, or -3 flags, then simply use this
argument and return */
if (has_arg[arg]) {
test_vals[0] = argval[arg];
return 1;
}
/*
* Special case: Generate test vals for floating point functions
* where the input argument is an unsigned bit-level
* representation of a float. For this case we want to test the
* regions around zero, the smallest normalized and largest
* denormalized numbers, one, and the largest normalized number,
* as well as inf and nan.
*/
if ((min == 1 && max == 1)) {
unsigned smallest_norm = 0x00800000;
unsigned one = 0x3f800000;
unsigned largest_norm = 0x7f000000;
unsigned inf = 0x7f800000;
unsigned nan = 0x7fc00000;
unsigned sign = 0x80000000;
/* Test range should be at most 1/2 the range of one exponent
value */
if (test_range > (1 << 23)) {
test_range = 1 << 23;
}
/* Functions where the input argument is an unsigned bit-level
representation of a float. The number of tests generated
inside this loop body is the value k referenced in the
comment for the global variable MAX_TEST_VALS. */
for (i = 0; i < test_range; i++) {
/* Denorms around zero */
test_vals[test_count++] = i;
test_vals[test_count++] = sign | i;
/* Region around norm to denorm transition */
test_vals[test_count++] = smallest_norm + i;
test_vals[test_count++] = smallest_norm - i;
test_vals[test_count++] = sign | (smallest_norm + i);
test_vals[test_count++] = sign | (smallest_norm - i);
/* Region around one */
test_vals[test_count++] = one + i;
test_vals[test_count++] = one - i;
test_vals[test_count++] = sign | (one + i);
test_vals[test_count++] = sign | (one - i);
/* Region below largest norm */
test_vals[test_count++] = largest_norm - i;
test_vals[test_count++] = sign | (largest_norm - i);
}
/* special vals */
test_vals[test_count++] = inf; /* inf */
test_vals[test_count++] = sign | inf; /* -inf */
test_vals[test_count++] = nan; /* nan */
test_vals[test_count++] = sign | nan; /* -nan */
return test_count;
}
/*
* Normal case: Generate test vals for integer functions
*/
/* If the range is small enough, then do exhaustively */
if (max - MAX_TEST_VALS <= min) {
for (i = min; i <= max; i++)
test_vals[test_count++] = i;
return test_count;
}
/* Otherwise, need to sample. Do so near the boundaries, around
zero, and for some random cases. */
for (i = 0; i < test_range; i++) {
/* Test around the boundaries */
test_vals[test_count++] = min + i;
test_vals[test_count++] = max - i;
/* If zero falls between min and max, then also test around zero */
if (i >= min && i <= max)
test_vals[test_count++] = i;
if (-i >= min && -i <= max)
test_vals[test_count++] = -i;
/* Random case between min and max */
test_vals[test_count++] = random_val(min, max);
}
return test_count;
}
/*
* test_0_arg - Test a function with zero arguments
*/
static int test_0_arg(funct_t f, funct_t ft, char *name)
{
int r = f();
int rt = ft();
int error = (r != rt);
if (error && !grade)
printf("ERROR: Test %s() failed...\n...Gives %d[0x%x]. Should be %d[0x%x]\n", name, r, r, rt, rt);
return error;
}
/*
* test_1_arg - Test a function with one argument
*/
static int test_1_arg(funct_t f, funct_t ft, int arg1, char *name)
{
funct1_t f1 = (funct1_t) f;
funct1_t f1t = (funct1_t) ft;
int r, rt, error;
r = f1(arg1);
rt = f1t(arg1);
error = (r != rt);
if (error && !grade)
printf("ERROR: Test %s(%d[0x%x]) failed...\n...Gives %d[0x%x]. Should be %d[0x%x]\n", name, arg1, arg1, r, r, rt, rt);
return error;
}
/*
* test_2_arg - Test a function with two arguments
*/
static int test_2_arg(funct_t f, funct_t ft, int arg1, int arg2, char *name)
{
funct2_t f2 = (funct2_t) f;
funct2_t f2t = (funct2_t) ft;
int r = f2(arg1, arg2);
int rt = f2t(arg1, arg2);
int error = (r != rt);
if (error && !grade)
printf("ERROR: Test %s(%d[0x%x],%d[0x%x]) failed...\n...Gives %d[0x%x]. Should be %d[0x%x]\n", name, arg1, arg1, arg2, arg2, r, r, rt, rt);
return error;
}
/*
* test_3_arg - Test a function with three arguments
*/
static int test_3_arg(funct_t f, funct_t ft,
int arg1, int arg2, int arg3, char *name)
{
funct3_t f3 = (funct3_t) f;
funct3_t f3t = (funct3_t) ft;
int r = f3(arg1, arg2, arg3);
int rt = f3t(arg1, arg2, arg3);
int error = (r != rt);
if (error && !grade)
printf("ERROR: Test %s(%d[0x%x],%d[0x%x],%d[0x%x]) failed...\n...Gives %d[0x%x]. Should be %d[0x%x]\n", name, arg1, arg1, arg2, arg2, arg3, arg3, r, r, rt, rt);
return error;
}
/*
* test_function - Test a function. Return number of errors
*/
static int test_function(test_ptr t) {
int test_counts[3]; /* number of test values for each arg */
int args = t->args; /* number of function arguments */
int arg_test_range[3]; /* test range for each argument */
int i, a1, a2, a3;
int errors = 0;
/* These are the test values for each arg. Declared with the
static attribute so that the array will be allocated in bss
rather than the stack */
static int arg_test_vals[3][MAX_TEST_VALS];
/* Sanity check on the number of args */
if (args < 0 || args > 3) {
printf("Configuration error: invalid number of args (%d) for function %s\n", args, t->name);
exit(1);
}
/* Assign range of argument test vals so as to conserve the total
number of tests, independent of the number of arguments */
if (args == 1) {
arg_test_range[0] = TEST_RANGE;
}
else if (args == 2) {
arg_test_range[0] = pow((double)TEST_RANGE, 0.5); /* sqrt */
arg_test_range[1] = arg_test_range[0];
}
else {
arg_test_range[0] = pow((double)TEST_RANGE, 0.333); /* cbrt */
arg_test_range[1] = arg_test_range[0];
arg_test_range[2] = arg_test_range[0];
}
/* Sanity check on the ranges */
if (arg_test_range[0] < 1)
arg_test_range[0] = 1;
if (arg_test_range[1] < 1)
arg_test_range[1] = 1;
if (arg_test_range[2] < 1)
arg_test_range[2] = 1;
/* Create a test set for each argument */
for (i = 0; i < args; i++) {
test_counts[i] = gen_vals(arg_test_vals[i],
t->arg_ranges[i][0], /* min */
t->arg_ranges[i][1], /* max */
arg_test_range[i],
i);
}
/* Handle timeouts in the test code */
if (timeout_limit > 0) {
int rc;
rc = sigsetjmp(envbuf, 1);
if (rc) {
/* control will reach here if there is a timeout */
errors = 1;
printf("ERROR: Test %s failed.\n Timed out after %d secs (probably infinite loop)\n", t->name, timeout_limit);
return errors;
}
alarm(timeout_limit);
}
/* Test function has no arguments */
if (args == 0) {
errors += test_0_arg(t->solution_funct, t->test_funct, t->name);
return errors;
}
/*
* Test function has at least one argument
*/
/* Iterate over the values for first argument */
for (a1 = 0; a1 < test_counts[0]; a1++) {
if (args == 1) {
errors += test_1_arg(t->solution_funct,
t->test_funct,
arg_test_vals[0][a1],
t->name);
/* Stop testing if there is an error */
if (errors)
return errors;
}
else {
/* if necessary, iterate over values for second argument */
for (a2 = 0; a2 < test_counts[1]; a2++) {
if (args == 2) {
errors += test_2_arg(t->solution_funct,
t->test_funct,
arg_test_vals[0][a1],
arg_test_vals[1][a2],
t->name);
/* Stop testing if there is an error */
if (errors)
return errors;
}
else {
/* if necessary, iterate over vals for third arg */
for (a3 = 0; a3 < test_counts[2]; a3++) {
errors += test_3_arg(t->solution_funct,
t->test_funct,
arg_test_vals[0][a1],
arg_test_vals[1][a2],
arg_test_vals[2][a3],
t->name);
/* Stop testing if there is an error */
if (errors)
return errors;
} /* a3 */
}
} /* a2 */
}
} /* a1 */
return errors;
}
/*
* run_tests - Run series of tests. Return number of errors
*/
static int run_tests()
{
int i;
int errors = 0;
double points = 0.0;
double max_points = 0.0;
printf("Score\tRating\tErrors\tFunction\n");
for (i = 0; test_set[i].solution_funct; i++) {
int terrors;
double tscore;
double tpoints;
if (!test_fname || strcmp(test_set[i].name,test_fname) == 0) {
int rating = global_rating ? global_rating : test_set[i].rating;
terrors = test_function(&test_set[i]);
errors += terrors;
tscore = terrors == 0 ? 1.0 : 0.0;
tpoints = rating * tscore;
points += tpoints;
max_points += rating;
if (grade || terrors < 1)
printf(" %.0f\t%d\t%d\t%s\n",
tpoints, rating, terrors, test_set[i].name);
}
}
printf("Total points: %.0f/%.0f\n", points, max_points);
return errors;
}
/*
* get_num_val - Extract hex/decimal/or float value from string
*/
static int get_num_val(char *sval, unsigned *valp) {
char *endp;
/* See if it's an integer or floating point */
int ishex = 0;
int isfloat = 0;
int i;
for (i = 0; sval[i]; i++) {
switch (sval[i]) {
case 'x':
case 'X':
ishex = 1;
break;
case 'e':
case 'E':
if (!ishex)
isfloat = 1;
break;
case '.':
isfloat = 1;
break;
default:
break;
}
}
if (isfloat) {
float fval = strtof(sval, &endp);
if (!*endp) {
*valp = *(unsigned *) &fval;
return 1;
}
return 0;
} else {
long long int llval = strtoll(sval, &endp, 0);
long long int upperbits = llval >> 31;
/* will give -1 for negative, 0 or 1 for positive */
if (!*valp && (upperbits == 0 || upperbits == -1 || upperbits == 1)) {
*valp = (unsigned) llval;
return 1;
}
return 0;
}
}
/*
* usage - Display usage info
*/
static void usage(char *cmd) {
printf("Usage: %s [-hg] [-r <n>] [-f <name> [-1|-2|-3 <val>]*] [-T <time limit>]\n", cmd);
printf(" -1 <val> Specify first function argument\n");
printf(" -2 <val> Specify second function argument\n");
printf(" -3 <val> Specify third function argument\n");
printf(" -f <name> Test only the named function\n");
printf(" -g Compact output for grading (with no error msgs)\n");
printf(" -h Print this message\n");
printf(" -r <n> Give uniform weight of n for all problems\n");
printf(" -T <lim> Set timeout limit to lim\n");
exit(1);
}
/**************
* Main routine
**************/
int main(int argc, char *argv[])
{
char c;
/* parse command line args */
while ((c = getopt(argc, argv, "hgf:r:T:1:2:3:")) != -1)
switch (c) {
case 'h': /* help */
usage(argv[0]);
break;
case 'g': /* grading option for autograder */
grade = 1;
break;
case 'f': /* test only one function */
test_fname = strdup(optarg);
break;
case 'r': /* set global rating for each problem */
global_rating = atoi(optarg);
if (global_rating < 0)
usage(argv[0]);
break;
case '1': /* Get first argument */
has_arg[0] = get_num_val(optarg, &argval[0]);
if (!has_arg[0]) {
printf("Bad argument '%s'\n", optarg);
exit(0);
}
break;
case '2': /* Get first argument */
has_arg[1] = get_num_val(optarg, &argval[1]);
if (!has_arg[1]) {
printf("Bad argument '%s'\n", optarg);
exit(0);
}
break;
case '3': /* Get first argument */
has_arg[2] = get_num_val(optarg, &argval[2]);
if (!has_arg[2]) {
printf("Bad argument '%s'\n", optarg);
exit(0);
}
break;
case 'T': /* Set timeout limit */
timeout_limit = atoi(optarg);
break;
default:
usage(argv[0]);
}
if (timeout_limit > 0) {
Signal(SIGALRM, timeout_handler);
}
/* test each function */
run_tests();
return 0;
}

32
datalab-handout/btest.h Normal file
View file

@ -0,0 +1,32 @@
/*
* CS:APP Data Lab
*/
/* Declare different function types */
typedef int (*funct_t) (void);
typedef int (*funct1_t)(int);
typedef int (*funct2_t)(int, int);
typedef int (*funct3_t)(int, int, int);
/* Combine all the information about a function and its tests as structure */
typedef struct {
char *name; /* String name */
funct_t solution_funct; /* Function */
funct_t test_funct; /* Test function */
int args; /* Number of function arguments */
char *ops; /* List of legal operators. Special case: "$" for floating point */
int op_limit; /* Max number of ops allowed in solution */
int rating; /* Problem rating (1 -- 4) */
int arg_ranges[3][2]; /* Argument ranges. Always defined for 3 args, even if */
/* the function takes fewer. Special case: First arg */
/* must be set to {1,1} for f.p. puzzles */
} test_rec, *test_ptr;
extern test_rec test_set[];

95
datalab-handout/decl.c Normal file
View file

@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define TMin INT_MIN
#define TMax INT_MAX
#include "btest.h"
#include "bits.h"
test_rec test_set[] = {
/* Copyright (C) 1991-2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* This header is separate from features.h so that the compiler can
include it implicitly at the start of every compilation. It must
not itself include <features.h> or any other header that includes
<features.h> because the implicit include comes before any feature
test macros that may be defined in a source file before it first
explicitly includes a system header. GCC knows the name of this
header in order to preinclude it. */
/* glibc's intent is to support the IEC 559 math functionality, real
and complex. If the GCC (4.9 and later) predefined macros
specifying compiler intent are available, use them to determine
whether the overall intent is to support these features; otherwise,
presume an older compiler has intent to support these features and
define these macros by default. */
/* wchar_t uses Unicode 10.0.0. Version 10.0 of the Unicode Standard is
synchronized with ISO/IEC 10646:2017, fifth edition, plus
the following additions from Amendment 1 to the fifth edition:
- 56 emoji characters
- 285 hentaigana
- 3 additional Zanabazar Square characters */
//1
{"bitAnd", (funct_t) bitAnd, (funct_t) test_bitAnd, 2, "| ~", 8, 1,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"tmin", (funct_t) tmin, (funct_t) test_tmin, 0, "! ~ & ^ | + << >>", 4, 1,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"isZero", (funct_t) isZero, (funct_t) test_isZero, 1, "! ~ & ^ | + << >>", 2, 1,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"isTmin", (funct_t) isTmin, (funct_t) test_isTmin, 1, "! ~ & ^ | +", 10, 1,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
//2
{"allOddBits", (funct_t) allOddBits, (funct_t) test_allOddBits, 1,
"! ~ & ^ | + << >>", 12, 2,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"negate", (funct_t) negate, (funct_t) test_negate, 1,
"! ~ & ^ | + << >>", 5, 2,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"isNotEqual", (funct_t) isNotEqual, (funct_t) test_isNotEqual, 2,
"! ~ & ^ | + << >>", 6, 2,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
//3
{"isAsciiDigit", (funct_t) isAsciiDigit, (funct_t) test_isAsciiDigit, 1,
"! ~ & ^ | + << >>", 15, 3,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"conditional", (funct_t) conditional, (funct_t) test_conditional, 3, "! ~ & ^ | << >>", 16, 3,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"bitMask", (funct_t) bitMask, (funct_t) test_bitMask, 2,
"! ~ & ^ | + << >>", 16, 3,
{{0, 31},{0,31},{TMin,TMax}}},
//4
{"logicalNeg", (funct_t) logicalNeg, (funct_t) test_logicalNeg, 1,
"~ & ^ | + << >>", 12, 4,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"bitParity", (funct_t) bitParity, (funct_t) test_bitParity, 1, "! ~ & ^ | + << >>", 20, 4,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"absVal", (funct_t) absVal, (funct_t) test_absVal, 1, "! ~ & ^ | + << >>", 10, 4,
{{-TMax, TMax},{TMin,TMax},{TMin,TMax}}},
//float
{"floatScale2", (funct_t) floatScale2, (funct_t) test_floatScale2, 1,
"$", 30, 4,
{{1, 1},{1,1},{1,1}}},
{"floatFloat2Int", (funct_t) floatFloat2Int, (funct_t) test_floatFloat2Int, 1,
"$", 30, 4,
{{1, 1},{1,1},{1,1}}},
{"floatPower2", (funct_t) floatPower2, (funct_t) test_floatPower2, 1,
"$", 30, 4,
{{1, 1},{1,1},{1,1}}},
{"", NULL, NULL, 0, "", 0, 0,
{{0, 0},{0,0},{0,0}}}
};

BIN
datalab-handout/dlc Executable file

Binary file not shown.

439
datalab-handout/driver.pl Executable file
View file

@ -0,0 +1,439 @@
#!/usr/bin/perl
#######################################################################
# driver.pl - CS:APP Data Lab driver
#
# Copyright (c) 2004-2011, R. Bryant and D. O'Hallaron, All rights
# reserved. May not be used, modified, or copied without permission.
#
# Note: The driver can use either btest or the BDD checker to check
# puzzles for correctness. This version of the lab uses btest, which
# has been extended to do better testing of both integer and
# floating-point puzzles.
#
#######################################################################
use strict 'vars';
use Getopt::Std;
use lib ".";
use Driverlib;
# Set to 1 to use btest, 0 to use the BDD checker.
my $USE_BTEST = 1;
# Generic settings
$| = 1; # Flush stdout each time
umask(0077); # Files created by the user in tmp readable only by that user
$ENV{PATH} = "/usr/local/bin:/usr/bin:/bin";
#
# usage - print help message and terminate
#
sub usage {
printf STDERR "$_[0]\n";
printf STDERR "Usage: $0 [-h] [-u \"nickname\"]\n";
printf STDERR "Options:\n";
printf STDERR " -h Print this message.\n";
printf STDERR " -u \"nickname\" Send autoresult to server, using nickname on scoreboard)\n";
die "\n";
}
##############
# Main routine
##############
my $login = getlogin() || (getpwuid($<))[0] || "unknown";
my $tmpdir = "/var/tmp/datalab.$login.$$";
my $diemsg = "The files are in $tmpdir.";
my $driverfiles;
my $infile;
my $autograded;
my $status;
my $inpuzzles;
my $puzzlecnt;
my $line;
my $blank;
my $name;
my $c_points;
my $c_rating;
my $c_errors;
my $p_points;
my $p_rating;
my $p_errors;
my $total_c_points;
my $total_c_rating;
my $total_p_points;
my $total_p_rating;
my $tops;
my $tpoints;
my $trating;
my $foo;
my $name;
my $msg;
my $nickname;
my $autoresult;
my %puzzle_c_points;
my %puzzle_c_rating;
my %puzzle_c_errors;
my %puzzle_p_points;
my %puzzle_p_ops;
my %puzzle_p_maxops;
my %puzzle_number;
# Parse the command line arguments
no strict;
getopts('hu:f:A');
if ($opt_h) {
usage();
}
# The default input file is bits.c (change with -f)
$infile = "bits.c";
$nickname = "";
#####
# These are command line args that every driver must support
#
# Causes the driver to send an autoresult to the server on behalf of user
if ($opt_u) {
$nickname = $opt_u;
check_nickname($nickname);
}
# Hidden flag that indicates that the driver was invoked by an autograder
if ($opt_A) {
$autograded = $opt_A;
}
#####
# Drivers can also define an arbitary number of other command line args
#
# Optional hidden flag used by the autograder
if ($opt_f) {
$infile = $opt_f;
}
use strict 'vars';
################################################
# Compute the correctness and performance scores
################################################
# Make sure that an executable dlc (data lab compiler) exists
(-e "./dlc" and -x "./dlc")
or die "$0: ERROR: No executable dlc binary.\n";
# If using the bdd checker, then make sure it exists
if (!$USE_BTEST) {
(-e "./bddcheck/cbit/cbit" and -x "./bddcheck/cbit/cbit")
or die "$0: ERROR: No executable cbit binary.\n";
}
#
# Set up the contents of the scratch directory
#
system("mkdir $tmpdir") == 0
or die "$0: Could not make scratch directory $tmpdir.\n";
# Copy the student's work to the scratch directory
unless (system("cp $infile $tmpdir/bits.c") == 0) {
clean($tmpdir);
die "$0: Could not copy file $infile to scratch directory $tmpdir.\n";
}
# Copy the various autograding files to the scratch directory
if ($USE_BTEST) {
$driverfiles = "Makefile dlc btest.c decl.c tests.c btest.h bits.h";
unless (system("cp -r $driverfiles $tmpdir") == 0) {
clean($tmpdir);
die "$0: Could not copy autogradingfiles to $tmpdir.\n";
}
}
else {
$driverfiles = "dlc tests.c bddcheck";
unless (system("cp -r $driverfiles $tmpdir") == 0) {
clean($tmpdir);
die "$0: Could not copy support files to $tmpdir.\n";
}
}
# Change the current working directory to the scratch directory
unless (chdir($tmpdir)) {
clean($tmpdir);
die "$0: Could not change directory to $tmpdir.\n";
}
#
# Generate a zapped (for coding rules) version of bits.c. In this
# zapped version of bits.c, any functions with illegal operators are
# transformed to have empty function bodies.
#
print "1. Running './dlc -z' to identify coding rules violations.\n";
system("cp bits.c save-bits.c") == 0
or die "$0: ERROR: Could not create backup copy of bits.c. $diemsg\n";
system("./dlc -z -o zap-bits.c bits.c") == 0
or die "$0: ERROR: zapped bits.c did not compile. $diemsg\n";
#
# Run btest or BDD checker to determine correctness score
#
if ($USE_BTEST) {
print "\n2. Compiling and running './btest -g' to determine correctness score.\n";
system("cp zap-bits.c bits.c");
# Compile btest
system("make btestexplicit") == 0
or die "$0: Could not make btest in $tmpdir. $diemsg\n";
# Run btest
$status = system("./btest -g > btest-zapped.out 2>&1");
if ($status != 0) {
die "$0: ERROR: btest check failed. $diemsg\n";
}
}
else {
print "\n2. Running './bddcheck/check.pl -g' to determine correctness score.\n";
system("cp zap-bits.c bits.c");
$status = system("./bddcheck/check.pl -g > btest-zapped.out 2>&1");
if ($status != 0) {
die "$0: ERROR: BDD check failed. $diemsg\n";
}
}
#
# Run dlc to identify operator count violations.
#
print "\n3. Running './dlc -Z' to identify operator count violations.\n";
system("./dlc -Z -o Zap-bits.c save-bits.c") == 0
or die "$0: ERROR: dlc unable to generated Zapped bits.c file.\n";
#
# Run btest or the bdd checker to compute performance score
#
if ($USE_BTEST) {
print "\n4. Compiling and running './btest -g -r 2' to determine performance score.\n";
system("cp Zap-bits.c bits.c");
# Compile btest
system("make btestexplicit") == 0
or die "$0: Could not make btest in $tmpdir. $diemsg\n";
print "\n";
# Run btest
$status = system("./btest -g -r 2 > btest-Zapped.out 2>&1");
if ($status != 0) {
die "$0: ERROR: Zapped btest failed. $diemsg\n";
}
}
else {
print "\n4. Running './bddcheck/check.pl -g -r 2' to determine performance score.\n";
system("cp Zap-bits.c bits.c");
$status = system("./bddcheck/check.pl -g -r 2 > btest-Zapped.out 2>&1");
if ($status != 0) {
die "$0: ERROR: Zapped bdd checker failed. $diemsg\n";
}
}
#
# Run dlc to get the operator counts on the zapped input file
#
print "\n5. Running './dlc -e' to get operator count of each function.\n";
$status = system("./dlc -W1 -e zap-bits.c > dlc-opcount.out 2>&1");
if ($status != 0) {
die "$0: ERROR: bits.c did not compile. $diemsg\n";
}
#################################################################
# Collect the correctness and performance results for each puzzle
#################################################################
#
# Collect the correctness results
#
%puzzle_c_points = (); # Correctness score computed by btest
%puzzle_c_errors = (); # Correctness error discovered by btest
%puzzle_c_rating = (); # Correctness puzzle rating (max points)
$inpuzzles = 0; # Becomes true when we start reading puzzle results
$puzzlecnt = 0; # Each puzzle gets a unique number
$total_c_points = 0;
$total_c_rating = 0;
open(INFILE, "$tmpdir/btest-zapped.out")
or die "$0: ERROR: could not open input file $tmpdir/btest-zapped.out\n";
while ($line = <INFILE>) {
chomp($line);
# Notice that we're ready to read the puzzle scores
if ($line =~ /^Score/) {
$inpuzzles = 1;
next;
}
# Notice that we're through reading the puzzle scores
if ($line =~ /^Total/) {
$inpuzzles = 0;
next;
}
# Read and record a puzzle's name and score
if ($inpuzzles) {
($blank, $c_points, $c_rating, $c_errors, $name) = split(/\s+/, $line);
$puzzle_c_points{$name} = $c_points;
$puzzle_c_errors{$name} = $c_errors;
$puzzle_c_rating{$name} = $c_rating;
$puzzle_number{$name} = $puzzlecnt++;
$total_c_points += $c_points;
$total_c_rating += $c_rating;
}
}
close(INFILE);
#
# Collect the performance results
#
%puzzle_p_points = (); # Performance points
$inpuzzles = 0; # Becomes true when we start reading puzzle results
$total_p_points = 0;
$total_p_rating = 0;
open(INFILE, "$tmpdir/btest-Zapped.out")
or die "$0: ERROR: could not open input file $tmpdir/btest-Zapped.out\n";
while ($line = <INFILE>) {
chomp($line);
# Notice that we're ready to read the puzzle scores
if ($line =~ /^Score/) {
$inpuzzles = 1;
next;
}
# Notice that we're through reading the puzzle scores
if ($line =~ /^Total/) {
$inpuzzles = 0;
next;
}
# Read and record a puzzle's name and score
if ($inpuzzles) {
($blank, $p_points, $p_rating, $p_errors, $name) = split(/\s+/, $line);
$puzzle_p_points{$name} = $p_points;
$total_p_points += $p_points;
$total_p_rating += $p_rating;
}
}
close(INFILE);
#
# Collect the operator counts generated by dlc
#
open(INFILE, "$tmpdir/dlc-opcount.out")
or die "$0: ERROR: could not open input file $tmpdir/dlc-opcount.out\n";
$tops = 0;
while ($line = <INFILE>) {
chomp($line);
if ($line =~ /(\d+) operators/) {
($foo, $foo, $foo, $name, $msg) = split(/:/, $line);
$puzzle_p_ops{$name} = $1;
$tops += $1;
}
}
close(INFILE);
#
# Print a table of results sorted by puzzle number
#
print "\n";
printf("%s\t%s\n", "Correctness Results", "Perf Results");
printf("%s\t%s\t%s\t%s\t%s\t%s\n", "Points", "Rating", "Errors",
"Points", "Ops", "Puzzle");
foreach $name (sort {$puzzle_number{$a} <=> $puzzle_number{$b}}
keys %puzzle_number) {
printf("%d\t%d\t%d\t%d\t%d\t\%s\n",
$puzzle_c_points{$name},
$puzzle_c_rating{$name},
$puzzle_c_errors{$name},
$puzzle_p_points{$name},
$puzzle_p_ops{$name},
$name);
}
$tpoints = $total_c_points + $total_p_points;
$trating = $total_c_rating + $total_p_rating;
print "\nScore = $tpoints/$trating [$total_c_points/$total_c_rating Corr + $total_p_points/$total_p_rating Perf] ($tops total operators)\n";
#
# Optionally send the autoresult to the contest server if the driver
# was called with the -u command line flag.
#
if ($nickname) {
# Generate the autoresult
$autoresult = "$tpoints|$total_c_points|$total_p_points|$tops";
foreach $name (sort {$puzzle_number{$a} <=> $puzzle_number{$b}}
keys %puzzle_number) {
$autoresult .= " |$name:$puzzle_c_points{$name}:$puzzle_c_rating{$name}:$puzzle_p_points{$name}:$puzzle_p_ops{$name}";
}
# Post the autoresult to the server. The Linux login id is
# concatenated with the user-supplied nickname for some (very) loose
# authentication of submissions.
&Driverlib::driver_post("$login:$nickname", $autoresult, $autograded);
}
# Clean up and exit
clean ($tmpdir);
exit;
##################
# Helper functions
#
#
# check_nickname - Check a nickname for legality
#
sub check_nickname {
my $nickname = shift;
# Nicknames can't be empty
if (length($nickname) < 1) {
die "$0: Error: Empty nickname.\n";
}
# Nicknames can't be too long
if (length($nickname) > 35) {
die "$0: Error: Nickname exceeds 35 characters.\n";
}
# Nicknames can have restricted set of metacharacters (e.g., no #
# HTML tags)
if (!($nickname =~ /^[_-\w.,'@ ]+$/)) {
die "$0: Error: Illegal character in nickname. Only alphanumerics, apostrophes, commas, periods, dashes, underscores, and ampersands are allowed.\n";
}
# Nicknames can't be all whitespace
if ($nickname =~ /^\s*$/) {
die "$0: Error: Nickname is all whitespace.\n";
}
}
#
# clean - remove the scratch directory
#
sub clean {
my $tmpdir = shift;
system("rm -rf $tmpdir");
}

BIN
datalab-handout/fshow Executable file

Binary file not shown.

151
datalab-handout/fshow.c Normal file
View file

@ -0,0 +1,151 @@
/* Display structure of floating-point numbers */
#include <stdio.h>
#include <stdlib.h>
float strtof(const char *nptr, char **endptr);
#define FLOAT_SIZE 32
#define FRAC_SIZE 23
#define EXP_SIZE 8
#define BIAS ((1<<(EXP_SIZE-1))-1)
#define FRAC_MASK ((1<<FRAC_SIZE)-1)
#define EXP_MASK ((1<<EXP_SIZE)-1)
/* Floating point helpers */
unsigned f2u(float f)
{
union {
unsigned u;
float f;
} v;
v.u = 0;
v.f = f;
return v.u;
}
static float u2f(unsigned u)
{
union {
unsigned u;
float f;
} v;
v.u = u;
return v.f;
}
/* Get exponent */
unsigned get_exp(unsigned uf)
{
return (uf>>FRAC_SIZE) & EXP_MASK;
}
/* Get fraction */
unsigned get_frac(unsigned uf)
{
return uf & FRAC_MASK;
}
/* Get sign */
unsigned get_sign(unsigned uf)
{
return (uf>>(FLOAT_SIZE-1)) & 0x1;
}
void show_float(unsigned uf)
{
float f = u2f(uf);
unsigned exp = get_exp(uf);
unsigned frac = get_frac(uf);
unsigned sign = get_sign(uf);
printf("\nFloating point value %.10g\n", f);
printf("Bit Representation 0x%.8x, sign = %x, exponent = 0x%.2x, fraction = 0x%.6x\n",
uf, sign, exp, frac);
if (exp == EXP_MASK) {
if (frac == 0) {
printf("%cInfinity\n", sign ? '-' : '+');
} else
printf("Not-A-Number\n");
} else {
int denorm = (exp == 0);
int uexp = denorm ? 1-BIAS : exp - BIAS;
int mantissa = denorm ? frac : frac + (1<<FRAC_SIZE);
float fman = (float) mantissa / (float) (1<<FRAC_SIZE);
printf("%s. %c%.10f X 2^(%d)\n",
denorm ? "Denormalized" : "Normalized",
sign ? '-' : '+',
fman, uexp);
}
}
/* Extract hex/decimal/or float value from string */
static int get_num_val(char *sval, unsigned *valp) {
char *endp;
/* See if it's an integer or floating point */
int ishex = 0;
int isfloat = 0;
int i;
for (i = 0; sval[i]; i++) {
switch (sval[i]) {
case 'x':
case 'X':
ishex = 1;
break;
case 'e':
case 'E':
if (!ishex)
isfloat = 1;
break;
case '.':
isfloat = 1;
break;
default:
break;
}
}
if (isfloat) {
float fval = strtof(sval, &endp);
if (!*endp) {
*valp = *(unsigned *) &fval;
return 1;
}
return 0;
} else {
long long int llval = strtoll(sval, &endp, 0);
long long int upperbits = llval >> 31;
/* will give -1 for negative, 0 or 1 for positive */
if (valp && (upperbits == 0 || upperbits == -1 || upperbits == 1)) {
*valp = (unsigned) llval;
return 1;
}
return 0;
}
}
void usage(char *fname) {
printf("Usage: %s val1 val2 ...\n", fname);
printf("Values may be given as hex patterns or as floating point numbers\n");
exit(0);
}
int main(int argc, char *argv[])
{
int i;
unsigned uf;
if (argc < 2)
usage(argv[0]);
for (i = 1; i < argc; i++) {
char *sval = argv[i];
if (get_num_val(sval, &uf)) {
show_float(uf);
} else {
printf("Invalid 32-bit number: '%s'\n", sval);
usage(argv[0]);
}
}
return 0;
}

BIN
datalab-handout/ishow Executable file

Binary file not shown.

75
datalab-handout/ishow.c Normal file
View file

@ -0,0 +1,75 @@
/* Display value of fixed point numbers */
#include <stdlib.h>
#include <stdio.h>
/* Extract hex/decimal/or float value from string */
static int get_num_val(char *sval, unsigned *valp) {
char *endp;
/* See if it's an integer or floating point */
int ishex = 0;
int isfloat = 0;
int i;
for (i = 0; sval[i]; i++) {
switch (sval[i]) {
case 'x':
case 'X':
ishex = 1;
break;
case 'e':
case 'E':
if (!ishex)
isfloat = 1;
break;
case '.':
isfloat = 1;
break;
default:
break;
}
}
if (isfloat) {
return 0; /* Not supposed to have a float here */
} else {
long long int llval = strtoll(sval, &endp, 0);
long long int upperbits = llval >> 31;
/* will give -1 for negative, 0 or 1 for positive */
if (valp && (upperbits == 0 || upperbits == -1 || upperbits == 1)) {
*valp = (unsigned) llval;
return 1;
}
return 0;
}
}
void show_int(unsigned uf)
{
printf("Hex = 0x%.8x,\tSigned = %d,\tUnsigned = %u\n",
uf, (int) uf, uf);
}
void usage(char *fname) {
printf("Usage: %s val1 val2 ...\n", fname);
printf("Values may be given in hex or decimal\n");
exit(0);
}
int main(int argc, char *argv[])
{
int i;
unsigned uf;
if (argc < 2)
usage(argv[0]);
for (i = 1; i < argc; i++) {
char *sval = argv[i];
if (get_num_val(sval, &uf)) {
show_int(uf);
} else {
printf("Cannot convert '%s' to 32-bit number\n", sval);
}
}
return 0;
}

BIN
datalab-handout/lab1.doc Normal file

Binary file not shown.

156
datalab-handout/tests.c Normal file
View file

@ -0,0 +1,156 @@
/* Testing Code */
#include <limits.h>
#include <math.h>
/* Routines used by floation point test code */
/* Convert from bit level representation to floating point number */
float u2f(unsigned u) {
union {
unsigned u;
float f;
} a;
a.u = u;
return a.f;
}
/* Convert from floating point number to bit-level representation */
unsigned f2u(float f) {
union {
unsigned u;
float f;
} a;
a.f = f;
return a.u;
}
/* Copyright (C) 1991-2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* This header is separate from features.h so that the compiler can
include it implicitly at the start of every compilation. It must
not itself include <features.h> or any other header that includes
<features.h> because the implicit include comes before any feature
test macros that may be defined in a source file before it first
explicitly includes a system header. GCC knows the name of this
header in order to preinclude it. */
/* glibc's intent is to support the IEC 559 math functionality, real
and complex. If the GCC (4.9 and later) predefined macros
specifying compiler intent are available, use them to determine
whether the overall intent is to support these features; otherwise,
presume an older compiler has intent to support these features and
define these macros by default. */
/* wchar_t uses Unicode 10.0.0. Version 10.0 of the Unicode Standard is
synchronized with ISO/IEC 10646:2017, fifth edition, plus
the following additions from Amendment 1 to the fifth edition:
- 56 emoji characters
- 285 hentaigana
- 3 additional Zanabazar Square characters */
//1
int test_bitAnd(int x, int y)
{
return x&y;
}
int test_tmin(void) {
return 0x80000000;
}
int test_isZero(int x) {
return x == 0;
}
int test_isTmin(int x) {
return x == 0x80000000;
}
//2
int test_allOddBits(int x) {
int i;
for (i = 1; i < 32; i+=2)
if ((x & (1<<i)) == 0)
return 0;
return 1;
}
int test_negate(int x) {
return -x;
}
int test_isNotEqual(int x, int y)
{
return x != y;
}
//3
int test_isAsciiDigit(int x) {
return (0x30 <= x) && (x <= 0x39);
}
int test_conditional(int x, int y, int z)
{
return x?y:z;
}
int test_bitMask(int highbit, int lowbit)
{
int result = 0;
int i;
for (i = lowbit; i <= highbit; i++)
result |= 1 << i;
return result;
}
//4
int test_logicalNeg(int x)
{
return !x;
}
int test_bitParity(int x) {
int result = 0;
int i;
for (i = 0; i < 32; i++)
result ^= (x >> i) & 0x1;
return result;
}
int test_absVal(int x) {
return (x < 0) ? -x : x;
}
//float
unsigned test_floatScale2(unsigned uf) {
float f = u2f(uf);
float tf = 2*f;
if (isnan(f))
return uf;
else
return f2u(tf);
}
int test_floatFloat2Int(unsigned uf) {
float f = u2f(uf);
int x = (int) f;
return x;
}
unsigned test_floatPower2(int x) {
float result = 1.0;
float p2 = 2.0;
int recip = (x < 0);
/* treat tmin specially */
if ((unsigned)x == 0x80000000) {
return 0;
}
if (recip) {
x = -x;
p2 = 0.5;
}
while (x > 0) {
if (x & 0x1)
result = result * p2;
p2 = p2 * p2;
x >>= 1;
}
return f2u(result);
}

BIN
linklab/linkbomb Executable file

Binary file not shown.

BIN
linklab/linkbomb3 Executable file

Binary file not shown.

BIN
linklab/linklab/main.o Normal file

Binary file not shown.

BIN
linklab/linklab/phase2.o Normal file

Binary file not shown.

BIN
linklab/linklab/phase3.o Normal file

Binary file not shown.

BIN
linklab/linklab1 Executable file

Binary file not shown.

BIN
linklab/main.o Normal file

Binary file not shown.

BIN
linklab/phase1.o Normal file

Binary file not shown.

16
linklab/phase1.txt Normal file
View file

@ -0,0 +1,16 @@
./phase1.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <do_phase>:
0: f3 0f 1e fa endbr64
4: 55 push %rbp
5: 48 89 e5 mov %rsp,%rbp
8: b8 00 00 00 00 mov $0x0,%eax 9: R_X86_64_32 .data+0x4c
d: 48 89 c7 mov %rax,%rdi
10: /-- e8 00 00 00 00 call 15 <do_phase+0x15> 11: R_X86_64_PLT32 puts-0x4
15: \-> 90 nop
16: 5d pop %rbp
17: c3 ret

102
linklab/phase2.elf Normal file
View file

@ -0,0 +1,102 @@
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 952 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 15
Section header string table index: 14
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000085 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 00000290
0000000000000060 0000000000000018 I 12 1 8
[ 3] .data PROGBITS 0000000000000000 000000c8
0000000000000010 0000000000000000 WA 0 0 8
[ 4] .rela.data RELA 0000000000000000 000002f0
0000000000000030 0000000000000018 I 12 3 8
[ 5] .bss NOBITS 0000000000000000 000000d8
0000000000000000 0000000000000000 WA 0 0 1
[ 6] .rodata PROGBITS 0000000000000000 000000d8
0000000000000002 0000000000000000 A 0 0 1
[ 7] .comment PROGBITS 0000000000000000 000000da
000000000000002c 0000000000000001 MS 0 0 1
[ 8] .note.GNU-stack PROGBITS 0000000000000000 00000106
0000000000000000 0000000000000000 0 0 1
[ 9] .note.gnu.pr[...] NOTE 0000000000000000 00000108
0000000000000020 0000000000000000 A 0 0 8
[10] .eh_frame PROGBITS 0000000000000000 00000128
0000000000000038 0000000000000000 A 0 0 8
[11] .rela.eh_frame RELA 0000000000000000 00000320
0000000000000018 0000000000000018 I 12 10 8
[12] .symtab SYMTAB 0000000000000000 00000160
00000000000000f0 0000000000000018 13 4 8
[13] .strtab STRTAB 0000000000000000 00000250
0000000000000040 0000000000000000 0 0 1
[14] .shstrtab STRTAB 0000000000000000 00000338
0000000000000079 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), l (large), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
There is no dynamic section in this file.
Relocation section '.rela.text' at offset 0x290 contains 4 entries:
Offset Info Type Sym. Value Sym. Name + Addend
00000000004a 00050000000b R_X86_64_32S 0000000000000020 IqLUAJPrUp + 0
000000000054 000700000004 R_X86_64_PLT32 0000000000000000 putchar - 4
00000000006a 000700000004 R_X86_64_PLT32 0000000000000000 putchar - 4
00000000007f 000800000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
Relocation section '.rela.data' at offset 0x2f0 contains 2 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000000 000300000001 R_X86_64_64 0000000000000000 .rodata + 0
000000000008 000600000001 R_X86_64_64 0000000000000000 do_phase + 0
Relocation section '.rela.eh_frame' at offset 0x320 contains 1 entry:
Offset Info Type Sym. Value Sym. Name + Addend
000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
No processor specific unwind information to decode
Symbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS phase2.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
3: 0000000000000000 0 SECTION LOCAL DEFAULT 6 .rodata
4: 0000000000000000 8 OBJECT GLOBAL DEFAULT 3 phase_id
5: 0000000000000020 256 OBJECT GLOBAL DEFAULT 5 IqLUAJPrUp
6: 0000000000000000 133 FUNC GLOBAL DEFAULT 1 do_phase
7: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND putchar
8: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __stack_chk_fail
9: 0000000000000008 8 OBJECT GLOBAL DEFAULT 3 phase
No version information found in this file.
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
Properties: x86 feature: IBT, SHSTK

102
linklab/phase2.elf.new Normal file
View file

@ -0,0 +1,102 @@
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 952 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 15
Section header string table index: 14
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000085 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 00000290
0000000000000060 0000000000000018 I 12 1 8
[ 3] .data PROGBITS 0000000000000000 000000c8
0000000000000010 0000000000000000 WA 0 0 8
[ 4] .rela.data RELA 0000000000000000 000002f0
0000000000000030 0000000000000018 I 12 3 8
[ 5] .bss NOBITS 0000000000000000 000000d8
0000000000000000 0000000000000000 WA 0 0 1
[ 6] .rodata PROGBITS 0000000000000000 000000d8
0000000000000002 0000000000000000 A 0 0 1
[ 7] .comment PROGBITS 0000000000000000 000000da
000000000000002c 0000000000000001 MS 0 0 1
[ 8] .note.GNU-stack PROGBITS 0000000000000000 00000106
0000000000000000 0000000000000000 0 0 1
[ 9] .note.gnu.pr[...] NOTE 0000000000000000 00000108
0000000000000020 0000000000000000 A 0 0 8
[10] .eh_frame PROGBITS 0000000000000000 00000128
0000000000000038 0000000000000000 A 0 0 8
[11] .rela.eh_frame RELA 0000000000000000 00000320
0000000000000018 0000000000000018 I 12 10 8
[12] .symtab SYMTAB 0000000000000000 00000160
00000000000000f0 0000000000000018 13 4 8
[13] .strtab STRTAB 0000000000000000 00000250
0000000000000040 0000000000000000 0 0 1
[14] .shstrtab STRTAB 0000000000000000 00000338
0000000000000079 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), l (large), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
There is no dynamic section in this file.
Relocation section '.rela.text' at offset 0x290 contains 4 entries:
Offset Info Type Sym. Value Sym. Name + Addend
00000000004a 00050000000b R_X86_64_32S 0000000000000020 IqLUAJPrUp + 0
000000000054 000700000004 R_X86_64_PLT32 0000000000000000 putchar - 4
00000000006a 000700000004 R_X86_64_PLT32 0000000000000000 putchar - 4
00000000007f 000800000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
Relocation section '.rela.data' at offset 0x2f0 contains 2 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000000 000300000001 R_X86_64_64 0000000000000000 .rodata + 0
000000000008 000600000001 R_X86_64_64 0000000000000000 do_phase + 0
Relocation section '.rela.eh_frame' at offset 0x320 contains 1 entry:
Offset Info Type Sym. Value Sym. Name + Addend
000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
No processor specific unwind information to decode
Symbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS phase2.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
3: 0000000000000000 0 SECTION LOCAL DEFAULT 6 .rodata
4: 0000000000000000 8 OBJECT GLOBAL DEFAULT 3 phase_id
5: 0000000000000020 256 OBJECT GLOBAL DEFAULT UND IqLUAJPrUp
6: 0000000000000000 133 FUNC GLOBAL DEFAULT 1 do_phase
7: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND putchar
8: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __stack_chk_fail
9: 0000000000000008 8 OBJECT GLOBAL DEFAULT 3 phase
No version information found in this file.
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
Properties: x86 feature: IBT, SHSTK

BIN
linklab/phase2.o Normal file

Binary file not shown.

41
linklab/phase2.txt Normal file
View file

@ -0,0 +1,41 @@
./phase2.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <do_phase>:
0: f3 0f 1e fa endbr64
4: 55 push %rbp
5: 48 89 e5 mov %rsp,%rbp
8: 48 83 ec 20 sub $0x20,%rsp
c: 64 48 8b 04 25 28 00 00 00 mov %fs:0x28,%rax
15: 48 89 45 f8 mov %rax,-0x8(%rbp)
19: 31 c0 xor %eax,%eax
1b: 48 b8 79 68 69 6a 65 72 73 76 movabs $0x767372656a696879,%rax
25: 48 89 45 ee mov %rax,-0x12(%rbp)
29: 66 c7 45 f6 71 00 movw $0x71,-0xa(%rbp)
2f: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%rbp)
36: /----- eb 24 jmp 5c <do_phase+0x5c>
38: /--|----> 8b 45 e8 mov -0x18(%rbp),%eax
3b: | | 48 98 cltq
3d: | | 0f b6 44 05 ee movzbl -0x12(%rbp,%rax,1),%eax
42: | | 0f b6 c0 movzbl %al,%eax
45: | | 48 98 cltq
47: | | 0f b6 80 00 00 00 00 movzbl 0x0(%rax),%eax 4a: R_X86_64_32S IqLUAJPrUp
4e: | | 0f be c0 movsbl %al,%eax
51: | | 89 c7 mov %eax,%edi
53: | | /-- e8 00 00 00 00 call 58 <do_phase+0x58> 54: R_X86_64_PLT32 putchar-0x4
58: | | \-> 83 45 e8 01 addl $0x1,-0x18(%rbp)
5c: | \----> 8b 45 e8 mov -0x18(%rbp),%eax
5f: | 83 f8 08 cmp $0x8,%eax
62: \-------- 76 d4 jbe 38 <do_phase+0x38>
64: bf 0a 00 00 00 mov $0xa,%edi
69: /-- e8 00 00 00 00 call 6e <do_phase+0x6e> 6a: R_X86_64_PLT32 putchar-0x4
6e: \-> 90 nop
6f: 48 8b 45 f8 mov -0x8(%rbp),%rax
73: 64 48 2b 04 25 28 00 00 00 sub %fs:0x28,%rax
7c: /-- 74 05 je 83 <do_phase+0x83>
7e: +-- e8 00 00 00 00 call 83 <do_phase+0x83> 7f: R_X86_64_PLT32 __stack_chk_fail-0x4
83: \-> c9 leave
84: c3 ret

1
linklab/phase2_patch.c Normal file
View file

@ -0,0 +1 @@
char IqLUAJPrUp[256] = "220defghi307mn2pqBstuvwxyzABCDEFGHIJKLMNOPQRSTUVW4YZ220defghi307mn2pqBstuvwxyzABCDEFGHIJKLMNOPQRSTUVW4YZ220defghi307mn2pqBstuvwxyzABCDEFGHIJKLMNOPQRSTUVW4YZ220defghi307mn2pqBstuvwxyzABCDEFGHIJKLMNOPQRSTUVW4YZ220defghi307mn2pqBstuvwxyzABCDEFGHIJKLMNOPQRSTU";

BIN
linklab/phase2_patch.o Normal file

Binary file not shown.

BIN
linklab/phase3.o Normal file

Binary file not shown.

229
linklab/phase3.txt Normal file
View file

@ -0,0 +1,229 @@
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 1952 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 16
Section header string table index: 15
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000147 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 00000408
0000000000000060 0000000000000018 I 13 1 8
[ 3] .data PROGBITS 0000000000000000 00000188
0000000000000010 0000000000000000 WA 0 0 8
[ 4] .rela.data RELA 0000000000000000 00000468
0000000000000030 0000000000000018 I 13 3 8
[ 5] .bss NOBITS 0000000000000000 00000198
0000000000000000 0000000000000000 WA 0 0 1
[ 6] .rodata PROGBITS 0000000000000000 00000198
00000000000000d8 0000000000000000 A 0 0 8
[ 7] .rela.rodata RELA 0000000000000000 00000498
0000000000000270 0000000000000018 I 13 6 8
[ 8] .comment PROGBITS 0000000000000000 00000270
000000000000002c 0000000000000001 MS 0 0 1
[ 9] .note.GNU-stack PROGBITS 0000000000000000 0000029c
0000000000000000 0000000000000000 0 0 1
[10] .note.gnu.pr[...] NOTE 0000000000000000 000002a0
0000000000000020 0000000000000000 A 0 0 8
[11] .eh_frame PROGBITS 0000000000000000 000002c0
0000000000000038 0000000000000000 A 0 0 8
[12] .rela.eh_frame RELA 0000000000000000 00000708
0000000000000018 0000000000000018 I 13 11 8
[13] .symtab SYMTAB 0000000000000000 000002f8
00000000000000d8 0000000000000018 14 4 8
[14] .strtab STRTAB 0000000000000000 000003d0
0000000000000035 0000000000000000 0 0 1
[15] .shstrtab STRTAB 0000000000000000 00000720
000000000000007e 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), l (large), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
There is no dynamic section in this file.
Relocation section '.rela.text' at offset 0x408 contains 4 entries:
Offset Info Type Sym. Value Sym. Name + Addend
00000000005e 00030000000b R_X86_64_32S 0000000000000000 .rodata + 8
000000000112 000600000004 R_X86_64_PLT32 0000000000000000 putchar - 4
00000000012c 000600000004 R_X86_64_PLT32 0000000000000000 putchar - 4
000000000141 000700000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
Relocation section '.rela.data' at offset 0x468 contains 2 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000000 000300000001 R_X86_64_64 0000000000000000 .rodata + 0
000000000008 000500000001 R_X86_64_64 0000000000000000 do_phase + 0
Relocation section '.rela.rodata' at offset 0x498 contains 26 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000008 000200000001 R_X86_64_64 0000000000000000 .text + 65
000000000010 000200000001 R_X86_64_64 0000000000000000 .text + 6e
000000000018 000200000001 R_X86_64_64 0000000000000000 .text + 77
000000000020 000200000001 R_X86_64_64 0000000000000000 .text + 80
000000000028 000200000001 R_X86_64_64 0000000000000000 .text + 89
000000000030 000200000001 R_X86_64_64 0000000000000000 .text + 8f
000000000038 000200000001 R_X86_64_64 0000000000000000 .text + 95
000000000040 000200000001 R_X86_64_64 0000000000000000 .text + 9b
000000000048 000200000001 R_X86_64_64 0000000000000000 .text + a1
000000000050 000200000001 R_X86_64_64 0000000000000000 .text + a7
000000000058 000200000001 R_X86_64_64 0000000000000000 .text + ad
000000000060 000200000001 R_X86_64_64 0000000000000000 .text + b3
000000000068 000200000001 R_X86_64_64 0000000000000000 .text + b9
000000000070 000200000001 R_X86_64_64 0000000000000000 .text + bf
000000000078 000200000001 R_X86_64_64 0000000000000000 .text + c5
000000000080 000200000001 R_X86_64_64 0000000000000000 .text + cb
000000000088 000200000001 R_X86_64_64 0000000000000000 .text + d1
000000000090 000200000001 R_X86_64_64 0000000000000000 .text + d7
000000000098 000200000001 R_X86_64_64 0000000000000000 .text + dd
0000000000a0 000200000001 R_X86_64_64 0000000000000000 .text + e3
0000000000a8 000200000001 R_X86_64_64 0000000000000000 .text + e9
0000000000b0 000200000001 R_X86_64_64 0000000000000000 .text + ef
0000000000b8 000200000001 R_X86_64_64 0000000000000000 .text + f5
0000000000c0 000200000001 R_X86_64_64 0000000000000000 .text + fb
0000000000c8 000200000001 R_X86_64_64 0000000000000000 .text + 101
0000000000d0 000200000001 R_X86_64_64 0000000000000000 .text + 107
Relocation section '.rela.eh_frame' at offset 0x708 contains 1 entry:
Offset Info Type Sym. Value Sym. Name + Addend
000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
No processor specific unwind information to decode
Symbol table '.symtab' contains 9 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS phase3.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
3: 0000000000000000 0 SECTION LOCAL DEFAULT 6 .rodata
4: 0000000000000000 8 OBJECT GLOBAL DEFAULT 3 phase_id
5: 0000000000000000 327 FUNC GLOBAL DEFAULT 1 do_phase
6: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND putchar
7: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __stack_chk_fail
8: 0000000000000008 8 OBJECT GLOBAL DEFAULT 3 phase
No version information found in this file.
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
Properties: x86 feature: IBT, SHSTK
./phase3.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <do_phase>:
0: f3 0f 1e fa endbr64
4: 55 push %rbp
5: 48 89 e5 mov %rsp,%rbp
8: 48 83 ec 20 sub $0x20,%rsp
c: 64 48 8b 04 25 28 00 00 00 mov %fs:0x28,%rax
15: 48 89 45 f8 mov %rax,-0x8(%rbp)
19: 31 c0 xor %eax,%eax
1b: 48 b8 58 55 4e 4a 45 54 49 41 movabs $0x414954454a4e5558,%rax
25: 48 89 45 ee mov %rax,-0x12(%rbp)
29: 66 c7 45 f6 59 00 movw $0x59,-0xa(%rbp)
2f: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%rbp)
36: /----- e9 df 00 00 00 jmp 11a <do_phase+0x11a>
3b: /--|----> 8b 45 e8 mov -0x18(%rbp),%eax
3e: | | 48 98 cltq
40: | | 0f b6 44 05 ee movzbl -0x12(%rbp,%rax,1),%eax
45: | | 88 45 e7 mov %al,-0x19(%rbp)
48: | | 0f be 45 e7 movsbl -0x19(%rbp),%eax
4c: | | 83 e8 41 sub $0x41,%eax
4f: | | 83 f8 19 cmp $0x19,%eax
52: | | /-- 0f 87 b3 00 00 00 ja 10b <do_phase+0x10b>
58: | | | 89 c0 mov %eax,%eax
5a: | | | 48 8b 04 c5 00 00 00 00 mov 0x0(,%rax,8),%rax 5e: R_X86_64_32S .rodata+0x8
62: | | | 3e ff e0 notrack jmp *%rax
65: | | | c6 45 e7 58 movb $0x58,-0x19(%rbp)
69: | | +-- e9 9d 00 00 00 jmp 10b <do_phase+0x10b>
6e: | | | c6 45 e7 68 movb $0x68,-0x19(%rbp)
72: | | +-- e9 94 00 00 00 jmp 10b <do_phase+0x10b>
77: | | | c6 45 e7 42 movb $0x42,-0x19(%rbp) // B
7b: | | +-- e9 8b 00 00 00 jmp 10b <do_phase+0x10b>
80: | | | c6 45 e7 70 movb $0x70,-0x19(%rbp)
84: | | +-- e9 82 00 00 00 jmp 10b <do_phase+0x10b>
89: | | | c6 45 e7 6d movb $0x6d,-0x19(%rbp)
8d: | | +-- eb 7c jmp 10b <do_phase+0x10b>
8f: | | | c6 45 e7 38 movb $0x38,-0x19(%rbp)
93: | | +-- eb 76 jmp 10b <do_phase+0x10b>
95: | | | c6 45 e7 39 movb $0x39,-0x19(%rbp)
99: | | +-- eb 70 jmp 10b <do_phase+0x10b>
9b: | | | c6 45 e7 33 movb $0x33,-0x19(%rbp) // 3
9f: | | +-- eb 6a jmp 10b <do_phase+0x10b>
a1: | | | c6 45 e7 59 movb $0x59,-0x19(%rbp)
a5: | | +-- eb 64 jmp 10b <do_phase+0x10b>
a7: | | | c6 45 e7 4f movb $0x4f,-0x19(%rbp)
ab: | | +-- eb 5e jmp 10b <do_phase+0x10b>
ad: | | | c6 45 e7 37 movb $0x37,-0x19(%rbp) // 7
b1: | | +-- eb 58 jmp 10b <do_phase+0x10b>
b3: | | | c6 45 e7 3e movb $0x3e,-0x19(%rbp)
b7: | | +-- eb 52 jmp 10b <do_phase+0x10b>
b9: | | | c6 45 e7 3e movb $0x3e,-0x19(%rbp)
bd: | | +-- eb 4c jmp 10b <do_phase+0x10b>
bf: | | | c6 45 e7 31 movb $0x31,-0x19(%rbp)
c3: | | +-- eb 46 jmp 10b <do_phase+0x10b>
c5: | | | c6 45 e7 7a movb $0x7a,-0x19(%rbp)
c9: | | +-- eb 40 jmp 10b <do_phase+0x10b>
cb: | | | c6 45 e7 57 movb $0x57,-0x19(%rbp)
cf: | | +-- eb 3a jmp 10b <do_phase+0x10b>
d1: | | | c6 45 e7 32 movb $0x32,-0x19(%rbp) // 2
d5: | | +-- eb 34 jmp 10b <do_phase+0x10b>
d7: | | | c6 45 e7 51 movb $0x51,-0x19(%rbp)
db: | | +-- eb 2e jmp 10b <do_phase+0x10b>
dd: | | | c6 45 e7 70 movb $0x70,-0x19(%rbp)
e1: | | +-- eb 28 jmp 10b <do_phase+0x10b>
e3: | | | c6 45 e7 30 movb $0x30,-0x19(%rbp) // 0
e7: | | +-- eb 22 jmp 10b <do_phase+0x10b>
e9: | | | c6 45 e7 54 movb $0x54,-0x19(%rbp)
ed: | | +-- eb 1c jmp 10b <do_phase+0x10b>
ef: | | | c6 45 e7 4d movb $0x4d,-0x19(%rbp)
f3: | | +-- eb 16 jmp 10b <do_phase+0x10b>
f5: | | | c6 45 e7 34 movb $0x34,-0x19(%rbp) // 4
f9: | | +-- eb 10 jmp 10b <do_phase+0x10b>
fb: | | | c6 45 e7 40 movb $0x40,-0x19(%rbp)
ff: | | +-- eb 0a jmp 10b <do_phase+0x10b>
101: | | | c6 45 e7 35 movb $0x35,-0x19(%rbp)
105: | | +-- eb 04 jmp 10b <do_phase+0x10b>
107: | | | c6 45 e7 36 movb $0x36,-0x19(%rbp)
10b: | | \-> 0f be 45 e7 movsbl -0x19(%rbp),%eax
10f: | | 89 c7 mov %eax,%edi
111: | | /-- e8 00 00 00 00 call 116 <do_phase+0x116> 112: R_X86_64_PLT32 putchar-0x4
116: | | \-> 83 45 e8 01 addl $0x1,-0x18(%rbp)
11a: | \----> 8b 45 e8 mov -0x18(%rbp),%eax
11d: | 83 f8 08 cmp $0x8,%eax
120: \-------- 0f 86 15 ff ff ff jbe 3b <do_phase+0x3b>
126: bf 0a 00 00 00 mov $0xa,%edi
12b: /-- e8 00 00 00 00 call 130 <do_phase+0x130> 12c: R_X86_64_PLT32 putchar-0x4
130: \-> 90 nop
131: 48 8b 45 f8 mov -0x8(%rbp),%rax
135: 64 48 2b 04 25 28 00 00 00 sub %fs:0x28,%rax
13e: /-- 74 05 je 145 <do_phase+0x145>
140: +-- e8 00 00 00 00 call 145 <do_phase+0x145> 141: R_X86_64_PLT32 __stack_chk_fail-0x4
145: \-> c9 leave
146: c3 ret