From: Alan Modra <amodra@bigpond.net.au>
To: binutils@sourceware.org
Subject: phdr p_offset
Date: Fri, 21 Apr 2006 10:30:00 -0000 [thread overview]
Message-ID: <20060421072525.GQ27430@bubble.grove.modra.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 6783 bytes --]
Currently, non-loaded PT_NOTE program headers don't have their p_offset
set correctly, eg. the attached testcase shows
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00000034 0x00000034 0x00060 0x00060 R 0x4
LOAD 0x000000 0x00000000 0x00000000 0x00098 0x00098 R E 0x10000
NOTE 0x000000 0x00000098 0x00000098 0x00008 0x00000 R 0x1
This patch fixes the problem by assigning file positions for non-loaded
sections before we write out the program headers.
* elf.c (assign_file_positions_except_relocs): Move code setting
file position of non-loaded sections..
(assign_file_positions_for_segments): ..to here.
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.330
diff -u -p -r1.330 elf.c
--- bfd/elf.c 21 Apr 2006 03:42:47 -0000 1.330
+++ bfd/elf.c 21 Apr 2006 06:23:08 -0000
@@ -4119,6 +4119,10 @@ assign_file_positions_for_segments (bfd
bfd_vma filehdr_vaddr, filehdr_paddr;
bfd_vma phdrs_vaddr, phdrs_paddr;
Elf_Internal_Phdr *p;
+ Elf_Internal_Shdr **i_shdrpp;
+ Elf_Internal_Shdr **hdrpp;
+ unsigned int i;
+ unsigned int num_sec;
if (elf_tdata (abfd)->segment_map == NULL)
{
@@ -4136,7 +4140,6 @@ assign_file_positions_for_segments (bfd
m = m->next)
{
unsigned int new_count;
- unsigned int i;
new_count = 0;
for (i = 0; i < m->count; i ++)
@@ -4210,7 +4213,6 @@ assign_file_positions_for_segments (bfd
m != NULL;
m = m->next, p++)
{
- unsigned int i;
asection **secpp;
/* If elf_segment_map is not from map_sections_to_segments, the
@@ -4535,6 +4537,51 @@ assign_file_positions_for_segments (bfd
}
}
+ /* Assign file positions for the other sections. */
+ i_shdrpp = elf_elfsections (abfd);
+ num_sec = elf_numsections (abfd);
+ for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
+ {
+ struct elf_obj_tdata *tdata = elf_tdata (abfd);
+ Elf_Internal_Shdr *hdr;
+
+ hdr = *hdrpp;
+ if (hdr->bfd_section != NULL
+ && hdr->bfd_section->filepos != 0)
+ hdr->sh_offset = hdr->bfd_section->filepos;
+ else if ((hdr->sh_flags & SHF_ALLOC) != 0)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: warning: allocated section `%s' not in segment"),
+ abfd,
+ (hdr->bfd_section == NULL
+ ? "*unknown*"
+ : hdr->bfd_section->name)));
+ if ((abfd->flags & D_PAGED) != 0)
+ off += vma_page_aligned_bias (hdr->sh_addr, off,
+ bed->maxpagesize);
+ else
+ off += vma_page_aligned_bias (hdr->sh_addr, off,
+ hdr->sh_addralign);
+ off = _bfd_elf_assign_file_position_for_section (hdr, off,
+ FALSE);
+ }
+ else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
+ && hdr->bfd_section == NULL)
+ || hdr == i_shdrpp[tdata->symtab_section]
+ || hdr == i_shdrpp[tdata->symtab_shndx_section]
+ || hdr == i_shdrpp[tdata->strtab_section])
+ hdr->sh_offset = -1;
+ else
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
+
+ if (i == SHN_LORESERVE - 1)
+ {
+ i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ }
+ }
+
/* Now that we have set the section file positions, we can set up
the file positions for the non PT_LOAD segments. */
for (m = elf_tdata (abfd)->segment_map, p = phdrs;
@@ -4550,7 +4597,6 @@ assign_file_positions_for_segments (bfd
PT_LOAD segment, so it will not be processed above. */
if (p->p_type == PT_DYNAMIC && m->sections[0]->filepos == 0)
{
- unsigned int i;
Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
i = 1;
@@ -4753,16 +4799,16 @@ static bfd_boolean
assign_file_positions_except_relocs (bfd *abfd,
struct bfd_link_info *link_info)
{
- struct elf_obj_tdata * const tdata = elf_tdata (abfd);
- Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd);
- Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
- unsigned int num_sec = elf_numsections (abfd);
+ struct elf_obj_tdata *tdata = elf_tdata (abfd);
+ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
file_ptr off;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
&& bfd_get_format (abfd) != bfd_core)
{
+ Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
+ unsigned int num_sec = elf_numsections (abfd);
Elf_Internal_Shdr **hdrpp;
unsigned int i;
@@ -4797,57 +4843,12 @@ assign_file_positions_except_relocs (bfd
}
else
{
- unsigned int i;
- Elf_Internal_Shdr **hdrpp;
-
/* Assign file positions for the loaded sections based on the
assignment of sections to segments. */
if (! assign_file_positions_for_segments (abfd, link_info))
return FALSE;
- /* Assign file positions for the other sections. */
-
- off = elf_tdata (abfd)->next_file_pos;
- for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
- {
- Elf_Internal_Shdr *hdr;
-
- hdr = *hdrpp;
- if (hdr->bfd_section != NULL
- && hdr->bfd_section->filepos != 0)
- hdr->sh_offset = hdr->bfd_section->filepos;
- else if ((hdr->sh_flags & SHF_ALLOC) != 0)
- {
- ((*_bfd_error_handler)
- (_("%B: warning: allocated section `%s' not in segment"),
- abfd,
- (hdr->bfd_section == NULL
- ? "*unknown*"
- : hdr->bfd_section->name)));
- if ((abfd->flags & D_PAGED) != 0)
- off += vma_page_aligned_bias (hdr->sh_addr, off,
- bed->maxpagesize);
- else
- off += vma_page_aligned_bias (hdr->sh_addr, off,
- hdr->sh_addralign);
- off = _bfd_elf_assign_file_position_for_section (hdr, off,
- FALSE);
- }
- else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
- && hdr->bfd_section == NULL)
- || hdr == i_shdrpp[tdata->symtab_section]
- || hdr == i_shdrpp[tdata->symtab_shndx_section]
- || hdr == i_shdrpp[tdata->strtab_section])
- hdr->sh_offset = -1;
- else
- off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
-
- if (i == SHN_LORESERVE - 1)
- {
- i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
- hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
- }
- }
+ off = tdata->next_file_pos;
}
/* Place the section headers. */
@@ -4855,7 +4856,7 @@ assign_file_positions_except_relocs (bfd
i_ehdrp->e_shoff = off;
off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
- elf_tdata (abfd)->next_file_pos = off;
+ tdata->next_file_pos = off;
return TRUE;
}
--
Alan Modra
IBM OzLabs - Linux Technology Centre
[-- Attachment #2: note.s --]
[-- Type: text/plain, Size: 52 bytes --]
.text
nop
.section .note.alan
.long 2
.long 1
[-- Attachment #3: note.lnk --]
[-- Type: text/plain, Size: 183 bytes --]
PHDRS
{
headers PT_PHDR PHDRS ;
text PT_LOAD FILEHDR PHDRS ;
note PT_NOTE ;
}
SECTIONS
{
. = . + SIZEOF_HEADERS;
.text : { *(.text) } :text
.note : { *(.note*) } :note
}
next reply other threads:[~2006-04-21 7:25 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-21 10:30 Alan Modra [this message]
2006-04-28 0:03 ` Ben Elliston
2006-04-28 4:06 ` Alan Modra
2006-04-28 10:37 ` Daniel Jacobowitz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060421072525.GQ27430@bubble.grove.modra.org \
--to=amodra@bigpond.net.au \
--cc=binutils@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).