From: OpenOCD-Gerrit <ope...@us...> - 2021-05-01 12:37:09
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 9206bd243b0b594821ca96b37517b2e3de80dc39 (commit) via 11d918d9c1f7cb637a525a92521b747d2d4c840f (commit) from a60979b069b5964639d87ce268a37078c0fb57bb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9206bd243b0b594821ca96b37517b2e3de80dc39 Author: Florian Meister <flo...@ad...> Date: Wed Jun 5 10:19:52 2019 +0200 target/image: allow loading of 64-bit ELF files Change-Id: I9b88edacf5ffcc3c1caeab8c426693de0d92a695 Signed-off-by: Florian Meister <flo...@ad...> Signed-off-by: Christian Hoff <chr...@ad...> Reviewed-on: http://openocd.zylin.com/5204 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> Reviewed-by: Ooi, Cinly <cin...@in...> Reviewed-by: Tomas Vanek <va...@fb...> diff --git a/configure.ac b/configure.ac index 5c7dab570..979bb161b 100644 --- a/configure.ac +++ b/configure.ac @@ -49,6 +49,9 @@ AC_SEARCH_LIBS([openpty], [util]) AC_CHECK_HEADERS([sys/socket.h]) AC_CHECK_HEADERS([elf.h]) +AC_EGREP_HEADER(Elf64_Ehdr, [elf.h], [ + AC_DEFINE([HAVE_ELF64], [1], [Define to 1 if the system has the type `Elf64_Ehdr'.]) +]) AC_CHECK_HEADERS([dirent.h]) AC_CHECK_HEADERS([fcntl.h]) AC_CHECK_HEADERS([malloc.h]) diff --git a/src/helper/replacements.h b/src/helper/replacements.h index ac5009549..fff2dde0e 100644 --- a/src/helper/replacements.h +++ b/src/helper/replacements.h @@ -246,8 +246,10 @@ typedef uint32_t Elf32_Word; typedef uint32_t Elf32_Size; typedef Elf32_Off Elf32_Hashelt; +#define EI_NIDENT 16 + typedef struct { - unsigned char e_ident[16]; /* Magic number and other info */ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ Elf32_Half e_type; /* Object file type */ Elf32_Half e_machine; /* Architecture */ Elf32_Word e_version; /* Object file version */ @@ -289,6 +291,44 @@ typedef struct { #endif /* HAVE_ELF_H */ +#ifndef HAVE_ELF64 + +typedef uint64_t Elf64_Addr; +typedef uint16_t Elf64_Half; +typedef uint64_t Elf64_Off; +typedef uint32_t Elf64_Word; +typedef uint64_t Elf64_Xword; + +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + +typedef struct { + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + +#endif /* HAVE_ELF64 */ + #if defined HAVE_LIBUSB1 && !defined HAVE_LIBUSB_ERROR_NAME const char *libusb_error_name(int error_code); #endif /* defined HAVE_LIBUSB1 && !defined HAVE_LIBUSB_ERROR_NAME */ diff --git a/src/target/image.c b/src/target/image.c index e63cd0f9c..9608375a5 100644 --- a/src/target/image.c +++ b/src/target/image.c @@ -11,6 +11,9 @@ * Copyright (C) 2009 by Franck Hereson * * fra...@se... * * * + * Copyright (C) 2018 by Advantest * + * flo...@ad... * + * * * 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 * * the Free Software Foundation; either version 2 of the License, or * @@ -42,6 +45,10 @@ ((elf->endianness == ELFDATA2LSB) ? \ le_to_h_u32((uint8_t *)&field) : be_to_h_u32((uint8_t *)&field)) +#define field64(elf, field) \ + ((elf->endianness == ELFDATA2LSB) ? \ + le_to_h_u64((uint8_t *)&field) : be_to_h_u64((uint8_t *)&field)) + static int autodetect_image_type(struct image *image, const char *url) { int retval; @@ -49,7 +56,7 @@ static int autodetect_image_type(struct image *image, const char *url) size_t read_bytes; uint8_t buffer[9]; - /* read the first 4 bytes of image */ + /* read the first 9 bytes of image */ retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY); if (retval != ERROR_OK) return retval; @@ -350,22 +357,29 @@ static int image_ihex_buffer_complete(struct image *image) return retval; } -static int image_elf_read_headers(struct image *image) +static int image_elf32_read_headers(struct image *image) { struct image_elf *elf = image->type_private; size_t read_bytes; uint32_t i, j; int retval; - uint32_t nload, load_to_vaddr = 0; + uint32_t nload; + bool load_to_vaddr = false; + + retval = fileio_seek(elf->fileio, 0); + if (retval != ERROR_OK) { + LOG_ERROR("cannot seek to ELF file header, read failed"); + return retval; + } - elf->header = malloc(sizeof(Elf32_Ehdr)); + elf->header32 = malloc(sizeof(Elf32_Ehdr)); - if (elf->header == NULL) { - LOG_ERROR("insufficient memory to perform operation "); + if (elf->header32 == NULL) { + LOG_ERROR("insufficient memory to perform operation"); return ERROR_FILEIO_OPERATION_FAILED; } - retval = fileio_read(elf->fileio, sizeof(Elf32_Ehdr), (uint8_t *)elf->header, &read_bytes); + retval = fileio_read(elf->fileio, sizeof(Elf32_Ehdr), (uint8_t *)elf->header32, &read_bytes); if (retval != ERROR_OK) { LOG_ERROR("cannot read ELF file header, read failed"); return ERROR_FILEIO_OPERATION_FAILED; @@ -375,47 +389,153 @@ static int image_elf_read_headers(struct image *image) return ERROR_FILEIO_OPERATION_FAILED; } - if (strncmp((char *)elf->header->e_ident, ELFMAG, SELFMAG) != 0) { - LOG_ERROR("invalid ELF file, bad magic number"); + elf->segment_count = field16(elf, elf->header32->e_phnum); + if (elf->segment_count == 0) { + LOG_ERROR("invalid ELF file, no program headers"); return ERROR_IMAGE_FORMAT_ERROR; } - if (elf->header->e_ident[EI_CLASS] != ELFCLASS32) { - LOG_ERROR("invalid ELF file, only 32bits files are supported"); - return ERROR_IMAGE_FORMAT_ERROR; + + retval = fileio_seek(elf->fileio, field32(elf, elf->header32->e_phoff)); + if (retval != ERROR_OK) { + LOG_ERROR("cannot seek to ELF program header table, read failed"); + return retval; } - elf->endianness = elf->header->e_ident[EI_DATA]; - if ((elf->endianness != ELFDATA2LSB) - && (elf->endianness != ELFDATA2MSB)) { - LOG_ERROR("invalid ELF file, unknown endianness setting"); - return ERROR_IMAGE_FORMAT_ERROR; + elf->segments32 = malloc(elf->segment_count*sizeof(Elf32_Phdr)); + if (elf->segments32 == NULL) { + LOG_ERROR("insufficient memory to perform operation"); + return ERROR_FILEIO_OPERATION_FAILED; + } + + retval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf32_Phdr), + (uint8_t *)elf->segments32, &read_bytes); + if (retval != ERROR_OK) { + LOG_ERROR("cannot read ELF segment headers, read failed"); + return retval; + } + if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr)) { + LOG_ERROR("cannot read ELF segment headers, only partially read"); + return ERROR_FILEIO_OPERATION_FAILED; + } + + /* count useful segments (loadable), ignore BSS section */ + image->num_sections = 0; + for (i = 0; i < elf->segment_count; i++) + if ((field32(elf, + elf->segments32[i].p_type) == PT_LOAD) && + (field32(elf, elf->segments32[i].p_filesz) != 0)) + image->num_sections++; + + assert(image->num_sections > 0); + + /** + * some ELF linkers produce binaries with *all* the program header + * p_paddr fields zero (there can be however one loadable segment + * that has valid physical address 0x0). + * If we have such a binary with more than + * one PT_LOAD header, then use p_vaddr instead of p_paddr + * (ARM ELF standard demands p_paddr = 0 anyway, and BFD + * library uses this approach to workaround zero-initialized p_paddrs + * when obtaining lma - look at elf.c of BDF) + */ + for (nload = 0, i = 0; i < elf->segment_count; i++) + if (elf->segments32[i].p_paddr != 0) + break; + else if ((field32(elf, + elf->segments32[i].p_type) == PT_LOAD) && + (field32(elf, elf->segments32[i].p_memsz) != 0)) + ++nload; + + if (i >= elf->segment_count && nload > 1) + load_to_vaddr = true; + + /* alloc and fill sections array with loadable segments */ + image->sections = malloc(image->num_sections * sizeof(struct imagesection)); + if (image->sections == NULL) { + LOG_ERROR("insufficient memory to perform operation"); + return ERROR_FILEIO_OPERATION_FAILED; + } + + for (i = 0, j = 0; i < elf->segment_count; i++) { + if ((field32(elf, + elf->segments32[i].p_type) == PT_LOAD) && + (field32(elf, elf->segments32[i].p_filesz) != 0)) { + image->sections[j].size = field32(elf, elf->segments32[i].p_filesz); + if (load_to_vaddr) + image->sections[j].base_address = field32(elf, + elf->segments32[i].p_vaddr); + else + image->sections[j].base_address = field32(elf, + elf->segments32[i].p_paddr); + image->sections[j].private = &elf->segments32[i]; + image->sections[j].flags = field32(elf, elf->segments32[i].p_flags); + j++; + } + } + + image->start_address_set = true; + image->start_address = field32(elf, elf->header32->e_entry); + + return ERROR_OK; +} + +static int image_elf64_read_headers(struct image *image) +{ + struct image_elf *elf = image->type_private; + size_t read_bytes; + uint32_t i, j; + int retval; + uint32_t nload; + bool load_to_vaddr = false; + + retval = fileio_seek(elf->fileio, 0); + if (retval != ERROR_OK) { + LOG_ERROR("cannot seek to ELF file header, read failed"); + return retval; + } + + elf->header64 = malloc(sizeof(Elf64_Ehdr)); + + if (elf->header64 == NULL) { + LOG_ERROR("insufficient memory to perform operation"); + return ERROR_FILEIO_OPERATION_FAILED; + } + + retval = fileio_read(elf->fileio, sizeof(Elf64_Ehdr), (uint8_t *)elf->header64, &read_bytes); + if (retval != ERROR_OK) { + LOG_ERROR("cannot read ELF file header, read failed"); + return ERROR_FILEIO_OPERATION_FAILED; + } + if (read_bytes != sizeof(Elf64_Ehdr)) { + LOG_ERROR("cannot read ELF file header, only partially read"); + return ERROR_FILEIO_OPERATION_FAILED; } - elf->segment_count = field16(elf, elf->header->e_phnum); + elf->segment_count = field16(elf, elf->header64->e_phnum); if (elf->segment_count == 0) { LOG_ERROR("invalid ELF file, no program headers"); return ERROR_IMAGE_FORMAT_ERROR; } - retval = fileio_seek(elf->fileio, field32(elf, elf->header->e_phoff)); + retval = fileio_seek(elf->fileio, field64(elf, elf->header64->e_phoff)); if (retval != ERROR_OK) { LOG_ERROR("cannot seek to ELF program header table, read failed"); return retval; } - elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr)); - if (elf->segments == NULL) { - LOG_ERROR("insufficient memory to perform operation "); + elf->segments64 = malloc(elf->segment_count*sizeof(Elf64_Phdr)); + if (elf->segments64 == NULL) { + LOG_ERROR("insufficient memory to perform operation"); return ERROR_FILEIO_OPERATION_FAILED; } - retval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf32_Phdr), - (uint8_t *)elf->segments, &read_bytes); + retval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf64_Phdr), + (uint8_t *)elf->segments64, &read_bytes); if (retval != ERROR_OK) { LOG_ERROR("cannot read ELF segment headers, read failed"); return retval; } - if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr)) { + if (read_bytes != elf->segment_count*sizeof(Elf64_Phdr)) { LOG_ERROR("cannot read ELF segment headers, only partially read"); return ERROR_FILEIO_OPERATION_FAILED; } @@ -424,8 +544,8 @@ static int image_elf_read_headers(struct image *image) image->num_sections = 0; for (i = 0; i < elf->segment_count; i++) if ((field32(elf, - elf->segments[i].p_type) == PT_LOAD) && - (field32(elf, elf->segments[i].p_filesz) != 0)) + elf->segments64[i].p_type) == PT_LOAD) && + (field64(elf, elf->segments64[i].p_filesz) != 0)) image->num_sections++; assert(image->num_sections > 0); @@ -441,44 +561,95 @@ static int image_elf_read_headers(struct image *image) * when obtaining lma - look at elf.c of BDF) */ for (nload = 0, i = 0; i < elf->segment_count; i++) - if (elf->segments[i].p_paddr != 0) + if (elf->segments64[i].p_paddr != 0) break; else if ((field32(elf, - elf->segments[i].p_type) == PT_LOAD) && - (field32(elf, elf->segments[i].p_memsz) != 0)) + elf->segments64[i].p_type) == PT_LOAD) && + (field64(elf, elf->segments64[i].p_memsz) != 0)) ++nload; if (i >= elf->segment_count && nload > 1) - load_to_vaddr = 1; + load_to_vaddr = true; /* alloc and fill sections array with loadable segments */ image->sections = malloc(image->num_sections * sizeof(struct imagesection)); + if (image->sections == NULL) { + LOG_ERROR("insufficient memory to perform operation"); + return ERROR_FILEIO_OPERATION_FAILED; + } + for (i = 0, j = 0; i < elf->segment_count; i++) { if ((field32(elf, - elf->segments[i].p_type) == PT_LOAD) && - (field32(elf, elf->segments[i].p_filesz) != 0)) { - image->sections[j].size = field32(elf, elf->segments[i].p_filesz); + elf->segments64[i].p_type) == PT_LOAD) && + (field64(elf, elf->segments64[i].p_filesz) != 0)) { + image->sections[j].size = field64(elf, elf->segments64[i].p_filesz); if (load_to_vaddr) - image->sections[j].base_address = field32(elf, - elf->segments[i].p_vaddr); + image->sections[j].base_address = field64(elf, + elf->segments64[i].p_vaddr); else - image->sections[j].base_address = field32(elf, - elf->segments[i].p_paddr); - image->sections[j].private = &elf->segments[i]; - image->sections[j].flags = field32(elf, elf->segments[i].p_flags); + image->sections[j].base_address = field64(elf, + elf->segments64[i].p_paddr); + image->sections[j].private = &elf->segments64[i]; + image->sections[j].flags = field32(elf, elf->segments64[i].p_flags); j++; } } image->start_address_set = true; - image->start_address = field32(elf, elf->header->e_entry); + image->start_address = field64(elf, elf->header64->e_entry); return ERROR_OK; } -static int image_elf_read_section(struct image *image, +static int image_elf_read_headers(struct image *image) +{ + struct image_elf *elf = image->type_private; + size_t read_bytes; + unsigned char e_ident[EI_NIDENT]; + int retval; + + retval = fileio_read(elf->fileio, EI_NIDENT, e_ident, &read_bytes); + if (retval != ERROR_OK) { + LOG_ERROR("cannot read ELF file header, read failed"); + return ERROR_FILEIO_OPERATION_FAILED; + } + if (read_bytes != EI_NIDENT) { + LOG_ERROR("cannot read ELF file header, only partially read"); + return ERROR_FILEIO_OPERATION_FAILED; + } + + if (strncmp((char *)e_ident, ELFMAG, SELFMAG) != 0) { + LOG_ERROR("invalid ELF file, bad magic number"); + return ERROR_IMAGE_FORMAT_ERROR; + } + + elf->endianness = e_ident[EI_DATA]; + if ((elf->endianness != ELFDATA2LSB) + && (elf->endianness != ELFDATA2MSB)) { + LOG_ERROR("invalid ELF file, unknown endianness setting"); + return ERROR_IMAGE_FORMAT_ERROR; + } + + switch (e_ident[EI_CLASS]) { + case ELFCLASS32: + LOG_DEBUG("ELF32 image detected."); + elf->is_64_bit = false; + return image_elf32_read_headers(image); + + case ELFCLASS64: + LOG_DEBUG("ELF64 image detected."); + elf->is_64_bit = true; + return image_elf64_read_headers(image); + + default: + LOG_ERROR("invalid ELF file, only 32/64 bit ELF files are supported"); + return ERROR_IMAGE_FORMAT_ERROR; + } +} + +static int image_elf32_read_section(struct image *image, int section, - uint32_t offset, + target_addr_t offset, uint32_t size, uint8_t *buffer, size_t *size_read) @@ -490,13 +661,13 @@ static int image_elf_read_section(struct image *image, *size_read = 0; - LOG_DEBUG("load segment %d at 0x%" PRIx32 " (sz = 0x%" PRIx32 ")", section, offset, size); + LOG_DEBUG("load segment %d at 0x%" TARGET_PRIxADDR " (sz = 0x%" PRIx32 ")", section, offset, size); /* read initialized data in current segment if any */ if (offset < field32(elf, segment->p_filesz)) { /* maximal size present in file for the current segment */ read_size = MIN(size, field32(elf, segment->p_filesz) - offset); - LOG_DEBUG("read elf: size = 0x%zx at 0x%" PRIx32 "", read_size, + LOG_DEBUG("read elf: size = 0x%zx at 0x%" TARGET_PRIxADDR "", read_size, field32(elf, segment->p_offset) + offset); /* read initialized area of the segment */ retval = fileio_seek(elf->fileio, field32(elf, segment->p_offset) + offset); @@ -519,6 +690,64 @@ static int image_elf_read_section(struct image *image, return ERROR_OK; } +static int image_elf64_read_section(struct image *image, + int section, + target_addr_t offset, + uint32_t size, + uint8_t *buffer, + size_t *size_read) +{ + struct image_elf *elf = image->type_private; + Elf64_Phdr *segment = (Elf64_Phdr *)image->sections[section].private; + size_t read_size, really_read; + int retval; + + *size_read = 0; + + LOG_DEBUG("load segment %d at 0x%" TARGET_PRIxADDR " (sz = 0x%" PRIx32 ")", section, offset, size); + + /* read initialized data in current segment if any */ + if (offset < field64(elf, segment->p_filesz)) { + /* maximal size present in file for the current segment */ + read_size = MIN(size, field64(elf, segment->p_filesz) - offset); + LOG_DEBUG("read elf: size = 0x%zx at 0x%" TARGET_PRIxADDR "", read_size, + field64(elf, segment->p_offset) + offset); + /* read initialized area of the segment */ + retval = fileio_seek(elf->fileio, field64(elf, segment->p_offset) + offset); + if (retval != ERROR_OK) { + LOG_ERROR("cannot find ELF segment content, seek failed"); + return retval; + } + retval = fileio_read(elf->fileio, read_size, buffer, &really_read); + if (retval != ERROR_OK) { + LOG_ERROR("cannot read ELF segment content, read failed"); + return retval; + } + size -= read_size; + *size_read += read_size; + /* need more data ? */ + if (!size) + return ERROR_OK; + } + + return ERROR_OK; +} + +static int image_elf_read_section(struct image *image, + int section, + target_addr_t offset, + uint32_t size, + uint8_t *buffer, + size_t *size_read) +{ + struct image_elf *elf = image->type_private; + + if (elf->is_64_bit) + return image_elf64_read_section(image, section, offset, size, buffer, size_read); + else + return image_elf32_read_section(image, section, offset, size, buffer, size_read); +} + static int image_mot_buffer_complete_inner(struct image *image, char *lpszLine, struct imagesection *section) @@ -840,7 +1069,7 @@ int image_open(struct image *image, const char *url, const char *type_string) int image_read_section(struct image *image, int section, - uint32_t offset, + target_addr_t offset, uint32_t size, uint8_t *buffer, size_t *size_read) @@ -850,7 +1079,7 @@ int image_read_section(struct image *image, /* don't read past the end of a section */ if (offset + size > image->sections[section].size) { LOG_DEBUG( - "read past end of section: 0x%8.8" PRIx32 " + 0x%8.8" PRIx32 " > 0x%8.8" PRIx32 "", + "read past end of section: 0x%8.8" TARGET_PRIxADDR " + 0x%8.8" PRIx32 " > 0x%8.8" PRIx32 "", offset, size, image->sections[section].size); @@ -878,9 +1107,9 @@ int image_read_section(struct image *image, *size_read = size; return ERROR_OK; - } else if (image->type == IMAGE_ELF) + } else if (image->type == IMAGE_ELF) { return image_elf_read_section(image, section, offset, size, buffer, size_read); - else if (image->type == IMAGE_MEMORY) { + } else if (image->type == IMAGE_MEMORY) { struct image_memory *image_memory = image->type_private; uint32_t address = image->sections[section].base_address + offset; @@ -933,7 +1162,7 @@ int image_read_section(struct image *image, return ERROR_OK; } -int image_add_section(struct image *image, uint32_t base, uint32_t size, int flags, uint8_t const *data) +int image_add_section(struct image *image, target_addr_t base, uint32_t size, int flags, uint8_t const *data) { struct imagesection *section; @@ -988,11 +1217,19 @@ void image_close(struct image *image) fileio_close(image_elf->fileio); - free(image_elf->header); - image_elf->header = NULL; + if (image_elf->is_64_bit) { + free(image_elf->header64); + image_elf->header64 = NULL; - free(image_elf->segments); - image_elf->segments = NULL; + free(image_elf->segments64); + image_elf->segments64 = NULL; + } else { + free(image_elf->header32); + image_elf->header32 = NULL; + + free(image_elf->segments32); + image_elf->segments32 = NULL; + } } else if (image->type == IMAGE_MEMORY) { struct image_memory *image_memory = image->type_private; diff --git a/src/target/image.h b/src/target/image.h index 53c27d812..c8d00d1d7 100644 --- a/src/target/image.h +++ b/src/target/image.h @@ -8,6 +8,9 @@ * Copyright (C) 2008 by Spencer Oliver * * sp...@sp... * * * + * Copyright (C) 2018 by Advantest * + * flo...@ad... * + * * * 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 * * the Free Software Foundation; either version 2 of the License, or * @@ -80,8 +83,15 @@ struct image_memory { struct image_elf { struct fileio *fileio; - Elf32_Ehdr *header; - Elf32_Phdr *segments; + bool is_64_bit; + union { + Elf32_Ehdr *header32; + Elf64_Ehdr *header64; + }; + union { + Elf32_Phdr *segments32; + Elf64_Phdr *segments64; + }; uint32_t segment_count; uint8_t endianness; }; @@ -92,11 +102,11 @@ struct image_mot { }; int image_open(struct image *image, const char *url, const char *type_string); -int image_read_section(struct image *image, int section, uint32_t offset, +int image_read_section(struct image *image, int section, target_addr_t offset, uint32_t size, uint8_t *buffer, size_t *size_read); void image_close(struct image *image); -int image_add_section(struct image *image, uint32_t base, uint32_t size, +int image_add_section(struct image *image, target_addr_t base, uint32_t size, int flags, uint8_t const *data); int image_calculate_checksum(const uint8_t *buffer, uint32_t nbytes, commit 11d918d9c1f7cb637a525a92521b747d2d4c840f Author: Antonio Borneo <bor...@gm...> Date: Wed Apr 14 23:44:57 2021 +0200 libusb: don't use typedef's Libusb defines both the struct and a typedef to the struct using the same struct name. It's then possible to use either 'struct x' and 'x'. E.g.: typedef struct libusb_device libusb_device; OpenOCD is not consistent and uses a mix of 'struct x' and 'x'. To make OpenOCD code uniform, stick at project's coding style and use 'struct x' in place of the typedef'd name. Change-Id: I901458b680e42830d3f371e47997157f91b7f675 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: http://openocd.zylin.com/6165 Tested-by: jenkins Reviewed-by: Jonathan McDowell <noo...@ea...> Reviewed-by: Marc Schink <de...@za...> Reviewed-by: Tomas Vanek <va...@fb...> diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index 7688aeaab..0c219805f 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -349,8 +349,8 @@ static void aice_unpack_dthmb(uint8_t *cmd_ack_code, uint8_t *target_id, /* calls the given usb_bulk_* function, allowing for the data to * trickle in with some timeouts */ static int usb_bulk_with_retries( - int (*f)(libusb_device_handle *, int, char *, int, int, int *), - libusb_device_handle *dev, int ep, + int (*f)(struct libusb_device_handle *, int, char *, int, int, int *), + struct libusb_device_handle *dev, int ep, char *bytes, int size, int timeout, int *transferred) { int tries = 3, count = 0; @@ -369,7 +369,7 @@ static int usb_bulk_with_retries( return ERROR_OK; } -static int wrap_usb_bulk_write(libusb_device_handle *dev, int ep, +static int wrap_usb_bulk_write(struct libusb_device_handle *dev, int ep, char *buff, int size, int timeout, int *transferred) { @@ -379,7 +379,7 @@ static int wrap_usb_bulk_write(libusb_device_handle *dev, int ep, return 0; } -static inline int usb_bulk_write_ex(libusb_device_handle *dev, int ep, +static inline int usb_bulk_write_ex(struct libusb_device_handle *dev, int ep, char *bytes, int size, int timeout) { int tr = 0; diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c index c9ee53d2e..f535119f3 100644 --- a/src/jtag/drivers/cmsis_dap_usb_bulk.c +++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c @@ -41,8 +41,8 @@ #include "cmsis_dap.h" struct cmsis_dap_backend_data { - libusb_context *usb_ctx; - libusb_device_handle *dev_handle; + struct libusb_context *usb_ctx; + struct libusb_device_handle *dev_handle; unsigned int ep_out; unsigned int ep_in; int interface; @@ -56,8 +56,8 @@ static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz); static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], char *serial) { int err; - libusb_context *ctx; - libusb_device **device_list; + struct libusb_context *ctx; + struct libusb_device **device_list; err = libusb_init(&ctx); if (err) { @@ -73,7 +73,7 @@ static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p } for (int i = 0; i < num_devices; i++) { - libusb_device *dev = device_list[i]; + struct libusb_device *dev = device_list[i]; struct libusb_device_descriptor dev_desc; err = libusb_get_device_descriptor(dev, &dev_desc); @@ -101,7 +101,7 @@ static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p if (dev_desc.iSerialNumber == 0 && serial && serial[0]) continue; - libusb_device_handle *dev_handle = NULL; + struct libusb_device_handle *dev_handle = NULL; err = libusb_open(dev, &dev_handle); if (err) { /* It's to be expected that most USB devices can't be opened diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c index 184882abc..f0122d534 100644 --- a/src/jtag/drivers/libusb_helper.c +++ b/src/jtag/drivers/libusb_helper.c @@ -31,7 +31,7 @@ #define MAX_USB_PORTS 7 static struct libusb_context *jtag_libusb_context; /**< Libusb context **/ -static libusb_device **devs; /**< The usb device list **/ +static struct libusb_device **devs; /**< The usb device list **/ static int jtag_libusb_error(int err) { @@ -71,7 +71,7 @@ static bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc, } #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS -static bool jtag_libusb_location_equal(libusb_device *device) +static bool jtag_libusb_location_equal(struct libusb_device *device) { uint8_t port_path[MAX_USB_PORTS]; uint8_t dev_bus; @@ -88,7 +88,7 @@ static bool jtag_libusb_location_equal(libusb_device *device) return jtag_usb_location_equal(dev_bus, port_path, path_len); } #else /* HAVE_LIBUSB_GET_PORT_NUMBERS */ -static bool jtag_libusb_location_equal(libusb_device *device) +static bool jtag_libusb_location_equal(struct libusb_device *device) { return true; } @@ -96,7 +96,7 @@ static bool jtag_libusb_location_equal(libusb_device *device) /* Returns true if the string descriptor indexed by str_index in device matches string */ -static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_index, +static bool string_descriptor_equal(struct libusb_device_handle *device, uint8_t str_index, const char *string) { int retval; @@ -123,7 +123,7 @@ static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_in return matched; } -static bool jtag_libusb_match_serial(libusb_device_handle *device, +static bool jtag_libusb_match_serial(struct libusb_device_handle *device, struct libusb_device_descriptor *dev_desc, const char *serial, adapter_get_alternate_serial_fn adapter_get_alternate_serial) { diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h index 74bb23c52..fa7d06e28 100644 --- a/src/jtag/drivers/libusb_helper.h +++ b/src/jtag/drivers/libusb_helper.h @@ -24,7 +24,7 @@ /* this callback should return a non NULL value only when the serial could not * be retrieved by the standard 'libusb_get_string_descriptor_ascii' */ -typedef char * (*adapter_get_alternate_serial_fn)(libusb_device_handle *device, +typedef char * (*adapter_get_alternate_serial_fn)(struct libusb_device_handle *device, struct libusb_device_descriptor *dev_desc); int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c index fe8b6b82c..7cda3b816 100644 --- a/src/jtag/drivers/mpsse.c +++ b/src/jtag/drivers/mpsse.c @@ -62,8 +62,8 @@ #define SIO_RESET_PURGE_TX 2 struct mpsse_ctx { - libusb_context *usb_ctx; - libusb_device_handle *usb_dev; + struct libusb_context *usb_ctx; + struct libusb_device_handle *usb_dev; unsigned int usb_write_timeout; unsigned int usb_read_timeout; uint8_t in_ep; @@ -85,7 +85,7 @@ struct mpsse_ctx { }; /* Returns true if the string descriptor indexed by str_index in device matches string */ -static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_index, +static bool string_descriptor_equal(struct libusb_device_handle *device, uint8_t str_index, const char *string) { int retval; @@ -99,7 +99,7 @@ static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_in return strncmp(string, desc_string, sizeof(desc_string)) == 0; } -static bool device_location_equal(libusb_device *device, const char *location) +static bool device_location_equal(struct libusb_device *device, const char *location) { bool result = false; #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS @@ -161,7 +161,7 @@ static bool device_location_equal(libusb_device *device, const char *location) static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, const uint16_t *pid, const char *product, const char *serial, const char *location) { - libusb_device **list; + struct libusb_device **list; struct libusb_device_descriptor desc; struct libusb_config_descriptor *config0; int err; @@ -171,7 +171,7 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con LOG_ERROR("libusb_get_device_list() failed with %s", libusb_error_name(cnt)); for (ssize_t i = 0; i < cnt; i++) { - libusb_device *device = list[i]; + struct libusb_device *device = list[i]; err = libusb_get_device_descriptor(device, &desc); if (err != LIBUSB_SUCCESS) { diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c index 006e7c5c7..ad629ca68 100644 --- a/src/jtag/drivers/rlink.c +++ b/src/jtag/drivers/rlink.c @@ -96,14 +96,14 @@ #define ST7_PC_TDO ST7_PC_IO9 #define ST7_PA_DBGACK ST7_PA_IO10 -static libusb_device_handle *pHDev; +static struct libusb_device_handle *pHDev; /* * ep1 commands are up to USB_EP1OUT_SIZE bytes in length. * This function takes care of zeroing the unused bytes before sending the packet. * Any reply packet is not handled by this function. */ -static int ep1_generic_commandl(libusb_device_handle *pHDev_param, size_t length, ...) +static int ep1_generic_commandl(struct libusb_device_handle *pHDev_param, size_t length, ...) { uint8_t usb_buffer[USB_EP1OUT_SIZE]; uint8_t *usb_buffer_p; @@ -143,7 +143,7 @@ static int ep1_generic_commandl(libusb_device_handle *pHDev_param, size_t length #if 0 static ssize_t ep1_memory_read( - libusb_device_handle *pHDev_param, uint16_t addr, + struct libusb_device_handle *pHDev_param, uint16_t addr, size_t length, uint8_t *buffer) { uint8_t usb_buffer[USB_EP1OUT_SIZE]; @@ -202,7 +202,7 @@ static ssize_t ep1_memory_read( } #endif -static ssize_t ep1_memory_write(libusb_device_handle *pHDev_param, uint16_t addr, +static ssize_t ep1_memory_write(struct libusb_device_handle *pHDev_param, uint16_t addr, size_t length, uint8_t const *buffer) { uint8_t usb_buffer[USB_EP1OUT_SIZE]; @@ -258,7 +258,7 @@ static ssize_t ep1_memory_write(libusb_device_handle *pHDev_param, uint16_t addr #if 0 -static ssize_t ep1_memory_writel(libusb_device_handle *pHDev_param, uint16_t addr, +static ssize_t ep1_memory_writel(struct libusb_device_handle *pHDev_param, uint16_t addr, size_t length, ...) { uint8_t buffer[USB_EP1OUT_SIZE - 4]; @@ -295,7 +295,7 @@ static ssize_t ep1_memory_writel(libusb_device_handle *pHDev_param, uint16_t add static uint8_t dtc_entry_download; /* The buffer is specially formatted to represent a valid image to load into the DTC. */ -static int dtc_load_from_buffer(libusb_device_handle *pHDev_param, const uint8_t *buffer, +static int dtc_load_from_buffer(struct libusb_device_handle *pHDev_param, const uint8_t *buffer, size_t length) { struct header_s { @@ -469,7 +469,7 @@ static int dtc_start_download(void) } static int dtc_run_download( - libusb_device_handle *pHDev_param, + struct libusb_device_handle *pHDev_param, uint8_t *command_buffer, int command_buffer_size, uint8_t *reply_buffer, diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index a5f8bdff1..a088a83ee 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -3016,7 +3016,7 @@ static int stlink_close(void *handle) * based on the length (0x1a = 26) we could easily decide if we have to fixup the serial * and then we have just to convert the raw data into printable characters using sprintf */ -static char *stlink_usb_get_alternate_serial(libusb_device_handle *device, +static char *stlink_usb_get_alternate_serial(struct libusb_device_handle *device, struct libusb_device_descriptor *dev_desc) { int usb_retval; diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c index ccc023fb8..096e254fa 100644 --- a/src/jtag/drivers/ulink.c +++ b/src/jtag/drivers/ulink.c @@ -266,7 +266,7 @@ static int ulink_usb_open(struct ulink **device) { ssize_t num_devices, i; bool found; - libusb_device **usb_devices; + struct libusb_device **usb_devices; struct libusb_device_descriptor usb_desc; struct libusb_device_handle *usb_device_handle; diff --git a/src/jtag/drivers/versaloon/versaloon.c b/src/jtag/drivers/versaloon/versaloon.c index b51779500..194a3751c 100644 --- a/src/jtag/drivers/versaloon/versaloon.c +++ b/src/jtag/drivers/versaloon/versaloon.c @@ -35,7 +35,7 @@ uint16_t versaloon_buf_size; struct versaloon_pending_t versaloon_pending[VERSALOON_MAX_PENDING_NUMBER]; uint16_t versaloon_pending_idx; -libusb_device_handle *versaloon_usb_device_handle; +struct libusb_device_handle *versaloon_usb_device_handle; static uint32_t versaloon_usb_to = VERSALOON_TIMEOUT; static RESULT versaloon_init(void); diff --git a/src/jtag/drivers/versaloon/versaloon.h b/src/jtag/drivers/versaloon/versaloon.h index 9d92bcaa1..fcf223574 100644 --- a/src/jtag/drivers/versaloon/versaloon.h +++ b/src/jtag/drivers/versaloon/versaloon.h @@ -107,6 +107,6 @@ struct versaloon_interface_t { }; extern struct versaloon_interface_t versaloon_interface; -extern libusb_device_handle *versaloon_usb_device_handle; +extern struct libusb_device_handle *versaloon_usb_device_handle; #endif /* OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H */ diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index 9aaed36b7..f08fa9165 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -812,7 +812,7 @@ static int vsllink_check_usb_strings( static int vsllink_usb_open(struct vsllink *vsllink) { ssize_t num_devices, i; - libusb_device **usb_devices; + struct libusb_device **usb_devices; struct libusb_device_descriptor usb_desc; struct libusb_device_handle *usb_device_handle; int retval; @@ -823,7 +823,7 @@ static int vsllink_usb_open(struct vsllink *vsllink) return ERROR_FAIL; for (i = 0; i < num_devices; i++) { - libusb_device *device = usb_devices[i]; + struct libusb_device *device = usb_devices[i]; retval = libusb_get_device_descriptor(device, &usb_desc); if (retval != 0) diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index df1ab6529..c49280743 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -213,8 +213,8 @@ struct scan_result { struct xds110_info { /* USB connection handles and data buffers */ - libusb_context *ctx; - libusb_device_handle *dev; + struct libusb_context *ctx; + struct libusb_device_handle *dev; unsigned char read_payload[USB_PAYLOAD_SIZE]; unsigned char write_packet[3]; unsigned char write_payload[USB_PAYLOAD_SIZE]; @@ -317,9 +317,9 @@ static inline uint16_t xds110_get_u16(uint8_t *buffer) static bool usb_connect(void) { - libusb_context *ctx = NULL; - libusb_device **list = NULL; - libusb_device_handle *dev = NULL; + struct libusb_context *ctx = NULL; + struct libusb_device **list = NULL; + struct libusb_device_handle *dev = NULL; struct libusb_device_descriptor desc; ----------------------------------------------------------------------- Summary of changes: configure.ac | 3 + src/helper/replacements.h | 42 +++- src/jtag/aice/aice_usb.c | 8 +- src/jtag/drivers/cmsis_dap_usb_bulk.c | 12 +- src/jtag/drivers/libusb_helper.c | 10 +- src/jtag/drivers/libusb_helper.h | 2 +- src/jtag/drivers/mpsse.c | 12 +- src/jtag/drivers/rlink.c | 14 +- src/jtag/drivers/stlink_usb.c | 2 +- src/jtag/drivers/ulink.c | 2 +- src/jtag/drivers/versaloon/versaloon.c | 2 +- src/jtag/drivers/versaloon/versaloon.h | 2 +- src/jtag/drivers/vsllink.c | 4 +- src/jtag/drivers/xds110.c | 10 +- src/target/image.c | 345 +++++++++++++++++++++++++++------ src/target/image.h | 18 +- 16 files changed, 389 insertions(+), 99 deletions(-) hooks/post-receive -- Main OpenOCD repository |