Changeset 40d3604 in mainline
- Timestamp:
- 2018-04-30T20:12:50Z (7 years ago)
- Parents:
- 4c5f04f (diff), 64d38cd (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. - git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-04-30 20:12:50)
- git-committer:
- GitHub <noreply@…> (2018-04-30 20:12:50)
- Location:
- uspace/lib/c
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/arch/abs32le/_link.ld.in
r4c5f04f r40d3604 9 9 10 10 SECTIONS { 11 #ifdef SHLIB 12 . = SEGMENT_START("text-segment", 0); 13 #else 11 14 . = SEGMENT_START("text-segment", 0x400000); 12 #ifndef SHLIB13 15 PROVIDE (__executable_start = .); 14 16 #endif -
uspace/lib/c/arch/amd64/_link.ld.in
r4c5f04f r40d3604 10 10 11 11 SECTIONS { 12 #ifdef SHLIB 13 . = SEGMENT_START("text-segment", 0); 14 #else 12 15 . = SEGMENT_START("text-segment", 0x400000); 13 #ifndef SHLIB14 16 PROVIDE (__executable_start = .); 15 17 #endif -
uspace/lib/c/arch/arm32/_link.ld.in
r4c5f04f r40d3604 9 9 10 10 SECTIONS { 11 #ifdef SHLIB 12 . = SEGMENT_START("text-segment", 0); 13 #else 11 14 . = SEGMENT_START("text-segment", 0x400000); 12 #ifndef SHLIB13 15 PROVIDE (__executable_start = .); 14 16 #endif -
uspace/lib/c/arch/ia32/_link.ld.in
r4c5f04f r40d3604 18 18 19 19 SECTIONS { 20 #ifdef SHLIB 21 . = SEGMENT_START("text-segment", 0); 22 #else 20 23 . = SEGMENT_START("text-segment", 0x400000); 21 #ifndef SHLIB22 24 PROVIDE (__executable_start = .); 23 25 #endif -
uspace/lib/c/arch/ia64/_link.ld.in
r4c5f04f r40d3604 9 9 10 10 SECTIONS { 11 #ifdef SHLIB 12 . = SEGMENT_START("text-segment", 0); 13 #else 11 14 . = SEGMENT_START("text-segment", 0x400000); 12 #ifndef SHLIB13 15 PROVIDE (__executable_start = .); 14 16 #endif -
uspace/lib/c/arch/mips32/_link.ld.in
r4c5f04f r40d3604 9 9 10 10 SECTIONS { 11 #ifdef SHLIB 12 . = SEGMENT_START("text-segment", 0); 13 #else 11 14 . = SEGMENT_START("text-segment", 0x400000); 12 #ifndef SHLIB13 15 PROVIDE (__executable_start = .); 14 16 #endif -
uspace/lib/c/arch/ppc32/_link.ld.in
r4c5f04f r40d3604 10 10 11 11 SECTIONS { 12 #ifdef SHLIB 13 . = SEGMENT_START("text-segment", 0); 14 #else 12 15 . = SEGMENT_START("text-segment", 0x400000); 13 #ifndef SHLIB14 16 PROVIDE (__executable_start = .); 15 17 #endif -
uspace/lib/c/arch/riscv64/_link.ld.in
r4c5f04f r40d3604 10 10 11 11 SECTIONS { 12 #ifdef SHLIB 13 . = SEGMENT_START("text-segment", 0); 14 #else 12 15 . = SEGMENT_START("text-segment", 0x400000); 13 #ifndef SHLIB14 16 PROVIDE (__executable_start = .); 15 17 #endif -
uspace/lib/c/arch/sparc64/_link.ld.in
r4c5f04f r40d3604 10 10 11 11 SECTIONS { 12 #ifdef SHLIB 13 . = SEGMENT_START("text-segment", 0); 14 #else 12 15 . = SEGMENT_START("text-segment", 0x400000); 13 #ifndef SHLIB14 16 PROVIDE (__executable_start = .); 15 17 #endif -
uspace/lib/c/generic/elf/elf_load.c
r4c5f04f r40d3604 62 62 int rc; 63 63 64 rc = elf_load_file(file, 0, 0,&info->finfo);64 rc = elf_load_file(file, 0, &info->finfo); 65 65 if (rc != EE_OK) { 66 66 DPRINTF("Failed to load executable '%s'.\n", file_name); -
uspace/lib/c/generic/elf/elf_mod.c
r4c5f04f r40d3604 58 58 #include <str_error.h> 59 59 #include <stdlib.h> 60 #include <macros.h> 60 61 61 62 #include <elf/elf_load.h> … … 73 74 }; 74 75 75 static unsigned int elf_load_module(elf_ld_t *elf, size_t so_bias); 76 static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry); 76 static unsigned int elf_load_module(elf_ld_t *elf); 77 77 static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry); 78 78 … … 86 86 * 87 87 * @param file ELF file. 88 * @param so_bias Bias to use if the file is a shared object.89 88 * @param info Pointer to a structure for storing information 90 89 * extracted from the binary. … … 93 92 * 94 93 */ 95 int elf_load_file(int file, size_t so_bias,eld_flags_t flags, elf_finfo_t *info)94 int elf_load_file(int file, eld_flags_t flags, elf_finfo_t *info) 96 95 { 97 96 elf_ld_t elf; … … 110 109 elf.flags = flags; 111 110 112 int ret = elf_load_module(&elf , so_bias);111 int ret = elf_load_module(&elf); 113 112 114 113 vfs_put(ofile); … … 116 115 } 117 116 118 int elf_load_file_name(const char *path, size_t so_bias, eld_flags_t flags, 119 elf_finfo_t *info) 117 int elf_load_file_name(const char *path, eld_flags_t flags, elf_finfo_t *info) 120 118 { 121 119 int file; 122 120 errno_t rc = vfs_lookup(path, 0, &file); 123 121 if (rc == EOK) { 124 int ret = elf_load_file(file, so_bias,flags, info);122 int ret = elf_load_file(file, flags, info); 125 123 vfs_put(file); 126 124 return ret; … … 130 128 } 131 129 130 /** Process TLS program header. 131 * 132 * @param elf Pointer to loader state buffer. 133 * @param hdr TLS program header 134 * @param info Place to store TLS info 135 */ 136 static void tls_program_header(void *base, elf_tls_info_t *info) 137 { 138 const elf_segment_header_t *tls = elf_get_phdr(base, PT_TLS); 139 size_t bias = elf_get_bias(base); 140 141 if (tls == NULL) { 142 /* Ensure valid TLS info even if there is no TLS header. */ 143 info->tdata = NULL; 144 info->tdata_size = 0; 145 info->tbss_size = 0; 146 info->tls_align = 1; 147 } else { 148 info->tdata = (void *) tls->p_vaddr + bias; 149 info->tdata_size = tls->p_filesz; 150 info->tbss_size = tls->p_memsz - tls->p_filesz; 151 info->tls_align = tls->p_align; 152 } 153 } 154 132 155 /** Load an ELF binary. 133 156 * … … 137 160 * 138 161 * @param elf Pointer to loader state buffer. 139 * @param so_bias Bias to use if the file is a shared object.140 162 * @return EE_OK on success or EE_xx error code. 141 163 */ 142 static unsigned int elf_load_module(elf_ld_t *elf , size_t so_bias)164 static unsigned int elf_load_module(elf_ld_t *elf) 143 165 { 144 166 elf_header_t header_buf; … … 154 176 return EE_IO; 155 177 } 156 157 elf->header = header;158 178 159 179 /* Identify ELF */ … … 188 208 } 189 209 210 if (header->e_phoff == 0) { 211 DPRINTF("Program header table is not present!\n"); 212 return EE_INCOMPATIBLE; 213 } 214 215 /* Read program header table. 216 * Normally, there is very few program headers, so don't bother 217 * with allocating memory dynamically. 218 */ 219 const int phdr_cap = 16; 220 elf_segment_header_t phdr[phdr_cap]; 221 size_t phdr_len = header->e_phnum * header->e_phentsize; 222 223 if (phdr_len > sizeof(phdr)) { 224 DPRINTF("more than %d program headers\n", phdr_cap); 225 return EE_UNSUPPORTED; 226 } 227 228 pos = header->e_phoff; 229 rc = vfs_read(elf->fd, &pos, phdr, phdr_len, &nr); 230 if (rc != EOK || nr != phdr_len) { 231 DPRINTF("Read error.\n"); 232 return EE_IO; 233 } 234 235 uintptr_t module_base = UINTPTR_MAX; 236 uintptr_t module_top = 0; 237 uintptr_t base_offset = UINTPTR_MAX; 238 239 /* Walk through PT_LOAD headers, to find out the size of the module. */ 240 for (i = 0; i < header->e_phnum; i++) { 241 if (phdr[i].p_type != PT_LOAD) 242 continue; 243 244 if (module_base > phdr[i].p_vaddr) { 245 module_base = phdr[i].p_vaddr; 246 base_offset = phdr[i].p_offset; 247 } 248 module_top = max(module_top, phdr[i].p_vaddr + phdr[i].p_memsz); 249 } 250 251 if (base_offset != 0) { 252 DPRINTF("ELF headers not present in the text segment.\n"); 253 return EE_INVALID; 254 } 255 190 256 /* Shared objects can be loaded with a bias */ 191 if (header->e_type == ET_DYN) 192 elf->bias = so_bias; 193 else 257 if (header->e_type != ET_DYN) { 194 258 elf->bias = 0; 195 196 /* Ensure valid TLS info even if there is no TLS header. */ 197 elf->info->tls.tdata = NULL; 198 elf->info->tls.tdata_size = 0; 199 elf->info->tls.tbss_size = 0; 200 elf->info->tls.tls_align = 1; 201 202 elf->info->interp = NULL; 203 elf->info->dynamic = NULL; 204 205 /* Walk through all segment headers and process them. */ 259 } else { 260 if (module_base != 0) { 261 DPRINTF("Unexpected shared object format.\n"); 262 return EE_INVALID; 263 } 264 265 /* Attempt to allocate a span of memory large enough for the 266 * shared object. 267 */ 268 // FIXME: This is not reliable when we're running 269 // multi-threaded. Even if this part succeeds, later 270 // allocation can fail because another thread took the 271 // space in the meantime. This is only relevant for 272 // dlopen() though. 273 void *area = as_area_create(AS_AREA_ANY, module_top, 274 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE | 275 AS_AREA_LATE_RESERVE, AS_AREA_UNPAGED); 276 277 if (area == AS_MAP_FAILED) { 278 DPRINTF("Can't find suitable memory area.\n"); 279 return EE_MEMORY; 280 } 281 282 elf->bias = (uintptr_t) area; 283 as_area_destroy(area); 284 } 285 286 /* Load all loadable segments. */ 206 287 for (i = 0; i < header->e_phnum; i++) { 207 elf_segment_header_t segment_hdr; 208 209 pos = header->e_phoff + i * sizeof(elf_segment_header_t); 210 rc = vfs_read(elf->fd, &pos, &segment_hdr, 211 sizeof(elf_segment_header_t), &nr); 212 if (rc != EOK || nr != sizeof(elf_segment_header_t)) { 213 DPRINTF("Read error.\n"); 214 return EE_IO; 215 } 216 217 ret = segment_header(elf, &segment_hdr); 288 if (phdr[i].p_type != PT_LOAD) 289 continue; 290 291 ret = load_segment(elf, &phdr[i]); 218 292 if (ret != EE_OK) 219 293 return ret; 220 294 } 221 295 296 void *base = (void *) module_base + elf->bias; 297 elf->info->base = base; 298 299 /* Handle TLS. */ 300 tls_program_header(base, &elf->info->tls); 301 302 /* Handle PT_INTERP. */ 303 304 const elf_segment_header_t *interphdr = elf_get_phdr(base, PT_INTERP); 305 306 if (interphdr == NULL) { 307 interphdr = NULL; 308 } else { 309 elf->info->interp = 310 (const char *) (interphdr->p_vaddr + elf->bias); 311 if (elf->info->interp[interphdr->p_filesz - 1] != '\0') { 312 DPRINTF("Unterminated ELF interp string.\n"); 313 elf->info->interp = NULL; 314 } else { 315 DPRINTF("interpreter: \"%s\"\n", elf->info->interp); 316 } 317 } 318 319 /* Handle PT_DYNAMIC. */ 320 321 const elf_segment_header_t *dynphdr = elf_get_phdr(base, PT_DYNAMIC); 322 323 if (dynphdr == NULL) { 324 elf->info->dynamic = NULL; 325 } else { 326 /* Record pointer to dynamic section into info structure */ 327 elf->info->dynamic = (void *) (dynphdr->p_vaddr + elf->bias); 328 DPRINTF("dynamic section found at %p\n", 329 (void *)elf->info->dynamic); 330 } 331 222 332 elf->info->entry = 223 333 (entry_point_t)((uint8_t *)header->e_entry + elf->bias); … … 239 349 240 350 return error_codes[rc]; 241 }242 243 /** Process TLS program header.244 *245 * @param elf Pointer to loader state buffer.246 * @param hdr TLS program header247 * @param info Place to store TLS info248 */249 static void tls_program_header(elf_ld_t *elf, elf_segment_header_t *hdr,250 elf_tls_info_t *info)251 {252 info->tdata = (void *)((uint8_t *)hdr->p_vaddr + elf->bias);253 info->tdata_size = hdr->p_filesz;254 info->tbss_size = hdr->p_memsz - hdr->p_filesz;255 info->tls_align = hdr->p_align;256 }257 258 /** Process segment header.259 *260 * @param elf Pointer to loader state buffer.261 * @param entry Segment header.262 *263 * @return EE_OK on success, error code otherwise.264 */265 static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)266 {267 switch (entry->p_type) {268 case PT_NULL:269 case PT_PHDR:270 case PT_NOTE:271 break;272 case PT_LOAD:273 return load_segment(elf, entry);274 break;275 case PT_INTERP:276 elf->info->interp =277 (void *)((uint8_t *)entry->p_vaddr + elf->bias);278 279 // FIXME: This actually won't work, because the text segment is280 // not loaded yet.281 #if 0282 if (elf->info->interp[entry->p_filesz - 1] != '\0') {283 DPRINTF("Unterminated ELF interp string.\n");284 return EE_INVALID;285 }286 DPRINTF("interpreter: \"%s\"\n", elf->info->interp);287 #endif288 break;289 case PT_DYNAMIC:290 /* Record pointer to dynamic section into info structure */291 elf->info->dynamic =292 (void *)((uint8_t *)entry->p_vaddr + elf->bias);293 DPRINTF("dynamic section found at %p\n",294 (void *)elf->info->dynamic);295 break;296 case 0x70000000:297 case 0x70000001:298 case 0x70000002:299 case 0x70000003:300 // FIXME: Architecture-specific headers.301 /* PT_MIPS_REGINFO, PT_MIPS_ABIFLAGS, PT_ARM_UNWIND, ... */302 break;303 case PT_TLS:304 /* Parse TLS program header */305 tls_program_header(elf, entry, &elf->info->tls);306 DPRINTF("TLS header found at %p\n",307 (void *)((uint8_t *)entry->p_vaddr + elf->bias));308 break;309 case PT_SHLIB:310 default:311 DPRINTF("Segment p_type %d unknown.\n", entry->p_type);312 return EE_UNSUPPORTED;313 break;314 }315 return EE_OK;316 351 } 317 352 -
uspace/lib/c/generic/rtld/module.c
r4c5f04f r40d3604 202 202 str_cpy(name_buf + 5, NAME_BUF_SIZE - 5, name); 203 203 204 /* FIXME: need to real allocation of address space */205 m->bias = rtld->next_bias;206 rtld->next_bias += 0x100000;207 204 208 205 DPRINTF("filename:'%s'\n", name_buf); 209 DPRINTF("load '%s' at 0x%zx\n", name_buf, m->bias); 210 211 rc = elf_load_file_name(name_buf, m->bias, ELDF_RW, &info); 206 207 rc = elf_load_file_name(name_buf, ELDF_RW, &info); 212 208 if (rc != EE_OK) { 213 209 printf("Failed to load '%s'\n", name_buf); 214 210 exit(1); 215 211 } 212 213 m->bias = elf_get_bias(info.base); 214 215 DPRINTF("loaded '%s' at 0x%zx\n", name_buf, m->bias); 216 216 217 217 if (info.dynamic == NULL) { -
uspace/lib/c/generic/rtld/rtld.c
r4c5f04f r40d3604 53 53 list_initialize(&runtime_env->modules); 54 54 list_initialize(&runtime_env->imodules); 55 runtime_env->next_bias = 0x2000000;56 55 runtime_env->program = NULL; 57 56 runtime_env->next_id = 1; … … 121 120 env->program = prog; 122 121 123 /* Work around non-existent memory space allocation. */124 env->next_bias = 0x1000000;125 126 122 /* 127 123 * Now we can continue with loading all other modules. -
uspace/lib/c/include/elf/elf_mod.h
r4c5f04f r40d3604 78 78 entry_point_t entry; 79 79 80 /** The base address where the file has been loaded. 81 * Points to the ELF file header. 82 */ 83 void *base; 84 80 85 /** ELF interpreter name or NULL if statically-linked */ 81 86 const char *interp; … … 101 106 eld_flags_t flags; 102 107 103 /** A copy of the ELF file header */104 elf_header_t *header;105 106 108 /** Store extracted info here */ 107 109 elf_finfo_t *info; … … 109 111 110 112 extern const char *elf_error(unsigned int); 111 extern int elf_load_file(int, size_t,eld_flags_t, elf_finfo_t *);112 extern int elf_load_file_name(const char *, size_t,eld_flags_t, elf_finfo_t *);113 extern int elf_load_file(int, eld_flags_t, elf_finfo_t *); 114 extern int elf_load_file_name(const char *, eld_flags_t, elf_finfo_t *); 113 115 114 116 #endif -
uspace/lib/c/include/types/rtld/rtld.h
r4c5f04f r40d3604 61 61 /** List of initial modules */ 62 62 list_t imodules; 63 64 /** Temporary hack to place each module at different address. */65 uintptr_t next_bias;66 63 } rtld_t; 67 64
Note:
See TracChangeset
for help on using the changeset viewer.