Get Cosmopolitan into releasable state

A new rollup tool now exists for flattening out the headers in a way
that works better for our purposes than cpp. A lot of the API clutter
has been removed. APIs that aren't a sure thing in terms of general
recommendation are now marked internal.

There's now a smoke test for the amalgamation archive and gigantic
header file. So we can now guarantee you can use this project on the
easiest difficulty setting without the gigantic repository.

A website is being created, which is currently a work in progress:
https://justine.storage.googleapis.com/cosmopolitan/index.html
This commit is contained in:
Justine Tunney 2020-11-25 08:19:00 -08:00
parent dba7552c1e
commit ea0b5d9d1c
775 changed files with 6864 additions and 3963 deletions

View file

@ -1,15 +1,10 @@
#ifndef COSMOPOLITAN_LIBC_ELF_H_
#define COSMOPOLITAN_LIBC_ELF_H_
#ifndef __STRICT_ANSI__
#include "libc/bits/safemacros.h"
#include "libc/elf/def.h"
#include "libc/elf/struct/ehdr.h"
#include "libc/elf/struct/phdr.h"
#include "libc/elf/struct/shdr.h"
#include "libc/elf/struct/sym.h"
#include "libc/limits.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/runtime/ezmap.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@ -17,101 +12,20 @@ COSMOPOLITAN_C_START_
cosmopolitan § executable & linkable format
*/
struct MappedFile;
Elf64_Ehdr *mapelfread(const char *, struct MappedFile *);
char *GetElfStringTable(const Elf64_Ehdr *, size_t);
Elf64_Sym *GetElfSymbolTable(const Elf64_Ehdr *, size_t, Elf64_Xword *);
bool IsElf64Binary(const Elf64_Ehdr *, size_t);
forceinline void checkelfaddress(const Elf64_Ehdr *elf, size_t mapsize,
intptr_t addr, size_t addrsize) {
#if !(TRUSTWORTHY + ELF_TRUSTWORTHY + 0) || ELF_UNTRUSTWORTHY + 0
if (addr < (intptr_t)elf || addr + addrsize > (intptr_t)elf + mapsize) {
abort();
}
#endif
}
static inline bool iselfsymbolcontent(const Elf64_Sym *sym) {
return sym->st_size > 0 && (ELF64_ST_TYPE(sym->st_info) == STT_FUNC ||
ELF64_ST_TYPE(sym->st_info) == STT_OBJECT);
}
static inline Elf64_Phdr *getelfsegmentheaderaddress(const Elf64_Ehdr *elf,
size_t mapsize,
unsigned i) {
intptr_t addr =
((intptr_t)elf + (intptr_t)elf->e_phoff + (intptr_t)elf->e_phentsize * i);
checkelfaddress(elf, mapsize, addr, elf->e_phentsize);
return (Elf64_Phdr *)addr;
}
static inline Elf64_Shdr *getelfsectionheaderaddress(const Elf64_Ehdr *elf,
size_t mapsize,
Elf64_Half i) {
intptr_t addr =
((intptr_t)elf + (intptr_t)elf->e_shoff + (intptr_t)elf->e_shentsize * i);
checkelfaddress(elf, mapsize, addr, elf->e_shentsize);
return (Elf64_Shdr *)addr;
}
static inline void *getelfsectionaddress(const Elf64_Ehdr *elf, size_t mapsize,
const Elf64_Shdr *shdr) {
intptr_t addr, size;
addr = (intptr_t)elf + (intptr_t)shdr->sh_offset;
size = (intptr_t)shdr->sh_size;
checkelfaddress(elf, mapsize, addr, size);
return (void *)addr;
}
static inline char *getelfsectionnamestringtable(const Elf64_Ehdr *elf,
size_t mapsize) {
if (!elf->e_shoff || !elf->e_shentsize) return NULL;
return getelfsectionaddress(
elf, mapsize, getelfsectionheaderaddress(elf, mapsize, elf->e_shstrndx));
}
static inline void getelfvirtualaddressrange(const Elf64_Ehdr *elf,
size_t elfsize,
intptr_t *out_start,
intptr_t *out_end) {
unsigned i;
Elf64_Phdr *phdr;
intptr_t start, end, pstart, pend;
start = INTPTR_MAX;
end = 0;
for (i = 0; i < elf->e_phnum; ++i) {
phdr = getelfsegmentheaderaddress(elf, elfsize, i);
if (phdr->p_type != PT_LOAD) continue;
pstart = phdr->p_vaddr;
pend = phdr->p_vaddr + phdr->p_memsz;
if (pstart < start) start = pstart;
if (pend > end) end = pend;
}
if (out_start) *out_start = start;
if (out_end) *out_end = end;
}
static inline char *GetElfString(const Elf64_Ehdr *elf, size_t mapsize,
const char *strtab, Elf64_Word rva) {
intptr_t addr = (intptr_t)strtab + rva;
#if !(TRUSTWORTHY + ELF_TRUSTWORTHY + 0)
checkelfaddress(elf, mapsize, addr, 0);
checkelfaddress(elf, mapsize, addr,
strnlen((char *)addr, (intptr_t)elf + mapsize - addr) + 1);
#endif
return (char *)addr;
}
static inline const char *GetElfSectionName(const Elf64_Ehdr *elf,
size_t mapsize, Elf64_Shdr *shdr) {
if (!elf || !shdr) return NULL;
return GetElfString(elf, mapsize, getelfsectionnamestringtable(elf, mapsize),
shdr->sh_name);
}
void CheckElfAddress(const Elf64_Ehdr *, size_t, intptr_t, size_t);
bool IsElfSymbolContent(const Elf64_Sym *);
Elf64_Phdr *GetElfSegmentHeaderAddress(const Elf64_Ehdr *, size_t, unsigned);
Elf64_Shdr *GetElfSectionHeaderAddress(const Elf64_Ehdr *, size_t, Elf64_Half);
void *GetElfSectionAddress(const Elf64_Ehdr *, size_t, const Elf64_Shdr *);
char *GetElfSectionNameStringTable(const Elf64_Ehdr *, size_t);
void GetElfVirtualAddressRange(const Elf64_Ehdr *, size_t, intptr_t *,
intptr_t *);
char *GetElfString(const Elf64_Ehdr *, size_t, const char *, Elf64_Word);
const char *GetElfSectionName(const Elf64_Ehdr *, size_t, Elf64_Shdr *);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* !ANSI */
#endif /* COSMOPOLITAN_LIBC_ELF_H_ */