return idx;
}
+static inline bfd_vma
+segment_size (Elf_Internal_Phdr *segment)
+{
+ return (segment->p_memsz > segment->p_filesz
+ ? segment->p_memsz : segment->p_filesz);
+}
+
+
+/* Returns the end address of the segment + 1. */
+static inline bfd_vma
+segment_end (Elf_Internal_Phdr *segment, bfd_vma start)
+{
+ return start + segment_size (segment);
+}
+
+static inline bfd_size_type
+section_size (asection *section, Elf_Internal_Phdr *segment)
+{
+ if ((section->flags & SEC_HAS_CONTENTS) != 0
+ || (section->flags & SEC_THREAD_LOCAL) == 0
+ || segment->p_type == PT_TLS)
+ return section->size;
+ return 0;
+}
+
+/* Returns TRUE if the given section is contained within the given
+ segment. LMA addresses are compared against PADDR when
+ bed->want_p_paddr_set_to_zero is false, VMA against VADDR when true. */
+static bool
+is_contained_by (asection *section, Elf_Internal_Phdr *segment,
+ bfd_vma paddr, bfd_vma vaddr, unsigned int opb,
+ const struct elf_backend_data *bed)
+{
+ bfd_vma seg_addr = !bed->want_p_paddr_set_to_zero ? paddr : vaddr;
+ bfd_vma addr = !bed->want_p_paddr_set_to_zero ? section->lma : section->vma;
+ bfd_vma octet;
+ if (_bfd_mul_overflow (addr, opb, &octet))
+ return false;
+ /* The third and fourth lines below are testing that the section end
+ address is within the segment. It's written this way to avoid
+ overflow. Add seg_addr + section_size to both sides of the
+ inequality to make it obvious. */
+ return (octet >= seg_addr
+ && segment_size (segment) >= section_size (section, segment)
+ && (octet - seg_addr
+ <= segment_size (segment) - section_size (section, segment)));
+}
+
+/* Handle PT_NOTE segment. */
+static bool
+is_note (Elf_Internal_Phdr *p, asection *s)
+{
+ return (p->p_type == PT_NOTE
+ && elf_section_type (s) == SHT_NOTE
+ && (ufile_ptr) s->filepos >= p->p_offset
+ && p->p_filesz >= s->size
+ && ((ufile_ptr) s->filepos - p->p_offset
+ <= p->p_filesz - s->size));
+}
+
/* Rewrite program header information. */
static bool
num_segments = elf_elfheader (ibfd)->e_phnum;
- /* Returns the end address of the segment + 1. */
-#define SEGMENT_END(segment, start) \
- (start + (segment->p_memsz > segment->p_filesz \
- ? segment->p_memsz : segment->p_filesz))
-
-#define SECTION_SIZE(section, segment) \
- (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) \
- != SEC_THREAD_LOCAL || segment->p_type == PT_TLS) \
- ? section->size : 0)
-
- /* Returns TRUE if the given section is contained within
- the given segment. VMA addresses are compared. */
-#define IS_CONTAINED_BY_VMA(section, segment, opb) \
- (section->vma * (opb) >= segment->p_vaddr \
- && (section->vma * (opb) + SECTION_SIZE (section, segment) \
- <= (SEGMENT_END (segment, segment->p_vaddr))))
-
- /* Returns TRUE if the given section is contained within
- the given segment. LMA addresses are compared. */
-#define IS_CONTAINED_BY_LMA(section, segment, base, opb) \
- (section->lma * (opb) >= base \
- && (section->lma + SECTION_SIZE (section, segment) / (opb) >= section->lma) \
- && (section->lma * (opb) + SECTION_SIZE (section, segment) \
- <= SEGMENT_END (segment, base)))
-
- /* Handle PT_NOTE segment. */
-#define IS_NOTE(p, s) \
- (p->p_type == PT_NOTE \
- && elf_section_type (s) == SHT_NOTE \
- && (bfd_vma) s->filepos >= p->p_offset \
- && ((bfd_vma) s->filepos + s->size \
- <= p->p_offset + p->p_filesz))
-
- /* Special case: corefile "NOTE" section containing regs, prpsinfo
- etc. */
-#define IS_COREFILE_NOTE(p, s) \
- (IS_NOTE (p, s) \
- && bfd_get_format (ibfd) == bfd_core \
- && s->vma == 0 \
- && s->lma == 0)
-
/* 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. */
8. PT_DYNAMIC should not contain empty sections at the beginning
(with the possible exception of .dynamic). */
#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed, opb) \
- ((((segment->p_paddr \
- ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr, opb) \
- : IS_CONTAINED_BY_VMA (section, segment, opb)) \
+ (((is_contained_by (section, segment, segment->p_paddr, \
+ segment->p_vaddr, opb, bed) \
&& (section->flags & SEC_ALLOC) != 0) \
- || IS_NOTE (segment, section)) \
+ || is_note (segment, section)) \
&& segment->p_type != PT_GNU_STACK \
&& (segment->p_type != PT_TLS \
|| (section->flags & SEC_THREAD_LOCAL)) \
|| segment->p_type == PT_TLS \
|| (section->flags & SEC_THREAD_LOCAL) == 0) \
&& (segment->p_type != PT_DYNAMIC \
- || SECTION_SIZE (section, segment) > 0 \
+ || section_size (section, segment) > 0 \
|| (segment->p_paddr \
? segment->p_paddr != section->lma * (opb) \
: segment->p_vaddr != section->vma * (opb)) \
/* Returns TRUE iff seg1 starts after the end of seg2. */
#define SEGMENT_AFTER_SEGMENT(seg1, seg2, field) \
- (seg1->field >= SEGMENT_END (seg2, seg2->field))
+ (seg1->field >= segment_end (seg2, seg2->field))
/* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both
their VMA address ranges and their LMA address ranges overlap.
{
/* Extend SEGMENT2 to include SEGMENT and then delete
SEGMENT. */
- extra_length = (SEGMENT_END (segment, segment->p_vaddr)
- - SEGMENT_END (segment2, segment2->p_vaddr));
+ extra_length = (segment_end (segment, segment->p_vaddr)
+ - segment_end (segment2, segment2->p_vaddr));
if (extra_length > 0)
{
{
/* Extend SEGMENT to include SEGMENT2 and then delete
SEGMENT2. */
- extra_length = (SEGMENT_END (segment2, segment2->p_vaddr)
- - SEGMENT_END (segment, segment->p_vaddr));
+ extra_length = (segment_end (segment2, segment2->p_vaddr)
+ - segment_end (segment, segment->p_vaddr));
if (extra_length > 0)
{
/* Match up the physical address of the segment with the
LMA address of the output section. */
- if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr,
- opb)
- || IS_COREFILE_NOTE (segment, section)
- || (bed->want_p_paddr_set_to_zero
- && IS_CONTAINED_BY_VMA (output_section, segment, opb)))
+ if (is_contained_by (output_section, segment, map->p_paddr,
+ map->p_paddr + map->p_vaddr_offset, opb, bed)
+ || is_note (segment, section))
{
if (matching_lma == NULL
|| output_section->lma < matching_lma->lma)
BFD_ASSERT (output_section != NULL);
- if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr,
- opb)
- || IS_COREFILE_NOTE (segment, section))
+ if (is_contained_by (output_section, segment, map->p_paddr,
+ map->p_paddr + map->p_vaddr_offset, opb, bed)
+ || is_note (segment, section))
{
if (map->count == 0)
{
}
}
-#undef SEGMENT_END
-#undef SECTION_SIZE
-#undef IS_CONTAINED_BY_VMA
-#undef IS_CONTAINED_BY_LMA
-#undef IS_NOTE
-#undef IS_COREFILE_NOTE
#undef IS_SOLARIS_PT_INTERP
#undef IS_SECTION_IN_INPUT_SEGMENT
#undef INCLUDE_SECTION_IN_SEGMENT