2020-06-15 14:18:57 +00:00
|
|
|
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
2023-12-08 03:11:56 +00:00
|
|
|
|
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
|
2020-06-15 14:18:57 +00:00
|
|
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
|
|
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
|
|
|
|
│ │
|
2020-12-28 01:18:44 +00:00
|
|
|
|
│ 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. │
|
2020-06-15 14:18:57 +00:00
|
|
|
|
│ │
|
2020-12-28 01:18:44 +00:00
|
|
|
|
│ 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. │
|
2020-06-15 14:18:57 +00:00
|
|
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
|
|
|
#include "libc/calls/calls.h"
|
2023-06-08 11:37:05 +00:00
|
|
|
|
#include "libc/calls/struct/iovec.h"
|
2020-06-15 14:18:57 +00:00
|
|
|
|
#include "libc/calls/struct/stat.h"
|
2023-06-08 11:37:05 +00:00
|
|
|
|
#include "libc/dce.h"
|
2023-07-02 17:19:16 +00:00
|
|
|
|
#include "libc/elf/def.h"
|
2020-06-15 14:18:57 +00:00
|
|
|
|
#include "libc/elf/elf.h"
|
2023-06-08 11:37:05 +00:00
|
|
|
|
#include "libc/elf/struct/rela.h"
|
2022-08-06 10:51:50 +00:00
|
|
|
|
#include "libc/elf/struct/shdr.h"
|
|
|
|
|
#include "libc/elf/struct/sym.h"
|
2023-06-08 11:37:05 +00:00
|
|
|
|
#include "libc/errno.h"
|
2023-06-09 08:23:18 +00:00
|
|
|
|
#include "libc/fmt/magnumstrs.internal.h"
|
2022-08-19 17:00:41 +00:00
|
|
|
|
#include "libc/intrin/bswap.h"
|
2023-06-08 11:37:05 +00:00
|
|
|
|
#include "libc/intrin/kprintf.h"
|
2020-06-15 14:18:57 +00:00
|
|
|
|
#include "libc/log/log.h"
|
2023-06-08 11:37:05 +00:00
|
|
|
|
#include "libc/macros.internal.h"
|
2022-08-19 17:00:41 +00:00
|
|
|
|
#include "libc/mem/alg.h"
|
|
|
|
|
#include "libc/mem/arraylist.internal.h"
|
2020-06-15 14:18:57 +00:00
|
|
|
|
#include "libc/mem/mem.h"
|
|
|
|
|
#include "libc/runtime/runtime.h"
|
|
|
|
|
#include "libc/str/str.h"
|
|
|
|
|
#include "libc/sysv/consts/map.h"
|
|
|
|
|
#include "libc/sysv/consts/o.h"
|
|
|
|
|
#include "libc/sysv/consts/prot.h"
|
2023-07-03 02:57:43 +00:00
|
|
|
|
#include "third_party/getopt/getopt.internal.h"
|
2020-06-15 14:18:57 +00:00
|
|
|
|
#include "third_party/xed/x86.h"
|
2022-03-16 20:33:13 +00:00
|
|
|
|
#include "tool/build/lib/getargs.h"
|
2023-06-08 11:37:05 +00:00
|
|
|
|
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/**
|
|
|
|
|
* @fileoverview Build Package Script.
|
|
|
|
|
*
|
|
|
|
|
* FIRST PURPOSE
|
|
|
|
|
*
|
|
|
|
|
* This script verifies the well-formedness of dependencies, e.g.
|
|
|
|
|
*
|
2024-03-03 00:57:56 +00:00
|
|
|
|
* o/tool/build/package \
|
2022-03-16 20:33:13 +00:00
|
|
|
|
* -o o/libc/stubs/stubs.pkg \
|
|
|
|
|
* o/libc/stubs/{a,b,...}.o
|
2020-06-15 14:18:57 +00:00
|
|
|
|
*
|
2024-03-03 00:57:56 +00:00
|
|
|
|
* o/tool/build/package \
|
2022-03-16 20:33:13 +00:00
|
|
|
|
* -o o/libc/nexgen32e/nexgen32e.pkg \
|
|
|
|
|
* -d o/libc/stubs/stubs.pkg \
|
|
|
|
|
* o/libc/nexgen32e/{a,b,...}.o
|
2020-06-15 14:18:57 +00:00
|
|
|
|
*
|
|
|
|
|
* We want the following:
|
|
|
|
|
*
|
|
|
|
|
* 1. FOO declares in FOO_DIRECTDEPS where its undefined symbols are.
|
|
|
|
|
* 2. FOO_DIRECTDEPS is complete, so FOO ∪ FOO_DIRECTDEPS has no UNDEFs.
|
|
|
|
|
* 3. FOO_DIRECTDEPS is non-transitive; thus this tool is incremental.
|
|
|
|
|
* 4. Package relationships on a whole are acyclic.
|
|
|
|
|
*
|
|
|
|
|
* These rules help keep the structure of large codebases easy to
|
|
|
|
|
* understand. More importantly, it allows us to further optimize
|
|
|
|
|
* compiled objects very cheaply as the build progresses.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define PACKAGE_MAGIC bswap_32(0xBEEFBEEFu)
|
2023-06-08 11:37:05 +00:00
|
|
|
|
#define PACKAGE_ABI 2
|
|
|
|
|
|
|
|
|
|
struct ObjectArrayParam {
|
|
|
|
|
size_t len;
|
|
|
|
|
size_t size;
|
|
|
|
|
void *pp;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ObjectParam {
|
|
|
|
|
size_t size;
|
|
|
|
|
void *p;
|
|
|
|
|
uint32_t *magic;
|
|
|
|
|
int32_t *abi;
|
|
|
|
|
struct ObjectArrayParam *arrays;
|
|
|
|
|
};
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
struct Packages {
|
|
|
|
|
size_t i, n;
|
|
|
|
|
struct Package {
|
|
|
|
|
uint32_t magic;
|
|
|
|
|
int32_t abi;
|
2020-11-09 23:41:11 +00:00
|
|
|
|
uint32_t path; // pkg->strings.p[path]
|
|
|
|
|
int64_t fd; // not persisted
|
|
|
|
|
void *addr; // not persisted
|
2023-06-08 11:37:05 +00:00
|
|
|
|
ssize_t size; // not persisted
|
2020-06-15 14:18:57 +00:00
|
|
|
|
struct Strings {
|
|
|
|
|
size_t i, n;
|
2020-11-09 23:41:11 +00:00
|
|
|
|
char *p; // persisted as pkg+RVA
|
|
|
|
|
} strings; // TODO(jart): interning?
|
2020-06-15 14:18:57 +00:00
|
|
|
|
struct Objects {
|
|
|
|
|
size_t i, n;
|
|
|
|
|
struct Object {
|
2020-11-09 23:41:11 +00:00
|
|
|
|
uint32_t path; // pkg->strings.p[path]
|
|
|
|
|
struct Elf64_Ehdr *elf; // not persisted
|
|
|
|
|
size_t size; // not persisted
|
|
|
|
|
char *strs; // not persisted
|
|
|
|
|
Elf64_Sym *syms; // not persisted
|
|
|
|
|
Elf64_Xword symcount; // not persisted
|
2023-06-08 11:37:05 +00:00
|
|
|
|
int section_offset;
|
|
|
|
|
int section_count;
|
2023-11-19 00:56:11 +00:00
|
|
|
|
} *p;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
} objects;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
struct Sections {
|
|
|
|
|
size_t i, n;
|
|
|
|
|
struct Section {
|
|
|
|
|
int name;
|
|
|
|
|
enum SectionKind {
|
|
|
|
|
kUndef,
|
|
|
|
|
kText,
|
|
|
|
|
kPrivilegedText,
|
|
|
|
|
kData,
|
|
|
|
|
kBss,
|
|
|
|
|
kOther,
|
|
|
|
|
} kind;
|
2023-11-19 00:56:11 +00:00
|
|
|
|
} *p;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
} sections;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
struct Symbols {
|
|
|
|
|
size_t i, n;
|
|
|
|
|
struct Symbol {
|
2020-11-09 23:41:11 +00:00
|
|
|
|
uint32_t name; // pkg->strings.p[name]
|
2020-06-15 14:18:57 +00:00
|
|
|
|
enum SectionKind kind : 8;
|
2022-04-21 16:15:36 +00:00
|
|
|
|
uint8_t bind_ : 4;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
uint8_t type : 4;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
uint16_t object; // pkg->objects.p[object]
|
|
|
|
|
uint16_t section; // pkg->sections.p[section]
|
2023-11-19 00:56:11 +00:00
|
|
|
|
} *p; // persisted as pkg+RVA
|
2023-06-08 11:37:05 +00:00
|
|
|
|
} symbols, undefs; // TODO(jart): hash undefs?
|
2023-11-19 00:56:11 +00:00
|
|
|
|
} **p; // persisted across multiple files
|
2020-06-15 14:18:57 +00:00
|
|
|
|
};
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
struct Relas {
|
|
|
|
|
size_t i, n;
|
|
|
|
|
struct Strings s;
|
|
|
|
|
struct Rela {
|
|
|
|
|
const char *symbol_name;
|
|
|
|
|
const char *object_path;
|
2023-11-19 00:56:11 +00:00
|
|
|
|
} *p;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
} prtu;
|
|
|
|
|
|
2024-05-07 07:37:41 +00:00
|
|
|
|
#include "libc/mem/tinymalloc.inc"
|
|
|
|
|
|
2023-06-10 16:15:19 +00:00
|
|
|
|
static wontreturn void Die(const char *path, const char *reason) {
|
2023-07-03 09:47:05 +00:00
|
|
|
|
tinyprint(2, path, ": ", reason, "\n", NULL);
|
2023-06-10 16:15:19 +00:00
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static wontreturn void SysExit(const char *path, const char *func) {
|
|
|
|
|
const char *errstr;
|
Apply clang-format update to repo (#1154)
Commit bc6c183 introduced a bunch of discrepancies between what files
look like in the repo and what clang-format says they should look like.
However, there were already a few discrepancies prior to that. Most of
these discrepancies seemed to be unintentional, but a few of them were
load-bearing (e.g., a #include that violated header ordering needing
something to have been #defined by a 'later' #include.)
I opted to take what I hope is a relatively smooth-brained approach: I
reverted the .clang-format change, ran clang-format on the whole repo,
reapplied the .clang-format change, reran clang-format again, and then
reverted the commit that contained the first run. Thus the full effect
of this PR should only be to apply the changed formatting rules to the
repo, and from skimming the results, this seems to be the case.
My work can be checked by applying the short, manual commits, and then
rerunning the command listed in the autogenerated commits (those whose
messages I have prefixed auto:) and seeing if your results agree.
It might be that the other diffs should be fixed at some point but I'm
leaving that aside for now.
fd '\.c(c|pp)?$' --print0| xargs -0 clang-format -i
2024-04-25 17:38:00 +00:00
|
|
|
|
if (!(errstr = _strerrno(errno)))
|
|
|
|
|
errstr = "EUNKNOWN";
|
2023-07-03 09:47:05 +00:00
|
|
|
|
tinyprint(2, path, ": ", func, " failed with ", errstr, "\n", NULL);
|
2023-06-08 11:37:05 +00:00
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int CompareSymbolName(const struct Symbol *a, const struct Symbol *b,
|
|
|
|
|
const char *tab) {
|
2021-04-18 18:34:59 +00:00
|
|
|
|
return strcmp(tab + a->name, tab + b->name);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void PrintSymbols(struct Package *pkg, struct Symbols *syms,
|
|
|
|
|
const char *name) {
|
|
|
|
|
int i;
|
|
|
|
|
kprintf(" - %s=%d\n", name, syms->i);
|
|
|
|
|
for (i = 0; i < syms->i; ++i) {
|
|
|
|
|
kprintf(" - id=%d\n", i);
|
|
|
|
|
kprintf(" name=%d [%s]\n", syms->p[i].name,
|
|
|
|
|
pkg->strings.p + syms->p[i].name);
|
|
|
|
|
kprintf(" kind=%d\n", syms->p[i].kind);
|
|
|
|
|
kprintf(" bind=%d\n", syms->p[i].bind_);
|
|
|
|
|
kprintf(" type=%d\n", syms->p[i].type);
|
|
|
|
|
kprintf(" object=%d [%s]\n", syms->p[i].object,
|
|
|
|
|
pkg->strings.p + pkg->objects.p[syms->p[i].object].path);
|
|
|
|
|
kprintf(" section=%d [%s]\n", syms->p[i].section,
|
|
|
|
|
syms->p[i].section == SHN_ABS
|
|
|
|
|
? "SHN_ABS"
|
|
|
|
|
: pkg->strings.p + pkg->sections.p[syms->p[i].section].name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void PrintObject(struct Package *pkg, struct Object *obj) {
|
|
|
|
|
int i, o;
|
|
|
|
|
kprintf(" path=%d [%s]\n", obj->path, pkg->strings.p + obj->path);
|
|
|
|
|
kprintf(" sections=%d\n", obj->section_count);
|
|
|
|
|
for (i = 0; i < obj->section_count; ++i) {
|
|
|
|
|
o = obj->section_offset;
|
|
|
|
|
kprintf(" - id=%d %p (%d+%d)\n", i, pkg->sections.p, o, i);
|
|
|
|
|
kprintf(" name=%d [%s]\n", pkg->sections.p[o + i].name,
|
|
|
|
|
pkg->strings.p + pkg->sections.p[o + i].name);
|
|
|
|
|
kprintf(" kind=%d\n", pkg->sections.p[o + i].kind);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void PrintPackage(struct Package *pkg) {
|
2023-09-02 03:49:13 +00:00
|
|
|
|
int i;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
kprintf("- %s\n", pkg->strings.p + pkg->path);
|
|
|
|
|
kprintf(" objects=%d\n", pkg->objects.i);
|
|
|
|
|
for (i = 0; i < pkg->objects.i; ++i) {
|
|
|
|
|
kprintf(" - id=%d\n", i);
|
|
|
|
|
PrintObject(pkg, pkg->objects.p + i);
|
|
|
|
|
}
|
|
|
|
|
PrintSymbols(pkg, &pkg->symbols, "symbols");
|
|
|
|
|
PrintSymbols(pkg, &pkg->undefs, "undefs");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void PrintPackages(struct Package *p, int n) {
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < n; ++i) {
|
|
|
|
|
PrintPackage(p + i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct Package *LoadPackage(const char *path) {
|
2020-06-15 14:18:57 +00:00
|
|
|
|
int fd;
|
2023-09-02 03:49:13 +00:00
|
|
|
|
ssize_t size;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
struct Package *pkg;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
if ((fd = open(path, O_RDONLY)) == -1) {
|
|
|
|
|
SysExit(path, "open");
|
|
|
|
|
}
|
|
|
|
|
if ((size = lseek(fd, 0, SEEK_END)) == -1) {
|
|
|
|
|
SysExit(path, "lseek");
|
|
|
|
|
}
|
|
|
|
|
if ((pkg = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)) ==
|
|
|
|
|
MAP_FAILED) {
|
|
|
|
|
SysExit(path, "mmap");
|
|
|
|
|
}
|
|
|
|
|
close(fd);
|
|
|
|
|
if (pkg->magic != PACKAGE_MAGIC) {
|
2023-06-10 16:15:19 +00:00
|
|
|
|
Die(path, "not a cosmo .pkg file");
|
2023-06-08 11:37:05 +00:00
|
|
|
|
}
|
|
|
|
|
if (pkg->abi < PACKAGE_ABI) {
|
2023-06-10 16:15:19 +00:00
|
|
|
|
Die(path, "package has old abi try running make clean");
|
2023-06-08 11:37:05 +00:00
|
|
|
|
}
|
|
|
|
|
pkg->strings.p = (void *)((uintptr_t)pkg->strings.p + (uintptr_t)pkg);
|
|
|
|
|
pkg->objects.p = (void *)((uintptr_t)pkg->objects.p + (uintptr_t)pkg);
|
|
|
|
|
pkg->symbols.p = (void *)((uintptr_t)pkg->symbols.p + (uintptr_t)pkg);
|
|
|
|
|
pkg->sections.p = (void *)((uintptr_t)pkg->sections.p + (uintptr_t)pkg);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
pkg->addr = pkg;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
pkg->size = size;
|
|
|
|
|
if (mprotect(pkg, size, PROT_READ)) {
|
|
|
|
|
SysExit(path, "mprotect");
|
|
|
|
|
}
|
2020-06-15 14:18:57 +00:00
|
|
|
|
return pkg;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void AddDependency(struct Packages *deps, const char *path) {
|
2020-06-15 14:18:57 +00:00
|
|
|
|
struct Package *pkg;
|
|
|
|
|
pkg = LoadPackage(path);
|
2023-06-08 11:37:05 +00:00
|
|
|
|
append(deps, &pkg);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void WritePackage(struct Package *pkg) {
|
|
|
|
|
int fd;
|
|
|
|
|
size_t n;
|
|
|
|
|
int64_t o;
|
|
|
|
|
const char *path;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
pkg->magic = PACKAGE_MAGIC;
|
|
|
|
|
pkg->abi = PACKAGE_ABI;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
path = pkg->strings.p + pkg->path;
|
|
|
|
|
if ((fd = creat(path, 0644)) == -1) {
|
|
|
|
|
SysExit(path, "creat");
|
|
|
|
|
}
|
|
|
|
|
o = sizeof(*pkg);
|
|
|
|
|
// write objects
|
|
|
|
|
n = pkg->objects.i * sizeof(*pkg->objects.p);
|
|
|
|
|
if (pwrite(fd, pkg->objects.p, n, o) != n) {
|
|
|
|
|
SysExit(path, "pwrite");
|
|
|
|
|
}
|
|
|
|
|
pkg->objects.p = (void *)o;
|
|
|
|
|
o += n;
|
|
|
|
|
// write symbols
|
|
|
|
|
n = pkg->symbols.i * sizeof(*pkg->symbols.p);
|
|
|
|
|
if (pwrite(fd, pkg->symbols.p, n, o) != n) {
|
|
|
|
|
SysExit(path, "pwrite");
|
|
|
|
|
}
|
|
|
|
|
pkg->symbols.p = (void *)o;
|
|
|
|
|
o += n;
|
|
|
|
|
// write sections
|
|
|
|
|
n = pkg->sections.i * sizeof(*pkg->sections.p);
|
|
|
|
|
if (pwrite(fd, pkg->sections.p, n, o) != n) {
|
|
|
|
|
SysExit(path, "pwrite");
|
|
|
|
|
}
|
|
|
|
|
pkg->sections.p = (void *)o;
|
|
|
|
|
o += n;
|
|
|
|
|
// write strings
|
|
|
|
|
n = pkg->strings.i * sizeof(*pkg->strings.p);
|
|
|
|
|
pwrite(fd, pkg->strings.p, n, o);
|
|
|
|
|
pkg->strings.p = (void *)o;
|
|
|
|
|
// write header
|
|
|
|
|
if (pwrite(fd, pkg, sizeof(*pkg), 0) != sizeof(*pkg)) {
|
|
|
|
|
SysExit(path, "pwrite");
|
|
|
|
|
}
|
|
|
|
|
// we're done
|
|
|
|
|
if (close(fd) == -1) {
|
|
|
|
|
SysExit(path, "close");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static wontreturn void PrintUsage(int fd, int exitcode) {
|
2023-07-03 09:47:05 +00:00
|
|
|
|
tinyprint(fd, "\n\
|
2023-06-08 11:37:05 +00:00
|
|
|
|
NAME\n\
|
|
|
|
|
\n\
|
|
|
|
|
Cosmopolitan Monorepo Packager\n\
|
|
|
|
|
\n\
|
|
|
|
|
SYNOPSIS\n\
|
|
|
|
|
\n\
|
|
|
|
|
",
|
2023-07-03 09:47:05 +00:00
|
|
|
|
program_invocation_name, " [FLAGS] OBJECT...\n\
|
2023-06-08 11:37:05 +00:00
|
|
|
|
\n\
|
|
|
|
|
DESCRIPTION\n\
|
|
|
|
|
\n\
|
|
|
|
|
This program verifies the well-formedness of symbolic references\n\
|
|
|
|
|
and package dependencies in the cosmopolitan monolithic repository.\n\
|
|
|
|
|
Validation happens incrementally and is granular to static libraries.\n\
|
|
|
|
|
Each .a file should have its own .pkg file too, created by this tool.\n\
|
|
|
|
|
\n\
|
|
|
|
|
FLAGS\n\
|
|
|
|
|
\n\
|
|
|
|
|
-h show this help\n\
|
|
|
|
|
-o PATH package output path\n\
|
|
|
|
|
-d PATH package dependency path [repeatable]\n\
|
|
|
|
|
\n\
|
|
|
|
|
",
|
2023-07-03 09:47:05 +00:00
|
|
|
|
NULL);
|
2023-06-08 11:37:05 +00:00
|
|
|
|
exit(exitcode);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void GetOpts(struct Package *pkg, struct Packages *deps, int argc,
|
|
|
|
|
char *argv[]) {
|
2023-09-02 03:49:13 +00:00
|
|
|
|
long opt;
|
2022-03-16 20:33:13 +00:00
|
|
|
|
const char *arg;
|
|
|
|
|
struct GetArgs ga;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
pkg->path = -1;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
while ((opt = getopt(argc, argv, "ho:d:")) != -1) {
|
2020-06-15 14:18:57 +00:00
|
|
|
|
switch (opt) {
|
|
|
|
|
case 'o':
|
|
|
|
|
pkg->path = concat(&pkg->strings, optarg, strlen(optarg) + 1);
|
|
|
|
|
break;
|
|
|
|
|
case 'd':
|
|
|
|
|
AddDependency(deps, optarg);
|
|
|
|
|
break;
|
2021-01-16 20:05:41 +00:00
|
|
|
|
case 'h':
|
2023-06-08 11:37:05 +00:00
|
|
|
|
PrintUsage(1, 0);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
default:
|
2023-06-08 11:37:05 +00:00
|
|
|
|
PrintUsage(2, 1);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-08 11:37:05 +00:00
|
|
|
|
if (pkg->path == -1) {
|
2024-03-03 00:57:56 +00:00
|
|
|
|
tinyprint(2, "error: no packages passed to package\n", NULL);
|
2023-06-08 11:37:05 +00:00
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
if (optind == argc) {
|
2024-03-03 00:57:56 +00:00
|
|
|
|
tinyprint(2,
|
|
|
|
|
"no objects passed to package; is your foo.mk $(FOO_OBJS) glob "
|
|
|
|
|
"broken?\n",
|
|
|
|
|
NULL);
|
2023-06-08 11:37:05 +00:00
|
|
|
|
exit(1);
|
|
|
|
|
}
|
2022-03-16 20:33:13 +00:00
|
|
|
|
getargs_init(&ga, argv + optind);
|
|
|
|
|
while ((arg = getargs_next(&ga))) {
|
2023-06-08 11:37:05 +00:00
|
|
|
|
struct Object obj = {0};
|
|
|
|
|
obj.path = concat(&pkg->strings, arg, strlen(arg) + 1);
|
|
|
|
|
append(&pkg->objects, &obj);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
2022-03-16 20:33:13 +00:00
|
|
|
|
getargs_destroy(&ga);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void IndexSections(struct Package *pkg, struct Object *obj) {
|
|
|
|
|
int i;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
const char *name;
|
|
|
|
|
struct Section sect;
|
|
|
|
|
const Elf64_Shdr *shdr;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
obj->section_offset = pkg->sections.i;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
for (i = 0; i < obj->elf->e_shnum; ++i) {
|
2021-09-28 05:58:51 +00:00
|
|
|
|
bzero(§, sizeof(sect));
|
2023-06-10 16:15:19 +00:00
|
|
|
|
if (!(shdr = GetElfSectionHeaderAddress(obj->elf, obj->size, i)) ||
|
|
|
|
|
!(name = GetElfSectionName(obj->elf, obj->size, shdr))) {
|
|
|
|
|
Die("error", "elf overflow");
|
|
|
|
|
}
|
2023-06-08 11:37:05 +00:00
|
|
|
|
if (shdr->sh_type == SHT_NULL) {
|
|
|
|
|
sect.kind = kUndef;
|
|
|
|
|
} else if (shdr->sh_type == SHT_NOBITS) {
|
|
|
|
|
sect.kind = kBss;
|
|
|
|
|
} else if (shdr->sh_type == SHT_PROGBITS &&
|
|
|
|
|
!(shdr->sh_flags & SHF_EXECINSTR)) {
|
|
|
|
|
sect.kind = kData;
|
|
|
|
|
} else if (shdr->sh_type == SHT_PROGBITS &&
|
|
|
|
|
(shdr->sh_flags & SHF_EXECINSTR)) {
|
|
|
|
|
if (strcmp(name, ".privileged")) {
|
2020-06-15 14:18:57 +00:00
|
|
|
|
sect.kind = kText;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
} else {
|
|
|
|
|
sect.kind = kPrivilegedText;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2023-06-08 11:37:05 +00:00
|
|
|
|
sect.kind = kOther;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
2023-06-08 11:37:05 +00:00
|
|
|
|
sect.name = concat(&pkg->strings, name, strlen(name) + 1);
|
|
|
|
|
append(&pkg->sections, §);
|
|
|
|
|
++obj->section_count;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static enum SectionKind ClassifySection(struct Package *pkg, struct Object *obj,
|
|
|
|
|
uint8_t type, Elf64_Section shndx) {
|
Apply clang-format update to repo (#1154)
Commit bc6c183 introduced a bunch of discrepancies between what files
look like in the repo and what clang-format says they should look like.
However, there were already a few discrepancies prior to that. Most of
these discrepancies seemed to be unintentional, but a few of them were
load-bearing (e.g., a #include that violated header ordering needing
something to have been #defined by a 'later' #include.)
I opted to take what I hope is a relatively smooth-brained approach: I
reverted the .clang-format change, ran clang-format on the whole repo,
reapplied the .clang-format change, reran clang-format again, and then
reverted the commit that contained the first run. Thus the full effect
of this PR should only be to apply the changed formatting rules to the
repo, and from skimming the results, this seems to be the case.
My work can be checked by applying the short, manual commits, and then
rerunning the command listed in the autogenerated commits (those whose
messages I have prefixed auto:) and seeing if your results agree.
It might be that the other diffs should be fixed at some point but I'm
leaving that aside for now.
fd '\.c(c|pp)?$' --print0| xargs -0 clang-format -i
2024-04-25 17:38:00 +00:00
|
|
|
|
if (shndx == SHN_ABS)
|
|
|
|
|
return kOther;
|
|
|
|
|
if (type == STT_COMMON)
|
|
|
|
|
return kBss;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
return pkg->sections.p[obj->section_offset + shndx].kind;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void LoadSymbols(struct Package *pkg, uint32_t object) {
|
2020-06-15 14:18:57 +00:00
|
|
|
|
Elf64_Xword i;
|
|
|
|
|
const char *name;
|
|
|
|
|
struct Object *obj;
|
|
|
|
|
struct Symbol symbol;
|
|
|
|
|
obj = &pkg->objects.p[object];
|
|
|
|
|
symbol.object = object;
|
|
|
|
|
for (i = 0; i < obj->symcount; ++i) {
|
2023-06-08 11:37:05 +00:00
|
|
|
|
symbol.section = obj->section_offset + obj->syms[i].st_shndx;
|
2022-04-21 16:15:36 +00:00
|
|
|
|
symbol.bind_ = ELF64_ST_BIND(obj->syms[i].st_info);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
symbol.type = ELF64_ST_TYPE(obj->syms[i].st_info);
|
2022-04-21 16:15:36 +00:00
|
|
|
|
if (symbol.bind_ != STB_LOCAL &&
|
2020-06-15 14:18:57 +00:00
|
|
|
|
(symbol.type == STT_OBJECT || symbol.type == STT_FUNC ||
|
2024-02-01 11:39:46 +00:00
|
|
|
|
symbol.type == STT_COMMON || symbol.type == STT_NOTYPE ||
|
|
|
|
|
symbol.type == STT_GNU_IFUNC)) {
|
2023-06-10 16:15:19 +00:00
|
|
|
|
if (!(name = GetElfString(obj->elf, obj->size, obj->strs,
|
|
|
|
|
obj->syms[i].st_name))) {
|
|
|
|
|
Die("error", "elf overflow");
|
|
|
|
|
}
|
2023-06-08 11:37:05 +00:00
|
|
|
|
if (strcmp(name, "_GLOBAL_OFFSET_TABLE_")) {
|
|
|
|
|
symbol.kind =
|
|
|
|
|
ClassifySection(pkg, obj, symbol.type, obj->syms[i].st_shndx);
|
|
|
|
|
symbol.name = concat(&pkg->strings, name, strlen(name) + 1);
|
|
|
|
|
append(symbol.kind != kUndef ? &pkg->symbols : &pkg->undefs, &symbol);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-11 12:48:39 +00:00
|
|
|
|
static Elf64_Shdr *FindElfSection(Elf64_Ehdr *elf, size_t esize,
|
|
|
|
|
const char *name) {
|
2023-06-08 11:37:05 +00:00
|
|
|
|
long i;
|
|
|
|
|
Elf64_Shdr *shdr;
|
2023-06-10 16:15:19 +00:00
|
|
|
|
const char *secname;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
for (i = 0; i < elf->e_shnum; ++i) {
|
2023-06-10 16:15:19 +00:00
|
|
|
|
if ((secname = GetElfSectionName(
|
|
|
|
|
elf, esize, (shdr = GetElfSectionHeaderAddress(elf, esize, i)))) &&
|
|
|
|
|
!strcmp(secname, name)) {
|
2023-06-08 11:37:05 +00:00
|
|
|
|
return shdr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void LoadPriviligedRefsToUndefs(struct Package *pkg,
|
|
|
|
|
struct Object *obj) {
|
|
|
|
|
long x;
|
|
|
|
|
struct Rela r;
|
|
|
|
|
const char *s;
|
|
|
|
|
Elf64_Shdr *shdr;
|
|
|
|
|
Elf64_Rela *rela, *erela;
|
2023-07-11 12:48:39 +00:00
|
|
|
|
if ((shdr = FindElfSection(obj->elf, obj->size, ".rela.privileged"))) {
|
2023-06-10 16:15:19 +00:00
|
|
|
|
if (!(rela = GetElfSectionAddress(obj->elf, obj->size, shdr))) {
|
|
|
|
|
Die("error", "elf overflow");
|
|
|
|
|
}
|
2023-06-08 11:37:05 +00:00
|
|
|
|
erela = rela + shdr->sh_size / sizeof(*rela);
|
|
|
|
|
for (; rela < erela; ++rela) {
|
Apply clang-format update to repo (#1154)
Commit bc6c183 introduced a bunch of discrepancies between what files
look like in the repo and what clang-format says they should look like.
However, there were already a few discrepancies prior to that. Most of
these discrepancies seemed to be unintentional, but a few of them were
load-bearing (e.g., a #include that violated header ordering needing
something to have been #defined by a 'later' #include.)
I opted to take what I hope is a relatively smooth-brained approach: I
reverted the .clang-format change, ran clang-format on the whole repo,
reapplied the .clang-format change, reran clang-format again, and then
reverted the commit that contained the first run. Thus the full effect
of this PR should only be to apply the changed formatting rules to the
repo, and from skimming the results, this seems to be the case.
My work can be checked by applying the short, manual commits, and then
rerunning the command listed in the autogenerated commits (those whose
messages I have prefixed auto:) and seeing if your results agree.
It might be that the other diffs should be fixed at some point but I'm
leaving that aside for now.
fd '\.c(c|pp)?$' --print0| xargs -0 clang-format -i
2024-04-25 17:38:00 +00:00
|
|
|
|
if (!ELF64_R_TYPE(rela->r_info))
|
|
|
|
|
continue;
|
|
|
|
|
if (!(x = ELF64_R_SYM(rela->r_info)))
|
|
|
|
|
continue;
|
|
|
|
|
if (x > obj->symcount)
|
|
|
|
|
Die("error", "elf overflow");
|
|
|
|
|
if (obj->syms[x].st_shndx)
|
|
|
|
|
continue; // symbol is defined
|
2023-06-08 11:37:05 +00:00
|
|
|
|
if (ELF64_ST_BIND(obj->syms[x].st_info) != STB_WEAK &&
|
|
|
|
|
ELF64_ST_BIND(obj->syms[x].st_info) != STB_GLOBAL) {
|
2023-07-03 09:47:05 +00:00
|
|
|
|
tinyprint(2, "warning: undefined symbol not global\n", NULL);
|
2023-06-08 11:37:05 +00:00
|
|
|
|
continue;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
2023-06-10 16:15:19 +00:00
|
|
|
|
if (!(s = GetElfString(obj->elf, obj->size, obj->strs,
|
|
|
|
|
obj->syms[x].st_name))) {
|
|
|
|
|
Die("error", "elf overflow");
|
|
|
|
|
}
|
|
|
|
|
r.symbol_name = strdup(s);
|
2023-06-08 11:37:05 +00:00
|
|
|
|
r.object_path = strdup(pkg->strings.p + obj->path);
|
|
|
|
|
append(&prtu, &r);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void OpenObject(struct Package *pkg, struct Object *obj, int oid) {
|
2020-06-15 14:18:57 +00:00
|
|
|
|
int fd;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
const char *path;
|
|
|
|
|
path = pkg->strings.p + obj->path;
|
|
|
|
|
if ((fd = open(path, O_RDONLY)) == -1) {
|
|
|
|
|
SysExit(path, "open");
|
|
|
|
|
}
|
|
|
|
|
if ((obj->size = lseek(fd, 0, SEEK_END)) == -1) {
|
|
|
|
|
SysExit(path, "lseek");
|
|
|
|
|
}
|
|
|
|
|
if ((obj->elf = mmap(0, obj->size, PROT_READ, MAP_SHARED, fd, 0)) ==
|
|
|
|
|
MAP_FAILED) {
|
|
|
|
|
SysExit(path, "mmap");
|
|
|
|
|
}
|
|
|
|
|
close(fd);
|
|
|
|
|
if (!IsElf64Binary(obj->elf, obj->size)) {
|
2023-06-10 16:15:19 +00:00
|
|
|
|
Die(path, "not an elf64 binary");
|
2023-06-08 11:37:05 +00:00
|
|
|
|
}
|
2023-06-18 07:55:09 +00:00
|
|
|
|
if (!(obj->strs = GetElfStringTable(obj->elf, obj->size, ".strtab"))) {
|
2023-06-10 16:15:19 +00:00
|
|
|
|
Die(path, "missing elf string table");
|
2023-06-08 11:37:05 +00:00
|
|
|
|
}
|
2023-07-02 17:19:16 +00:00
|
|
|
|
if (!(obj->syms =
|
|
|
|
|
GetElfSymbols(obj->elf, obj->size, SHT_SYMTAB, &obj->symcount))) {
|
2023-06-10 16:15:19 +00:00
|
|
|
|
Die(path, "missing elf symbol table");
|
2023-06-08 11:37:05 +00:00
|
|
|
|
}
|
|
|
|
|
IndexSections(pkg, obj);
|
|
|
|
|
LoadPriviligedRefsToUndefs(pkg, obj);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void CloseObject(struct Object *obj) {
|
Apply clang-format update to repo (#1154)
Commit bc6c183 introduced a bunch of discrepancies between what files
look like in the repo and what clang-format says they should look like.
However, there were already a few discrepancies prior to that. Most of
these discrepancies seemed to be unintentional, but a few of them were
load-bearing (e.g., a #include that violated header ordering needing
something to have been #defined by a 'later' #include.)
I opted to take what I hope is a relatively smooth-brained approach: I
reverted the .clang-format change, ran clang-format on the whole repo,
reapplied the .clang-format change, reran clang-format again, and then
reverted the commit that contained the first run. Thus the full effect
of this PR should only be to apply the changed formatting rules to the
repo, and from skimming the results, this seems to be the case.
My work can be checked by applying the short, manual commits, and then
rerunning the command listed in the autogenerated commits (those whose
messages I have prefixed auto:) and seeing if your results agree.
It might be that the other diffs should be fixed at some point but I'm
leaving that aside for now.
fd '\.c(c|pp)?$' --print0| xargs -0 clang-format -i
2024-04-25 17:38:00 +00:00
|
|
|
|
if (munmap(obj->elf, obj->size))
|
|
|
|
|
notpossible;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void LoadObjects(struct Package *pkg) {
|
2020-06-15 14:18:57 +00:00
|
|
|
|
size_t i;
|
|
|
|
|
struct Object *obj;
|
|
|
|
|
for (i = 0; i < pkg->objects.i; ++i) {
|
2021-04-18 18:34:59 +00:00
|
|
|
|
obj = pkg->objects.p + i;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
OpenObject(pkg, obj, i);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
LoadSymbols(pkg, i);
|
|
|
|
|
CloseObject(obj);
|
|
|
|
|
}
|
2021-04-18 18:34:59 +00:00
|
|
|
|
qsort_r(pkg->symbols.p, pkg->symbols.i, sizeof(*pkg->symbols.p),
|
|
|
|
|
(void *)CompareSymbolName, pkg->strings.p);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static struct Symbol *BisectSymbol(struct Package *pkg, const char *name) {
|
2021-04-18 18:34:59 +00:00
|
|
|
|
int c;
|
|
|
|
|
long m, l, r;
|
|
|
|
|
l = 0;
|
|
|
|
|
r = pkg->symbols.i - 1;
|
|
|
|
|
while (l <= r) {
|
2023-07-10 17:16:55 +00:00
|
|
|
|
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
2021-04-18 18:34:59 +00:00
|
|
|
|
c = strcmp(pkg->strings.p + pkg->symbols.p[m].name, name);
|
|
|
|
|
if (c < 0) {
|
|
|
|
|
l = m + 1;
|
|
|
|
|
} else if (c > 0) {
|
|
|
|
|
r = m - 1;
|
|
|
|
|
} else {
|
|
|
|
|
return pkg->symbols.p + m;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static bool FindSymbol(const char *name, struct Package *pkg,
|
|
|
|
|
struct Packages *directdeps, struct Package **out_pkg,
|
|
|
|
|
struct Symbol **out_sym) {
|
2023-09-02 03:49:13 +00:00
|
|
|
|
size_t i;
|
2021-04-18 18:34:59 +00:00
|
|
|
|
struct Symbol *sym;
|
|
|
|
|
if ((sym = BisectSymbol(pkg, name))) {
|
Apply clang-format update to repo (#1154)
Commit bc6c183 introduced a bunch of discrepancies between what files
look like in the repo and what clang-format says they should look like.
However, there were already a few discrepancies prior to that. Most of
these discrepancies seemed to be unintentional, but a few of them were
load-bearing (e.g., a #include that violated header ordering needing
something to have been #defined by a 'later' #include.)
I opted to take what I hope is a relatively smooth-brained approach: I
reverted the .clang-format change, ran clang-format on the whole repo,
reapplied the .clang-format change, reran clang-format again, and then
reverted the commit that contained the first run. Thus the full effect
of this PR should only be to apply the changed formatting rules to the
repo, and from skimming the results, this seems to be the case.
My work can be checked by applying the short, manual commits, and then
rerunning the command listed in the autogenerated commits (those whose
messages I have prefixed auto:) and seeing if your results agree.
It might be that the other diffs should be fixed at some point but I'm
leaving that aside for now.
fd '\.c(c|pp)?$' --print0| xargs -0 clang-format -i
2024-04-25 17:38:00 +00:00
|
|
|
|
if (out_sym)
|
|
|
|
|
*out_sym = sym;
|
|
|
|
|
if (out_pkg)
|
|
|
|
|
*out_pkg = pkg;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; i < directdeps->i; ++i) {
|
2021-04-18 18:34:59 +00:00
|
|
|
|
if ((sym = BisectSymbol(directdeps->p[i], name))) {
|
Apply clang-format update to repo (#1154)
Commit bc6c183 introduced a bunch of discrepancies between what files
look like in the repo and what clang-format says they should look like.
However, there were already a few discrepancies prior to that. Most of
these discrepancies seemed to be unintentional, but a few of them were
load-bearing (e.g., a #include that violated header ordering needing
something to have been #defined by a 'later' #include.)
I opted to take what I hope is a relatively smooth-brained approach: I
reverted the .clang-format change, ran clang-format on the whole repo,
reapplied the .clang-format change, reran clang-format again, and then
reverted the commit that contained the first run. Thus the full effect
of this PR should only be to apply the changed formatting rules to the
repo, and from skimming the results, this seems to be the case.
My work can be checked by applying the short, manual commits, and then
rerunning the command listed in the autogenerated commits (those whose
messages I have prefixed auto:) and seeing if your results agree.
It might be that the other diffs should be fixed at some point but I'm
leaving that aside for now.
fd '\.c(c|pp)?$' --print0| xargs -0 clang-format -i
2024-04-25 17:38:00 +00:00
|
|
|
|
if (out_sym)
|
|
|
|
|
*out_sym = sym;
|
|
|
|
|
if (out_pkg)
|
|
|
|
|
*out_pkg = directdeps->p[i];
|
2020-06-15 14:18:57 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void CheckStrictDeps(struct Package *pkg, struct Packages *deps) {
|
2020-06-15 14:18:57 +00:00
|
|
|
|
size_t i, j;
|
|
|
|
|
struct Package *dep;
|
|
|
|
|
struct Symbol *undef;
|
|
|
|
|
for (i = 0; i < pkg->undefs.i; ++i) {
|
|
|
|
|
undef = &pkg->undefs.p[i];
|
Apply clang-format update to repo (#1154)
Commit bc6c183 introduced a bunch of discrepancies between what files
look like in the repo and what clang-format says they should look like.
However, there were already a few discrepancies prior to that. Most of
these discrepancies seemed to be unintentional, but a few of them were
load-bearing (e.g., a #include that violated header ordering needing
something to have been #defined by a 'later' #include.)
I opted to take what I hope is a relatively smooth-brained approach: I
reverted the .clang-format change, ran clang-format on the whole repo,
reapplied the .clang-format change, reran clang-format again, and then
reverted the commit that contained the first run. Thus the full effect
of this PR should only be to apply the changed formatting rules to the
repo, and from skimming the results, this seems to be the case.
My work can be checked by applying the short, manual commits, and then
rerunning the command listed in the autogenerated commits (those whose
messages I have prefixed auto:) and seeing if your results agree.
It might be that the other diffs should be fixed at some point but I'm
leaving that aside for now.
fd '\.c(c|pp)?$' --print0| xargs -0 clang-format -i
2024-04-25 17:38:00 +00:00
|
|
|
|
if (undef->bind_ == STB_WEAK)
|
|
|
|
|
continue;
|
2021-04-18 18:34:59 +00:00
|
|
|
|
if (!FindSymbol(pkg->strings.p + undef->name, pkg, deps, NULL, NULL)) {
|
2023-07-03 09:47:05 +00:00
|
|
|
|
tinyprint(2, pkg->strings.p + pkg->path, ": undefined symbol '",
|
|
|
|
|
pkg->strings.p + undef->name, "' (",
|
|
|
|
|
pkg->strings.p + pkg->objects.p[undef->object].path,
|
|
|
|
|
") not defined by direct dependencies:\n", NULL);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
for (j = 0; j < deps->i; ++j) {
|
|
|
|
|
dep = deps->p[j];
|
2023-07-03 09:47:05 +00:00
|
|
|
|
tinyprint(2, "\t", dep->strings.p + dep->path, "\n", NULL);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
free(pkg->undefs.p);
|
2021-09-28 05:58:51 +00:00
|
|
|
|
bzero(&pkg->undefs, sizeof(pkg->undefs));
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void CheckYourPrivilege(struct Package *pkg, struct Packages *deps) {
|
2023-09-02 03:49:13 +00:00
|
|
|
|
int i, f;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
const char *name;
|
|
|
|
|
struct Symbol *sym;
|
|
|
|
|
struct Package *dep;
|
|
|
|
|
for (f = i = 0; i < prtu.i; ++i) {
|
|
|
|
|
name = prtu.p[i].symbol_name;
|
|
|
|
|
if (FindSymbol(name, pkg, deps, &dep, &sym) &&
|
|
|
|
|
dep->sections.p[sym->section].kind == kText) {
|
2023-07-03 09:47:05 +00:00
|
|
|
|
tinyprint(2, prtu.p[i].object_path,
|
|
|
|
|
": privileged code referenced unprivileged symbol '", name,
|
|
|
|
|
"' in section '",
|
|
|
|
|
dep->strings.p + dep->sections.p[sym->section].name, "'\n",
|
|
|
|
|
NULL);
|
2023-06-08 11:37:05 +00:00
|
|
|
|
++f;
|
|
|
|
|
}
|
|
|
|
|
}
|
Apply clang-format update to repo (#1154)
Commit bc6c183 introduced a bunch of discrepancies between what files
look like in the repo and what clang-format says they should look like.
However, there were already a few discrepancies prior to that. Most of
these discrepancies seemed to be unintentional, but a few of them were
load-bearing (e.g., a #include that violated header ordering needing
something to have been #defined by a 'later' #include.)
I opted to take what I hope is a relatively smooth-brained approach: I
reverted the .clang-format change, ran clang-format on the whole repo,
reapplied the .clang-format change, reran clang-format again, and then
reverted the commit that contained the first run. Thus the full effect
of this PR should only be to apply the changed formatting rules to the
repo, and from skimming the results, this seems to be the case.
My work can be checked by applying the short, manual commits, and then
rerunning the command listed in the autogenerated commits (those whose
messages I have prefixed auto:) and seeing if your results agree.
It might be that the other diffs should be fixed at some point but I'm
leaving that aside for now.
fd '\.c(c|pp)?$' --print0| xargs -0 clang-format -i
2024-04-25 17:38:00 +00:00
|
|
|
|
if (f)
|
|
|
|
|
exit(1);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static bool IsSymbolDirectlyReachable(struct Package *pkg,
|
|
|
|
|
struct Packages *deps,
|
|
|
|
|
const char *symbol) {
|
|
|
|
|
return FindSymbol(symbol, pkg, deps, 0, 0);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 11:37:05 +00:00
|
|
|
|
static void Package(int argc, char *argv[], struct Package *pkg,
|
|
|
|
|
struct Packages *deps) {
|
2023-09-02 03:49:13 +00:00
|
|
|
|
size_t i;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
GetOpts(pkg, deps, argc, argv);
|
|
|
|
|
LoadObjects(pkg);
|
|
|
|
|
CheckStrictDeps(pkg, deps);
|
2023-06-08 11:37:05 +00:00
|
|
|
|
CheckYourPrivilege(pkg, deps);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
WritePackage(pkg);
|
|
|
|
|
for (i = 0; i < deps->i; ++i) {
|
Apply clang-format update to repo (#1154)
Commit bc6c183 introduced a bunch of discrepancies between what files
look like in the repo and what clang-format says they should look like.
However, there were already a few discrepancies prior to that. Most of
these discrepancies seemed to be unintentional, but a few of them were
load-bearing (e.g., a #include that violated header ordering needing
something to have been #defined by a 'later' #include.)
I opted to take what I hope is a relatively smooth-brained approach: I
reverted the .clang-format change, ran clang-format on the whole repo,
reapplied the .clang-format change, reran clang-format again, and then
reverted the commit that contained the first run. Thus the full effect
of this PR should only be to apply the changed formatting rules to the
repo, and from skimming the results, this seems to be the case.
My work can be checked by applying the short, manual commits, and then
rerunning the command listed in the autogenerated commits (those whose
messages I have prefixed auto:) and seeing if your results agree.
It might be that the other diffs should be fixed at some point but I'm
leaving that aside for now.
fd '\.c(c|pp)?$' --print0| xargs -0 clang-format -i
2024-04-25 17:38:00 +00:00
|
|
|
|
if (munmap(deps->p[i]->addr, deps->p[i]->size))
|
|
|
|
|
notpossible;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
|
struct Package pkg;
|
|
|
|
|
struct Packages deps;
|
2023-06-08 11:37:05 +00:00
|
|
|
|
if (argc == 2 && !strcmp(argv[1], "-n")) {
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
2023-11-19 00:56:11 +00:00
|
|
|
|
#ifdef MODE_DBG
|
2023-07-28 13:17:34 +00:00
|
|
|
|
ShowCrashReports();
|
|
|
|
|
#endif
|
2021-09-28 05:58:51 +00:00
|
|
|
|
bzero(&pkg, sizeof(pkg));
|
|
|
|
|
bzero(&deps, sizeof(deps));
|
2020-06-15 14:18:57 +00:00
|
|
|
|
Package(argc, argv, &pkg, &deps);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|