mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-26 07:49:05 +00:00
Fix the build
This commit is contained in:
parent
1ee2e89326
commit
18536950b3
8 changed files with 212 additions and 42 deletions
build/bootstrap
libc/elf
tool/build
Binary file not shown.
|
@ -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_Shdr *GetElfSymbolTable(const Elf64_Ehdr *, size_t, int, Elf64_Xword *);
|
||||||
Elf64_Phdr *GetElfProgramHeaderAddress(const Elf64_Ehdr *, size_t, Elf64_Half);
|
Elf64_Phdr *GetElfProgramHeaderAddress(const Elf64_Ehdr *, size_t, Elf64_Half);
|
||||||
Elf64_Shdr *GetElfSectionHeaderAddress(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);
|
const char *GetElfString(const Elf64_Ehdr *, size_t, const char *, Elf64_Word);
|
||||||
void *GetElfSectionAddress(const Elf64_Ehdr *, size_t, const Elf64_Shdr *);
|
void *GetElfSectionAddress(const Elf64_Ehdr *, size_t, const Elf64_Shdr *);
|
||||||
const char *GetElfSectionName(const Elf64_Ehdr *, size_t, Elf64_Shdr *);
|
const char *GetElfSectionName(const Elf64_Ehdr *, size_t, Elf64_Shdr *);
|
||||||
|
|
44
libc/elf/findelfsectionbyname.c
Normal file
44
libc/elf/findelfsectionbyname.c
Normal file
|
@ -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;
|
||||||
|
}
|
139
tool/build/apelink.c
Normal file
139
tool/build/apelink.c
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -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) {
|
static void CheckPrivilegedCrossReferences(void) {
|
||||||
long i;
|
long i;
|
||||||
unsigned long x;
|
unsigned long x;
|
||||||
Elf64_Shdr *shdr;
|
Elf64_Shdr *shdr;
|
||||||
const char *secname;
|
const char *secname;
|
||||||
Elf64_Rela *rela, *erela;
|
Elf64_Rela *rela, *erela;
|
||||||
if (!(shdr = FindElfSectionByName(".rela.privileged"))) return;
|
shdr = FindElfSectionByName(elf, esize, secstrs, ".rela.privileged");
|
||||||
if (!(rela = GetElfSectionAddress(elf, esize, shdr))) return;
|
if (!shdr || !(rela = GetElfSectionAddress(elf, esize, shdr))) return;
|
||||||
erela = rela + shdr->sh_size / sizeof(*rela);
|
erela = rela + shdr->sh_size / sizeof(*rela);
|
||||||
for (; rela < erela; ++rela) {
|
for (; rela < erela; ++rela) {
|
||||||
if (!ELF64_R_TYPE(rela->r_info)) continue;
|
if (!ELF64_R_TYPE(rela->r_info)) continue;
|
||||||
|
|
|
@ -34,24 +34,6 @@
|
||||||
#include "third_party/getopt/getopt.internal.h"
|
#include "third_party/getopt/getopt.internal.h"
|
||||||
#include "tool/build/lib/getargs.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 \
|
#define VERSION \
|
||||||
"cosmopolitan mkdeps v2.0\n" \
|
"cosmopolitan mkdeps v2.0\n" \
|
||||||
"copyright 2023 justine tunney\n" \
|
"copyright 2023 justine tunney\n" \
|
||||||
|
|
|
@ -450,8 +450,8 @@ static void LoadSymbols(struct Package *pkg, uint32_t object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Elf64_Shdr *FindElfSectionByName(Elf64_Ehdr *elf, size_t esize,
|
static Elf64_Shdr *FindElfSection(Elf64_Ehdr *elf, size_t esize,
|
||||||
const char *name) {
|
const char *name) {
|
||||||
long i;
|
long i;
|
||||||
Elf64_Shdr *shdr;
|
Elf64_Shdr *shdr;
|
||||||
const char *secname;
|
const char *secname;
|
||||||
|
@ -472,7 +472,7 @@ static void LoadPriviligedRefsToUndefs(struct Package *pkg,
|
||||||
const char *s;
|
const char *s;
|
||||||
Elf64_Shdr *shdr;
|
Elf64_Shdr *shdr;
|
||||||
Elf64_Rela *rela, *erela;
|
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))) {
|
if (!(rela = GetElfSectionAddress(obj->elf, obj->size, shdr))) {
|
||||||
Die("error", "elf overflow");
|
Die("error", "elf overflow");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/dce.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/errno.h"
|
||||||
#include "libc/fmt/magnumstrs.internal.h"
|
#include "libc/fmt/magnumstrs.internal.h"
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
|
@ -34,6 +37,7 @@ static int infd;
|
||||||
static int outfd;
|
static int outfd;
|
||||||
static ssize_t insize;
|
static ssize_t insize;
|
||||||
static ssize_t outsize;
|
static ssize_t outsize;
|
||||||
|
static const char *prog;
|
||||||
static const char *inpath;
|
static const char *inpath;
|
||||||
static const char *outpath;
|
static const char *outpath;
|
||||||
static unsigned char *inmap;
|
static unsigned char *inmap;
|
||||||
|
@ -59,7 +63,7 @@ NAME\n\
|
||||||
SYNOPSIS\n\
|
SYNOPSIS\n\
|
||||||
\n\
|
\n\
|
||||||
",
|
",
|
||||||
program_invocation_name, " [FLAGS] SRC DST\n\
|
prog, " [FLAGS] SRC DST\n\
|
||||||
\n\
|
\n\
|
||||||
DESCRIPTION\n\
|
DESCRIPTION\n\
|
||||||
\n\
|
\n\
|
||||||
|
@ -106,11 +110,23 @@ static void GetOpts(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CopyZip(void) {
|
static void CopyZip(void) {
|
||||||
|
char *secstrs;
|
||||||
int rela, recs;
|
int rela, recs;
|
||||||
|
Elf64_Ehdr *ehdr;
|
||||||
unsigned long ldest, cdest, ltotal, ctotal, length;
|
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
|
// 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;
|
ineof = inmap + insize;
|
||||||
eocd = ineof - kZipCdirHdrMinSize;
|
eocd = ineof - kZipCdirHdrMinSize;
|
||||||
stop = MAX(eocd - 65536, inmap);
|
stop = MAX(eocd - 65536, inmap);
|
||||||
|
@ -196,9 +212,11 @@ static void CopyZip(void) {
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int i, opt;
|
int i, opt;
|
||||||
if (!IsOptimized()) {
|
#ifndef NDEBUG
|
||||||
ShowCrashReports();
|
ShowCrashReports();
|
||||||
}
|
#endif
|
||||||
|
prog = argv[0];
|
||||||
|
if (!prog) prog = "apelink";
|
||||||
GetOpts(argc, argv);
|
GetOpts(argc, argv);
|
||||||
if ((infd = open(inpath, O_RDONLY)) == -1) {
|
if ((infd = open(inpath, O_RDONLY)) == -1) {
|
||||||
SysDie(inpath, "open");
|
SysDie(inpath, "open");
|
||||||
|
|
Loading…
Add table
Reference in a new issue