fix elf section padding

This commit is contained in:
Freya Murphy 2024-09-30 15:10:16 -04:00
parent 33138944c5
commit 6991a233ad
Signed by: freya
GPG key ID: 744AB800E383AE52
2 changed files with 33 additions and 20 deletions

View file

@ -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);

View file

@ -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;
}; };