mcc

mcc is a machine code compiler.

Log | Files | << Repositories


tree 7bedd321f8c0496d33ef9463e3db1677278ed605
parent 9cf188fcadac0e9ba7febbdd1e5bb4d715a04f60
author esote <esote.net@gmail.com> 1558210572 -0500
committer esote <esote.net@gmail.com> 1558210572 -0500
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQTXAxYDuIzimYoNSPuhTmRAjzzC8gUCXSArHwAKCRChTmRAjzzC
 8lMvAP49QD9sekMTl9dpqWnm4fstHQ0h0Yb5+KtLFm81BRobggD/UajI50eyTQPt
 1vNX7+EcfftluSELxBA980RXJpWBNw8=
 =zL9J
 -----END PGP SIGNATURE-----

Remove bss section if memsize is zero

Warn if len could overflow on 32-bit executables.

 README     |  2 ++
 mcc.c      | 50 +++++++++++++++++++++++++++++++++++---------------
 write_32.c | 25 ++++++++++++++++++++-----
 write_64.c | 25 ++++++++++++++++++++-----
 4 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/README b/README
index 53feb23..992a359 100644
--- a/README
+++ b/README
@@ -13,3 +13,5 @@ Programmer's manual:
 
 	.bss is aligned to a 16-byte constraint and .text to an 8-byte
 	constraint.
+
+	If memsize is zero no .bss section will be written for the executable.
diff --git a/mcc.c b/mcc.c
index b1883d8..8da5209 100644
--- a/mcc.c
+++ b/mcc.c
@@ -30,7 +30,7 @@
 
 uint64_t	byte_len(FILE *const);
 void		write_mcode(FILE *const, FILE *const);
-void		write_section_names(FILE *const);
+void		write_section_names(FILE *const, struct mcc_opts const *const);
 
 #define COMMENT	';'
 
@@ -43,6 +43,7 @@ main(int argc, char *argv[])
 	char *end;
 	char *iname;
 	char const *oname;
+	uint64_t len;
 	uint64_t mem;
 	int use_64;
 	int ch;
@@ -65,13 +66,15 @@ main(int argc, char *argv[])
 			opts.text_vaddr.n32 = 0x8049000;
 			break;
 		case 'm':
-			/* TODO remove BSS section if mem == 0 */
 			mem = 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) {
+				warnx("if memsize is zero no .bss section will "
+					"be written");
 			}
 
 			break;
@@ -90,10 +93,7 @@ main(int argc, char *argv[])
 		}
 	}
 
-	if (mem == 0) {
-		warnx("memsize is 0, using .bss could segfault or overflow "
-			"into other sections");
-	} else if (!use_64 && mem > UINT32_MAX) {
+	if (!use_64 && mem > UINT32_MAX) {
 		warnx("memsize may overflow");
 	}
 
@@ -111,32 +111,52 @@ main(int argc, char *argv[])
 		err(1, "open out");
 	}
 
+	len = byte_len(in);
+
+	if (!use_64 && len > UINT32_MAX) {
+		warnx("input file byte length may overflow");
+	}
+
 	if (use_64) {
 		opts.mem.n64 = mem;
-		opts.len.n64 = byte_len(in);
+		opts.len.n64 = len;
 		write_ehdr64(out, &opts);
 		write_phdr64_text(out, &opts);
-		write_phdr64_bss(out, &opts);
 	} else {
 		opts.mem.n32 = (uint32_t)mem;
-		opts.len.n32 = (uint32_t)byte_len(in);
+		opts.len.n32 = (uint32_t)len;
 		write_ehdr32(out, &opts);
 		write_phdr32_text(out, &opts);
-		write_phdr32_bss(out, &opts);
+	}
+
+	if (opts.mem.n32 != 0) {
+		if (use_64) {
+			write_phdr64_bss(out, &opts);
+		} else {
+			write_phdr32_bss(out, &opts);
+		}
 	}
 
 	write_mcode(in, out);
-	write_section_names(out);
+	write_section_names(out, &opts);
 
 	if (use_64) {
 		write_shdr64_null(out);
 		write_shdr64_text(out, &opts);
-		write_shdr64_bss(out, &opts);
+
+		if (opts.mem.n64 != 0) {
+			write_shdr64_bss(out, &opts);
+		}
+
 		write_shdr64_shstrtab(out, &opts);
 	} else {
 		write_shdr32_null(out);
 		write_shdr32_text(out, &opts);
-		write_shdr32_bss(out, &opts);
+
+		if (opts.mem.n32 != 0) {
+			write_shdr32_bss(out, &opts);
+		}
+
 		write_shdr32_shstrtab(out, &opts);
 	}
 
@@ -233,7 +253,7 @@ write_mcode(FILE *const in, FILE *const out)
 }
 
 void
-write_section_names(FILE *const out)
+write_section_names(FILE *const out, struct mcc_opts const *const opts)
 {
 	static char const *const shstrtab = ".shstrtab";
 	static char const *const text = ".text";
@@ -253,7 +273,7 @@ write_section_names(FILE *const out)
 		err(1, "write text name");
 	}
 
