ections into expected offset in binary format.

Calculate binary file offset using address field, bacause software know only offset to known data, not where to load segment.
With that patch, kernel .data section can have any alignment/offset - kernel boor fine.

PR:		235391
Reviewed by:	markj
MFC after:	1 month
Differential Revision:	D21827
This commit is contained in:
Aleksandr Rybalko 2019-09-29 22:34:01 +00:00
parent 4093e719b4
commit 0705bb9de5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=352875

View File

@ -49,22 +49,23 @@ create_binary(int ifd, int ofd)
Elf *e;
Elf_Scn *scn;
Elf_Data *d;
Elf64_Addr baseaddr;
GElf_Shdr sh;
off_t base, off;
off_t baseoff, off;
int elferr;
if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL)
errx(EXIT_FAILURE, "elf_begin() failed: %s",
elf_errmsg(-1));
base = 0;
if (lseek(ofd, base, SEEK_SET) < 0)
baseoff = 0;
if (lseek(ofd, baseoff, SEEK_SET) < 0)
err(EXIT_FAILURE, "lseek failed");
/*
* Find base offset in the first iteration.
*/
base = -1;
baseoff = -1;
scn = NULL;
while ((scn = elf_nextscn(e, scn)) != NULL) {
if (gelf_getshdr(scn, &sh) == NULL) {
@ -76,14 +77,16 @@ create_binary(int ifd, int ofd)
sh.sh_type == SHT_NOBITS ||
sh.sh_size == 0)
continue;
if (base == -1 || (off_t) sh.sh_offset < base)
base = sh.sh_offset;
if (baseoff == -1 || (off_t) sh.sh_offset < baseoff) {
baseoff = sh.sh_offset;
baseaddr = sh.sh_addr;
}
}
elferr = elf_errno();
if (elferr != 0)
warnx("elf_nextscn failed: %s", elf_errmsg(elferr));
if (base == -1)
if (baseoff == -1)
return;
/*
@ -110,8 +113,8 @@ create_binary(int ifd, int ofd)
if (d->d_buf == NULL || d->d_size == 0)
continue;
/* lseek to section offset relative to `base'. */
off = sh.sh_offset - base;
/* lseek to section offset relative to `baseaddr'. */
off = sh.sh_addr - baseaddr;
if (lseek(ofd, off, SEEK_SET) < 0)
err(EXIT_FAILURE, "lseek failed");