fix elf section padding
This commit is contained in:
parent
33138944c5
commit
6991a233ad
2 changed files with 33 additions and 20 deletions
46
mld/link.c
46
mld/link.c
|
@ -125,6 +125,17 @@ static int relocate_segment_name(struct linker *linker, const char *name)
|
||||||
if (segtab_ent_push(ent, seg))
|
if (segtab_ent_push(ent, seg))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
} else {
|
} else {
|
||||||
|
// update vaddr to be page aligned
|
||||||
|
uint32_t m = seg->new_vaddr % SEC_ALIGN;
|
||||||
|
if (m) {
|
||||||
|
uint32_t add = SEC_ALIGN - m;
|
||||||
|
seg->new_vaddr += add;
|
||||||
|
if (B32(seg->phdr->p_flags) & PF_X)
|
||||||
|
linker->text_vaddr += add;
|
||||||
|
else
|
||||||
|
linker->data_vaddr += add;
|
||||||
|
}
|
||||||
|
|
||||||
// else create a new segment
|
// else create a new segment
|
||||||
if (segtab_push(&linker->segments, NULL, seg))
|
if (segtab_push(&linker->segments, NULL, seg))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -536,19 +547,21 @@ static void update_offsets(struct linker *linker)
|
||||||
linker->ehdr.e_phoff = B32(ptr);
|
linker->ehdr.e_phoff = B32(ptr);
|
||||||
ptr += linker->phdr_len * sizeof(Elf32_Phdr);
|
ptr += linker->phdr_len * sizeof(Elf32_Phdr);
|
||||||
|
|
||||||
// section padding
|
|
||||||
{
|
|
||||||
uint32_t mod = ptr % SEC_ALIGN;
|
|
||||||
if (mod != 0)
|
|
||||||
linker->secalign = (SEC_ALIGN - mod);
|
|
||||||
else
|
|
||||||
linker->secalign = 0;
|
|
||||||
ptr += linker->secalign;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sections
|
// sections
|
||||||
for (uint32_t i = 0; i < linker->segments.len; i++) {
|
for (uint32_t i = 0; i < linker->segments.len; i++) {
|
||||||
struct segment_table_entry *ent = &linker->segments.entries[i];
|
struct segment_table_entry *ent = &linker->segments.entries[i];
|
||||||
|
|
||||||
|
// section padding
|
||||||
|
{
|
||||||
|
uint32_t m = ptr % SEC_ALIGN;
|
||||||
|
if (m) {
|
||||||
|
uint32_t add = SEC_ALIGN - m;
|
||||||
|
ptr += add;
|
||||||
|
ent->off = ptr;
|
||||||
|
ent->padding = add;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t idx = i + 1;
|
uint32_t idx = i + 1;
|
||||||
uint32_t size = segtab_ent_size(ent);
|
uint32_t size = segtab_ent_size(ent);
|
||||||
linker->phdr[i].p_offset = B32(ptr);
|
linker->phdr[i].p_offset = B32(ptr);
|
||||||
|
@ -604,15 +617,16 @@ static int write_file(struct linker *linker)
|
||||||
// phdr
|
// phdr
|
||||||
res |= fwrite(linker->phdr, sizeof(Elf32_Phdr), linker->phdr_len, out);
|
res |= fwrite(linker->phdr, sizeof(Elf32_Phdr), linker->phdr_len, out);
|
||||||
|
|
||||||
// section padding
|
|
||||||
for (uint32_t i = 0; i < linker->secalign; i++) {
|
|
||||||
uint8_t zero = 0;
|
|
||||||
res |= fwrite(&zero, 1, 1, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
// sections
|
// sections
|
||||||
for (uint32_t i = 0; i < linker->segments.len; i++) {
|
for (uint32_t i = 0; i < linker->segments.len; i++) {
|
||||||
struct segment_table_entry *ent = &linker->segments.entries[i];
|
struct segment_table_entry *ent = &linker->segments.entries[i];
|
||||||
|
// section padding
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < ent->padding; i++) {
|
||||||
|
uint8_t zero = 0;
|
||||||
|
res |= fwrite(&zero, 1, 1, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (uint32_t j = 0; j < ent->len; j++) {
|
for (uint32_t j = 0; j < ent->len; j++) {
|
||||||
struct segment *seg = ent->parts[j];
|
struct segment *seg = ent->parts[j];
|
||||||
res |= fwrite(seg->bytes, 1, seg->size, out);
|
res |= fwrite(seg->bytes, 1, seg->size, out);
|
||||||
|
|
|
@ -170,6 +170,8 @@ struct segment_table_entry {
|
||||||
uint32_t vaddr;
|
uint32_t vaddr;
|
||||||
// weak segment pointers. we do not own these!!!
|
// weak segment pointers. we do not own these!!!
|
||||||
struct segment **parts;
|
struct segment **parts;
|
||||||
|
// section padding
|
||||||
|
uint32_t padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
int segtab_ent_init(struct segment_table_entry *ent);
|
int segtab_ent_init(struct segment_table_entry *ent);
|
||||||
|
@ -273,9 +275,6 @@ struct linker {
|
||||||
uint32_t strtab_shidx;
|
uint32_t strtab_shidx;
|
||||||
uint32_t shstrtab_shidx;
|
uint32_t shstrtab_shidx;
|
||||||
|
|
||||||
// section alignment after phdr bytes
|
|
||||||
uint32_t secalign;
|
|
||||||
|
|
||||||
// all segments
|
// all segments
|
||||||
struct segment_table segments;
|
struct segment_table segments;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue