Changeset d30e067 in mainline for uspace/lib/c
- Timestamp:
- 2025-03-02T20:02:33Z (5 months ago)
- Children:
- 8cdf360
- Parents:
- 7debda3 (diff), 4285f384 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib/c
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/arch/arm32/src/atomic.c
r7debda3 rd30e067 86 86 } 87 87 88 unsigned char __atomic_exchange_1(volatile void *mem0, unsigned char val, 89 int model) 90 { 91 volatile unsigned char *mem = mem0; 92 93 (void) model; 94 95 unsigned ret; 96 97 /* 98 * The following instructions between labels 1 and 2 constitute a 99 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 100 * the kernel will restart it. 101 */ 102 asm volatile ( 103 "1:\n" 104 " adr %[ret], 1b\n" 105 " str %[ret], %[rp0]\n" 106 " adr %[ret], 2f\n" 107 " str %[ret], %[rp1]\n" 108 " ldrb %[ret], %[addr]\n" 109 " strb %[imm], %[addr]\n" 110 "2:\n" 111 : [ret] "=&r" (ret), 112 [rp0] "=m" (ras_page[0]), 113 [rp1] "=m" (ras_page[1]), 114 [addr] "+m" (*mem) 115 : [imm] "r" (val) 116 ); 117 118 ras_page[0] = 0; 119 ras_page[1] = 0xffffffff; 120 121 return ret; 122 } 123 124 unsigned short __atomic_exchange_2(volatile void *mem0, unsigned short val, 125 int model) 126 { 127 volatile unsigned short *mem = mem0; 128 129 (void) model; 130 131 unsigned ret; 132 133 /* 134 * The following instructions between labels 1 and 2 constitute a 135 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 136 * the kernel will restart it. 137 */ 138 asm volatile ( 139 "1:\n" 140 " adr %[ret], 1b\n" 141 " str %[ret], %[rp0]\n" 142 " adr %[ret], 2f\n" 143 " str %[ret], %[rp1]\n" 144 " ldrh %[ret], %[addr]\n" 145 " strh %[imm], %[addr]\n" 146 "2:\n" 147 : [ret] "=&r" (ret), 148 [rp0] "=m" (ras_page[0]), 149 [rp1] "=m" (ras_page[1]), 150 [addr] "+m" (*mem) 151 : [imm] "r" (val) 152 ); 153 154 ras_page[0] = 0; 155 ras_page[1] = 0xffffffff; 156 157 return ret; 158 } 159 160 unsigned __atomic_exchange_4(volatile void *mem0, unsigned val, int model) 161 { 162 volatile unsigned *mem = mem0; 163 164 (void) model; 165 166 unsigned ret; 167 168 /* 169 * The following instructions between labels 1 and 2 constitute a 170 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 171 * the kernel will restart it. 172 */ 173 asm volatile ( 174 "1:\n" 175 " adr %[ret], 1b\n" 176 " str %[ret], %[rp0]\n" 177 " adr %[ret], 2f\n" 178 " str %[ret], %[rp1]\n" 179 " ldr %[ret], %[addr]\n" 180 " str %[imm], %[addr]\n" 181 "2:\n" 182 : [ret] "=&r" (ret), 183 [rp0] "=m" (ras_page[0]), 184 [rp1] "=m" (ras_page[1]), 185 [addr] "+m" (*mem) 186 : [imm] "r" (val) 187 ); 188 189 ras_page[0] = 0; 190 ras_page[1] = 0xffffffff; 191 192 return ret; 193 } 194 88 195 unsigned short __atomic_fetch_add_2(volatile void *mem0, unsigned short val, 89 196 int model) … … 164 271 } 165 272 273 bool __atomic_test_and_set(volatile void *ptr, int memorder) 274 { 275 volatile unsigned char *b = ptr; 276 277 unsigned char orig = __atomic_exchange_n(b, (unsigned char) true, memorder); 278 return orig != 0; 279 } 280 166 281 void __sync_synchronize(void) 167 282 { -
uspace/lib/c/generic/device/hw_res.c
r7debda3 rd30e067 1 1 /* 2 * Copyright (c) 202 4Jiri Svoboda2 * Copyright (c) 2025 Jiri Svoboda 3 3 * Copyright (c) 2010 Lenka Trochtova 4 4 * All rights reserved. … … 162 162 } 163 163 164 /** Get bus flags.164 /** Query legacy IO claims. 165 165 * 166 166 * @param sess HW res session 167 * @param r flags Place to store the flags168 * 169 * @return Error code. 170 * 171 */ 172 errno_t hw_res_ get_flags(async_sess_t *sess, hw_res_flags_t *rflags)173 { 174 async_exch_t *exch = async_exchange_begin(sess); 175 176 sysarg_t flags;167 * @param rclaims Place to store the claims 168 * 169 * @return Error code. 170 * 171 */ 172 errno_t hw_res_query_legacy_io(async_sess_t *sess, hw_res_claims_t *rclaims) 173 { 174 async_exch_t *exch = async_exchange_begin(sess); 175 176 sysarg_t claims; 177 177 const errno_t ret = async_req_1_1(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE), 178 HW_RES_ GET_FLAGS, &flags);178 HW_RES_QUERY_LEGACY_IO, &claims); 179 179 180 180 async_exchange_end(exch); 181 181 182 182 if (ret == EOK) 183 *rflags = flags; 183 *rclaims = claims; 184 185 return ret; 186 } 187 188 /** Claim legacy IO devices. 189 * 190 * @param sess HW res session 191 * @param claims Claims 192 * 193 * @return Error code. 194 * 195 */ 196 errno_t hw_res_claim_legacy_io(async_sess_t *sess, hw_res_claims_t claims) 197 { 198 async_exch_t *exch = async_exchange_begin(sess); 199 200 const errno_t ret = async_req_2_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE), 201 HW_RES_CLAIM_LEGACY_IO, claims); 202 203 async_exchange_end(exch); 184 204 185 205 return ret; -
uspace/lib/c/generic/elf/elf_load.c
r7debda3 rd30e067 60 60 rtld_t *env; 61 61 #endif 62 errno_t rc; 62 errno_t rc = EOK; 63 elf_finfo_t *finfo = &info->finfo; 63 64 64 rc = elf_load_file(file, 0, &info->finfo);65 rc = elf_load_file(file, 0, finfo); 65 66 if (rc != EOK) { 66 DPRINTF("Failed to load executable '%s'.\n", file_name);67 DPRINTF("Failed to load executable.\n"); 67 68 return rc; 68 69 } 69 70 71 #ifdef CONFIG_RTLD 72 DPRINTF("- prog dynamic: %p\n", finfo->dynamic); 73 rc = rtld_prog_process(finfo, &env); 74 if (rc != EOK) { 75 DPRINTF("Failed to process executable.\n"); 76 return rc; 77 } 78 info->env = env; 79 return EOK; 80 #else 70 81 if (info->finfo.dynamic == NULL) { 71 /* Statically linked program */72 DPRINTF("Binary is statically linked.\n");73 82 info->env = NULL; 74 83 return EOK; 75 84 } 76 85 77 DPRINTF("Binary is dynamically linked.\n"); 78 #ifdef CONFIG_RTLD 79 DPRINTF("- prog dynamic: %p\n", info->finfo.dynamic); 80 81 rc = rtld_prog_process(&info->finfo, &env); 82 info->env = env; 83 #else 84 rc = ENOTSUP; 86 DPRINTF("Error: trying to run a dynamically-linked executable with CONFIG_RTLD disabled.\n"); 87 return ENOTSUP; 85 88 #endif 86 return rc;87 89 } 88 90 -
uspace/lib/c/generic/libc.c
r7debda3 rd30e067 96 96 97 97 #ifdef CONFIG_RTLD 98 if (__pcb != NULL && __pcb->rtld_runtime != NULL) { 98 if (__pcb == NULL) { 99 /* 100 * A binary loaded by kernel, not the loader. 101 * Noop - code loaded by kernel doesn't need RTLD. 102 */ 103 } else { 104 assert(__pcb->rtld_runtime != NULL); 99 105 runtime_env = (rtld_t *) __pcb->rtld_runtime; 100 } else {101 if (rtld_init_static() != EOK)102 abort();103 106 } 104 107 #endif -
uspace/lib/c/generic/rtld/module.c
r7debda3 rd30e067 55 55 #include "../private/libc.h" 56 56 57 /** Create module for static executable. 58 * 57 /** Create the "entrypoint" module, of the program executable 58 * 59 * @param p_info Program ELF file info 59 60 * @param rtld Run-time dynamic linker 60 61 * @param rmodule Place to store pointer to new module or @c NULL 61 62 * @return EOK on success, ENOMEM if out of memory 62 63 */ 63 errno_t module_create_ static_exec(rtld_t *rtld, module_t **rmodule)64 errno_t module_create_entrypoint(elf_finfo_t *p_info, rtld_t *rtld, module_t **rmodule) 64 65 { 65 66 module_t *module; 67 bool is_dynamic = p_info->dynamic != NULL; 68 DPRINTF("module_create_entrypoint\n"); 66 69 67 70 module = calloc(1, sizeof(module_t)); 68 if (module == NULL) { 69 DPRINTF("malloc failed\n"); 71 if (module == NULL) 70 72 return ENOMEM; 71 } 72 73 74 uintptr_t bias = elf_get_bias(p_info->base); 75 76 /* 77 * First we need to process dynamic sections of the executable 78 * program and insert it into the module graph. 79 */ 80 if (is_dynamic) { 81 DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic); 82 dynamic_parse(p_info->dynamic, bias, &module->dyn); 83 } else { 84 DPRINTF("Executable is not dynamically linked\n"); 85 } 86 87 module->bias = bias; 73 88 module->id = rtld_get_next_id(rtld); 74 89 module->dyn.soname = "[program]"; … … 76 91 module->rtld = rtld; 77 92 module->exec = true; 78 module->local = true; 79 80 const elf_segment_header_t *tls = 81 elf_get_phdr(__progsymbols.elfstart, PT_TLS); 82 83 if (tls) { 84 uintptr_t bias = elf_get_bias(__progsymbols.elfstart); 85 module->tdata = (void *) (tls->p_vaddr + bias); 86 module->tdata_size = tls->p_filesz; 87 module->tbss_size = tls->p_memsz - tls->p_filesz; 88 module->tls_align = tls->p_align; 89 } else { 90 module->tdata = NULL; 91 module->tdata_size = 0; 92 module->tbss_size = 0; 93 module->tls_align = 1; 94 } 93 module->local = !is_dynamic; 94 95 module->tdata = p_info->tls.tdata; 96 module->tdata_size = p_info->tls.tdata_size; 97 module->tbss_size = p_info->tls.tbss_size; 98 module->tls_align = p_info->tls.tls_align; 99 100 DPRINTF("prog tdata at %p size %zu, tbss size %zu\n", 101 module->tdata, module->tdata_size, module->tbss_size); 95 102 96 103 list_append(&module->modules_link, &rtld->modules); … … 398 405 * be correct, "zero" offset (i.e. the total size) must be aligned 399 406 * to the strictest alignment present. 400 * Note that the padding is actually in front of the TLS data,401 * not after it.402 407 */ 403 408 rtld->tls_size = ALIGN_UP(rtld->tls_size, rtld->tls_align); 404 409 405 /* Space for the TCB. */ 410 /* 411 * Space for the TCB. 412 * Later, the TLS zero offset is equal to the pointer to tcb_t, so 413 * adding the sizeof(tcb_t) block AFTER we calculated the alignment 414 * of the remainder above is correct. 415 */ 406 416 rtld->tls_size += sizeof(tcb_t); 407 417 #endif -
uspace/lib/c/generic/rtld/rtld.c
r7debda3 rd30e067 43 43 44 44 rtld_t *runtime_env; 45 static rtld_t rt_env_static; 46 47 /** Initialize the runtime linker for use in a statically-linked executable. */ 48 errno_t rtld_init_static(void) 49 { 50 errno_t rc; 51 52 runtime_env = &rt_env_static; 53 list_initialize(&runtime_env->modules); 54 list_initialize(&runtime_env->imodules); 55 runtime_env->program = NULL; 56 runtime_env->next_id = 1; 57 58 rc = module_create_static_exec(runtime_env, NULL); 59 if (rc != EOK) 60 return rc; 61 62 modules_process_tls(runtime_env); 63 64 return EOK; 65 } 66 67 /** Initialize and process a dynamically linked executable. 45 46 /** Initialize and process an executable. 68 47 * 69 48 * @param p_info Program info … … 73 52 { 74 53 rtld_t *env; 75 module_t *prog; 76 77 DPRINTF("Load dynamically linked program.\n"); 54 bool is_dynamic = p_info->dynamic != NULL; 55 DPRINTF("rtld_prog_process\n"); 78 56 79 57 /* Allocate new RTLD environment to pass to the loaded program */ … … 82 60 return ENOMEM; 83 61 84 env->next_id = 1;85 86 prog = calloc(1, sizeof(module_t));87 if (prog == NULL) {88 free(env);89 return ENOMEM;90 }91 92 /*93 * First we need to process dynamic sections of the executable94 * program and insert it into the module graph.95 */96 97 DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);98 dynamic_parse(p_info->dynamic, 0, &prog->dyn);99 prog->bias = 0;100 prog->dyn.soname = "[program]";101 prog->rtld = env;102 prog->id = rtld_get_next_id(env);103 prog->exec = true;104 prog->local = false;105 106 prog->tdata = p_info->tls.tdata;107 prog->tdata_size = p_info->tls.tdata_size;108 prog->tbss_size = p_info->tls.tbss_size;109 prog->tls_align = p_info->tls.tls_align;110 111 DPRINTF("prog tdata at %p size %zu, tbss size %zu\n",112 prog->tdata, prog->tdata_size, prog->tbss_size);113 114 /* Initialize list of loaded modules */115 62 list_initialize(&env->modules); 116 63 list_initialize(&env->imodules); 117 list_append(&prog->modules_link, &env->modules); 64 env->next_id = 1; 65 66 module_t *module; 67 errno_t rc = module_create_entrypoint(p_info, env, &module); 68 if (rc != EOK) { 69 free(env); 70 return rc; 71 } 118 72 119 73 /* Pointer to program module. Used as root of the module graph. */ 120 env->program = prog;74 env->program = module; 121 75 122 76 /* … … 124 78 */ 125 79 126 DPRINTF("Load all program dependencies\n"); 127 errno_t rc = module_load_deps(prog, 0); 128 if (rc != EOK) { 129 return rc; 80 if (is_dynamic) { 81 DPRINTF("Load all program dependencies\n"); 82 rc = module_load_deps(module, 0); 83 if (rc != EOK) { 84 free(module); 85 free(env); 86 return rc; 87 } 130 88 } 131 89 … … 137 95 */ 138 96 139 /* Process relocations in all modules */ 140 DPRINTF("Relocate all modules\n"); 141 modules_process_relocs(env, prog); 142 143 *rre = env; 97 if (is_dynamic) { 98 /* Process relocations in all modules */ 99 DPRINTF("Relocate all modules\n"); 100 modules_process_relocs(env, module); 101 } 102 103 if (rre != NULL) 104 *rre = env; 144 105 return EOK; 145 106 } -
uspace/lib/c/generic/thread/fibril_synch.c
r7debda3 rd30e067 1 1 /* 2 * Copyright (c) 2025 Jiri Svoboda 2 3 * Copyright (c) 2009 Jakub Jermar 3 4 * All rights reserved. … … 112 113 #define AWAITER_INIT { .fid = fibril_get_id() } 113 114 114 static void print_deadlock(fibril_owner_info_t *oi) 115 /** Print deadlock message nad blocking chain. 116 * 117 * @param oi Owner info for the resource being acquired 118 * @param f Fibril that is trying to acquire the resource 119 */ 120 static void print_deadlock(fibril_owner_info_t *oi, fibril_t *f) 115 121 { 116 122 // FIXME: Print to stderr. 117 118 fibril_t *f = (fibril_t *) fibril_get_id();119 123 120 124 if (deadlocked) { … … 143 147 } 144 148 145 static void check_fibril_for_deadlock(fibril_owner_info_t *oi, fibril_t *fib) 146 { 149 /** Check whether fibril trying to acquire a resource will cause deadlock. 150 * 151 * @param wanted_oi Owner info for the primitive that the fibril wants 152 * @param fib Fibril that wants to aquire the primitive 153 */ 154 static void check_fibril_for_deadlock(fibril_owner_info_t *wanted_oi, 155 fibril_t *fib) 156 { 157 fibril_owner_info_t *oi; 158 147 159 futex_assert_is_locked(&fibril_synch_futex); 148 160 161 oi = wanted_oi; 149 162 while (oi && oi->owned_by) { 150 163 if (oi->owned_by == fib) { 151 164 futex_unlock(&fibril_synch_futex); 152 print_deadlock( oi);165 print_deadlock(wanted_oi, fib); 153 166 abort(); 154 167 } … … 157 170 } 158 171 172 /** Check whether trying to acquire a resource will cause deadlock. 173 * 174 * @param oi Owner info for the primitive that the current fibril wants 175 */ 159 176 static void check_for_deadlock(fibril_owner_info_t *oi) 160 177 { … … 246 263 futex_lock(&fibril_synch_futex); 247 264 248 if (!frw->writers ) {265 if (!frw->writers && list_empty(&frw->waiters)) { 249 266 /* Consider the first reader the owner. */ 250 267 if (frw->readers++ == 0) -
uspace/lib/c/generic/thread/tls.c
r7debda3 rd30e067 59 59 #endif 60 60 61 static ptrdiff_t _tcb_data_offset( void)61 static ptrdiff_t _tcb_data_offset(const void *elf) 62 62 { 63 63 const elf_segment_header_t *tls = 64 elf_get_phdr( __progsymbols.elfstart, PT_TLS);64 elf_get_phdr(elf, PT_TLS); 65 65 66 66 size_t tls_align = tls ? tls->p_align : 1; … … 74 74 } 75 75 76 /** Get address of static TLS block */76 /** Get address of static TLS block - only when RTLD is not initialized */ 77 77 void *tls_get(void) 78 78 { … … 80 80 assert(runtime_env == NULL); 81 81 #endif 82 return (uint8_t *)__tcb_get() + _tcb_data_offset( );82 return (uint8_t *)__tcb_get() + _tcb_data_offset(__progsymbols.elfstart); 83 83 } 84 84 85 85 static tcb_t *tls_make_generic(const void *elf, void *(*alloc)(size_t, size_t)) 86 86 { 87 /* 88 * See also rtld/module.c -> modules_process_tls(), where we have less 89 * messy code for the dynamic-linking version of this. 90 */ 87 91 assert(!elf_get_phdr(elf, PT_DYNAMIC)); 88 92 #ifdef CONFIG_RTLD … … 100 104 assert(tls_align <= PAGE_SIZE); 101 105 106 /* 107 * FIXME: the calculation of alloc_size shouldn't include the alignment 108 * of tcb_t (at least in Variant II) 109 * See https://github.com/HelenOS/helenos/pull/240/files/4ef27ebf98a0656e09889b7d00efdec03343f1aa#r1929592924 110 * (you will also need to fix _tcb_data_offset) 111 */ 112 102 113 #ifdef CONFIG_TLS_VARIANT_1 103 114 size_t alloc_size = … … 114 125 #ifdef CONFIG_TLS_VARIANT_1 115 126 tcb_t *tcb = area; 116 uint8_t *data = (uint8_t *)tcb + _tcb_data_offset( );127 uint8_t *data = (uint8_t *)tcb + _tcb_data_offset(elf); 117 128 memset(tcb, 0, sizeof(*tcb)); 118 129 #else 119 130 uint8_t *data = area; 120 tcb_t *tcb = (tcb_t *) (data - _tcb_data_offset( ));131 tcb_t *tcb = (tcb_t *) (data - _tcb_data_offset(elf)); 121 132 memset(tcb, 0, sizeof(tcb_t)); 122 133 tcb->self = tcb; -
uspace/lib/c/include/device/hw_res.h
r7debda3 rd30e067 1 1 /* 2 * Copyright (c) 202 4Jiri Svoboda2 * Copyright (c) 2025 Jiri Svoboda 3 3 * Copyright (c) 2010 Lenka Trochtova 4 4 * All rights reserved. … … 57 57 HW_RES_DMA_CHANNEL_SETUP, 58 58 HW_RES_DMA_CHANNEL_REMAIN, 59 HW_RES_GET_FLAGS 59 HW_RES_QUERY_LEGACY_IO, 60 HW_RES_CLAIM_LEGACY_IO 60 61 } hw_res_method_t; 61 62 … … 118 119 } 119 120 121 /** Claims to legacy devices */ 120 122 typedef enum { 121 /** This is an PCI/ISA bridge, not 'classic' ISA bus */122 hw f_isa_bridge = 0x1123 } hw_res_ flags_t;123 /** 'Legacy' ISA IDE I/O ranges */ 124 hwc_isa_ide = 0x1 125 } hw_res_claims_t; 124 126 125 127 extern errno_t hw_res_get_resource_list(async_sess_t *, hw_resource_list_t *); … … 131 133 uint32_t, uint8_t); 132 134 extern errno_t hw_res_dma_channel_remain(async_sess_t *, unsigned, size_t *); 133 extern errno_t hw_res_get_flags(async_sess_t *, hw_res_flags_t *); 135 extern errno_t hw_res_query_legacy_io(async_sess_t *, hw_res_claims_t *); 136 extern errno_t hw_res_claim_legacy_io(async_sess_t *, hw_res_claims_t); 134 137 135 138 #endif -
uspace/lib/c/include/rtld/module.h
r7debda3 rd30e067 41 41 #include <types/rtld/rtld.h> 42 42 43 extern errno_t module_create_ static_exec(rtld_t *, module_t **);43 extern errno_t module_create_entrypoint(elf_finfo_t *, rtld_t *, module_t **); 44 44 extern void module_process_relocs(module_t *); 45 45 extern module_t *module_find(rtld_t *, const char *); -
uspace/lib/c/include/rtld/rtld.h
r7debda3 rd30e067 45 45 extern rtld_t *runtime_env; 46 46 47 extern errno_t rtld_init_static(void);48 47 extern errno_t rtld_prog_process(elf_finfo_t *, rtld_t **); 49 48 extern tcb_t *rtld_tls_make(rtld_t *);
Note:
See TracChangeset
for help on using the changeset viewer.