Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(462)

Side by Side Diff: fusl/ldso/dynlink.c

Issue 1689833004: [fusl] Update fusl (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: remove stray space Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « fusl/ldso/dlstart.c ('k') | fusl/src/internal/dynlink.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #define _GNU_SOURCE 1 #define _GNU_SOURCE
2 #include <stdio.h> 2 #include <stdio.h>
3 #include <stdlib.h> 3 #include <stdlib.h>
4 #include <stdarg.h> 4 #include <stdarg.h>
5 #include <stddef.h> 5 #include <stddef.h>
6 #include <string.h> 6 #include <string.h>
7 #include <unistd.h> 7 #include <unistd.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <elf.h> 9 #include <elf.h>
10 #include <sys/mman.h> 10 #include <sys/mman.h>
11 #include <limits.h> 11 #include <limits.h>
12 #include <fcntl.h> 12 #include <fcntl.h>
13 #include <sys/stat.h> 13 #include <sys/stat.h>
14 #include <errno.h> 14 #include <errno.h>
15 #include <link.h> 15 #include <link.h>
16 #include <setjmp.h> 16 #include <setjmp.h>
17 #include <pthread.h> 17 #include <pthread.h>
18 #include <ctype.h> 18 #include <ctype.h>
19 #include <dlfcn.h> 19 #include <dlfcn.h>
20 #include "pthread_impl.h" 20 #include "pthread_impl.h"
21 #include "libc.h" 21 #include "libc.h"
22 #include "dynlink.h" 22 #include "dynlink.h"
23 23
24 static void error(const char *, ...); 24 static void error(const char *, ...);
25 25
26 #ifdef SHARED
27
28 #define MAXP2(a,b) (-(-(a)&-(b))) 26 #define MAXP2(a,b) (-(-(a)&-(b)))
29 #define ALIGN(x,y) ((x)+(y)-1 & -(y)) 27 #define ALIGN(x,y) ((x)+(y)-1 & -(y))
30 28
31 struct debug { 29 struct debug {
32 int ver; 30 int ver;
33 void *head; 31 void *head;
34 void (*bp)(void); 32 void (*bp)(void);
35 int state; 33 int state;
36 void *base; 34 void *base;
37 }; 35 };
(...skipping 1091 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 if (p==&ldso) { 1127 if (p==&ldso) {
1130 got += i; 1128 got += i;
1131 } else { 1129 } else {
1132 while (i--) *got++ += (size_t)base; 1130 while (i--) *got++ += (size_t)base;
1133 } 1131 }
1134 j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM); 1132 j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
1135 i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO); 1133 i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
1136 Sym *sym = p->syms + j; 1134 Sym *sym = p->syms + j;
1137 rel[0] = (unsigned char *)got - base; 1135 rel[0] = (unsigned char *)got - base;
1138 for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) { 1136 for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) {
1139 » » rel[1] = sym-p->syms << 8 | R_MIPS_JUMP_SLOT; 1137 » » rel[1] = (sym-p->syms) << 8 | R_MIPS_JUMP_SLOT;
1140 do_relocs(p, rel, sizeof rel, 2); 1138 do_relocs(p, rel, sizeof rel, 2);
1141 } 1139 }
1142 } 1140 }
1143 1141
1144 static void reloc_all(struct dso *p) 1142 static void reloc_all(struct dso *p)
1145 { 1143 {
1146 size_t dyn[DYN_CNT]; 1144 size_t dyn[DYN_CNT];
1147 for (; p; p=p->next) { 1145 for (; p; p=p->next) {
1148 if (p->relocated) continue; 1146 if (p->relocated) continue;
1149 decode_vec(p->dynv, dyn, DYN_CNT); 1147 decode_vec(p->dynv, dyn, DYN_CNT);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1327 * replaced later due to copy relocations in the main program. */ 1325 * replaced later due to copy relocations in the main program. */
1328 1326
1329 __attribute__((__visibility__("hidden"))) 1327 __attribute__((__visibility__("hidden")))
1330 void __dls2(unsigned char *base, size_t *sp) 1328 void __dls2(unsigned char *base, size_t *sp)
1331 { 1329 {
1332 if (DL_FDPIC) { 1330 if (DL_FDPIC) {
1333 void *p1 = (void *)sp[-2]; 1331 void *p1 = (void *)sp[-2];
1334 void *p2 = (void *)sp[-1]; 1332 void *p2 = (void *)sp[-1];
1335 if (!p1) { 1333 if (!p1) {
1336 size_t *auxv, aux[AUX_CNT]; 1334 size_t *auxv, aux[AUX_CNT];
1337 » » » for (auxv=sp+1+*sp+1; *auxv; auxv++); auxv++; 1335 » » » for (auxv=sp+1+*sp+1; *auxv; auxv++)
1336 » » » » ; // Pass
1337 » » » auxv++;
1338 decode_vec(auxv, aux, AUX_CNT); 1338 decode_vec(auxv, aux, AUX_CNT);
1339 if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE]; 1339 if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];
1340 else ldso.base = (void *)(aux[AT_PHDR] & -4096); 1340 else ldso.base = (void *)(aux[AT_PHDR] & -4096);
1341 } 1341 }
1342 app_loadmap = p2 ? p1 : 0; 1342 app_loadmap = p2 ? p1 : 0;
1343 ldso.loadmap = p2 ? p2 : p1; 1343 ldso.loadmap = p2 ? p2 : p1;
1344 ldso.base = laddr(&ldso, 0); 1344 ldso.base = laddr(&ldso, 0);
1345 } else { 1345 } else {
1346 ldso.base = base; 1346 ldso.base = base;
1347 } 1347 }
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 * linker had ldd not taken its place. */ 1514 * linker had ldd not taken its place. */
1515 if (ldd_mode) { 1515 if (ldd_mode) {
1516 for (i=0; i<app.phnum; i++) { 1516 for (i=0; i<app.phnum; i++) {
1517 if (app.phdr[i].p_type == PT_INTERP) 1517 if (app.phdr[i].p_type == PT_INTERP)
1518 ldso.name = laddr(&app, app.phdr[i].p_va ddr); 1518 ldso.name = laddr(&app, app.phdr[i].p_va ddr);
1519 } 1519 }
1520 dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base); 1520 dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);
1521 } 1521 }
1522 } 1522 }
1523 if (app.tls.size) { 1523 if (app.tls.size) {
1524 » » libc.tls_head = &app.tls; 1524 » » libc.tls_head = tls_tail = &app.tls;
1525 app.tls_id = tls_cnt = 1; 1525 app.tls_id = tls_cnt = 1;
1526 #ifdef TLS_ABOVE_TP 1526 #ifdef TLS_ABOVE_TP
1527 app.tls.offset = 0; 1527 app.tls.offset = 0;
1528 tls_offset = app.tls.size 1528 tls_offset = app.tls.size
1529 + ( -((uintptr_t)app.tls.image + app.tls.size) 1529 + ( -((uintptr_t)app.tls.image + app.tls.size)
1530 & (app.tls.align-1) ); 1530 & (app.tls.align-1) );
1531 #else 1531 #else
1532 tls_offset = app.tls.offset = app.tls.size 1532 tls_offset = app.tls.offset = app.tls.size
1533 + ( -((uintptr_t)app.tls.image + app.tls.size) 1533 + ( -((uintptr_t)app.tls.image + app.tls.size)
1534 & (app.tls.align-1) ); 1534 & (app.tls.align-1) );
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1577 /* Donate unused parts of app and library mapping to malloc */ 1577 /* Donate unused parts of app and library mapping to malloc */
1578 reclaim_gaps(&app); 1578 reclaim_gaps(&app);
1579 reclaim_gaps(&ldso); 1579 reclaim_gaps(&ldso);
1580 1580
1581 /* Load preload/needed libraries, add their symbols to the global 1581 /* Load preload/needed libraries, add their symbols to the global
1582 * namespace, and perform all remaining relocations. */ 1582 * namespace, and perform all remaining relocations. */
1583 if (env_preload) load_preload(env_preload); 1583 if (env_preload) load_preload(env_preload);
1584 load_deps(&app); 1584 load_deps(&app);
1585 make_global(&app); 1585 make_global(&app);
1586 1586
1587 #ifndef DYNAMIC_IS_RO 1587 » for (i=0; app.dynv[i]; i+=2) {
1588 » for (i=0; app.dynv[i]; i+=2) 1588 » » if (!DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG)
1589 » » if (app.dynv[i]==DT_DEBUG)
1590 app.dynv[i+1] = (size_t)&debug; 1589 app.dynv[i+1] = (size_t)&debug;
1591 #endif 1590 » » if (DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG_INDIRECT) {
1591 » » » size_t *ptr = (size_t *) app.dynv[i+1];
1592 » » » *ptr = (size_t)&debug;
1593 » » }
1594 » }
1592 1595
1593 /* The main program must be relocated LAST since it may contin 1596 /* The main program must be relocated LAST since it may contin
1594 * copy relocations which depend on libraries' relocations. */ 1597 * copy relocations which depend on libraries' relocations. */
1595 reloc_all(app.next); 1598 reloc_all(app.next);
1596 reloc_all(&app); 1599 reloc_all(&app);
1597 1600
1598 update_tls_size(); 1601 update_tls_size();
1599 if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) { 1602 if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) {
1600 void *initial_tls = calloc(libc.tls_size, 1); 1603 void *initial_tls = calloc(libc.tls_size, 1);
1601 if (!initial_tls) { 1604 if (!initial_tls) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 orig_tail = tail; 1729 orig_tail = tail;
1727 end: 1730 end:
1728 __release_ptc(); 1731 __release_ptc();
1729 if (p) gencnt++; 1732 if (p) gencnt++;
1730 pthread_rwlock_unlock(&lock); 1733 pthread_rwlock_unlock(&lock);
1731 if (p) do_init_fini(orig_tail); 1734 if (p) do_init_fini(orig_tail);
1732 pthread_setcancelstate(cs, 0); 1735 pthread_setcancelstate(cs, 0);
1733 return p; 1736 return p;
1734 } 1737 }
1735 1738
1736 static int invalid_dso_handle(void *h) 1739 __attribute__((__visibility__("hidden")))
1740 int __dl_invalid_handle(void *h)
1737 { 1741 {
1738 struct dso *p; 1742 struct dso *p;
1739 for (p=head; p; p=p->next) if (h==p) return 0; 1743 for (p=head; p; p=p->next) if (h==p) return 0;
1740 error("Invalid library handle %p", (void *)h); 1744 error("Invalid library handle %p", (void *)h);
1741 return 1; 1745 return 1;
1742 } 1746 }
1743 1747
1744 static void *addr2dso(size_t a) 1748 static void *addr2dso(size_t a)
1745 { 1749 {
1746 struct dso *p; 1750 struct dso *p;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1781 p = p->next; 1785 p = p->next;
1782 } 1786 }
1783 struct symdef def = find_sym(p, s, 0); 1787 struct symdef def = find_sym(p, s, 0);
1784 if (!def.sym) goto failed; 1788 if (!def.sym) goto failed;
1785 if ((def.sym->st_info&0xf) == STT_TLS) 1789 if ((def.sym->st_info&0xf) == STT_TLS)
1786 return __tls_get_addr((size_t []){def.dso->tls_id, def.s ym->st_value}); 1790 return __tls_get_addr((size_t []){def.dso->tls_id, def.s ym->st_value});
1787 if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC) 1791 if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC)
1788 return def.dso->funcdescs + (def.sym - def.dso->syms); 1792 return def.dso->funcdescs + (def.sym - def.dso->syms);
1789 return laddr(def.dso, def.sym->st_value); 1793 return laddr(def.dso, def.sym->st_value);
1790 } 1794 }
1791 » if (invalid_dso_handle(p)) 1795 » if (__dl_invalid_handle(p))
1792 return 0; 1796 return 0;
1793 if ((ght = p->ghashtab)) { 1797 if ((ght = p->ghashtab)) {
1794 gh = gnu_hash(s); 1798 gh = gnu_hash(s);
1795 sym = gnu_lookup(gh, ght, p, s); 1799 sym = gnu_lookup(gh, ght, p, s);
1796 } else { 1800 } else {
1797 h = sysv_hash(s); 1801 h = sysv_hash(s);
1798 sym = sysv_lookup(s, h, p); 1802 sym = sysv_lookup(s, h, p);
1799 } 1803 }
1800 if (sym && (sym->st_info&0xf) == STT_TLS) 1804 if (sym && (sym->st_info&0xf) == STT_TLS)
1801 return __tls_get_addr((size_t []){p->tls_id, sym->st_value}); 1805 return __tls_get_addr((size_t []){p->tls_id, sym->st_value});
(...skipping 14 matching lines...) Expand all
1816 if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == ST T_FUNC) 1820 if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == ST T_FUNC)
1817 return p->deps[i]->funcdescs + (sym - p->deps[i]->syms); 1821 return p->deps[i]->funcdescs + (sym - p->deps[i]->syms);
1818 if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES)) 1822 if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
1819 return laddr(p->deps[i], sym->st_value); 1823 return laddr(p->deps[i], sym->st_value);
1820 } 1824 }
1821 failed: 1825 failed:
1822 error("Symbol not found: %s", s); 1826 error("Symbol not found: %s", s);
1823 return 0; 1827 return 0;
1824 } 1828 }
1825 1829
1826 int __dladdr(const void *addr, Dl_info *info) 1830 int dladdr(const void *addr, Dl_info *info)
1827 { 1831 {
1828 struct dso *p; 1832 struct dso *p;
1829 Sym *sym, *bestsym; 1833 Sym *sym, *bestsym;
1830 uint32_t nsym; 1834 uint32_t nsym;
1831 char *strings; 1835 char *strings;
1832 void *best = 0; 1836 void *best = 0;
1833 1837
1834 pthread_rwlock_rdlock(&lock); 1838 pthread_rwlock_rdlock(&lock);
1835 p = addr2dso((size_t)addr); 1839 p = addr2dso((size_t)addr);
1836 pthread_rwlock_unlock(&lock); 1840 pthread_rwlock_unlock(&lock);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 ret = (callback)(&info, sizeof (info), data); 1909 ret = (callback)(&info, sizeof (info), data);
1906 1910
1907 if (ret != 0) break; 1911 if (ret != 0) break;
1908 1912
1909 pthread_rwlock_rdlock(&lock); 1913 pthread_rwlock_rdlock(&lock);
1910 current = current->next; 1914 current = current->next;
1911 pthread_rwlock_unlock(&lock); 1915 pthread_rwlock_unlock(&lock);
1912 } 1916 }
1913 return ret; 1917 return ret;
1914 } 1918 }
1915 #else
1916 static int invalid_dso_handle(void *h)
1917 {
1918 error("Invalid library handle %p", (void *)h);
1919 return 1;
1920 }
1921 void *dlopen(const char *file, int mode)
1922 {
1923 error("Dynamic loading not supported");
1924 return 0;
1925 }
1926 void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
1927 {
1928 error("Symbol not found: %s", s);
1929 return 0;
1930 }
1931 int __dladdr (const void *addr, Dl_info *info)
1932 {
1933 return 0;
1934 }
1935 #endif
1936 1919
1937 int __dlinfo(void *dso, int req, void *res) 1920 __attribute__((__visibility__("hidden")))
1938 { 1921 void __dl_vseterr(const char *, va_list);
1939 » if (invalid_dso_handle(dso)) return -1;
1940 » if (req != RTLD_DI_LINKMAP) {
1941 » » error("Unsupported request %d", req);
1942 » » return -1;
1943 » }
1944 » *(struct link_map **)res = dso;
1945 » return 0;
1946 }
1947
1948 char *dlerror()
1949 {
1950 » pthread_t self = __pthread_self();
1951 » if (!self->dlerror_flag) return 0;
1952 » self->dlerror_flag = 0;
1953 » char *s = self->dlerror_buf;
1954 » if (s == (void *)-1)
1955 » » return "Dynamic linker failed to allocate memory for error messa ge";
1956 » else
1957 » » return s;
1958 }
1959
1960 int dlclose(void *p)
1961 {
1962 » return invalid_dso_handle(p);
1963 }
1964
1965 void __dl_thread_cleanup(void)
1966 {
1967 » pthread_t self = __pthread_self();
1968 » if (self->dlerror_buf != (void *)-1)
1969 » » free(self->dlerror_buf);
1970 }
1971 1922
1972 static void error(const char *fmt, ...) 1923 static void error(const char *fmt, ...)
1973 { 1924 {
1974 va_list ap; 1925 va_list ap;
1975 va_start(ap, fmt); 1926 va_start(ap, fmt);
1976 #ifdef SHARED
1977 if (!runtime) { 1927 if (!runtime) {
1978 vdprintf(2, fmt, ap); 1928 vdprintf(2, fmt, ap);
1979 dprintf(2, "\n"); 1929 dprintf(2, "\n");
1980 ldso_fail = 1; 1930 ldso_fail = 1;
1981 va_end(ap); 1931 va_end(ap);
1982 return; 1932 return;
1983 } 1933 }
1984 #endif 1934 » __dl_vseterr(fmt, ap);
1985 » pthread_t self = __pthread_self();
1986 » if (self->dlerror_buf != (void *)-1)
1987 » » free(self->dlerror_buf);
1988 » size_t len = vsnprintf(0, 0, fmt, ap);
1989 va_end(ap); 1935 va_end(ap);
1990 char *buf = malloc(len+1);
1991 if (buf) {
1992 va_start(ap, fmt);
1993 vsnprintf(buf, len+1, fmt, ap);
1994 va_end(ap);
1995 } else {
1996 buf = (void *)-1;
1997 }
1998 self->dlerror_buf = buf;
1999 self->dlerror_flag = 1;
2000 } 1936 }
OLDNEW
« no previous file with comments | « fusl/ldso/dlstart.c ('k') | fusl/src/internal/dynlink.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698