-	if (fwrite(bss, BSS_LEN, 1, out) != 1) {
+	if (opts->mem.n32 != 0 && fwrite(bss, BSS_LEN, 1, out) != 1) {
 		err(1, "write bss name");
 	}
 }
diff --git a/write_32.c b/write_32.c
index 412996e..6551843 100644
--- a/write_32.c
+++ b/write_32.c
@@ -32,9 +32,15 @@ write_ehdr32(FILE *const out, struct mcc_opts *const opts)
 	e.e_phentsize = sizeof(Elf32_Phdr);
 	e.e_shentsize = sizeof(Elf32_Shdr);
 
-	e.e_phnum = 2;
-	e.e_shnum = 4;
-	e.e_shstrndx = 3;
+	if (opts->mem.n32 == 0) {
+		e.e_phnum = 1;
+		e.e_shnum = 3;
+		e.e_shstrndx = 2;
+	} else {
+		e.e_phnum = 2;
+		e.e_shnum = 4;
+		e.e_shstrndx = 3;
+	}
 
 	/* program hdrs start after elf hdr */
 	e.e_phoff = e.e_ehsize;
@@ -45,7 +51,11 @@ write_ehdr32(FILE *const out, struct mcc_opts *const opts)
 
 	/* section hdrs start after elf hdr, program hdrs, text, and shstrtab */
 	e.e_shoff = opts->off.n32 + opts->len.n32 + NULL_LEN + SHSTRTAB_LEN +
-		TEXT_LEN + BSS_LEN;
+		TEXT_LEN;
+
+	if (opts->mem.n32 != 0) {
+		e.e_shoff += BSS_LEN;
+	}
 
 	if (fwrite(&e, sizeof(Elf32_Ehdr), 1, out) != 1) {
 		err(1, "write ehdr32");
@@ -160,7 +170,12 @@ write_shdr32_shstrtab(FILE *const out, struct mcc_opts const *const opts)
 	shstrtab.sh_flags = 0;
 	shstrtab.sh_addr = 0;
 	shstrtab.sh_offset = opts->off.n32 + opts->len.n32;
-	shstrtab.sh_size = NULL_LEN + SHSTRTAB_LEN + TEXT_LEN + BSS_LEN;
+	shstrtab.sh_size = NULL_LEN + SHSTRTAB_LEN + TEXT_LEN;
+
+	if (opts->mem.n32 != 0) {
+		shstrtab.sh_size += BSS_LEN;
+	}
+
 	shstrtab.sh_link = 0;
 	shstrtab.sh_info = 0;
 	shstrtab.sh_addralign = SHSTRTAB_ADDRALIGN;
diff --git a/write_64.c b/write_64.c
index 88a6157..f558160 100644
--- a/write_64.c
+++ b/write_64.c
@@ -32,9 +32,15 @@ write_ehdr64(FILE *const out, struct mcc_opts *const opts)
 	e.e_phentsize = sizeof(Elf64_Phdr);
 	e.e_shentsize = sizeof(Elf64_Shdr);
 
-	e.e_phnum = 2;
-	e.e_shnum = 4;
-	e.e_shstrndx = 3;
+	if (opts->mem.n64 == 0) {
+		e.e_phnum = 1;
+		e.e_shnum = 3;
+		e.e_shstrndx = 2;
+	} else {
+		e.e_phnum = 2;
+		e.e_shnum = 4;
+		e.e_shstrndx = 3;
+	}
 
 	/* program hdrs start after elf hdr */
 	e.e_phoff = e.e_ehsize;
@@ -45,7 +51,11 @@ write_ehdr64(FILE *const out, struct mcc_opts *const opts)
 
 	/* section hdrs start after elf hdr, program hdrs, text, and shstrtab */
 	e.e_shoff = opts->off.n64 + opts->len.n64 + NULL_LEN + SHSTRTAB_LEN +
-		TEXT_LEN + BSS_LEN;
+		TEXT_LEN;
+
+	if (opts->mem.n64 != 0) {
+		e.e_shoff += BSS_LEN;
+	}
 
 	if (fwrite(&e, sizeof(Elf64_Ehdr), 1, out) != 1) {
 		err(1, "write ehdr64");
@@ -160,7 +170,12 @@ write_shdr64_shstrtab(FILE *const out, struct mcc_opts const *const opts)
 	shstrtab.sh_flags = 0;
 	shstrtab.sh_addr = 0;
 	shstrtab.sh_offset = opts->off.n64 + opts->len.n64;
-	shstrtab.sh_size = NULL_LEN + SHSTRTAB_LEN + TEXT_LEN + BSS_LEN;
+	shstrtab.sh_size = NULL_LEN + SHSTRTAB_LEN + TEXT_LEN;
+
+	if (opts->mem.n64 != 0) {
+		shstrtab.sh_size += BSS_LEN;
+	}
+
 	shstrtab.sh_link = 0;
 	shstrtab.sh_info = 0;
 	shstrtab.sh_addralign = SHSTRTAB_ADDRALIGN;