Changeset 7465910 in mainline
- Timestamp:
- 2018-05-01T17:46:56Z (7 years ago)
- Parents:
- 9e5cc73
- git-author:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-05-01 17:31:49)
- git-committer:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-05-01 17:46:56)
- Location:
- uspace/lib/c
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/elf/elf_load.c
r9e5cc73 r7465910 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
r9e5cc73 r7465910 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 unsigned int elf_load_module(elf_ld_t *elf); 76 77 static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry); 77 78 static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry); … … 86 87 * 87 88 * @param file ELF file. 88 * @param so_bias Bias to use if the file is a shared object.89 89 * @param info Pointer to a structure for storing information 90 90 * extracted from the binary. … … 93 93 * 94 94 */ 95 int elf_load_file(int file, size_t so_bias,eld_flags_t flags, elf_finfo_t *info)95 int elf_load_file(int file, eld_flags_t flags, elf_finfo_t *info) 96 96 { 97 97 elf_ld_t elf; … … 110 110 elf.flags = flags; 111 111 112 int ret = elf_load_module(&elf , so_bias);112 int ret = elf_load_module(&elf); 113 113 114 114 vfs_put(ofile); … … 116 116 } 117 117 118 int elf_load_file_name(const char *path, size_t so_bias, eld_flags_t flags, 119 elf_finfo_t *info) 118 int elf_load_file_name(const char *path, eld_flags_t flags, elf_finfo_t *info) 120 119 { 121 120 int file; 122 121 errno_t rc = vfs_lookup(path, 0, &file); 123 122 if (rc == EOK) { 124 int ret = elf_load_file(file, so_bias,flags, info);123 int ret = elf_load_file(file, flags, info); 125 124 vfs_put(file); 126 125 return ret; … … 137 136 * 138 137 * @param elf Pointer to loader state buffer. 139 * @param so_bias Bias to use if the file is a shared object.140 138 * @return EE_OK on success or EE_xx error code. 141 139 */ 142 static unsigned int elf_load_module(elf_ld_t *elf , size_t so_bias)140 static unsigned int elf_load_module(elf_ld_t *elf) 143 141 { 144 142 elf_header_t header_buf; … … 154 152 return EE_IO; 155 153 } 156 157 elf->header = header;158 154 159 155 /* Identify ELF */ … … 188 184 } 189 185 186 if (header->e_phoff == 0) { 187 DPRINTF("Program header table is not present!\n"); 188 return EE_UNSUPPORTED; 189 } 190 191 /* Read program header table. 192 * Normally, there are very few program headers, so don't bother 193 * with allocating memory dynamically. 194 */ 195 const int phdr_cap = 16; 196 elf_segment_header_t phdr[phdr_cap]; 197 size_t phdr_len = header->e_phnum * header->e_phentsize; 198 199 if (phdr_len > sizeof(phdr)) { 200 DPRINTF("more than %d program headers\n", phdr_cap); 201 return EE_UNSUPPORTED; 202 } 203 204 pos = header->e_phoff; 205 rc = vfs_read(elf->fd, &pos, phdr, phdr_len, &nr); 206 if (rc != EOK || nr != phdr_len) { 207 DPRINTF("Read error.\n"); 208 return EE_IO; 209 } 210 211 uintptr_t module_base = UINTPTR_MAX; 212 uintptr_t module_top = 0; 213 uintptr_t base_offset = UINTPTR_MAX; 214 215 /* Walk through PT_LOAD headers, to find out the size of the module. */ 216 for (i = 0; i < header->e_phnum; i++) { 217 if (phdr[i].p_type != PT_LOAD) 218 continue; 219 220 if (module_base > phdr[i].p_vaddr) { 221 module_base = phdr[i].p_vaddr; 222 base_offset = phdr[i].p_offset; 223 } 224 module_top = max(module_top, phdr[i].p_vaddr + phdr[i].p_memsz); 225 } 226 227 if (base_offset != 0) { 228 DPRINTF("ELF headers not present in the text segment.\n"); 229 return EE_INVALID; 230 } 231 190 232 /* Shared objects can be loaded with a bias */ 191 if (header->e_type == ET_DYN) 192 elf->bias = so_bias; 193 else 233 if (header->e_type != ET_DYN) { 194 234 elf->bias = 0; 235 } else { 236 if (module_base != 0) { 237 DPRINTF("Unexpected shared object format.\n"); 238 return EE_INVALID; 239 } 240 241 /* Attempt to allocate a span of memory large enough for the 242 * shared object. 243 */ 244 // FIXME: This is not reliable when we're running 245 // multi-threaded. Even if this part succeeds, later 246 // allocation can fail because another thread took the 247 // space in the meantime. This is only relevant for 248 // dlopen() though. 249 void *area = as_area_create(AS_AREA_ANY, module_top, 250 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE | 251 AS_AREA_LATE_RESERVE, AS_AREA_UNPAGED); 252 253 if (area == AS_MAP_FAILED) { 254 DPRINTF("Can't find suitable memory area.\n"); 255 return EE_MEMORY; 256 } 257 258 elf->bias = (uintptr_t) area; 259 as_area_destroy(area); 260 } 261 262 /* Load all loadable segments. */ 263 for (i = 0; i < header->e_phnum; i++) { 264 if (phdr[i].p_type != PT_LOAD) 265 continue; 266 267 ret = load_segment(elf, &phdr[i]); 268 if (ret != EE_OK) 269 return ret; 270 } 271 272 void *base = (void *) module_base + elf->bias; 273 elf->info->base = base; 195 274 196 275 /* Ensure valid TLS info even if there is no TLS header. */ … … 205 284 /* Walk through all segment headers and process them. */ 206 285 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); 286 if (phdr[i].p_type == PT_LOAD) 287 continue; 288 289 ret = segment_header(elf, &phdr[i]); 218 290 if (ret != EE_OK) 219 291 return ret; … … 270 342 case PT_NOTE: 271 343 break; 272 case PT_LOAD:273 return load_segment(elf, entry);274 break;275 344 case PT_INTERP: 276 345 elf->info->interp = 277 346 (void *)((uint8_t *)entry->p_vaddr + elf->bias); 278 347 279 // FIXME: This actually won't work, because the text segment is280 // not loaded yet.281 #if 0282 348 if (elf->info->interp[entry->p_filesz - 1] != '\0') { 283 349 DPRINTF("Unterminated ELF interp string.\n"); … … 285 351 } 286 352 DPRINTF("interpreter: \"%s\"\n", elf->info->interp); 287 #endif288 353 break; 289 354 case PT_DYNAMIC: -
uspace/lib/c/generic/rtld/module.c
r9e5cc73 r7465910 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
r9e5cc73 r7465910 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
r9e5cc73 r7465910 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
r9e5cc73 r7465910 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.