summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/BuildImage.c420
-rw-r--r--util/default.ld247
-rw-r--r--util/gdbinit31
-rw-r--r--util/listblob.c240
-rw-r--r--util/mkblob.c321
5 files changed, 0 insertions, 1259 deletions
diff --git a/util/BuildImage.c b/util/BuildImage.c
deleted file mode 100644
index f43f0b0..0000000
--- a/util/BuildImage.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/**
-** SCCS ID: @(#)BuildImage.c 2.2 1/16/25
-**
-** @file BuildImage.c
-**
-** @author K. Reek
-** @author Jon Coles
-** @author Warren R. Carithers
-** @author Garrett C. Smith
-**
-** Modify the bootstrap image to include the information
-** on the programs to be loaded, and produce the file
-** that contains the concatenation of these programs.
-**
-*/
-
-#define _POSIX_C_SOURCE 200809L
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#define TRUE 1
-#define FALSE 0
-
-#define DRIVE_FLOPPY 0x00
-#define DRIVE_USB 0x80
-
-#define SECT_SIZE 512
-
-char *progname; /* invocation name of this program */
-char *bootstrap_filename; /* path of file holding bootstrap program */
-char *output_filename; /* path of disk image file */
-FILE *out; /* output stream for disk image file */
-short drive = DRIVE_USB; /* boot drive */
-
-/*
-** Array into which program information will be stored, starting at the
-** end and moving back toward the front. The array is the same size as
-** a sector, which is guaranteed to be larger than the maximum possible
-** space available for this stuff in the bootstrap image. Thus, the
-** bootstrap image itself (and the amount of space available on the
-** device) are the only limiting factors on how many program sections
-** can be loaded.
-*/
-
-#define N_INFO (SECT_SIZE / sizeof(short))
-
-short info[N_INFO];
-int n_info = N_INFO;
-
-/**
-** quit with an appropriate message
-**
-** @param msg NULL, or a message to be printed to stderr
-** @param call_perror non-zero if perror() should be used; else,
-** fprintf() will be used
-**
-** does not return
-*/
-void quit(char *msg, int call_perror)
-{
- if (msg != NULL) {
- // preserve the error code in case we need it
- int err_num = errno;
- fprintf(stderr, "%s: ", progname);
- errno = err_num;
- if (call_perror) {
- perror(msg);
- } else {
- fprintf(stderr, "%s\n", msg);
- }
- }
- if (output_filename != NULL) {
- unlink(output_filename);
- }
- exit(EXIT_FAILURE);
- // NOTREACHED
-}
-
-const char usage_error_msg[] =
- "\nUsage: %s [ -d drive ] -b bootfile -o outfile { progfile loadpt } ...\n\n"
- "\t'drive' is either 'floppy' or 'usb' (default 'usb')\n\n"
- "\tThere must be at least one program file and load point.\n\n"
- "\tLoad points may be specified either as 32-bit quantities in hex,\n"
- "\tdecimal or octal (e.g. 0x10c00, 68608, 0206000 are all equivalent),\n"
- "\tor as an explicit segment:offset pair whose digits are always\n"
- "\tinterpreted as hexadecimal values (e.g. 10c0:0000, 1000:0c00 are\n"
- "\tboth equivalent to the previous examples).\n\n";
-
-/**
-** print a usage message and then call quit()
-**
-** does not return
-*/
-void usage_error(void)
-{
- fprintf(stderr, usage_error_msg, progname);
- quit(NULL, FALSE);
- // NOTREACHED
-}
-
-/**
-** copy the contents of a binary file into the output file, padding the
-** last sector with NUL bytes
-**
-** @param in open FILE to be read
-** @return the number of sectors copied from the file
-*/
-int copy_file(FILE *in)
-{
- int n_sectors = 0;
- char buf[SECT_SIZE];
- int n_bytes;
- int i;
-
- /*
- ** Copy the file to the output, being careful that the
- ** last sector is padded with null bytes out to the
- ** sector size.
- */
- n_sectors = 0;
- while ((n_bytes = fread(buf, 1, sizeof(buf), in)) > 0) {
- // pad this sector out to block size
- if (n_bytes < sizeof(buf)) {
- int i;
-
- for (i = n_bytes; i < sizeof(buf); i += 1) {
- buf[i] = '\0';
- }
- }
- if (fwrite(buf, 1, sizeof(buf), out) != sizeof(buf)) {
- quit("Write failed or was wrong size", FALSE);
- }
- n_sectors += 1;
- }
- return n_sectors;
-}
-
-/**
-** process a file whose contents should be at a specific'
-** address in memory when the program is loaded
-**
-** @param name path to the file to be copied
-** @param addr string containing the load address
-*/
-void process_file(char *name, char *addr)
-{
- long address;
- short segment, offset;
- int n_bytes;
-
- /*
- ** Open the input file.
- */
- FILE *in = fopen(name, "rb");
- if (in == NULL) {
- quit(name, TRUE);
- }
-
- /*
- ** Copy the file to the output, being careful that the
- ** last block is padded with null bytes.
- */
- int n_sectors = copy_file(in);
- fclose(in);
-
- /*
- ** Decode the address they gave us. We'll accept two forms:
- ** "nnnn:nnnn" for a segment:offset value (assumed to be hex),
- ** "nnnnnnn" for a decimal, hex, or octal value
- */
- int valid_address = FALSE;
- char *cp = strchr(addr, ':');
- if (cp != NULL) {
- // must be in nnnn:nnnn form exactly
- if (strlen(addr) == 9 && cp == addr + 4) {
- char *ep1, *ep2;
- int a1, a2;
-
- segment = strtol(addr, &ep1, 16);
- offset = strtol(addr + 5, &ep2, 16);
- address = (segment << 4) + offset;
- valid_address = *ep1 == '\0' && *ep2 == '\0';
- } else {
- fprintf(stderr, "Bad address format - '%s'\n", addr);
- quit(NULL, FALSE);
- }
- } else {
- // just a number, possibly hex or octal
- char *ep;
-
- address = strtol(addr, &ep, 0);
- segment = (short)(address >> 4);
- offset = (short)(address & 0xf);
- valid_address = *ep == '\0' && address <= 0x0009ffff;
- }
-
- if (!valid_address) {
- fprintf(stderr, "%s: Invalid address: %s\n", progname, addr);
- quit(NULL, FALSE);
- }
-
- /*
- ** Make sure the program will fit!
- */
- if (address + n_sectors * SECT_SIZE > 0x0009ffff) {
- fprintf(stderr, "Program %s too large to start at 0x%08x\n", name,
- (unsigned int)address);
- quit(NULL, FALSE);
- }
-
- if (n_info < 3) {
- quit("Too many programs!", FALSE);
- }
-
- /*
- ** Looks good: report and store the information.
- */
- fprintf(stderr, " %s: %d sectors, loaded at 0x%x\n", name, n_sectors,
- (unsigned int)address);
-
- info[--n_info] = n_sectors;
- info[--n_info] = segment;
- info[--n_info] = offset;
-}
-
-/*
-** Global variables set by getopt()
-*/
-
-extern int optind, optopt;
-extern char *optarg;
-
-/**
-** process the command-line arguments
-**
-** @param ac the count of entries in av
-** @param av the argument vector
-*/
-void process_args(int ac, char **av)
-{
- int c;
-
- while ((c = getopt(ac, av, ":d:o:b:")) != EOF) {
- switch (c) {
- case ':': /* missing arg value */
- fprintf(stderr, "missing operand after -%c\n", optopt);
- /* FALL THROUGH */
-
- case '?': /* error */
- usage_error();
- /* NOTREACHED */
-
- case 'b': /* -b bootstrap_file */
- bootstrap_filename = optarg;
- break;
-
- case 'd': /* -d drive */
- switch (*optarg) {
- case 'f':
- drive = DRIVE_FLOPPY;
- break;
- case 'u':
- drive = DRIVE_USB;
- break;
- default:
- usage_error();
- }
- break;
-
- case 'o': /* -o output_file */
- output_filename = optarg;
- break;
-
- default:
- usage_error();
- }
- }
-
- if (!bootstrap_filename) {
- fprintf(stderr, "%s: no bootstrap file specified\n", progname);
- exit(2);
- }
-
- if (!output_filename) {
- fprintf(stderr, "%s: no disk image file specified\n", progname);
- exit(2);
- }
-
- /*
- ** Must have at least two remaining arguments (file to load,
- ** address at which it should be loaded), and must have an
- ** even number of remaining arguments.
- */
- int remain = ac - optind;
- if (remain < 2 || (remain & 1) != 0) {
- usage_error();
- }
-}
-
-/**
-** build a bootable image file from one or more binary files
-**
-** usage:
-** BuildImage [ -d drive ] -b bootfile -o outfile { binfile1 loadpt1 } ... ]
-**
-** @param ac command-line argument count
-** @param av command-line argument vector
-** @return EXIT_SUCCESS or EXIT_FAILURE
-*/
-int main(int ac, char **av)
-{
- FILE *bootimage;
- int bootimage_size;
- int n_bytes, n_words;
- short existing_data[N_INFO];
- int i;
-
- /*
- ** Save the program name for error messages
- */
- progname = strrchr(av[0], '/');
- if (progname != NULL) {
- progname++;
- } else {
- progname = av[0];
- }
-
- /*
- ** Process arguments
- */
- process_args(ac, av);
-
- /*
- ** Open the output file
- */
-
- out = fopen(output_filename, "wb+");
- if (out == NULL) {
- quit(output_filename, TRUE);
- }
-
- /*
- ** Open the bootstrap file and copy it to the output image.
- */
- bootimage = fopen(bootstrap_filename, "rb");
- if (bootimage == NULL) {
- quit(bootstrap_filename, TRUE);
- }
-
- /*
- ** Remember the size of the bootstrap for later, as we
- ** need to patch some things into it
- */
- int n_sectors = copy_file(bootimage);
- fclose(bootimage);
-
- bootimage_size = n_sectors * SECT_SIZE;
- fprintf(stderr, " %s: %d sectors\n", bootstrap_filename, n_sectors);
-
- /*
- ** Process the programs one by one
- */
- ac -= optind;
- av += optind;
- while (ac >= 2) {
- process_file(av[0], av[1]);
- ac -= 2;
- av += 2;
- }
-
- /*
- ** Check for oddball leftover argument
- */
- if (ac > 0) {
- usage_error();
- }
-
- /*
- ** Seek to where the array of module data must begin and read
- ** what's already there.
- */
- n_words = (N_INFO - n_info);
- n_bytes = n_words * sizeof(info[0]);
- fseek(out, bootimage_size - n_bytes, SEEK_SET);
- if (fread(existing_data, sizeof(info[0]), n_words, out) != n_words) {
- quit("Read from boot image failed or was too short", FALSE);
- }
-
- /*
- ** If that space is non-zero, we have a problem
- */
- for (i = 0; i < n_words; i += 1) {
- if (existing_data[i] != 0) {
- quit("Too many programs to load!", FALSE);
- }
- }
-
- /*
- ** We know that we're only overwriting zeros at the end of
- ** the bootstrap image, so it is ok to go ahead and do it.
- */
- fseek(out, bootimage_size - n_bytes, SEEK_SET);
- if (fwrite(info + n_info, sizeof(info[0]), n_words, out) != n_words) {
- quit("Write to boot image failed or was too short", FALSE);
- }
-
- /*
- ** Write the drive index to the image.
- */
- fseek(out, 508, SEEK_SET);
- fwrite((void *)&drive, sizeof(drive), 1, out);
-
- fclose(out);
-
- return EXIT_SUCCESS;
-}
diff --git a/util/default.ld b/util/default.ld
deleted file mode 100644
index 0c600e4..0000000
--- a/util/default.ld
+++ /dev/null
@@ -1,247 +0,0 @@
-GNU ld (GNU Binutils for Ubuntu) 2.30
- Supported emulations:
- elf_x86_64
- elf32_x86_64
- elf_i386
- elf_iamcu
- i386linux
- elf_l1om
- elf_k1om
- i386pep
- i386pe
-using internal linker script:
-==================================================
-/* Script for -z combreloc: combine and sort reloc sections */
-/* Copyright (C) 2014-2018 Free Software Foundation, Inc.
- Copying and distribution of this script, with or without modification,
- are permitted in any medium without royalty provided the copyright
- notice and this notice are preserved. */
-OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
- "elf64-x86-64")
-OUTPUT_ARCH(i386:x86-64)
-ENTRY(_start)
-SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib");
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .note.gnu.build-id : { *(.note.gnu.build-id) }
- .hash : { *(.hash) }
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rela.dyn :
- {
- *(.rela.init)
- *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
- *(.rela.fini)
- *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
- *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
- *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
- *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
- *(.rela.ctors)
- *(.rela.dtors)
- *(.rela.got)
- *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
- *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
- *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
- *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
- *(.rela.ifunc)
- }
- .rela.plt :
- {
- *(.rela.plt)
- PROVIDE_HIDDEN (__rela_iplt_start = .);
- *(.rela.iplt)
- PROVIDE_HIDDEN (__rela_iplt_end = .);
- }
- .init :
- {
- KEEP (*(SORT_NONE(.init)))
- }
- .plt : { *(.plt) *(.iplt) }
-.plt.got : { *(.plt.got) }
-.plt.sec : { *(.plt.sec) }
- .text :
- {
- *(.text.unlikely .text.*_unlikely .text.unlikely.*)
- *(.text.exit .text.exit.*)
- *(.text.startup .text.startup.*)
- *(.text.hot .text.hot.*)
- *(.text .stub .text.* .gnu.linkonce.t.*)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- }
- .fini :
- {
- KEEP (*(SORT_NONE(.fini)))
- }
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
- .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
- .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
- .gcc_except_table.*) }
- .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
- /* These sections are generated by the Sun/Oracle C++ compiler. */
- .exception_ranges : ONLY_IF_RO { *(.exception_ranges
- .exception_ranges*) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
- /* Exception handling */
- .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
- .gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
- .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
- .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
- /* Thread Local Storage sections */
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .preinit_array :
- {
- PROVIDE_HIDDEN (__preinit_array_start = .);
- KEEP (*(.preinit_array))
- PROVIDE_HIDDEN (__preinit_array_end = .);
- }
- .init_array :
- {
- PROVIDE_HIDDEN (__init_array_start = .);
- KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
- KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
- PROVIDE_HIDDEN (__init_array_end = .);
- }
- .fini_array :
- {
- PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
- KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
- PROVIDE_HIDDEN (__fini_array_end = .);
- }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin.o(.ctors))
- KEEP (*crtbegin?.o(.ctors))
- /* We don't want to include the .ctor section from
- the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin.o(.dtors))
- KEEP (*crtbegin?.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .jcr : { KEEP (*(.jcr)) }
- .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
- .dynamic : { *(.dynamic) }
- .got : { *(.got) *(.igot) }
- . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
- .got.plt : { *(.got.plt) *(.igot.plt) }
- .data :
- {
- *(.data .data.* .gnu.linkonce.d.*)
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- _edata = .; PROVIDE (edata = .);
- . = .;
- __bss_start = .;
- .bss :
- {
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections.
- FIXME: Why do we need it? When there is no .bss section, we don't
- pad the .data section. */
- . = ALIGN(. != 0 ? 64 / 8 : 1);
- }
- .lbss :
- {
- *(.dynlbss)
- *(.lbss .lbss.* .gnu.linkonce.lb.*)
- *(LARGE_COMMON)
- }
- . = ALIGN(64 / 8);
- . = SEGMENT_START("ldata-segment", .);
- .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
- {
- *(.lrodata .lrodata.* .gnu.linkonce.lr.*)
- }
- .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
- {
- *(.ldata .ldata.* .gnu.linkonce.l.*)
- . = ALIGN(. != 0 ? 64 / 8 : 1);
- }
- . = ALIGN(64 / 8);
- _end = .; PROVIDE (end = .);
- . = DATA_SEGMENT_END (.);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* DWARF 3 */
- .debug_pubtypes 0 : { *(.debug_pubtypes) }
- .debug_ranges 0 : { *(.debug_ranges) }
- /* DWARF Extension. */
- .debug_macro 0 : { *(.debug_macro) }
- .debug_addr 0 : { *(.debug_addr) }
- .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
- /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
-}
-
-
-==================================================
diff --git a/util/gdbinit b/util/gdbinit
deleted file mode 100644
index ca2c885..0000000
--- a/util/gdbinit
+++ /dev/null
@@ -1,31 +0,0 @@
-# adapted from the xv6 .gdbinit.tmpl file
-set $lastcs = -1
-
-define hook-stop
- # There doesn't seem to be a good way to detect if we're in 16- or
- # 32-bit mode, but we always run with CS == 8 in 32-bit mode.
- if $cs == 8 || $cs == 27
- if $lastcs != 8 && $lastcs != 27
- set architecture i386
- end
- x/i $pc
- else
- if $lastcs == -1 || $lastcs == 8 || $lastcs == 27
- set architecture i8086
- end
- # Translate the segment:offset into a physical address
- printf "[%4x:%4x] ", $cs, $eip
- x/i $cs*16+$eip
- end
- set $lastcs = $cs
-end
-
-echo + target remote localhost:1337\n
-target remote localhost:1337
-
-# If this fails, it's probably because your GDB doesn't support ELF.
-# Look at the tools page at
-# http://pdos.csail.mit.edu/6.828/2009/tools.html
-# for instructions on building GDB with ELF support.
-echo + symbol-file build/kernel/kernel\n
-symbol-file build/kernel/kernel
diff --git a/util/listblob.c b/util/listblob.c
deleted file mode 100644
index e6266a3..0000000
--- a/util/listblob.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/**
-** @file listblob.c
-**
-** @author Warren R. Carithers
-**
-** Examine a binary blob of ELF files.
-*/
-#define _DEFAULT_SOURCE
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <elf.h>
-#include <ctype.h>
-
-/*
-** Blob file organization
-**
-** The file begins with a four-byte magic number and a four-byte integer
-** indicating the number of ELF files contained in the blob. This is
-** followed by an array of 32-byte file entries, and then the contents
-** of the ELF files in the order they appear in the program file table.
-**
-** Bytes Contents
-** ----- ----------------------------
-** 0 - 3 File magic number ("BLB\0")
-** 4 - 7 Number of ELF files in blob ("n")
-** 8 - n*32+8 Program file table
-** n*32+9 - ? ELF file contents
-**
-** Each program file table entry contains the following information:
-**
-** name File name (up to 19 characters long)
-** offset Byte offset to the ELF header for this file
-** size Size of this ELF file, in bytes
-** flags Flags related to this file
-*/
-
-// blob header: 8 bytes
-typedef struct header_s {
- char magic[4];
- uint32_t num;
-} header_t;
-
-// The program table entry is 32 bytes long. To accomplish this, the
-// name field is 20 bytes long, which allows file names of 19 characters
-// (followed by a trailing NUL byte).
-//
-// If that field is made longer, it should be incremented in multiples
-// of four to avoid the insertion of padding bytes.
-#define NAMELEN 20
-
-// program descriptor: 32 bytes
-typedef struct prog_s {
- char name[NAMELEN]; // truncated name (19 chars plus NUL)
- uint32_t offset; // offset from the beginning of the blob
- uint32_t size; // size of this ELF module
- uint32_t flags; // miscellaneous flags
-} prog_t;
-
-// modules must be written as multiples of eight bytes
-#define FL_ROUNDUP 0x00000001
-
-// mask for mod 8 checking
-#define FSIZE_MASK 0x00000007
-
-// program list entry
-typedef struct node_s {
- prog_t *data;
- struct node_s *next;
-} node_t;
-
-node_t *progs, *last_prog; // list pointers
-uint32_t n_progs; // number of files being copied
-uint32_t offset; // current file area offset
-bool defs = false; // print CPP #defines?
-bool enums = false; // print C enums?
-
-// header string for the userids.h file
-const char header[] =
- "/**\n"
- "** @file userids.h\n"
- "**\n"
- "** @author Warren R. Carithers\n"
- "**\n"
- "** @brief IDs for user-level programs\n"
- "**\n"
- "** NOTE: this file is automatically generated when the user.img file\n"
- "** is created. Do not edit this manually!\n"
- "*/\n"
- "\n"
- "#ifndef USERIDS_H_\n"
- "#define USERIDS_H_\n"
- "\n"
- "#ifndef ASM_SRC\n"
- "/*\n"
- "** These IDs are used to identify the various user programs.\n"
- "** Each call to exec() will provide one of these as the first\n"
- "** argument.\n"
- "**\n"
- "** This list should be updated if/when the collection of\n"
- "** user processes changes.\n"
- "*/\n"
- "enum users_e {";
-
-// trailer string for the userids.h file
-const char trailer[] = "\n\t// sentinel\n\t, N_USERS\n"
- "};\n"
- "#endif /* !ASM_SRC */\n"
- "\n"
- "#endif";
-
-/**
-** Name: process
-**
-** Process a program list entry
-**
-** @param num Program list index
-** @param prog Pointer to the program list entry
-*/
-void process(uint32_t num, prog_t *prog)
-{
- if (defs || enums) {
- char *slash = strrchr(prog->name, '/');
- if (slash == NULL) {
- slash = prog->name;
- } else {
- ++slash;
- }
-
- slash[0] = toupper(slash[0]);
-
- if (defs) {
- // just printing #define statements
- printf("#define %-15s %2d\n", prog->name, num);
-
- } else {
- // printing a new userids.h file
- if (num == 0) {
- // first one, so print the file header
- puts(header);
- putchar('\t');
- } else {
- // second or later entry; limit to 8 per line
- fputs(((num & 0x7) == 0) ? ",\n\t" : ", ", stdout);
- }
- printf("%s", prog->name);
- }
-
- } else {
- // just printing information
- printf("Entry %2d: ", num);
- printf("%-s,", prog->name);
- printf(" offset 0x%x, size 0x%x, flags %08x\n", prog->offset,
- prog->size, prog->flags);
- }
-}
-
-void usage(char *name)
-{
- fprintf(stderr, "usage: %s [-d | -e] blob_name\n", name);
-}
-
-int main(int argc, char *argv[])
-{
- if (argc < 2 || argc > 3) {
- usage(argv[0]);
- exit(1);
- }
-
- int nameix = 1;
-
- // could use getopt() for this, but this is easy enough
- if (argc == 3) {
- if (strcmp(argv[1], "-d") == 0) {
- defs = true;
- } else if (strcmp(argv[1], "-e") == 0) {
- enums = true;
- } else {
- usage(argv[0]);
- exit(1);
- }
- nameix = 2;
- }
-
- char *name = argv[nameix];
-
- int fd = open(name, O_RDONLY);
- if (fd < 0) {
- perror(name);
- exit(1);
- }
-
- header_t hdr;
-
- int n = read(fd, &hdr, sizeof(header_t));
- if (n != sizeof(header_t)) {
- fprintf(stderr, "%s: header read returned only %d bytes\n", name, n);
- close(fd);
- exit(1);
- }
-
- if (strcmp(hdr.magic, "BLB") != 0) {
- fprintf(stderr, "%s: bad magic number\n", name);
- close(fd);
- exit(1);
- }
-
- if (hdr.num < 1) {
- fprintf(stderr, "%s: no programs in blob?\n", name);
- close(fd);
- exit(1);
- }
-
- prog_t progs[hdr.num];
-
- n = read(fd, progs, hdr.num * sizeof(prog_t));
- if (n != (int)(hdr.num * sizeof(prog_t))) {
- fprintf(stderr, "%s: prog table only %d bytes, expected %lu\n", name, n,
- hdr.num * sizeof(prog_t));
- close(fd);
- exit(1);
- }
-
- for (uint32_t i = 0; i < hdr.num; ++i) {
- process(i, &progs[i]);
- }
-
- if (enums) {
- // print the file trailer
- puts(trailer);
- }
-
- close(fd);
- return 0;
-}
diff --git a/util/mkblob.c b/util/mkblob.c
deleted file mode 100644
index ea6a946..0000000
--- a/util/mkblob.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/**
-** @file mkblob.c
-**
-** @author Warren R. Carithers
-**
-** Create a binary blob from a collection of ELF files.
-*/
-#define _DEFAULT_SOURCE
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <elf.h>
-
-/*
-** Blob file organization
-**
-** The file begins with a four-byte magic number and a four-byte integer
-** indicating the number of ELF files contained in the blob. This is
-** followed by an array of 32-byte file table entries, and then the contents
-** of the ELF files in the order they appear in the program file table.
-**
-** Bytes Contents
-** ----- ----------------------------
-** 0 - 3 File magic number ("BLB\0")
-** 4 - 7 Number of ELF files in blob ("n")
-** 8 - n*32+8 Program file table
-** n*32+9 - ? ELF file contents
-**
-** Each program file table entry contains the following information:
-**
-** name File name (up to 19 characters long)
-** offset Byte offset to the ELF header for this file
-** size Size of this ELF file, in bytes
-** flags Flags related to this file
-*/
-
-// blob header
-typedef struct header_s {
- char magic[4];
- uint32_t num;
-} header_t;
-
-// length of the file name field
-#define NAMELEN 20
-
-// program descriptor
-typedef struct prog_s {
- char name[NAMELEN]; // truncated name (15 chars)
- uint32_t offset; // offset from the beginning of the blob
- uint32_t size; // size of this ELF module
- uint32_t flags; // miscellaneous flags
-} prog_t;
-
-// modules must be written as multiples of eight bytes
-#define FL_ROUNDUP 0x00000001
-
-// mask for mod 8 checking
-#define FSIZE_MASK 0x00000007
-
-// program list entry
-typedef struct node_s {
- prog_t *data;
- char *fullname;
- struct node_s *next;
-} node_t;
-
-node_t *progs, *last_prog; // list pointers
-uint32_t n_progs; // number of files being copied
-uint32_t offset; // current file area offset
-
-/**
-** Name: process
-**
-** Do the initial processing for an ELF file
-**
-** @param name The name of the file
-*/
-void process(const char *name)
-{
- struct stat info;
-
- // check the name length
- if (strlen(name) >= NAMELEN) {
- fprintf(stderr, "%s: name exceeds length limit (%d)\n", name,
- NAMELEN - 1);
- return;
- }
-
- // does it exist?
- if (stat(name, &info) < 0) {
- perror(name);
- return;
- }
-
- // is it a regular file?
- if (!S_ISREG(info.st_mode)) {
- fprintf(stderr, "%s: not a regular file\n", name);
- return;
- }
-
- // open it and check the file header
- int fd = open(name, O_RDONLY);
- if (fd < 0) {
- perror(name);
- return;
- }
-
- // read and check the ELF header
- Elf32_Ehdr hdr;
- int n = read(fd, &hdr, sizeof(Elf32_Ehdr));
- close(fd);
-
- if (n != sizeof(Elf32_Ehdr)) {
- fprintf(stderr, "%s: header read was short - only %d\n", name, n);
- return;
- }
-
- if (hdr.e_ident[EI_MAG0] != ELFMAG0 || hdr.e_ident[EI_MAG1] != ELFMAG1 ||
- hdr.e_ident[EI_MAG2] != ELFMAG2 || hdr.e_ident[EI_MAG3] != ELFMAG3) {
- fprintf(stderr, "%s: bad ELF magic number\n", name);
- return;
- }
-
- // ok, it's a valid ELF file - create the prog list entry
- prog_t *new = calloc(1, sizeof(prog_t));
- if (new == NULL) {
- fprintf(stderr, "%s: calloc prog returned NULL\n", name);
- return;
- }
-
- node_t *node = calloc(1, sizeof(node_t));
- if (node == NULL) {
- free(new);
- fprintf(stderr, "%s: calloc node returned NULL\n", name);
- return;
- }
-
- node->data = new;
- node->fullname = strdup(name);
-
- // copy in the name
-
- // only want the last component
- const char *slash = strrchr(name, '/');
- if (slash == NULL) {
- // only the file name
- slash = name;
- } else {
- // skip the slash
- ++slash;
- }
-
- strncpy(new->name, slash, sizeof(new->name) - 1);
- new->offset = offset;
- new->size = info.st_size;
-
- // bump our counters
- ++n_progs;
- offset += info.st_size;
-
- // make sure it's a multiple of eight bytes long
- if ((info.st_size & FSIZE_MASK) != 0) {
- // nope, so we must round it up when we write it out
- new->flags |= FL_ROUNDUP;
- // increases the offset to the next file
- offset += 8 - (info.st_size & FSIZE_MASK);
- }
-
- // add to the list
- if (progs == NULL) {
- // first entry
- progs = node;
- } else {
- // add to the end
- if (last_prog == NULL) {
- fprintf(stderr, "%s: progs ! NULL, last_prog is NULL\n", name);
- free(new);
- free(node->fullname);
- free(node);
- return;
- }
- last_prog->next = node;
- }
- last_prog = node;
-}
-
-/**
-** Name: copy
-**
-** Copy the contents of a program list entry into the blob
-**
-** @param ofd The output FILE* to be written
-** @param prog Pointer to the program list entry for the file
-*/
-void copy(FILE *ofd, node_t *node)
-{
- prog_t *prog = node->data;
-
- // open it so we can copy it
- int fd = open(node->fullname, O_RDONLY);
- if (fd < 0) {
- perror(node->fullname);
- return;
- }
-
- uint8_t buf[512];
-
- // copy it block-by-block
- do {
- int n = read(fd, buf, 512);
- // no bytes --> we're done
- if (n < 1) {
- break;
- }
- // copy it, and verify the copy count
- int k = fwrite(buf, 1, n, ofd);
- if (k != n) {
- fprintf(stderr, "%s: write of %d returned %d\n", prog->name, n, k);
- }
- } while (1);
-
- printf("%s: copied %d", prog->name, prog->size);
-
- // do we need to round up?
- if ((prog->flags & FL_ROUNDUP) != 0) {
- // we'll fill with NUL bytes
- uint64_t filler = 0;
-
- // how many filler bytes do we need?
- int nbytes = 8 - (prog->size & FSIZE_MASK);
-
- // do it, and check the transfer count to be sure
- int n = fwrite(&filler, 1, nbytes, ofd);
- if (n != nbytes) {
- fprintf(stderr, "%s: fill write of %d returned %d\n", prog->name,
- nbytes, n);
- }
-
- // report that we added some filler bytes
- printf("(+%d)", n);
- }
- puts(" bytes");
-
- // all done!
- close(fd);
-}
-
-int main(int argc, char *argv[])
-{
- // construct program list
- for (int i = 1; i < argc; ++i) {
- process(argv[i]);
- }
-
- if (n_progs < 1) {
- fputs("Nothing to do... exiting.", stderr);
- exit(0);
- }
-
- // create the output file
- FILE *ofd;
- ofd = fopen("user.img", "wb");
- if (ofd == NULL) {
- perror("user.img");
- exit(1);
- }
-
- printf("Processing %d ELF files\n", n_progs);
-
- // we need to adjust the offset values so they are relative to the
- // start of the blob, not relative to the start of the file area.
- // do this by adding the sum of the file header and program entries
- // to each offset field.
-
- uint32_t hlen = sizeof(header_t) + n_progs * sizeof(prog_t);
- node_t *curr = progs;
- while (curr != NULL) {
- curr->data->offset += hlen;
- curr = curr->next;
- }
-
- // write out the blob header
- header_t hdr = { "BLB", n_progs };
- if (fwrite(&hdr, sizeof(header_t), 1, ofd) != 1) {
- perror("blob header");
- fclose(ofd);
- exit(1);
- }
-
- // next, the program entries
- curr = progs;
- while (curr != NULL) {
- if (fwrite(curr->data, sizeof(prog_t), 1, ofd) != 1) {
- perror("blob prog entry write");
- fclose(ofd);
- exit(1);
- }
- curr = curr->next;
- }
-
- // finally, copy the files
- curr = progs;
- while (curr != NULL) {
- prog_t *prog = curr->data;
- copy(ofd, curr);
- node_t *tmp = curr;
- curr = curr->next;
- free(tmp->data);
- free(tmp->fullname);
- free(tmp);
- }
-
- fclose(ofd);
-
- return 0;
-}