Changes in uspace/app/taskdump/elf_core.c [8fd04ba9:79ae36dd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/taskdump/elf_core.c
r8fd04ba9 r79ae36dd 1 1 /* 2 * Copyright (c) 201 1Jiri Svoboda2 * Copyright (c) 2010 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 38 38 * Looking at core files produced by Linux, these don't have section headers, 39 39 * only program headers, although objdump shows them as having sections. 40 * Basically at the beginning there should be a note segment followed 41 * by one loadable segment per memory area. 42 * 43 * The note segment contains a series of records with register state, 44 * process info etc. We only write one record NT_PRSTATUS which contains 45 * process/register state (anything which is not register state we fill 46 * with zeroes). 47 */ 48 49 #include <align.h> 50 #include <elf/elf.h> 51 #include <elf/elf_linux.h> 40 * Basically at the beginning there should be a note segment (which we 41 * do not write) and one loadable segment per memory area (which we do write). 42 * 43 * The note segment probably contains register state, etc. -- we don't 44 * deal with these yet. Nevertheless you can use these core files with 45 * objdump or gdb. 46 */ 47 52 48 #include <stdio.h> 53 49 #include <stdlib.h> … … 62 58 #include <udebug.h> 63 59 #include <macros.h> 64 #include <libarch/istate.h> 65 66 #include " elf_core.h"60 61 #include <elf.h> 62 #include "include/elf_core.h" 67 63 68 64 static off64_t align_foff_up(off64_t, uintptr_t, size_t); 69 static int align_pos(int, size_t);65 static int write_all(int, void *, size_t); 70 66 static int write_mem_area(int, as_area_info_t *, async_sess_t *); 71 67 … … 87 83 */ 88 84 int elf_core_save(const char *file_name, as_area_info_t *ainfo, unsigned int n, 89 async_sess_t *sess , istate_t *istate)85 async_sess_t *sess) 90 86 { 91 87 elf_header_t elf_hdr; … … 94 90 elf_word flags; 95 91 elf_segment_header_t *p_hdr; 96 elf_prstatus_t pr_status;97 elf_note_t note;98 size_t word_size;99 92 100 93 int fd; 101 ssize_t rc;94 int rc; 102 95 unsigned int i; 103 96 104 #ifdef __32_BITS__ 105 word_size = 4; 106 #endif 107 #ifdef __64_BITS__ 108 word_size = 8; 109 #endif 110 memset(&pr_status, 0, sizeof(pr_status)); 111 istate_to_elf_regs(istate, &pr_status.regs); 112 113 n_ph = n + 1; 114 115 p_hdr = malloc(sizeof(elf_segment_header_t) * n_ph); 97 n_ph = n; 98 99 p_hdr = malloc(sizeof(elf_segment_header_t) * n); 116 100 if (p_hdr == NULL) { 117 101 printf("Failed allocating memory.\n"); … … 131 115 * ELF header 132 116 * program headers 133 * note segment134 117 * repeat: 135 118 * (pad for alignment) 136 * core segment119 * segment data 137 120 * end repeat 138 121 */ … … 164 147 foff = elf_hdr.e_phoff + n_ph * sizeof(elf_segment_header_t); 165 148 166 memset(&p_hdr[0], 0, sizeof(p_hdr[0])); 167 p_hdr[0].p_type = PT_NOTE; 168 p_hdr[0].p_offset = foff; 169 p_hdr[0].p_vaddr = 0; 170 p_hdr[0].p_paddr = 0; 171 p_hdr[0].p_filesz = sizeof(elf_note_t) 172 + ALIGN_UP((str_size("CORE") + 1), word_size) 173 + ALIGN_UP(sizeof(elf_prstatus_t), word_size); 174 p_hdr[0].p_memsz = 0; 175 p_hdr[0].p_flags = 0; 176 p_hdr[0].p_align = 1; 177 178 foff += p_hdr[0].p_filesz; 179 180 for (i = 0; i < n; ++i) { 181 foff = align_foff_up(foff, ainfo[i].start_addr, PAGE_SIZE); 149 for (i = 1; i <= n; ++i) { 150 foff = align_foff_up(foff, ainfo[i - 1].start_addr, PAGE_SIZE); 182 151 183 152 flags = 0; 184 if (ainfo[i ].flags & AS_AREA_READ)153 if (ainfo[i - 1].flags & AS_AREA_READ) 185 154 flags |= PF_R; 186 if (ainfo[i ].flags & AS_AREA_WRITE)155 if (ainfo[i - 1].flags & AS_AREA_WRITE) 187 156 flags |= PF_W; 188 if (ainfo[i ].flags & AS_AREA_EXEC)157 if (ainfo[i - 1].flags & AS_AREA_EXEC) 189 158 flags |= PF_X; 190 159 191 memset(&p_hdr[i + 1], 0, sizeof(p_hdr[i +1]));192 p_hdr[i +1].p_type = PT_LOAD;193 p_hdr[i +1].p_offset = foff;194 p_hdr[i + 1].p_vaddr = ainfo[i].start_addr;195 p_hdr[i +1].p_paddr = 0;196 p_hdr[i + 1].p_filesz = ainfo[i].size;197 p_hdr[i + 1].p_memsz = ainfo[i].size;198 p_hdr[i +1].p_flags = flags;199 p_hdr[i +1].p_align = PAGE_SIZE;200 201 foff += ainfo[i ].size;160 memset(&p_hdr[i - 1], 0, sizeof(p_hdr[i - 1])); 161 p_hdr[i - 1].p_type = PT_LOAD; 162 p_hdr[i - 1].p_offset = foff; 163 p_hdr[i - 1].p_vaddr = ainfo[i - 1].start_addr; 164 p_hdr[i - 1].p_paddr = 0; 165 p_hdr[i - 1].p_filesz = ainfo[i - 1].size; 166 p_hdr[i - 1].p_memsz = ainfo[i - 1].size; 167 p_hdr[i - 1].p_flags = flags; 168 p_hdr[i - 1].p_align = PAGE_SIZE; 169 170 foff += ainfo[i - 1].size; 202 171 } 203 172 204 173 rc = write_all(fd, &elf_hdr, sizeof(elf_hdr)); 205 if (rc != sizeof(elf_hdr)) {174 if (rc != EOK) { 206 175 printf("Failed writing ELF header.\n"); 207 176 free(p_hdr); … … 211 180 for (i = 0; i < n_ph; ++i) { 212 181 rc = write_all(fd, &p_hdr[i], sizeof(p_hdr[i])); 213 if (rc != sizeof(p_hdr[i])) {182 if (rc != EOK) { 214 183 printf("Failed writing program header.\n"); 215 184 free(p_hdr); … … 218 187 } 219 188 220 if (lseek(fd, p_hdr[0].p_offset, SEEK_SET) == (off64_t) -1) { 221 printf("Failed writing memory data.\n"); 222 free(p_hdr); 223 return EIO; 224 } 225 226 /* 227 * Write note header 228 */ 229 note.namesz = str_size("CORE") + 1; 230 note.descsz = sizeof(elf_prstatus_t); 231 note.type = NT_PRSTATUS; 232 233 rc = write_all(fd, ¬e, sizeof(elf_note_t)); 234 if (rc != sizeof(elf_note_t)) { 235 printf("Failed writing note header.\n"); 236 free(p_hdr); 237 return EIO; 238 } 239 240 rc = write_all(fd, "CORE", note.namesz); 241 if (rc != (ssize_t) note.namesz) { 242 printf("Failed writing note header.\n"); 243 free(p_hdr); 244 return EIO; 245 } 246 247 rc = align_pos(fd, word_size); 248 if (rc != EOK) { 249 printf("Failed writing note header.\n"); 250 free(p_hdr); 251 return EIO; 252 } 253 254 rc = write_all(fd, &pr_status, sizeof(elf_prstatus_t)); 255 if (rc != sizeof(elf_prstatus_t)) { 256 printf("Failed writing register data.\n"); 257 free(p_hdr); 258 return EIO; 259 } 260 261 for (i = 1; i < n_ph; ++i) { 189 for (i = 0; i < n_ph; ++i) { 262 190 if (lseek(fd, p_hdr[i].p_offset, SEEK_SET) == (off64_t) -1) { 263 191 printf("Failed writing memory data.\n"); … … 265 193 return EIO; 266 194 } 267 if (write_mem_area(fd, &ainfo[i - 1], sess) != EOK) {195 if (write_mem_area(fd, &ainfo[i], sess) != EOK) { 268 196 printf("Failed writing memory data.\n"); 269 197 free(p_hdr); … … 282 210 off64_t rva = vaddr % page_size; 283 211 off64_t rfo = foff % page_size; 284 212 285 213 if (rva >= rfo) 286 214 return (foff + (rva - rfo)); 287 215 288 216 return (foff + (page_size + (rva - rfo))); 289 217 } … … 303 231 size_t total; 304 232 uintptr_t addr; 305 ssize_t rc;233 int rc; 306 234 307 235 addr = area->start_addr; … … 317 245 318 246 rc = write_all(fd, buffer, to_copy); 319 if (rc != (ssize_t) to_copy) {247 if (rc != EOK) { 320 248 printf("Failed writing memory contents.\n"); 321 249 return EIO; … … 329 257 } 330 258 331 static int align_pos(int fd, size_t align) 332 { 333 off64_t cur_pos; 334 size_t rem, adv; 335 336 cur_pos = lseek(fd, 0, SEEK_CUR); 337 if (cur_pos < 0) 338 return -1; 339 340 rem = cur_pos % align; 341 adv = align - rem; 342 343 cur_pos = lseek(fd, adv, SEEK_CUR); 344 if (cur_pos < 0) 345 return -1; 259 /** Write until the buffer is written in its entirety. 260 * 261 * This function fails if it cannot write exactly @a len bytes to the file. 262 * 263 * @param fd The file to write to. 264 * @param buf Data, @a len bytes long. 265 * @param len Number of bytes to write. 266 * 267 * @return EOK on error, return value from write() if writing 268 * failed. 269 */ 270 static int write_all(int fd, void *data, size_t len) 271 { 272 int cnt = 0; 273 274 do { 275 data += cnt; 276 len -= cnt; 277 cnt = write(fd, data, len); 278 } while (cnt > 0 && (len - cnt) > 0); 279 280 if (cnt < 0) 281 return cnt; 282 283 if (len - cnt > 0) 284 return EIO; 346 285 347 286 return EOK; 348 287 } 349 288 289 350 290 /** @} 351 291 */
Note:
See TracChangeset
for help on using the changeset viewer.