Init
This commit is contained in:
commit
dede1e63fe
45 changed files with 5523 additions and 0 deletions
7
bomblab/bomb126/B22040723.txt
Normal file
7
bomblab/bomb126/B22040723.txt
Normal 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
3
bomblab/bomb126/README
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
This is bomb 126.
|
||||||
|
|
||||||
|
It belongs to B22040723 (me@kagurach.uk)
|
8
bomblab/bomb126/a.py
Normal file
8
bomblab/bomb126/a.py
Normal 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
BIN
bomblab/bomb126/bomb
Executable file
Binary file not shown.
115
bomblab/bomb126/bomb.c
Normal file
115
bomblab/bomb126/bomb.c
Normal 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
2001
bomblab/bomb126/linker.txt
Normal file
File diff suppressed because it is too large
Load diff
1
bomblab/bomb126/res1.txt
Normal file
1
bomblab/bomb126/res1.txt
Normal 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
430
bomblab/bomb126/strings.txt
Normal 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
131
bomblab/bomb126/symbols.txt
Normal 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
28
datalab-handout/.vscode/tasks.json
vendored
Normal 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"
|
||||||
|
}
|
12
datalab-handout/Driverhdrs.pm
Normal file
12
datalab-handout/Driverhdrs.pm
Normal 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;
|
138
datalab-handout/Driverlib.pm
Normal file
138
datalab-handout/Driverlib.pm
Normal 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
26
datalab-handout/Makefile
Normal 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
140
datalab-handout/README
Normal 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
389
datalab-handout/bits.c
Normal 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
72
datalab-handout/bits.h
Normal 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
BIN
datalab-handout/btest
Executable file
Binary file not shown.
583
datalab-handout/btest.c
Normal file
583
datalab-handout/btest.c
Normal 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
32
datalab-handout/btest.h
Normal 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
95
datalab-handout/decl.c
Normal 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
BIN
datalab-handout/dlc
Executable file
Binary file not shown.
439
datalab-handout/driver.pl
Executable file
439
datalab-handout/driver.pl
Executable 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
BIN
datalab-handout/fshow
Executable file
Binary file not shown.
151
datalab-handout/fshow.c
Normal file
151
datalab-handout/fshow.c
Normal 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
BIN
datalab-handout/ishow
Executable file
Binary file not shown.
75
datalab-handout/ishow.c
Normal file
75
datalab-handout/ishow.c
Normal 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
BIN
datalab-handout/lab1.doc
Normal file
Binary file not shown.
156
datalab-handout/tests.c
Normal file
156
datalab-handout/tests.c
Normal 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
BIN
linklab/linkbomb
Executable file
Binary file not shown.
BIN
linklab/linkbomb3
Executable file
BIN
linklab/linkbomb3
Executable file
Binary file not shown.
BIN
linklab/linklab/main.o
Normal file
BIN
linklab/linklab/main.o
Normal file
Binary file not shown.
BIN
linklab/linklab/phase2.o
Normal file
BIN
linklab/linklab/phase2.o
Normal file
Binary file not shown.
BIN
linklab/linklab/phase3.o
Normal file
BIN
linklab/linklab/phase3.o
Normal file
Binary file not shown.
BIN
linklab/linklab1
Executable file
BIN
linklab/linklab1
Executable file
Binary file not shown.
BIN
linklab/main.o
Normal file
BIN
linklab/main.o
Normal file
Binary file not shown.
BIN
linklab/phase1.o
Normal file
BIN
linklab/phase1.o
Normal file
Binary file not shown.
16
linklab/phase1.txt
Normal file
16
linklab/phase1.txt
Normal 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
102
linklab/phase2.elf
Normal 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
102
linklab/phase2.elf.new
Normal 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
BIN
linklab/phase2.o
Normal file
Binary file not shown.
41
linklab/phase2.txt
Normal file
41
linklab/phase2.txt
Normal 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
1
linklab/phase2_patch.c
Normal file
|
@ -0,0 +1 @@
|
||||||
|
char IqLUAJPrUp[256] = "220defghi307mn2pqBstuvwxyzABCDEFGHIJKLMNOPQRSTUVW4YZ220defghi307mn2pqBstuvwxyzABCDEFGHIJKLMNOPQRSTUVW4YZ220defghi307mn2pqBstuvwxyzABCDEFGHIJKLMNOPQRSTUVW4YZ220defghi307mn2pqBstuvwxyzABCDEFGHIJKLMNOPQRSTUVW4YZ220defghi307mn2pqBstuvwxyzABCDEFGHIJKLMNOPQRSTU";
|
BIN
linklab/phase2_patch.o
Normal file
BIN
linklab/phase2_patch.o
Normal file
Binary file not shown.
BIN
linklab/phase3.o
Normal file
BIN
linklab/phase3.o
Normal file
Binary file not shown.
229
linklab/phase3.txt
Normal file
229
linklab/phase3.txt
Normal 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
|
Loading…
Reference in a new issue