* fileio.c (elf_get_scn): Rather than trying to just match whether
any given section maps straight to a program header segment, use a more sophisticated decision that matches any section as long as it fits into the segment. This is needed for situations where the program header segment spans a larger area than the section data provided. (This can e.g. happen in an ELF file that contains no data at address 0, like a bootloader only.) git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1079 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
3a4b48b583
commit
f8e99df355
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2012-04-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (elf_get_scn): Rather than trying to just match whether
|
||||
any given section maps straight to a program header segment, use a
|
||||
more sophisticated decision that matches any section as long as it
|
||||
fits into the segment. This is needed for situations where the
|
||||
program header segment spans a larger area than the section data
|
||||
provided. (This can e.g. happen in an ELF file that contains no
|
||||
data at address 0, like a bootloader only.)
|
||||
|
||||
2012-04-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28744: Can't load bootloader to xmega128a1 (part 2, fix for
|
||||
|
|
28
fileio.c
28
fileio.c
|
@ -687,6 +687,28 @@ static int srec2b(char * infile, FILE * inf,
|
|||
}
|
||||
|
||||
#ifdef HAVE_LIBELF
|
||||
/*
|
||||
* Determine whether the ELF file section pointed to by `sh' fits
|
||||
* completely into the program header segment pointed to by `ph'.
|
||||
*
|
||||
* Assumes the section has been checked already before to actually
|
||||
* contain data (SHF_ALLOC, SHT_PROGBITS, sh_size > 0).
|
||||
*
|
||||
* Sometimes, program header segments might be larger than the actual
|
||||
* file sections. On VM architectures, this is used to allow mmapping
|
||||
* the entire ELF file "as is" (including things like the program
|
||||
* header table itself).
|
||||
*/
|
||||
static inline
|
||||
int is_section_in_segment(Elf32_Shdr *sh, Elf32_Phdr *ph)
|
||||
{
|
||||
if (sh->sh_offset < ph->p_offset)
|
||||
return 0;
|
||||
if (sh->sh_offset + sh->sh_size > ph->p_offset + ph->p_filesz)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the ELF section descriptor that corresponds to program
|
||||
* header `ph'. The program header is expected to be of p_type
|
||||
|
@ -711,8 +733,10 @@ static Elf_Scn *elf_get_scn(Elf *e, Elf32_Phdr *ph, Elf32_Shdr **shptr)
|
|||
sh->sh_type != SHT_PROGBITS)
|
||||
/* we are only interested in PROGBITS, ALLOC sections */
|
||||
continue;
|
||||
if (ph->p_vaddr == sh->sh_addr &&
|
||||
ph->p_offset == sh->sh_offset) {
|
||||
if (sh->sh_size == 0)
|
||||
/* we are not interested in empty sections */
|
||||
continue;
|
||||
if (is_section_in_segment(sh, ph)) {
|
||||
/* yeah, we found it */
|
||||
*shptr = sh;
|
||||
return s;
|
||||
|
|
Loading…
Reference in New Issue