* elf.c (_bfd_elf_make_section_from_shdr): Don't set lma based on
p_paddr if p_paddr is zero. (make_mapping): Set includes_filehdr and includes_phdrs for first PT_LOAD segment. (map_sections_to_segments): Set includes_phdrs for PT_PHDR segment. (assign_file_positions_for_segments): Handle includes_filehdr and includes_phdrs. Remove special handling of PT_PHDR and first PT_LOAD segments. (copy_private_bfd_data): Set includes_filehdr and includes_phdr when appropriate. Remove special handling of PT_PHDR segment. Use a more complex condition for when a section is included in a segment to handle Solaris linker oddities.
This commit is contained in:
parent
638536a7ef
commit
6933148af0
|
@ -1,3 +1,19 @@
|
||||||
|
Thu Nov 30 16:48:18 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
|
||||||
|
* elf.c (_bfd_elf_make_section_from_shdr): Don't set lma based on
|
||||||
|
p_paddr if p_paddr is zero.
|
||||||
|
(make_mapping): Set includes_filehdr and includes_phdrs for first
|
||||||
|
PT_LOAD segment.
|
||||||
|
(map_sections_to_segments): Set includes_phdrs for PT_PHDR
|
||||||
|
segment.
|
||||||
|
(assign_file_positions_for_segments): Handle includes_filehdr and
|
||||||
|
includes_phdrs. Remove special handling of PT_PHDR and first
|
||||||
|
PT_LOAD segments.
|
||||||
|
(copy_private_bfd_data): Set includes_filehdr and includes_phdr
|
||||||
|
when appropriate. Remove special handling of PT_PHDR segment.
|
||||||
|
Use a more complex condition for when a section is included in a
|
||||||
|
segment to handle Solaris linker oddities.
|
||||||
|
|
||||||
Thu Nov 30 11:17:33 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
|
Thu Nov 30 11:17:33 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
|
||||||
|
|
||||||
* coff-m88k.c (howto_table): Reformatted for easier reading;
|
* coff-m88k.c (howto_table): Reformatted for easier reading;
|
||||||
|
|
168
bfd/elf.c
168
bfd/elf.c
|
@ -224,6 +224,7 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name)
|
||||||
for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
|
for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
|
||||||
{
|
{
|
||||||
if (phdr->p_type == PT_LOAD
|
if (phdr->p_type == PT_LOAD
|
||||||
|
&& phdr->p_paddr != 0
|
||||||
&& phdr->p_vaddr != phdr->p_paddr
|
&& phdr->p_vaddr != phdr->p_paddr
|
||||||
&& phdr->p_vaddr <= hdr->sh_addr
|
&& phdr->p_vaddr <= hdr->sh_addr
|
||||||
&& phdr->p_vaddr + phdr->p_memsz >= hdr->sh_addr + hdr->sh_size)
|
&& phdr->p_vaddr + phdr->p_memsz >= hdr->sh_addr + hdr->sh_size)
|
||||||
|
@ -1511,6 +1512,13 @@ make_mapping (abfd, sections, from, to)
|
||||||
m->sections[i - from] = *hdrpp;
|
m->sections[i - from] = *hdrpp;
|
||||||
m->count = to - from;
|
m->count = to - from;
|
||||||
|
|
||||||
|
if (from == 0)
|
||||||
|
{
|
||||||
|
/* Include the headers in the first PT_LOAD segment. */
|
||||||
|
m->includes_filehdr = 1;
|
||||||
|
m->includes_phdrs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1582,6 +1590,7 @@ map_sections_to_segments (abfd)
|
||||||
/* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not. */
|
/* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not. */
|
||||||
m->p_flags = PF_R | PF_X;
|
m->p_flags = PF_R | PF_X;
|
||||||
m->p_flags_valid = 1;
|
m->p_flags_valid = 1;
|
||||||
|
m->includes_phdrs = 1;
|
||||||
|
|
||||||
*pm = m;
|
*pm = m;
|
||||||
pm = &m->next;
|
pm = &m->next;
|
||||||
|
@ -1733,7 +1742,8 @@ assign_file_positions_for_segments (abfd)
|
||||||
unsigned int alloc;
|
unsigned int alloc;
|
||||||
Elf_Internal_Phdr *phdrs;
|
Elf_Internal_Phdr *phdrs;
|
||||||
file_ptr off;
|
file_ptr off;
|
||||||
boolean found_load;
|
bfd_vma filehdr_vaddr, filehdr_paddr;
|
||||||
|
bfd_vma phdrs_vaddr, phdrs_paddr;
|
||||||
Elf_Internal_Phdr *p;
|
Elf_Internal_Phdr *p;
|
||||||
|
|
||||||
if (elf_tdata (abfd)->segment_map == NULL)
|
if (elf_tdata (abfd)->segment_map == NULL)
|
||||||
|
@ -1782,7 +1792,10 @@ assign_file_positions_for_segments (abfd)
|
||||||
off = bed->s->sizeof_ehdr;
|
off = bed->s->sizeof_ehdr;
|
||||||
off += alloc * bed->s->sizeof_phdr;
|
off += alloc * bed->s->sizeof_phdr;
|
||||||
|
|
||||||
found_load = false;
|
filehdr_vaddr = 0;
|
||||||
|
filehdr_paddr = 0;
|
||||||
|
phdrs_vaddr = 0;
|
||||||
|
phdrs_paddr = 0;
|
||||||
for (m = elf_tdata (abfd)->segment_map, p = phdrs;
|
for (m = elf_tdata (abfd)->segment_map, p = phdrs;
|
||||||
m != NULL;
|
m != NULL;
|
||||||
m = m->next, p++)
|
m = m->next, p++)
|
||||||
|
@ -1817,53 +1830,70 @@ assign_file_positions_for_segments (abfd)
|
||||||
else
|
else
|
||||||
p->p_align = 0;
|
p->p_align = 0;
|
||||||
|
|
||||||
|
p->p_offset = 0;
|
||||||
p->p_filesz = 0;
|
p->p_filesz = 0;
|
||||||
p->p_memsz = 0;
|
p->p_memsz = 0;
|
||||||
|
|
||||||
if (p->p_type == PT_LOAD)
|
if (m->includes_filehdr)
|
||||||
{
|
|
||||||
p->p_offset = off;
|
|
||||||
|
|
||||||
if (! found_load)
|
|
||||||
{
|
|
||||||
struct elf_segment_map *mi;
|
|
||||||
Elf_Internal_Phdr *pi;
|
|
||||||
struct elf_segment_map *mi_phdr;
|
|
||||||
Elf_Internal_Phdr *pi_phdr;
|
|
||||||
|
|
||||||
/* This is the first PT_LOAD segment. If there is a
|
|
||||||
PT_INTERP segment, adjust the offset of this segment
|
|
||||||
to include the program headers and the file header. */
|
|
||||||
pi_phdr = NULL;
|
|
||||||
for (mi = elf_tdata (abfd)->segment_map, pi = phdrs;
|
|
||||||
mi != NULL;
|
|
||||||
mi = mi->next, pi++)
|
|
||||||
{
|
|
||||||
if (mi->p_type == PT_INTERP)
|
|
||||||
{
|
{
|
||||||
p->p_offset = 0;
|
p->p_offset = 0;
|
||||||
p->p_filesz = off;
|
p->p_filesz = bed->s->sizeof_ehdr;
|
||||||
p->p_memsz = off;
|
p->p_memsz = bed->s->sizeof_ehdr;
|
||||||
|
if (m->count > 0)
|
||||||
|
{
|
||||||
|
BFD_ASSERT (p->p_type == PT_LOAD);
|
||||||
p->p_vaddr -= off;
|
p->p_vaddr -= off;
|
||||||
if (! m->p_paddr_valid)
|
if (! m->p_paddr_valid)
|
||||||
p->p_paddr -= off;
|
p->p_paddr -= off;
|
||||||
}
|
}
|
||||||
if (mi->p_type == PT_PHDR)
|
if (p->p_type == PT_LOAD)
|
||||||
{
|
{
|
||||||
mi_phdr = mi;
|
filehdr_vaddr = p->p_vaddr;
|
||||||
pi_phdr = pi;
|
filehdr_paddr = p->p_paddr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the PT_PHDR addresses. */
|
if (m->includes_phdrs)
|
||||||
if (pi_phdr != NULL)
|
|
||||||
{
|
{
|
||||||
pi_phdr->p_vaddr = p->p_vaddr + bed->s->sizeof_ehdr;
|
if (m->includes_filehdr)
|
||||||
if (! mi_phdr->p_paddr_valid)
|
{
|
||||||
pi_phdr->p_paddr = p->p_paddr + bed->s->sizeof_ehdr;
|
if (p->p_type == PT_LOAD)
|
||||||
|
{
|
||||||
|
phdrs_vaddr = p->p_vaddr + bed->s->sizeof_ehdr;
|
||||||
|
phdrs_paddr = p->p_paddr + bed->s->sizeof_ehdr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->p_offset = bed->s->sizeof_ehdr;
|
||||||
|
if (m->count > 0)
|
||||||
|
{
|
||||||
|
BFD_ASSERT (p->p_type == PT_LOAD);
|
||||||
|
p->p_vaddr -= off - p->p_offset;
|
||||||
|
if (! m->p_paddr_valid)
|
||||||
|
p->p_paddr -= off - p->p_offset;
|
||||||
|
}
|
||||||
|
if (p->p_type == PT_LOAD)
|
||||||
|
{
|
||||||
|
phdrs_vaddr = p->p_vaddr;
|
||||||
|
phdrs_paddr = p->p_paddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->p_filesz += alloc * bed->s->sizeof_phdr;
|
||||||
|
p->p_memsz += alloc * bed->s->sizeof_phdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
found_load = true;
|
if (p->p_type == PT_LOAD)
|
||||||
|
{
|
||||||
|
if (! m->includes_filehdr && ! m->includes_phdrs)
|
||||||
|
p->p_offset = off;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file_ptr adjust;
|
||||||
|
|
||||||
|
adjust = off - (p->p_offset + p->p_filesz);
|
||||||
|
p->p_filesz += adjust;
|
||||||
|
p->p_memsz += adjust;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1927,12 +1957,24 @@ assign_file_positions_for_segments (abfd)
|
||||||
m = m->next, p++)
|
m = m->next, p++)
|
||||||
{
|
{
|
||||||
if (p->p_type != PT_LOAD && m->count > 0)
|
if (p->p_type != PT_LOAD && m->count > 0)
|
||||||
p->p_offset = m->sections[0]->filepos;
|
|
||||||
if (p->p_type == PT_PHDR)
|
|
||||||
{
|
{
|
||||||
p->p_offset = bed->s->sizeof_ehdr;
|
BFD_ASSERT (! m->includes_filehdr && ! m->includes_phdrs);
|
||||||
p->p_filesz = count * bed->s->sizeof_phdr;
|
p->p_offset = m->sections[0]->filepos;
|
||||||
p->p_memsz = p->p_filesz;
|
}
|
||||||
|
if (m->count == 0)
|
||||||
|
{
|
||||||
|
if (m->includes_filehdr)
|
||||||
|
{
|
||||||
|
p->p_vaddr = filehdr_vaddr;
|
||||||
|
if (! m->p_paddr_valid)
|
||||||
|
p->p_paddr = filehdr_paddr;
|
||||||
|
}
|
||||||
|
else if (m->includes_phdrs)
|
||||||
|
{
|
||||||
|
p->p_vaddr = phdrs_vaddr;
|
||||||
|
if (! m->p_paddr_valid)
|
||||||
|
p->p_paddr = phdrs_paddr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2418,6 +2460,7 @@ copy_private_bfd_data (ibfd, obfd)
|
||||||
bfd *ibfd;
|
bfd *ibfd;
|
||||||
bfd *obfd;
|
bfd *obfd;
|
||||||
{
|
{
|
||||||
|
Elf_Internal_Ehdr *iehdr;
|
||||||
struct elf_segment_map *mfirst;
|
struct elf_segment_map *mfirst;
|
||||||
struct elf_segment_map **pm;
|
struct elf_segment_map **pm;
|
||||||
Elf_Internal_Phdr *p;
|
Elf_Internal_Phdr *p;
|
||||||
|
@ -2430,26 +2473,36 @@ copy_private_bfd_data (ibfd, obfd)
|
||||||
if (elf_tdata (ibfd)->phdr == NULL)
|
if (elf_tdata (ibfd)->phdr == NULL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
iehdr = elf_elfheader (ibfd);
|
||||||
|
|
||||||
mfirst = NULL;
|
mfirst = NULL;
|
||||||
pm = &mfirst;
|
pm = &mfirst;
|
||||||
|
|
||||||
c = elf_elfheader (ibfd)->e_phnum;
|
c = elf_elfheader (ibfd)->e_phnum;
|
||||||
for (i = 0, p = elf_tdata (ibfd)->phdr; i < c; i++, p++)
|
for (i = 0, p = elf_tdata (ibfd)->phdr; i < c; i++, p++)
|
||||||
{
|
{
|
||||||
struct elf_segment_map *m;
|
|
||||||
unsigned int csecs;
|
unsigned int csecs;
|
||||||
|
asection *s;
|
||||||
|
struct elf_segment_map *m;
|
||||||
|
unsigned int isec;
|
||||||
|
|
||||||
csecs = 0;
|
csecs = 0;
|
||||||
if (p->p_type != PT_PHDR)
|
|
||||||
{
|
|
||||||
asection *s;
|
|
||||||
|
|
||||||
|
/* The complicated case when p_vaddr is 0 is to handle the
|
||||||
|
Solaris linker, which generates a PT_INTERP section with
|
||||||
|
p_vaddr and p_memsz set to 0. */
|
||||||
for (s = ibfd->sections; s != NULL; s = s->next)
|
for (s = ibfd->sections; s != NULL; s = s->next)
|
||||||
if (s->vma >= p->p_vaddr
|
if (((s->vma >= p->p_vaddr
|
||||||
&& s->vma + s->_raw_size <= p->p_vaddr + p->p_memsz
|
&& (s->vma + s->_raw_size <= p->p_vaddr + p->p_memsz
|
||||||
|
|| s->vma + s->_raw_size <= p->p_vaddr + p->p_filesz))
|
||||||
|
|| (p->p_vaddr == 0
|
||||||
|
&& p->p_filesz > 0
|
||||||
|
&& (s->flags & SEC_HAS_CONTENTS) != 0
|
||||||
|
&& (bfd_vma) s->filepos >= p->p_offset
|
||||||
|
&& ((bfd_vma) s->filepos + s->_raw_size
|
||||||
|
<= p->p_offset + p->p_filesz)))
|
||||||
&& s->output_section != NULL)
|
&& s->output_section != NULL)
|
||||||
++csecs;
|
++csecs;
|
||||||
}
|
|
||||||
|
|
||||||
m = ((struct elf_segment_map *)
|
m = ((struct elf_segment_map *)
|
||||||
bfd_alloc (obfd,
|
bfd_alloc (obfd,
|
||||||
|
@ -2465,26 +2518,37 @@ copy_private_bfd_data (ibfd, obfd)
|
||||||
m->p_paddr = p->p_paddr;
|
m->p_paddr = p->p_paddr;
|
||||||
m->p_paddr_valid = 1;
|
m->p_paddr_valid = 1;
|
||||||
|
|
||||||
if (p->p_type != PT_PHDR)
|
m->includes_filehdr = (p->p_offset == 0
|
||||||
{
|
&& p->p_filesz >= iehdr->e_ehsize);
|
||||||
asection *s;
|
|
||||||
unsigned int isec;
|
m->includes_phdrs = (p->p_offset <= (bfd_vma) iehdr->e_phoff
|
||||||
|
&& (p->p_offset + p->p_filesz
|
||||||
|
>= ((bfd_vma) iehdr->e_phoff
|
||||||
|
+ iehdr->e_phnum * iehdr->e_phentsize)));
|
||||||
|
|
||||||
isec = 0;
|
isec = 0;
|
||||||
for (s = ibfd->sections; s != NULL; s = s->next)
|
for (s = ibfd->sections; s != NULL; s = s->next)
|
||||||
{
|
{
|
||||||
if (s->vma >= p->p_vaddr
|
if (((s->vma >= p->p_vaddr
|
||||||
&& s->vma + s->_raw_size <= p->p_vaddr + p->p_memsz
|
&& (s->vma + s->_raw_size <= p->p_vaddr + p->p_memsz
|
||||||
|
|| s->vma + s->_raw_size <= p->p_vaddr + p->p_filesz))
|
||||||
|
|| (p->p_vaddr == 0
|
||||||
|
&& p->p_filesz > 0
|
||||||
|
&& (s->flags & SEC_HAS_CONTENTS) != 0
|
||||||
|
&& (bfd_vma) s->filepos >= p->p_offset
|
||||||
|
&& ((bfd_vma) s->filepos + s->_raw_size
|
||||||
|
<= p->p_offset + p->p_filesz)))
|
||||||
&& s->output_section != NULL)
|
&& s->output_section != NULL)
|
||||||
{
|
{
|
||||||
m->sections[isec] = s->output_section;
|
m->sections[isec] = s->output_section;
|
||||||
++isec;
|
++isec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BFD_ASSERT (isec == csecs);
|
||||||
|
if (csecs > 0)
|
||||||
qsort (m->sections, (size_t) csecs, sizeof (asection *),
|
qsort (m->sections, (size_t) csecs, sizeof (asection *),
|
||||||
elf_sort_sections);
|
elf_sort_sections);
|
||||||
m->count = csecs;
|
m->count = csecs;
|
||||||
}
|
|
||||||
|
|
||||||
*pm = m;
|
*pm = m;
|
||||||
pm = &m->next;
|
pm = &m->next;
|
||||||
|
|
Loading…
Reference in New Issue