mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-02 17:28:30 +00:00
Invent tool for renaming ELF object symbols
This commit is contained in:
parent
5fd7b07fac
commit
3bf95ae7ec
2 changed files with 370 additions and 58 deletions
|
@ -289,15 +289,13 @@ static void RewriteTlsCodeAmd64(void) {
|
|||
uint8_t *p;
|
||||
Elf64_Shdr *shdr;
|
||||
for (i = 0; i < elf->e_shnum; ++i) {
|
||||
if (!(shdr = GetElfSectionHeaderAddress(elf, esize, i))) {
|
||||
if (!(shdr = GetElfSectionHeaderAddress(elf, esize, i)))
|
||||
Die("elf header overflow #1");
|
||||
}
|
||||
if (shdr->sh_type == SHT_PROGBITS && //
|
||||
(shdr->sh_flags & SHF_ALLOC) && //
|
||||
(shdr->sh_flags & SHF_EXECINSTR)) {
|
||||
if (!(p = GetElfSectionAddress(elf, esize, shdr))) {
|
||||
if (!(p = GetElfSectionAddress(elf, esize, shdr)))
|
||||
Die("elf header overflow #2");
|
||||
}
|
||||
ChangeTlsFsToGs(p, shdr->sh_size);
|
||||
}
|
||||
}
|
||||
|
@ -309,20 +307,16 @@ static void RewriteTlsCodeArm64(void) {
|
|||
Elf64_Shdr *shdr;
|
||||
uint32_t *p, *pe;
|
||||
for (i = 0; i < elf->e_shnum; ++i) {
|
||||
if (!(shdr = GetElfSectionHeaderAddress(elf, esize, i))) {
|
||||
if (!(shdr = GetElfSectionHeaderAddress(elf, esize, i)))
|
||||
Die("elf header overflow #1");
|
||||
}
|
||||
if (shdr->sh_type == SHT_PROGBITS && //
|
||||
(shdr->sh_flags & SHF_ALLOC) && //
|
||||
(shdr->sh_flags & SHF_EXECINSTR)) {
|
||||
if (!(p = GetElfSectionAddress(elf, esize, shdr))) {
|
||||
if (!(p = GetElfSectionAddress(elf, esize, shdr)))
|
||||
Die("elf header overflow #2");
|
||||
}
|
||||
for (pe = p + shdr->sh_size / 4; p <= pe; ++p) {
|
||||
if ((*p & -32) == MRS_TPIDR_EL0) {
|
||||
for (pe = p + shdr->sh_size / 4; p <= pe; ++p)
|
||||
if ((*p & -32) == MRS_TPIDR_EL0)
|
||||
*p = MOV_REG(*p & 31, COSMO_TLS_REG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -352,17 +346,14 @@ static void OptimizePatchableFunctionEntries(void) {
|
|||
continue;
|
||||
if (ELF64_ST_TYPE(syms[i].st_info) != STT_FUNC)
|
||||
continue;
|
||||
if (!(shdr = GetElfSectionHeaderAddress(elf, esize, syms[i].st_shndx))) {
|
||||
if (!(shdr = GetElfSectionHeaderAddress(elf, esize, syms[i].st_shndx)))
|
||||
Die("elf header overflow #3");
|
||||
}
|
||||
if (shdr->sh_type != SHT_PROGBITS)
|
||||
continue;
|
||||
if (!(p = GetElfSectionAddress(elf, esize, shdr))) {
|
||||
if (!(p = GetElfSectionAddress(elf, esize, shdr)))
|
||||
Die("elf section overflow");
|
||||
}
|
||||
if (ckd_sub(&sym_rva, syms[i].st_value, shdr->sh_addr)) {
|
||||
if (ckd_sub(&sym_rva, syms[i].st_value, shdr->sh_addr))
|
||||
Die("elf symbol beneath section");
|
||||
}
|
||||
if (sym_rva > esize - shdr->sh_offset || //
|
||||
(p += sym_rva) >= (unsigned char *)elf + esize || //
|
||||
syms[i].st_size >= esize - sym_rva) {
|
||||
|
@ -403,17 +394,14 @@ static void RelinkZipFiles(void) {
|
|||
recs = 0;
|
||||
cdir = (stop = eocd) - (cdsize = ZIP_CDIR_SIZE(eocd));
|
||||
for (cfile = cdir; cfile < stop; cfile += ZIP_CFILE_HDRSIZE(cfile)) {
|
||||
if (++recs >= 65536) {
|
||||
if (++recs >= 65536)
|
||||
Die("too many zip central directory records");
|
||||
}
|
||||
if (cfile < base || //
|
||||
cfile + kZipCfileHdrMinSize > xeof || //
|
||||
cfile + ZIP_CFILE_HDRSIZE(cfile) > xeof) {
|
||||
cfile + ZIP_CFILE_HDRSIZE(cfile) > xeof)
|
||||
Die("zip central directory entry overflows image");
|
||||
}
|
||||
if (READ32LE(cfile) != kZipCfileHdrMagic) {
|
||||
if (READ32LE(cfile) != kZipCfileHdrMagic)
|
||||
Die("bad __zip_cdir_size or zip central directory corrupted");
|
||||
}
|
||||
if ((rela = ZIP_CFILE_OFFSET(cfile)) < 0) {
|
||||
lfile = cfile + kZipCfileOffsetOffset + rela;
|
||||
} else {
|
||||
|
@ -421,33 +409,27 @@ static void RelinkZipFiles(void) {
|
|||
}
|
||||
if (lfile < base || //
|
||||
lfile + kZipLfileHdrMinSize > xeof || //
|
||||
lfile + ZIP_LFILE_SIZE(lfile) > xeof) {
|
||||
lfile + ZIP_LFILE_SIZE(lfile) > xeof)
|
||||
Die("zip local file overflows image");
|
||||
}
|
||||
if (READ32LE(lfile) != kZipLfileHdrMagic) {
|
||||
if (READ32LE(lfile) != kZipLfileHdrMagic)
|
||||
Die("zip central directory offset to local file corrupted");
|
||||
}
|
||||
if (rela < 0) {
|
||||
if (rela < 0)
|
||||
WRITE32LE(cfile + kZipCfileOffsetOffset, lfile - base);
|
||||
}
|
||||
}
|
||||
// append new eocd record to program image
|
||||
if (esize > INT_MAX - sizeof(foot) ||
|
||||
(cdoffset = esize) > INT_MAX - sizeof(foot)) {
|
||||
(cdoffset = esize) > INT_MAX - sizeof(foot))
|
||||
Die("the time has come to adopt zip64");
|
||||
}
|
||||
bzero(foot, sizeof(foot));
|
||||
WRITE32LE(foot, kZipCdirHdrMagic);
|
||||
WRITE32LE(foot + kZipCdirSizeOffset, cdsize);
|
||||
WRITE16LE(foot + kZipCdirRecordsOffset, recs);
|
||||
WRITE32LE(foot + kZipCdirOffsetOffset, cdoffset);
|
||||
WRITE16LE(foot + kZipCdirRecordsOnDiskOffset, recs);
|
||||
if (pwrite(fildes, cdir, cdsize, esize) != cdsize) {
|
||||
if (pwrite(fildes, cdir, cdsize, esize) != cdsize)
|
||||
SysExit("cdir pwrite");
|
||||
}
|
||||
if (pwrite(fildes, foot, sizeof(foot), esize + cdsize) != sizeof(foot)) {
|
||||
if (pwrite(fildes, foot, sizeof(foot), esize + cdsize) != sizeof(foot))
|
||||
SysExit("eocd pwrite");
|
||||
}
|
||||
eocd = foot;
|
||||
}
|
||||
|
||||
|
@ -656,29 +638,22 @@ static void PurgeIfuncSections(void) {
|
|||
}
|
||||
|
||||
static void FixupObject(void) {
|
||||
if ((fildes = open(epath, mode)) == -1) {
|
||||
if ((fildes = open(epath, mode)) == -1)
|
||||
SysExit("open");
|
||||
}
|
||||
if ((esize = lseek(fildes, 0, SEEK_END)) == -1) {
|
||||
if ((esize = lseek(fildes, 0, SEEK_END)) == -1)
|
||||
SysExit("lseek");
|
||||
}
|
||||
if (esize) {
|
||||
elf = Malloc(esize);
|
||||
if (pread(fildes, elf, esize, 0) != esize) {
|
||||
if (pread(fildes, elf, esize, 0) != esize)
|
||||
SysExit("pread");
|
||||
}
|
||||
if (!IsElf64Binary(elf, esize)) {
|
||||
if (!IsElf64Binary(elf, esize))
|
||||
Die("not an elf64 binary");
|
||||
}
|
||||
if (!(syms = GetElfSymbols(elf, esize, SHT_SYMTAB, &symcount))) {
|
||||
if (!(syms = GetElfSymbols(elf, esize, SHT_SYMTAB, &symcount)))
|
||||
Die("missing elf symbol table");
|
||||
}
|
||||
if (!(secstrs = GetElfSectionNameStringTable(elf, esize))) {
|
||||
if (!(secstrs = GetElfSectionNameStringTable(elf, esize)))
|
||||
Die("missing elf section string table");
|
||||
}
|
||||
if (!(symstrs = GetElfStringTable(elf, esize, ".strtab"))) {
|
||||
if (!(symstrs = GetElfStringTable(elf, esize, ".strtab")))
|
||||
Die("missing elf symbol string table");
|
||||
}
|
||||
CheckPrivilegedCrossReferences();
|
||||
if (mode == O_RDWR) {
|
||||
if (elf->e_machine == EM_NEXGEN32E) {
|
||||
|
@ -687,29 +662,25 @@ static void FixupObject(void) {
|
|||
GenerateIfuncInit();
|
||||
} else if (elf->e_machine == EM_AARCH64) {
|
||||
RewriteTlsCodeArm64();
|
||||
if (elf->e_type != ET_REL) {
|
||||
if (elf->e_type != ET_REL)
|
||||
UseFreebsdOsAbi();
|
||||
}
|
||||
}
|
||||
if (elf->e_type != ET_REL) {
|
||||
PurgeIfuncSections();
|
||||
RelinkZipFiles();
|
||||
}
|
||||
if (pwrite(fildes, elf, esize, 0) != esize) {
|
||||
if (pwrite(fildes, elf, esize, 0) != esize)
|
||||
SysExit("pwrite");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (close(fildes)) {
|
||||
if (close(fildes))
|
||||
SysExit("close");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
if (!IsOptimized()) {
|
||||
if (!IsOptimized())
|
||||
ShowCrashReports();
|
||||
}
|
||||
GetOpts(argc, argv);
|
||||
for (i = optind; i < argc; ++i) {
|
||||
epath = argv[i];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue