diff options
Diffstat (limited to 'kexec')
-rw-r--r-- | kexec/arch/ppc64/fs2dt.c | 8 | ||||
-rw-r--r-- | kexec/arch/ppc64/kexec-elf-ppc64.c | 176 | ||||
-rw-r--r-- | kexec/arch/ppc64/kexec-elf-rel-ppc64.c | 41 | ||||
-rw-r--r-- | kexec/arch/ppc64/kexec-zImage-ppc64.c | 3 | ||||
-rw-r--r-- | kexec/kexec-elf-rel.c | 38 | ||||
-rw-r--r-- | kexec/kexec-elf.c | 88 |
6 files changed, 220 insertions, 134 deletions
diff --git a/kexec/arch/ppc64/fs2dt.c b/kexec/arch/ppc64/fs2dt.c index 447da64..2b81402 100644 --- a/kexec/arch/ppc64/fs2dt.c +++ b/kexec/arch/ppc64/fs2dt.c @@ -374,7 +374,7 @@ void putnode(void) } int create_flatten_tree(struct kexec_info *info, unsigned char **bufp, - unsigned long *sizep, char *cmdline) + unsigned long *sizep, char *cmdline) { unsigned long len; unsigned long tlen; @@ -420,10 +420,10 @@ int create_flatten_tree(struct kexec_info *info, unsigned char **bufp, reserve(me, bb->totalsize); /* patched later in kexec_load */ - buf = (unsigned char *) realloc(*bufp, *sizep + bb->totalsize); + buf = (unsigned char *) malloc(bb->totalsize); *bufp = buf; - memcpy(buf+(*sizep), bb, bb->off_mem_rsvmap); - tlen = *sizep + bb->off_mem_rsvmap; + memcpy(buf, bb, bb->off_mem_rsvmap); + tlen = bb->off_mem_rsvmap; memcpy(buf+tlen, mem_rsrv, bb->off_dt_struct - bb->off_mem_rsvmap); tlen = tlen + (bb->off_dt_struct - bb->off_mem_rsvmap); memcpy(buf+tlen, dtstruct, bb->off_dt_strings - bb->off_dt_struct); diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c index 08106ce..50a59f5 100644 --- a/kexec/arch/ppc64/kexec-elf-ppc64.c +++ b/kexec/arch/ppc64/kexec-elf-ppc64.c @@ -4,6 +4,7 @@ * Copyright (C) 2004 Adam Litke (agl@us.ibm.com) * Copyright (C) 2004 IBM Corp. * Copyright (C) 2005 R Sharada (sharada@in.ibm.com) + * Copyright (C) 2006 Mohan Kumar M (mohan@in.ibm.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,6 +46,7 @@ unsigned long initrd_base, initrd_size; int create_flatten_tree(struct kexec_info *, unsigned char **, unsigned long *, char *); +int my_r2(struct mem_ehdr *ehdr); int elf_ppc64_probe(const char *buf, off_t len) { @@ -83,6 +85,10 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, struct bootblock *bb_ptr; unsigned int nr_segments, i; int result, opt; + unsigned long my_kernel, my_dt_offset; + unsigned int my_panic_kernel; + unsigned long my_stack, my_backup_start; + unsigned long toc_addr; #define OPT_APPEND (OPT_ARCH_MAX+0) #define OPT_RAMDISK (OPT_ARCH_MAX+1) @@ -167,7 +173,7 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, size = phdr->p_memsz; hole_addr = (unsigned long)locate_hole(info, size, 0, 0, - 0xFFFFFFFFFFFFFFFFUL, 1); + max_addr, 1); ehdr.e_phdr[0].p_paddr = hole_addr; result = elf_exec_load(&ehdr, info); if (result < 0) { @@ -175,24 +181,6 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, return result; } - /* Add a ram-disk to the current image */ - if (ramdisk) { - if (devicetreeblob) { - fprintf(stderr, "Can't use ramdisk with device tree blob input\n"); - return -1; - } - unsigned char *ramdisk_buf = NULL; - off_t ramdisk_size = 0; - unsigned long long ramdisk_addr; - - ramdisk_buf = slurp_file(ramdisk, &ramdisk_size); - add_buffer(info, ramdisk_buf, ramdisk_size, ramdisk_size, 0, 0, - 0xFFFFFFFFFFFFFFFFUL, 1); - ramdisk_addr = (unsigned long long)info->segment[info->nr_segments-1].mem; - initrd_base = ramdisk_addr; - initrd_size = ramdisk_size; - } - /* If panic kernel is being loaded, additional segments need * to be created. */ @@ -207,68 +195,136 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, } /* Add v2wrap to the current image */ - unsigned char *v2wrap_buf = NULL; - off_t v2wrap_size = 0; - unsigned long long *rsvmap_ptr; - struct bootblock *bb_ptr; - unsigned int devtree_size; + seg_buf = NULL; + seg_size = 0; - v2wrap_buf = (char *) malloc(purgatory_size); - if (v2wrap_buf == NULL) { + seg_buf = (char *) malloc(purgatory_size); + if (seg_buf == NULL) { free_elf_info(&ehdr); return -1; } - memcpy(v2wrap_buf, purgatory, purgatory_size); - v2wrap_size = purgatory_size; - if (devicetreeblob) { - unsigned char *blob_buf = NULL; - off_t blob_size = 0; - unsigned char *tmp_buf = NULL; + memcpy(seg_buf, purgatory, purgatory_size); + seg_size = purgatory_size; + elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, + 0, max_addr, 1); - /* Grab device tree from buffer */ - blob_buf = slurp_file(devicetreeblob, &blob_size); + /* Add a ram-disk to the current image + * Note: Add the ramdisk after elf_rel_build_load + */ + if (ramdisk) { + if (devicetreeblob) { + fprintf(stderr, + "Can't use ramdisk with device tree blob input\n"); + return -1; + } + seg_buf = slurp_file(ramdisk, &seg_size); + add_buffer(info, seg_buf, seg_size, seg_size, 0, 0, max_addr, 1); + hole_addr = (unsigned long long) + info->segment[info->nr_segments-1].mem; + initrd_base = hole_addr; + initrd_size = (unsigned long long) + info->segment[info->nr_segments-1].memsz; + } /* ramdisk */ + + if (devicetreeblob) { + unsigned char *blob_buf = NULL; + off_t blob_size = 0; - /* Append to purgatory */ - tmp_buf = (unsigned char *) realloc(v2wrap_buf, v2wrap_size + blob_size); - v2wrap_buf = tmp_buf; - memcpy(v2wrap_buf+v2wrap_size, blob_buf, blob_size); - v2wrap_size += blob_size; + /* Grab device tree from buffer */ + blob_buf = slurp_file(devicetreeblob, &blob_size); + add_buffer(info, blob_buf, blob_size, blob_size, 0, 0, + max_addr, -1); } else { - /* create from fs2dt */ - create_flatten_tree(info, &v2wrap_buf, &v2wrap_size); + /* create from fs2dt */ + seg_buf = NULL; + seg_size = 0; + create_flatten_tree(info, &seg_buf, &seg_size, cmdline); + add_buffer(info, seg_buf, seg_size, seg_size, + 0, 0, max_addr, -1); } - add_buffer(info, v2wrap_buf, v2wrap_size, v2wrap_size, 0, 0, - 0xFFFFFFFFFFFFFFFFUL, -1); /* patch reserve map address for flattened device-tree - find last entry (both 0) in the reserve mem list. Assume DT - entry is before this one */ + * find last entry (both 0) in the reserve mem list. Assume DT + * entry is before this one + */ bb_ptr = (struct bootblock *)( - (unsigned char *)info->segment[(info->nr_segments)-1].buf + - 0x100); + (unsigned char *)info->segment[(info->nr_segments)-1].buf); rsvmap_ptr = (long long *)( (unsigned char *)info->segment[(info->nr_segments)-1].buf + - bb_ptr->off_mem_rsvmap + 0x100); - while (*rsvmap_ptr || *(rsvmap_ptr+1)){ + bb_ptr->off_mem_rsvmap); + while (*rsvmap_ptr || *(rsvmap_ptr+1)) rsvmap_ptr += 2; - } rsvmap_ptr -= 2; *rsvmap_ptr = (unsigned long long)( - info->segment[(info->nr_segments)-1].mem + 0x100); - rsvmap_ptr++; - *rsvmap_ptr = (unsigned long long)bb_ptr->totalsize; + info->segment[(info->nr_segments)-1].mem); + rsvmap_ptr++; + *rsvmap_ptr = (unsigned long long)bb_ptr->totalsize; - unsigned int nr_segments; nr_segments = info->nr_segments; - lp = info->segment[nr_segments-1].buf + 0x100; - lp--; - *lp = info->segment[0].mem; - info->entry = info->segment[nr_segments-1].mem; - unsigned int i; + /* Set kernel */ + my_kernel = (unsigned long )info->segment[0].mem; + elf_rel_set_symbol(&info->rhdr, "kernel", &my_kernel, sizeof(my_kernel)); + + /* Set dt_offset */ + my_dt_offset = (unsigned long )info->segment[nr_segments-1].mem; + elf_rel_set_symbol(&info->rhdr, "dt_offset", &my_dt_offset, + sizeof(my_dt_offset)); + + if (info->kexec_flags & KEXEC_ON_CRASH) { + my_panic_kernel = 1; + /* Set panic flag */ + elf_rel_set_symbol(&info->rhdr, "panic_kernel", + &my_panic_kernel, sizeof(my_panic_kernel)); + + /* Set backup address */ + my_backup_start = info->backup_start; + elf_rel_set_symbol(&info->rhdr, "backup_start", + &my_backup_start, sizeof(my_backup_start)); + } + + /* Set stack address */ + my_stack = locate_hole(info, 16*1024, 0, 0, max_addr, 1); + my_stack += 16*1024; + elf_rel_set_symbol(&info->rhdr, "stack", &my_stack, sizeof(my_stack)); + + /* Set toc */ + toc_addr = (unsigned long) my_r2(&info->rhdr); + elf_rel_set_symbol(&info->rhdr, "my_toc", &toc_addr, sizeof(toc_addr)); + +#ifdef DEBUG + my_kernel = 0; + my_dt_offset = 0; + my_panic_kernel = 0; + my_backup_start = 0; + my_stack = 0; + toc_addr = 0; + + elf_rel_get_symbol(&info->rhdr, "kernel", &my_kernel, sizeof(my_kernel)); + elf_rel_get_symbol(&info->rhdr, "dt_offset", &my_dt_offset, + sizeof(my_dt_offset)); + elf_rel_get_symbol(&info->rhdr, "panic_kernel", &my_panic_kernel, + sizeof(my_panic_kernel)); + elf_rel_get_symbol(&info->rhdr, "backup_start", &my_backup_start, + sizeof(my_backup_start)); + elf_rel_get_symbol(&info->rhdr, "stack", &my_stack, sizeof(my_stack)); + elf_rel_get_symbol(&info->rhdr, "my_toc", &toc_addr, + sizeof(toc_addr)); + + fprintf(stderr, "info->entry is %p\n", info->entry); + fprintf(stderr, "kernel is %Lx\n", my_kernel); + fprintf(stderr, "dt_offset is %Lx\n", my_dt_offset); + fprintf(stderr, "panic_kernel is %x\n", my_panic_kernel); + fprintf(stderr, "backup_start is %Lx\n", my_backup_start); + fprintf(stderr, "stack is %Lx\n", my_stack); + fprintf(stderr, "toc_addr is %Lx\n", toc_addr); + fprintf(stderr, "purgatory size is %d\n", purgatory_size); +#endif + for (i = 0; i < nr_segments; i++) - printf("segment[i].mem:%lx\n", info->segment[i].mem); + fprintf(stderr, "segment[%d].mem:%p memsz:%ld\n", i, + info->segment[i].mem, info->segment[i].memsz); return 0; } diff --git a/kexec/arch/ppc64/kexec-elf-rel-ppc64.c b/kexec/arch/ppc64/kexec-elf-rel-ppc64.c index b50f266..a62552c 100644 --- a/kexec/arch/ppc64/kexec-elf-rel-ppc64.c +++ b/kexec/arch/ppc64/kexec-elf-rel-ppc64.c @@ -1,5 +1,6 @@ #include <stdio.h> #include <elf.h> +#include <string.h> #include "../../kexec.h" #include "../../kexec-elf.h" @@ -21,20 +22,19 @@ static struct mem_shdr *toc_section(const struct mem_ehdr *ehdr) { struct mem_shdr *shdr, *shdr_end; unsigned char *strtab; - strtab = ehdr->e_shdr[ehdr->e_shstrndx].sh_data; + strtab = (unsigned char *)ehdr->e_shdr[ehdr->e_shstrndx].sh_data; shdr_end = &ehdr->e_shdr[ehdr->e_shnum]; - for(shdr = ehdr->e_shdr; shdr != shdr_end; shdr++) { - if (strcmp(shdr->sh_name, ".toc") == 0) { + for(shdr = ehdr->e_shdr; shdr != shdr_end; shdr++) + if ( shdr->sh_size && + strcmp(&strtab[shdr->sh_name], ".toc") == 0) return shdr; - } - } return NULL; } /* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this gives the value maximum span in an instruction which uses a signed offset) */ -static unsigned long my_r2(const struct mem_ehdr *ehdr) +unsigned long my_r2(const struct mem_ehdr *ehdr) { struct mem_shdr *shdr; shdr = toc_section(ehdr); @@ -53,7 +53,7 @@ void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, /* Simply set it */ *(uint32_t *)location = value; break; - + case R_PPC64_ADDR64: /* Simply set it */ *(uint64_t *)location = value; @@ -78,15 +78,34 @@ void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, /* Convert value to relative */ value -= address; if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){ - die("REL24 %li out of range!\n", + die("REL24 %li out of range!\n", (long int)value); } /* Only replace bits 2 through 26 */ - *(uint32_t *)location - = (*(uint32_t *)location & ~0x03fffffc) - | (value & 0x03fffffc); + *(uint32_t *)location = (*(uint32_t *)location & ~0x03fffffc) + | (value & 0x03fffffc); + break; + + case R_PPC64_ADDR16_LO: + *(uint16_t *)location = value & 0xffff; + break; + + case R_PPC64_ADDR16_HI: + *(uint16_t *)location = (value>>16) & 0xffff; break; + + case R_PPC64_ADDR16_HA: + *(uint16_t *)location = ((value>>16) & 0xffff); + break; + + case R_PPC64_ADDR16_HIGHEST: + *(uint16_t *)location = ((value>>48) & 0xffff); + break; + case R_PPC64_ADDR16_HIGHER: + *(uint16_t *)location = ((value>>32) & 0xffff); + break; + default: die("Unknown rela relocation: %lu\n", r_type); break; diff --git a/kexec/arch/ppc64/kexec-zImage-ppc64.c b/kexec/arch/ppc64/kexec-zImage-ppc64.c index 2b5e00f..697a4db 100644 --- a/kexec/arch/ppc64/kexec-zImage-ppc64.c +++ b/kexec/arch/ppc64/kexec-zImage-ppc64.c @@ -153,7 +153,8 @@ int zImage_ppc64_load(FILE *file, int argc, char **argv, void **ret_entry, return -1; } mem_offset = p->p_vaddr - load_loc; - if (fread(segment->buf+mem_offset, p->p_filesz, 1, file) != 1) { + if (fread((void *)segment->buf+mem_offset, p->p_filesz, 1, + file) != 1) { perror("read error: "); return -1; } diff --git a/kexec/kexec-elf-rel.c b/kexec/kexec-elf-rel.c index 560c659..1f5cdf1 100644 --- a/kexec/kexec-elf-rel.c +++ b/kexec/kexec-elf-rel.c @@ -155,7 +155,7 @@ int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr) if (probe_debug) { fprintf(stderr, "No ELF section headers\n"); } - return -1; + return -1; } if (!machine_verify_elf_rel(ehdr)) { /* It does not meant the native architecture constraints */ @@ -251,7 +251,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, /* Allocate where we will put the relocated object */ buf = xmalloc(bufsz); - buf_addr = add_buffer(info, buf, bufsz, bufsz + bss_pad + bsssz, + buf_addr = add_buffer(info, buf, bufsz, bufsz + bss_pad + bsssz, buf_align, min, max, end); ehdr->rel_addr = buf_addr; ehdr->rel_size = bufsz + bss_pad + bsssz; @@ -269,7 +269,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, unsigned long off; /* Adjust the address */ data_addr = (data_addr + (align - 1)) & ~(align -1); - + /* Update the section */ off = data_addr - buf_addr; memcpy(buf + off, shdr->sh_data, shdr->sh_size); @@ -306,7 +306,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, continue; } if ((shdr->sh_info > ehdr->e_shnum) || - (shdr->sh_link > ehdr->e_shnum)) + (shdr->sh_link > ehdr->e_shnum)) { die("Invalid section number\n"); } @@ -350,12 +350,12 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, /* The final address of that location */ address = section->sh_addr + rel.r_offset; - + /* The relevant symbol */ sym = elf_sym(ehdr, symtab->sh_data + (rel.r_sym * elf_sym_size(ehdr))); -#if 0 +#ifdef DEBUG fprintf(stderr, "sym: %10s info: %02x other: %02x shndx: %lx value: %lx size: %lx\n", - strtab + sym.st_name, + strtab + sym.st_name, sym.st_info, sym.st_other, sym.st_shndx, @@ -364,8 +364,18 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, #endif if (sym.st_shndx == STN_UNDEF) { - die("Undefined symbol: %s\n", + /* + * NOTE: ppc64 elf .ro shows up a UNDEF section. + * From Elf 1.2 Spec: + * Relocation Entries: If the index is STN_UNDEF, + * the undefined symbol index, the relocation uses 0 + * as the "symbol value". + * So, is this really an error condition to flag die? + */ + /* + die("Undefined symbol: %s\n", strtab + sym.st_name); + */ } sec_base = 0; if (sym.st_shndx == SHN_COMMON) { @@ -383,14 +393,14 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, else { sec_base = ehdr->e_shdr[sym.st_shndx].sh_addr; } -#if 0 +#ifdef DEBUG fprintf(stderr, "sym: %s value: %lx addr: %lx\n", strtab + sym.st_name, value, address); #endif value = sym.st_value; value += sec_base; value += rel.r_addend; - machine_apply_elf_rel(ehdr, rel.r_type, + machine_apply_elf_rel(ehdr, rel.r_type, (void *)location, address, value); } } @@ -399,7 +409,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, return result; } -void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, +void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, const char *buf, off_t len, unsigned long min, unsigned long max, int end) { @@ -452,8 +462,8 @@ int elf_rel_find_symbol(struct mem_ehdr *ehdr, if (strcmp(strtab + sym.st_name, name) != 0) { continue; } - if ((sym.st_shndx == STN_UNDEF) || - (sym.st_shndx > ehdr->e_shnum)) + if ((sym.st_shndx == STN_UNDEF) || + (sym.st_shndx > ehdr->e_shnum)) { die("Symbol: %s has Bad section index %d\n", name, sym.st_shndx); @@ -491,7 +501,7 @@ void elf_rel_set_symbol(struct mem_ehdr *ehdr, result = elf_rel_find_symbol(ehdr, name, &sym); if (result < 0) { - die("Symbol: %s not found cannot set\n", + die("Symbol: %s not found cannot set\n", name); } if (sym.st_size != size) { diff --git a/kexec/kexec-elf.c b/kexec/kexec-elf.c index e4d07f4..021bca9 100644 --- a/kexec/kexec-elf.c +++ b/kexec/kexec-elf.c @@ -113,21 +113,21 @@ static int build_mem_elf32_ehdr(const char *buf, off_t len, struct mem_ehdr *ehd } return -1; } - if (elf32_to_cpu(ehdr, lehdr.e_entry) > ULONG_MAX) { + if (elf32_to_cpu(ehdr, lehdr.e_entry) > UINT32_MAX) { /* entry is to large */ if (probe_debug) { fprintf(stderr, "ELF e_entry to large\n"); } return -1; } - if (elf32_to_cpu(ehdr, lehdr.e_phoff) > ULONG_MAX) { + if (elf32_to_cpu(ehdr, lehdr.e_phoff) > UINT32_MAX) { /* phoff is to large */ if (probe_debug) { fprintf(stderr, "ELF e_phoff to large\n"); } return -1; } - if (elf32_to_cpu(ehdr, lehdr.e_shoff) > ULONG_MAX) { + if (elf32_to_cpu(ehdr, lehdr.e_shoff) > UINT32_MAX) { /* shoff is to large */ if (probe_debug) { fprintf(stderr, "ELF e_shoff to large\n"); @@ -146,7 +146,7 @@ static int build_mem_elf32_ehdr(const char *buf, off_t len, struct mem_ehdr *ehd ehdr->e_shstrndx = elf16_to_cpu(ehdr, lehdr.e_shstrndx); if ((ehdr->e_phnum > 0) && - (elf16_to_cpu(ehdr, lehdr.e_phentsize) != sizeof(Elf32_Phdr))) + (elf16_to_cpu(ehdr, lehdr.e_phentsize) != sizeof(Elf32_Phdr))) { /* Invalid program header size */ if (probe_debug) { @@ -185,21 +185,21 @@ static int build_mem_elf64_ehdr(const char *buf, off_t len, struct mem_ehdr *ehd } return -1; } - if (elf32_to_cpu(ehdr, lehdr.e_entry) > ULONG_MAX) { + if (elf32_to_cpu(ehdr, lehdr.e_entry) > UINT32_MAX) { /* entry is to large */ if (probe_debug) { fprintf(stderr, "ELF e_entry to large\n"); } return -1; } - if (elf32_to_cpu(ehdr, lehdr.e_phoff) > ULONG_MAX) { + if (elf32_to_cpu(ehdr, lehdr.e_phoff) > UINT32_MAX) { /* phoff is to large */ if (probe_debug) { fprintf(stderr, "ELF e_phoff to large\n"); } return -1; } - if (elf32_to_cpu(ehdr, lehdr.e_shoff) > ULONG_MAX) { + if (elf32_to_cpu(ehdr, lehdr.e_shoff) > UINT32_MAX) { /* shoff is to large */ if (probe_debug) { fprintf(stderr, "ELF e_shoff to large\n"); @@ -218,7 +218,7 @@ static int build_mem_elf64_ehdr(const char *buf, off_t len, struct mem_ehdr *ehd ehdr->e_shstrndx = elf16_to_cpu(ehdr, lehdr.e_shstrndx); if ((ehdr->e_phnum > 0) && - (elf16_to_cpu(ehdr, lehdr.e_phentsize) != sizeof(Elf64_Phdr))) + (elf16_to_cpu(ehdr, lehdr.e_phentsize) != sizeof(Elf64_Phdr))) { /* Invalid program header size */ if (probe_debug) { @@ -302,7 +302,7 @@ static int build_mem_ehdr(const char *buf, off_t len, struct mem_ehdr *ehdr) return 0; } -static int build_mem_elf32_phdr(const char *buf, off_t len, +static int build_mem_elf32_phdr(const char *buf, off_t len, struct mem_ehdr *ehdr, int idx) { struct mem_phdr *phdr; @@ -312,12 +312,12 @@ static int build_mem_elf32_phdr(const char *buf, off_t len, phdr = &ehdr->e_phdr[idx]; memcpy(&lphdr, pbuf, sizeof(lphdr)); - if ( (elf32_to_cpu(ehdr, lphdr.p_filesz) > ULONG_MAX) || - (elf32_to_cpu(ehdr, lphdr.p_memsz) > ULONG_MAX) || - (elf32_to_cpu(ehdr, lphdr.p_offset) > ULONG_MAX) || - (elf32_to_cpu(ehdr, lphdr.p_paddr) > ULONG_MAX) || - (elf32_to_cpu(ehdr, lphdr.p_vaddr) > ULONG_MAX) || - (elf32_to_cpu(ehdr, lphdr.p_align) > ULONG_MAX)) + if ( (elf32_to_cpu(ehdr, lphdr.p_filesz) > UINT32_MAX) || + (elf32_to_cpu(ehdr, lphdr.p_memsz) > UINT32_MAX) || + (elf32_to_cpu(ehdr, lphdr.p_offset) > UINT32_MAX) || + (elf32_to_cpu(ehdr, lphdr.p_paddr) > UINT32_MAX) || + (elf32_to_cpu(ehdr, lphdr.p_vaddr) > UINT32_MAX) || + (elf32_to_cpu(ehdr, lphdr.p_align) > UINT32_MAX)) { fprintf(stderr, "Program segment size out of range\n"); return -1; @@ -345,12 +345,12 @@ static int build_mem_elf64_phdr(const char *buf, off_t len, phdr = &ehdr->e_phdr[idx]; memcpy(&lphdr, pbuf, sizeof(lphdr)); - if ( (elf64_to_cpu(ehdr, lphdr.p_filesz) > ULONG_MAX) || - (elf64_to_cpu(ehdr, lphdr.p_memsz) > ULONG_MAX) || - (elf64_to_cpu(ehdr, lphdr.p_offset) > ULONG_MAX) || - (elf64_to_cpu(ehdr, lphdr.p_paddr) > ULONG_MAX) || - (elf64_to_cpu(ehdr, lphdr.p_vaddr) > ULONG_MAX) || - (elf64_to_cpu(ehdr, lphdr.p_align) > ULONG_MAX)) + if ( (elf64_to_cpu(ehdr, lphdr.p_filesz) > UINT64_MAX) || + (elf64_to_cpu(ehdr, lphdr.p_memsz) > UINT64_MAX) || + (elf64_to_cpu(ehdr, lphdr.p_offset) > UINT64_MAX) || + (elf64_to_cpu(ehdr, lphdr.p_paddr) > UINT64_MAX) || + (elf64_to_cpu(ehdr, lphdr.p_vaddr) > UINT64_MAX) || + (elf64_to_cpu(ehdr, lphdr.p_align) > UINT64_MAX)) { fprintf(stderr, "Program segment size out of range\n"); return -1; @@ -388,7 +388,7 @@ static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) fprintf(stderr, "Invalid ei_class?\n"); return -1; } - phdr_size *= ehdr->e_phnum; + phdr_size *= ehdr->e_phnum; if (ehdr->e_phoff + phdr_size > len) { /* The program header did not fit in the file buffer */ if (probe_debug) { @@ -396,7 +396,7 @@ static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) } return -1; } - + /* Allocate the e_phdr array */ mem_phdr_size = sizeof(ehdr->e_phdr[0]) * ehdr->e_phnum; ehdr->e_phdr = xmalloc(mem_phdr_size); @@ -440,7 +440,7 @@ static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) return 0; } -static int build_mem_elf32_shdr(const char *buf, off_t len, +static int build_mem_elf32_shdr(const char *buf, off_t len, struct mem_ehdr *ehdr, int idx) { struct mem_shdr *shdr; @@ -451,12 +451,12 @@ static int build_mem_elf32_shdr(const char *buf, off_t len, shdr = &ehdr->e_shdr[idx]; memcpy(&lshdr, sbuf, sizeof(lshdr)); - if ( (elf32_to_cpu(ehdr, lshdr.sh_flags) > ULONG_MAX) || - (elf32_to_cpu(ehdr, lshdr.sh_addr) > ULONG_MAX) || - (elf32_to_cpu(ehdr, lshdr.sh_offset) > ULONG_MAX) || - (elf32_to_cpu(ehdr, lshdr.sh_size) > ULONG_MAX) || - (elf32_to_cpu(ehdr, lshdr.sh_addralign) > ULONG_MAX) || - (elf32_to_cpu(ehdr, lshdr.sh_entsize) > ULONG_MAX)) + if ( (elf32_to_cpu(ehdr, lshdr.sh_flags) > UINT32_MAX) || + (elf32_to_cpu(ehdr, lshdr.sh_addr) > UINT32_MAX) || + (elf32_to_cpu(ehdr, lshdr.sh_offset) > UINT32_MAX) || + (elf32_to_cpu(ehdr, lshdr.sh_size) > UINT32_MAX) || + (elf32_to_cpu(ehdr, lshdr.sh_addralign) > UINT32_MAX) || + (elf32_to_cpu(ehdr, lshdr.sh_entsize) > UINT32_MAX)) { fprintf(stderr, "Program section size out of range\n"); return -1; @@ -510,7 +510,7 @@ static int build_mem_elf32_shdr(const char *buf, off_t len, return 0; } -static int build_mem_elf64_shdr(const char *buf, off_t len, +static int build_mem_elf64_shdr(const char *buf, off_t len, struct mem_ehdr *ehdr, int idx) { struct mem_shdr *shdr; @@ -521,12 +521,12 @@ static int build_mem_elf64_shdr(const char *buf, off_t len, shdr = &ehdr->e_shdr[idx]; memcpy(&lshdr, sbuf, sizeof(lshdr)); - if ( (elf64_to_cpu(ehdr, lshdr.sh_flags) > ULONG_MAX) || - (elf64_to_cpu(ehdr, lshdr.sh_addr) > ULONG_MAX) || - (elf64_to_cpu(ehdr, lshdr.sh_offset) > ULONG_MAX) || - (elf64_to_cpu(ehdr, lshdr.sh_size) > ULONG_MAX) || - (elf64_to_cpu(ehdr, lshdr.sh_addralign) > ULONG_MAX) || - (elf64_to_cpu(ehdr, lshdr.sh_entsize) > ULONG_MAX)) + if ( (elf64_to_cpu(ehdr, lshdr.sh_flags) > UINT64_MAX) || + (elf64_to_cpu(ehdr, lshdr.sh_addr) > UINT64_MAX) || + (elf64_to_cpu(ehdr, lshdr.sh_offset) > UINT64_MAX) || + (elf64_to_cpu(ehdr, lshdr.sh_size) > UINT64_MAX) || + (elf64_to_cpu(ehdr, lshdr.sh_addralign) > UINT64_MAX) || + (elf64_to_cpu(ehdr, lshdr.sh_entsize) > UINT64_MAX)) { fprintf(stderr, "Program section size out of range\n"); return -1; @@ -608,7 +608,7 @@ static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) } return -1; } - + /* Allocate the e_shdr array */ mem_shdr_size = sizeof(ehdr->e_shdr[0]) * ehdr->e_shnum; ehdr->e_shdr = xmalloc(mem_shdr_size); @@ -635,7 +635,7 @@ static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) { /* The section does not fit in the buffer */ if (probe_debug) { - fprintf(stderr, "ELF section %d not in file\n", + fprintf(stderr, "ELF section %d not in file\n", i); } return -1; @@ -653,14 +653,14 @@ static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) return 0; } -static void read_nhdr(const struct mem_ehdr *ehdr, +static void read_nhdr(const struct mem_ehdr *ehdr, ElfNN_Nhdr *hdr, const unsigned char *note) { memcpy(hdr, note, sizeof(*hdr)); hdr->n_namesz = elf32_to_cpu(ehdr, hdr->n_namesz); hdr->n_descsz = elf32_to_cpu(ehdr, hdr->n_descsz); hdr->n_type = elf32_to_cpu(ehdr, hdr->n_type); - + } static int build_mem_notes(const char *buf, off_t len, struct mem_ehdr *ehdr) { @@ -686,7 +686,7 @@ static int build_mem_notes(const char *buf, off_t len, struct mem_ehdr *ehdr) if (!note_start) { return 0; } - + /* Walk through and count the notes */ ehdr->e_notenum = 0; for(note = note_start; note < note_end; note+= note_size) { @@ -708,7 +708,7 @@ static int build_mem_notes(const char *buf, off_t len, struct mem_ehdr *ehdr) note_size += (hdr.n_namesz + 3) & ~3; desc = note + note_size; note_size += (hdr.n_descsz + 3) & ~3; - + if ((hdr.n_namesz != 0) && (name[hdr.n_namesz -1] != '\0')) { die("Note name is not null termiated"); } @@ -716,7 +716,7 @@ static int build_mem_notes(const char *buf, off_t len, struct mem_ehdr *ehdr) ehdr->e_note[i].n_name = name; ehdr->e_note[i].n_desc = desc; ehdr->e_note[i].n_descsz = hdr.n_descsz; - + } return 0; } |