Page MenuHomeFreeBSD

rtld: Compute obj->maxsize for obj_rtld
ClosedPublic

Authored by jhb on Aug 19 2025, 9:09 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Oct 12, 12:42 PM
Unknown Object (File)
Sat, Oct 11, 10:26 PM
Unknown Object (File)
Sat, Oct 11, 10:26 PM
Unknown Object (File)
Sat, Oct 11, 10:26 PM
Unknown Object (File)
Sat, Oct 11, 4:57 AM
Unknown Object (File)
Fri, Oct 10, 9:47 PM
Unknown Object (File)
Wed, Oct 8, 8:42 PM
Unknown Object (File)
Fri, Oct 3, 2:14 AM
Subscribers

Details

Summary

Compute this while parsing the program headers in parse_rtld_phdr().

Obtained from: CheriBSD
Sponsored by: AFRL, DARPA

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

jhb requested review of this revision.Aug 19 2025, 9:09 PM

It is slightly weird because you do assume that linker orders the PT_LOAD segments by vaddr, but you use it only for vaddrbase. For mapsize you use MAX() instead.

This revision is now accepted and ready to land.Aug 19 2025, 9:35 PM
In D52033#1188685, @kib wrote:

It is slightly weird because you do assume that linker orders the PT_LOAD segments by vaddr, but you use it only for vaddrbase. For mapsize you use MAX() instead.

Hmm, it is true that for obj_main we do assume they are sorted, but in map_object we don't assume sorting:

obj_main:

		case PT_LOAD:
			if (nsegs == 0) { /* First load segment */
				obj->vaddrbase = rtld_trunc_page(ph->p_vaddr);
				obj->mapbase = obj->vaddrbase + obj->relocbase;
			} else { /* Last load segment */
				obj->mapsize = rtld_round_page(
				    ph->p_vaddr + ph->p_memsz) -
				    obj->vaddrbase;
			}
			nsegs++;
			break;

map_object:

		case PT_LOAD:
			segs[++nsegs] = phdr;
			if ((segs[nsegs]->p_align & (page_size - 1)) != 0) {
				_rtld_error(
				    "%s: PT_LOAD segment %d not page-aligned",
				    path, nsegs);
				goto error;
			}
			if ((segs[nsegs]->p_flags & PF_X) == PF_X) {
				text_end = MAX(text_end,
				    rtld_round_page(segs[nsegs]->p_vaddr +
				    segs[nsegs]->p_memsz));
			}
			break;

Though I guess we do kind of assume sorting in map_object as well:

	base_vaddr = rtld_trunc_page(segs[0]->p_vaddr);
	base_vlimit = rtld_round_page(segs[nsegs]->p_vaddr +
	    segs[nsegs]->p_memsz);

I wonder if we could remove the MAX from the PF_X check in map_object then. I'm fine with removing the sorting to match obj_main if you prefer that.

The PF_X and text_end bit of code would also be easier to read if we just used phdr directly instead of segs[nsegs].

I think it is best to remove the MAX() from both places. We might add a check that segments are ordered.

If you prefer not to touch map_object, I can do this after your commit, and also will add the check.

This revision now requires review to proceed.Aug 21 2025, 3:26 PM
This revision is now accepted and ready to land.Aug 21 2025, 5:21 PM
This revision was automatically updated to reflect the committed changes.