mcc
mcc is a machine code compiler.
Log | Files | << Repositories
tree 3d5e55f9d2ee3fb466f125d93b47cdfdb858f482 parent 700d4c4b5b2021938fa7380afe9497a92f06bb9d author esote <esote.net@gmail.com> 1560709515 -0500 committer esote <esote.net@gmail.com> 1560709515 -0500 gpgsig -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQTXAxYDuIzimYoNSPuhTmRAjzzC8gUCXSArKAAKCRChTmRAjzzC 8gh7AQC1sU6y0K53c8Agqyjo1CSKOYgZLih32D4QOiZmlbTo3gEA1jnqPvDYRzJn 1SHJDaMKiF1ir091MQOMWjxpf9hxzgc= =LHpr -----END PGP SIGNATURE----- Options for custom bss and text addresses
README | 8 ++++--- mcc.1 | 8 +++++++ mcc.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 70 insertions(+), 26 deletions(-)
diff --git a/README b/README index d0ce109..f86604b 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ NAME mcc - machine code compiler SYNOPSIS - mcc [-3s] [-m memsize] [-o file] file + mcc [-3s] [-b addr] [-m memsize] [-o file] [-t addr] file DESCRIPTION mcc is a machine code compiler. It reads ASCII text '0' and '1' mapping @@ -22,8 +22,10 @@ DESCRIPTION In 64-bit mode the .bss and .text sections start at 0x402000 and 0x401000 respectively, and in 32-bit mode 0x804a000 and 0x8049000 - respectively. Program header segment alignment is set to 0x1000 (the - page size on most systems). + respectively. Use the -b and -t options to specify custom addresses. + + Program header segment alignment is set to 0x1000 (the page size on most + systems). .bss is aligned to a 16-byte constraint and .text to an 8-byte constraint. diff --git a/mcc.1 b/mcc.1 index 24fd57a..6cc99ec 100644 --- a/mcc.1 +++ b/mcc.1 @@ -23,8 +23,10 @@ .Sh SYNOPSIS .Nm mcc .Op Fl 3s +.Op Fl b Ar addr .Op Fl m Ar memsize .Op Fl o Ar file +.Op Fl t Ar addr file .Sh DESCRIPTION .Nm mcc @@ -54,6 +56,12 @@ executable. In 64-bit mode the .bss and .text sections start at 0x402000 and 0x401000 respectively, and in 32-bit mode 0x804a000 and 0x8049000 respectively. +Use the +.Fl b +and +.Fl t +options to specify custom addresses. +.Pp Program header segment alignment is set to 0x1000 (the page size on most systems). .Pp diff --git a/mcc.c b/mcc.c index 4f78314..a17f2e0 100644 --- a/mcc.c +++ b/mcc.c @@ -43,36 +43,48 @@ main(int argc, char *argv[]) char *end; char const *iname; char const *oname; - uint64_t len; - uint64_t mem; - int use_64; int ch; + int use_64; + int use_bss_addr; + int use_text_addr; opts.self_m = 0; + opts.mem.n64 = 0; + opts.bss_vaddr.n64 = 0x402000; + opts.text_vaddr.n64 = 0x401000; oname = "a.out"; - mem = 0; /* default 64-bit */ use_64 = 1; - opts.bss_vaddr.n64 = 0x402000; - opts.text_vaddr.n64 = 0x401000; - while ((ch = getopt(argc, argv, "3m:o:s")) != -1) { + use_bss_addr = 0; + use_text_addr = 0; + + while ((ch = getopt(argc, argv, "3b:m:o:st:")) != -1) { switch (ch) { case '3': use_64 = 0; - opts.bss_vaddr.n32 = 0x804a000; - opts.text_vaddr.n32 = 0x8049000; + break; + case 'b': + opts.bss_vaddr.n64 = strtoull(optarg, &end, 0); + + if (errno == EINVAL || errno == ERANGE) { + err(1, "bss address invalid"); + } else if (optarg == end) { + err(1, "no bss address read"); + } + + use_bss_addr = 1; break; case 'm': - mem = strtoull(optarg, &end, 10); + opts.mem.n64 = strtoull(optarg, &end, 10); if (errno == EINVAL || errno == ERANGE) { err(1, "memsize invalid"); } else if (optarg == end) { errx(1, "no memsize read"); - } else if (mem == 0) { + } else if (opts.mem.n64 == 0) { warnx("if memsize is zero no .bss section will " "be written"); } @@ -84,18 +96,26 @@ main(int argc, char *argv[]) case 's': opts.self_m = 1; break; + case 't': + opts.text_vaddr.n64 = strtoull(optarg, &end, 0); + + if (errno == EINVAL || errno == ERANGE) { + err(1, "text address invalid"); + } else if (optarg == end) { + err(1, "no text address read"); + } + + use_text_addr = 1; + break; default: (void)fprintf(stderr, - "usage: %s [-3s] [-m memsize] [-o file] file\n", + "usage: %s [-3s] [-b addr] [-m memsize] " + "[-o file] [-t addr] file\n", argv[0]); return 1; } } - if (!use_64 && mem > UINT32_MAX) { - warnx("memsize may overflow"); - } - argv += optind; if ((iname = *argv) == NULL) { @@ -110,20 +130,34 @@ main(int argc, char *argv[]) err(1, "open out"); } - len = byte_len(in); + opts.len.n64 = byte_len(in); + + if (!use_64) { + if (opts.mem.n64 > UINT32_MAX) { + warnx("memsize is larger than 32 bits"); + } + + if (opts.len.n64 > UINT32_MAX) { + warnx("input file byte length is larger than 32 bits"); + } + + if (!use_bss_addr) { + opts.bss_vaddr.n32 = 0x804a000; + } else if (opts.bss_vaddr.n64 > UINT32_MAX) { + warnx("bss address is larger than 32 bits"); + } - if (!use_64 && len > UINT32_MAX) { - warnx("input file byte length may overflow"); + if (!use_text_addr) { + opts.text_vaddr.n32 = 0x8049000; + } else if (opts.text_vaddr.n64 > UINT32_MAX) { + warnx("text address is larger than 32 bits"); + } } if (use_64) { - opts.mem.n64 = mem; - opts.len.n64 = len; write_ehdr64(out, &opts); write_phdr64_text(out, &opts); } else { - opts.mem.n32 = (uint32_t)mem; - opts.len.n32 = (uint32_t)len; write_ehdr32(out, &opts); write_phdr32_text(out, &opts); }