From 18536950b3db37da45641bc5805d82ea6056d283 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Tue, 11 Jul 2023 05:48:39 -0700 Subject: [PATCH] Fix the build --- build/bootstrap/zipcopy.com | Bin 45056 -> 49448 bytes libc/elf/elf.h | 1 + libc/elf/findelfsectionbyname.c | 44 ++++++++++ tool/build/apelink.c | 139 ++++++++++++++++++++++++++++++++ tool/build/fixupobj.c | 18 +---- tool/build/mkdeps.c | 18 ----- tool/build/package.c | 6 +- tool/build/zipcopy.c | 28 +++++-- 8 files changed, 212 insertions(+), 42 deletions(-) create mode 100644 libc/elf/findelfsectionbyname.c create mode 100644 tool/build/apelink.c diff --git a/build/bootstrap/zipcopy.com b/build/bootstrap/zipcopy.com index 3965ea38945dfd6993f3088b17eae93403faee39..a448c6cf8231be8785194c651a01744f8bbcd706 100755 GIT binary patch delta 18463 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 dfBan-{>K5Y_W!qz&-#C;rNul!Nw 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 diff --git a/libc/elf/elf.h b/libc/elf/elf.h index ee901be34..8a6eac8d5 100644 --- a/libc/elf/elf.h +++ b/libc/elf/elf.h @@ -18,6 +18,7 @@ Elf64_Sym *GetElfSymbols(const Elf64_Ehdr *, size_t, int, Elf64_Xword *); Elf64_Shdr *GetElfSymbolTable(const Elf64_Ehdr *, size_t, int, Elf64_Xword *); Elf64_Phdr *GetElfProgramHeaderAddress(const Elf64_Ehdr *, size_t, Elf64_Half); Elf64_Shdr *GetElfSectionHeaderAddress(const Elf64_Ehdr *, size_t, Elf64_Half); +Elf64_Shdr *FindElfSectionByName(Elf64_Ehdr *, size_t, char *, const char *); const char *GetElfString(const Elf64_Ehdr *, size_t, const char *, Elf64_Word); void *GetElfSectionAddress(const Elf64_Ehdr *, size_t, const Elf64_Shdr *); const char *GetElfSectionName(const Elf64_Ehdr *, size_t, Elf64_Shdr *); diff --git a/libc/elf/findelfsectionbyname.c b/libc/elf/findelfsectionbyname.c new file mode 100644 index 000000000..c70516afc --- /dev/null +++ b/libc/elf/findelfsectionbyname.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/elf/elf.h" +#include "libc/elf/struct/ehdr.h" +#include "libc/elf/struct/shdr.h" +#include "libc/str/str.h" + +/** + * Returns ELF section header for section with name. + * + * @param elf points to the start of the executable image data + * @param mapsize is the number of bytes past `elf` we can access + * @return pointer to section header within image, or null + */ +Elf64_Shdr *FindElfSectionByName(Elf64_Ehdr *elf, size_t mapsize, + char *shdrstrtab, const char *name) { + long i; + Elf64_Shdr *shdr; + const char *secname; + for (i = 0; i < elf->e_shnum; ++i) { + if ((shdr = GetElfSectionHeaderAddress(elf, mapsize, i)) && + (secname = GetElfString(elf, mapsize, shdrstrtab, shdr->sh_name)) && + !strcmp(name, secname)) { + return shdr; + } + } + return 0; +} diff --git a/tool/build/apelink.c b/tool/build/apelink.c new file mode 100644 index 000000000..871475eab --- /dev/null +++ b/tool/build/apelink.c @@ -0,0 +1,139 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/elf/elf.h" +#include "libc/elf/struct/ehdr.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "third_party/getopt/getopt.internal.h" + +#define VERSION \ + "apelink v1.0\n" \ + "copyright 2023 justine tunney\n" \ + "https://github.com/jart/cosmopolitan\n" + +#define MANUAL \ + " -o OUTPUT INPUT...\n" \ + "\n" \ + "DESCRIPTION\n" \ + "\n" \ + " Actually Portable Executable Linker\n" \ + "\n" \ + " This program may be used to turn ELF executables into\n" \ + " APE executables. It's useful for creating fat binaries\n" \ + " that run on multiple architectures.\n" \ + "\n" \ + "FLAGS\n" \ + "\n" \ + " -h show usage\n" \ + " -o OUTPUT set output path\n" \ + "\n" \ + "ARGUMENTS\n" \ + "\n" \ + " OUTPUT is your ape executable\n" \ + " INPUT may specify multiple APE or ELF builds of the\n" \ + " same program for different architectures that\n" \ + " shall be merged into a single output file\n" \ + "\n" + +static const char *prog; +static const char *outpath; + +static wontreturn void Die(const char *reason) { + tinyprint(2, prog, ": ", reason, "\n", NULL); + exit(1); +} + +static wontreturn void DieSys(const char *thing) { + perror(thing); + exit(1); +} + +static wontreturn void ShowUsage(int rc, int fd) { + tinyprint(fd, VERSION, "\nUSAGE\n\n ", prog, MANUAL, NULL); + exit(rc); +} + +static void GetOpts(int argc, char *argv[]) { + int opt; + while ((opt = getopt(argc, argv, "ho:")) != -1) { + switch (opt) { + case 'o': + outpath = optarg; + break; + case 'h': + ShowUsage(0, 1); + default: + ShowUsage(1, 2); + } + } + if (!outpath) { + Die("need output path"); + } + if (optind == argc) { + Die("missing input argument"); + } +} + +static void HandleInput(const char *inpath) { + int fildes; + ssize_t esize; + Elf64_Ehdr *elf; + if ((fildes = open(inpath, O_RDONLY)) == -1) { + DieSys("open"); + } + if ((esize = lseek(fildes, 0, SEEK_END)) == -1) { + DieSys("lseek"); + } + if (esize) { + if ((elf = mmap(0, esize, PROT_READ | PROT_WRITE, MAP_SHARED, fildes, 0)) == + MAP_FAILED) { + DieSys("mmap"); + } + if (IsElf64Binary(elf, esize)) { + } + if (munmap(elf, esize)) { + DieSys("munmap"); + } + } + if (close(fildes)) { + DieSys("close"); + } +} + +int main(int argc, char *argv[]) { + int i, opt; + + // get program name + prog = argv[0]; + if (!prog) prog = "apelink"; + + // read flags + GetOpts(argc, argv); + + // read args + for (i = optind; i < argc; ++i) { + HandleInput(argv[i]); + } + + return 0; +} diff --git a/tool/build/fixupobj.c b/tool/build/fixupobj.c index 5bc6db926..ed8fd7af1 100644 --- a/tool/build/fixupobj.c +++ b/tool/build/fixupobj.c @@ -139,28 +139,14 @@ static void GetOpts(int argc, char *argv[]) { } } -static Elf64_Shdr *FindElfSectionByName(const char *name) { - long i; - Elf64_Shdr *shdr; - const char *secname; - for (i = 0; i < elf->e_shnum; ++i) { - if ((shdr = GetElfSectionHeaderAddress(elf, esize, i)) && - (secname = GetElfString(elf, esize, secstrs, shdr->sh_name)) && - !strcmp(name, secname)) { - return shdr; - } - } - return 0; -} - static void CheckPrivilegedCrossReferences(void) { long i; unsigned long x; Elf64_Shdr *shdr; const char *secname; Elf64_Rela *rela, *erela; - if (!(shdr = FindElfSectionByName(".rela.privileged"))) return; - if (!(rela = GetElfSectionAddress(elf, esize, shdr))) return; + shdr = FindElfSectionByName(elf, esize, secstrs, ".rela.privileged"); + if (!shdr || !(rela = GetElfSectionAddress(elf, esize, shdr))) return; erela = rela + shdr->sh_size / sizeof(*rela); for (; rela < erela; ++rela) { if (!ELF64_R_TYPE(rela->r_info)) continue; diff --git a/tool/build/mkdeps.c b/tool/build/mkdeps.c index 50928f8d3..d2d6f8239 100644 --- a/tool/build/mkdeps.c +++ b/tool/build/mkdeps.c @@ -34,24 +34,6 @@ #include "third_party/getopt/getopt.internal.h" #include "tool/build/lib/getargs.h" -/** - * @fileoverview Make dependency generator. - * - * This generates Makefile code for source -> header dependencies. - * - * Includes look like this: - * - * - #include "root/of/repository/foo.h" - * - .include "root/of/repository/foo.inc" - * - * They do not look like this: - * - * - #include "foo.h" - * - # include "foo.h" - * - #include "foo.h" - * - */ - #define VERSION \ "cosmopolitan mkdeps v2.0\n" \ "copyright 2023 justine tunney\n" \ diff --git a/tool/build/package.c b/tool/build/package.c index d55bdfd40..821522d8d 100644 --- a/tool/build/package.c +++ b/tool/build/package.c @@ -450,8 +450,8 @@ static void LoadSymbols(struct Package *pkg, uint32_t object) { } } -static Elf64_Shdr *FindElfSectionByName(Elf64_Ehdr *elf, size_t esize, - const char *name) { +static Elf64_Shdr *FindElfSection(Elf64_Ehdr *elf, size_t esize, + const char *name) { long i; Elf64_Shdr *shdr; const char *secname; @@ -472,7 +472,7 @@ static void LoadPriviligedRefsToUndefs(struct Package *pkg, const char *s; Elf64_Shdr *shdr; Elf64_Rela *rela, *erela; - if ((shdr = FindElfSectionByName(obj->elf, obj->size, ".rela.privileged"))) { + if ((shdr = FindElfSection(obj->elf, obj->size, ".rela.privileged"))) { if (!(rela = GetElfSectionAddress(obj->elf, obj->size, shdr))) { Die("error", "elf overflow"); } diff --git a/tool/build/zipcopy.c b/tool/build/zipcopy.c index 302215546..8772dbf3a 100644 --- a/tool/build/zipcopy.c +++ b/tool/build/zipcopy.c @@ -18,6 +18,9 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/dce.h" +#include "libc/elf/elf.h" +#include "libc/elf/struct/ehdr.h" +#include "libc/elf/struct/shdr.h" #include "libc/errno.h" #include "libc/fmt/magnumstrs.internal.h" #include "libc/limits.h" @@ -34,6 +37,7 @@ static int infd; static int outfd; static ssize_t insize; static ssize_t outsize; +static const char *prog; static const char *inpath; static const char *outpath; static unsigned char *inmap; @@ -59,7 +63,7 @@ NAME\n\ SYNOPSIS\n\ \n\ ", - program_invocation_name, " [FLAGS] SRC DST\n\ + prog, " [FLAGS] SRC DST\n\ \n\ DESCRIPTION\n\ \n\ @@ -106,11 +110,23 @@ static void GetOpts(int argc, char *argv[]) { } static void CopyZip(void) { + char *secstrs; int rela, recs; + Elf64_Ehdr *ehdr; unsigned long ldest, cdest, ltotal, ctotal, length; - unsigned char *ineof, *stop, *eocd, *cdir, *lfile, *cfile; + unsigned char *szip, *ineof, *stop, *eocd, *cdir, *lfile, *cfile; // find zip eocd header + // + // if input is an elf file with sections, then the zip artifacts need + // to have been linked into a .zip section and then later copied into + // the file end by fixupobj.com. + // + if (IsElf64Binary((ehdr = (Elf64_Ehdr *)inmap), insize) && ehdr->e_shnum && + (secstrs = GetElfSectionNameStringTable(ehdr, insize)) && + !FindElfSectionByName(ehdr, insize, secstrs, ".zip")) { + return; // zip artifacts were never linked into this elf binary + } ineof = inmap + insize; eocd = ineof - kZipCdirHdrMinSize; stop = MAX(eocd - 65536, inmap); @@ -196,9 +212,11 @@ static void CopyZip(void) { int main(int argc, char *argv[]) { int i, opt; - if (!IsOptimized()) { - ShowCrashReports(); - } +#ifndef NDEBUG + ShowCrashReports(); +#endif + prog = argv[0]; + if (!prog) prog = "apelink"; GetOpts(argc, argv); if ((infd = open(inpath, O_RDONLY)) == -1) { SysDie(inpath, "open");