scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit b78e49f2a0bb8bc975ed436410ecca6b7abd819d
parent 1c65e2d45bdf3bfea3766c2122b4c187fb717e4d
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 18 Jan 2025 20:11:56 +0100

libmach: Add offset and load to Section

The load address in the address where the section is going
to be loaded that can be different to the base address where
the relocations are performed. In any UNIX system both addresses
are going to have the same value, but it could be different in
other systems.

In the case of coff the physical address is used as load address
as it does not have any other meaning in UNIX systems.

While elf support also virtual and physical addresses, it only
supports it for segments, and the current implementation of
getsec for elf only deals with sections.

Diffstat:
Minclude/bits/scc/mach.h | 2++
Msrc/libmach/coff32/coff32getsec.c | 2++
Msrc/libmach/coff32/coff32setsec.c | 10+++++++++-
Msrc/libmach/elf64/elf64getsec.c | 7+++++++
4 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/include/bits/scc/mach.h b/include/bits/scc/mach.h @@ -94,7 +94,9 @@ struct segment { struct section { char *name; unsigned long long base; + unsigned long long load; unsigned long long size; + unsigned long long offset; unsigned flags; int index; diff --git a/src/libmach/coff32/coff32getsec.c b/src/libmach/coff32/coff32getsec.c @@ -83,6 +83,8 @@ coff32getsec(Obj *obj, int *idx, Section *sec) sec->index = n; sec->size = scn->s_size; sec->base = scn->s_vaddr; + sec->load = scn->s_paddr; + sec->offset = scn->s_scnptr; sec->type = type; sec->flags = sflags; sec->align = 16; diff --git a/src/libmach/coff32/coff32setsec.c b/src/libmach/coff32/coff32setsec.c @@ -93,7 +93,15 @@ coff32setsec(Obj *obj, int *idx, Section *sec) if (!secname(coff, scn, sec)) return NULL; - scn->s_paddr = 0; + /* + * sec->offset is ignored because it is very unlikely + * that the vaule is meaningful here. The field offset + * was added only to allow getsec to retrive the information + * in a generic way, but it was never expected to be a 2 way + * relation. That pointer is updated when the object file + * is written using a mapping. + */ + scn->s_paddr = sec->load; scn->s_vaddr = sec->base; scn->s_size = sec->size; scn->s_scnptr = 0; diff --git a/src/libmach/elf64/elf64getsec.c b/src/libmach/elf64/elf64getsec.c @@ -45,10 +45,17 @@ elf64getsec(Obj *obj, int *idx, Section *sec) if (stype == 'T' || stype == 'D') sflags |= SRELOC; + /* + * We cannot differentiate between load and base address + * in a section, while we can use the physical address + * for that when dealing with segments. + */ sec->name = elf64str(obj, SEC_STRTBL, shdr->sh_name); sec->index = n; sec->size = shdr->sh_size; sec->base = shdr->sh_addr; + sec->load = shdr->sh_addr; + sec->offset = shdr->sh_offset; sec->type = stype; sec->flags = sflags; sec->align = shdr->sh_addralign;